🎉 Give unique names to objects when pasting

This commit is contained in:
Andrés Moya 2020-03-30 16:15:09 +02:00
parent 83a02ad6e6
commit 82c264b75f

View file

@ -930,26 +930,34 @@
;; --- Add shape to Workspace ;; --- Add shape to Workspace
(defn impl-retrieve-used-names (defn impl-retrieve-used-names
"Returns a set of already used names by shapes [objects]
in the current workspace page." (into #{} (map :name) (vals objects)))
[state]
(let [page-id (::page-id state) (defn extract-numeric-suffix
objects (get-in state [:workspace-data page-id :objects])] [basename]
(into #{} (map :name) (vals objects)))) (let [result (re-find #"(.*)-([0-9]+)$" basename)]
(if result
[(get result 1) (+ 1 (js/parseInt (get result 2)))]
[basename 1])))
(defn impl-generate-unique-name (defn impl-generate-unique-name
"A unique name generator based on the current workspace page." "A unique name generator"
[state basename] [objects basename]
(let [used (impl-retrieve-used-names state)] (let [used (impl-retrieve-used-names objects)
(loop [counter 1] [prefix initial] (extract-numeric-suffix basename)]
(let [candidate (str basename "-" counter)] (loop [counter initial]
(let [candidate (str prefix "-" counter)]
(if (contains? used candidate) (if (contains? used candidate)
(recur (inc counter)) (recur (inc counter))
candidate))))) candidate)))))
(defn impl-assoc-shape (defn impl-assoc-shape
"Add a shape to the current workspace page, inside a given frame.
Give it a name that is unique in the page"
[state {:keys [id frame-id] :as data}] [state {:keys [id frame-id] :as data}]
(let [name (impl-generate-unique-name state (:name data)) (let [page-id (::page-id state)
objects (get-in state [:workspace-data page-id :objects])
name (impl-generate-unique-name objects (:name data))
shape (assoc data :name name) shape (assoc data :name name)
page-id (::page-id state)] page-id (::page-id state)]
(-> state (-> state
@ -2051,27 +2059,48 @@
(defn- paste-impl (defn- paste-impl
[{:keys [selected objects] :as data}] [{:keys [selected objects] :as data}]
(letfn [(prepare-change [delta id] (letfn [(prepare-changes [state delta]
"Prepare objects to paste: generate new id, give them unique names,
and move to the position of mouse pointer"
(let [page-id (::page-id state)]
(loop [existing-objs (get-in state [:workspace-data page-id :objects])
chgs []
id (first selected)
ids (rest selected)]
(if (nil? id)
chgs
(let [result (prepare-change id existing-objs delta)
result (if (vector? result) result [result])]
(recur
(reduce conj existing-objs (map (fn [item] {(:id item) (:obj item)}) result))
(into chgs result)
(first ids)
(rest ids)))))))
(prepare-change [id existing-objs delta]
(let [obj (get objects id)] (let [obj (get objects id)]
(if (= :frame (:type obj)) (if (= :frame (:type obj))
(prepare-frame-change obj delta) (prepare-frame-change existing-objs obj delta)
(prepare-shape-change obj delta uuid/zero)))) (prepare-shape-change existing-objs obj delta uuid/zero))))
(prepare-shape-change [obj delta frame-id] (prepare-shape-change [objects obj delta frame-id]
(let [id (uuid/next) (let [id (uuid/next)
renamed-obj (assoc obj :id id :frame-id frame-id) name (impl-generate-unique-name objects (:name obj))
renamed-obj (assoc obj :id id :frame-id frame-id :name name)
moved-obj (geom/move renamed-obj delta)] moved-obj (geom/move renamed-obj delta)]
{:type :add-obj {:type :add-obj
:id id :id id
:frame-id frame-id :frame-id frame-id
:obj moved-obj})) :obj moved-obj}))
(prepare-frame-change [obj delta] (prepare-frame-change [objects obj delta]
(let [frame-id (uuid/next) (let [frame-id (uuid/next)
frame-name (impl-generate-unique-name objects (:name obj))
sch (->> (map #(get objects %) (:shapes obj)) sch (->> (map #(get objects %) (:shapes obj))
(map #(prepare-shape-change % delta frame-id))) (map #(prepare-shape-change objects % delta frame-id)))
renamed-frame (-> obj renamed-frame (-> obj
(assoc :id frame-id) (assoc :id frame-id)
(assoc :name frame-name)
(assoc :frame-id uuid/zero) (assoc :frame-id uuid/zero)
(assoc :shapes (mapv :id sch))) (assoc :shapes (mapv :id sch)))
moved-frame (geom/move renamed-frame delta) moved-frame (geom/move renamed-frame delta)
@ -2090,8 +2119,7 @@
delta {:x (- (:x mouse-pos) (:x orig-pos)) delta {:x (- (:x mouse-pos) (:x orig-pos))
:y (- (:y mouse-pos) (:y orig-pos))} :y (- (:y mouse-pos) (:y orig-pos))}
rchanges (->> (map (partial prepare-change delta) selected) rchanges (prepare-changes state delta)
(flatten))
uchanges (map (fn [ch] uchanges (map (fn [ch]
{:type :del-obj {:type :del-obj
:id (:id ch)}) :id (:id ch)})