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:
parent
574387acac
commit
29cd8530a3
2 changed files with 56 additions and 5 deletions
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
Loading…
Reference in a new issue