0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-08 07:50:43 -05:00

🎉 Remember displacements when duplicating several shapes in a row

This commit is contained in:
Andrés Moya 2021-07-30 11:12:41 +02:00
parent 574387acac
commit 29cd8530a3
2 changed files with 56 additions and 5 deletions

View file

@ -9,6 +9,7 @@
- Use space + mouse drag to pan, instead of only space [Taiga #1800](https://tree.taiga.io/project/penpot/us/1800).
- Allow to zoom with ctrl + middle button [Taiga #1428](https://tree.taiga.io/project/penpot/us/1428).
- Auto placement of duplicated objects [Taiga #1386](https://tree.taiga.io/project/penpot/us/1386).
### :bug: Bugs fixed
### :arrow_up: Deps updates

View file

@ -383,6 +383,53 @@
(into [fch] sch)))
(defn clear-memorize-duplicated
[]
(ptk/reify ::clear-memorize-duplicated
ptk/UpdateEvent
(update [_ state]
(d/dissoc-in state [:workspace-local :duplicated]))))
(defn memorize-duplicated
"When duplicate an object, remember the operation during the following seconds.
If the user moves the duplicated object, and then duplicates it again, check
the displacement and apply it to the third copy. This is useful for doing
grids or cascades of cloned objects."
[id-original id-duplicated]
(ptk/reify ::memorize-duplicated
ptk/UpdateEvent
(update [_ state]
(assoc-in state [:workspace-local :duplicated] {:id-original id-original
:id-duplicated id-duplicated}))
ptk/WatchEvent
(watch [_ _ stream]
(let [stoper (rx/filter (ptk/type? ::memorize-duplicated) stream)]
(->> (rx/timer 10000) ;; This time may be adjusted after some user testing.
(rx/take-until stoper)
(rx/map clear-memorize-duplicated))))))
(defn calc-duplicate-delta
[obj state objects]
(let [{:keys [id-original id-duplicated]}
(get-in state [:workspace-local :duplicated])]
(if (and (not= id-original (:id obj))
(not= id-duplicated (:id obj)))
;; The default is leave normal shapes in place, but put
;; new frames to the right of the original.
(if (= (:type obj) :frame)
(gpt/point (+ (:width obj) 50) 0)
(gpt/point 0 0))
(let [obj-original (get objects id-original)
obj-duplicated (get objects id-duplicated)
distance (gpt/subtract (gpt/point obj-duplicated)
(gpt/point obj-original))
new-pos (gpt/add (gpt/point obj-duplicated) distance)
delta (gpt/subtract new-pos (gpt/point obj))]
delta))))
(def duplicate-selected
(ptk/reify ::duplicate-selected
ptk/WatchEvent
@ -392,9 +439,7 @@
selected (wsh/lookup-selected state)
delta (if (= (count selected) 1)
(let [obj (get objects (first selected))]
(if (= (:type obj) :frame)
(gpt/point (+ (:width obj) 50) 0)
(gpt/point 0 0)))
(calc-duplicate-delta obj state objects))
(gpt/point 0 0))
unames (dwc/retrieve-used-names objects)
@ -405,15 +450,20 @@
uchanges (mapv #(array-map :type :del-obj :page-id page-id :id (:id %))
(reverse rchanges))
id-original (when (= (count selected) 1) (first selected))
selected (->> rchanges
(filter #(selected (:old-id %)))
(map #(get-in % [:obj :id]))
(into (d/ordered-set)))]
(into (d/ordered-set)))
id-duplicated (when (= (count selected) 1) (first selected))]
(rx/of (dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it})
(select-shapes selected))))))
(select-shapes selected)
(memorize-duplicated id-original id-duplicated))))))
(defn change-hover-state
[id value]