mirror of
https://github.com/penpot/penpot.git
synced 2025-02-13 18:48:37 -05:00
✨ Allows multiple selection and move
This commit is contained in:
parent
a06a8c648e
commit
c22b4a1de2
4 changed files with 72 additions and 56 deletions
|
@ -589,44 +589,43 @@
|
||||||
(= mode :draw) (rx/of :interrupt)
|
(= mode :draw) (rx/of :interrupt)
|
||||||
:else (rx/of (finish-path "changed-content")))))))
|
:else (rx/of (finish-path "changed-content")))))))
|
||||||
|
|
||||||
(defn move-path-point [start-point end-point]
|
(defn move-selected-path-point [from-point to-point]
|
||||||
(ptk/reify ::move-point
|
(letfn [(modify-content-point [content {dx :x dy :y} modifiers point]
|
||||||
ptk/UpdateEvent
|
(let [point-indices (ugp/point-indices content point) ;; [indices]
|
||||||
(update [_ state]
|
handler-indices (ugp/handler-indices content point) ;; [[index prefix]]
|
||||||
(let [id (get-path-id state)
|
|
||||||
content (get-in state (get-path state :content))
|
|
||||||
|
|
||||||
{dx :x dy :y} (gpt/subtract end-point start-point)
|
modify-point
|
||||||
|
(fn [modifiers index]
|
||||||
|
(-> modifiers
|
||||||
|
(update index assoc :x dx :y dy)))
|
||||||
|
|
||||||
handler-indices (-> (ugp/content->handlers content)
|
modify-handler
|
||||||
(get start-point))
|
(fn [modifiers [index prefix]]
|
||||||
|
(let [cx (d/prefix-keyword prefix :x)
|
||||||
|
cy (d/prefix-keyword prefix :y)]
|
||||||
|
(-> modifiers
|
||||||
|
(update index assoc cx dx cy dy))))]
|
||||||
|
|
||||||
command-for-point (fn [[index command]]
|
(as-> modifiers $
|
||||||
(let [point (ugp/command->point command)]
|
(reduce modify-point $ point-indices)
|
||||||
(= point start-point)))
|
(reduce modify-handler $ handler-indices))))]
|
||||||
|
|
||||||
point-indices (->> (d/enumerate content)
|
(ptk/reify ::move-point
|
||||||
(filter command-for-point)
|
ptk/UpdateEvent
|
||||||
(map first))
|
(update [_ state]
|
||||||
|
(let [id (get-path-id state)
|
||||||
|
content (get-in state (get-path state :content))
|
||||||
|
delta (gpt/subtract to-point from-point)
|
||||||
|
|
||||||
|
modifiers-reducer (partial modify-content-point content delta)
|
||||||
|
|
||||||
point-reducer (fn [modifiers index]
|
points (get-in state [:workspace-local :edit-path id :selected-points] #{})
|
||||||
(-> modifiers
|
|
||||||
(assoc-in [index :x] dx)
|
|
||||||
(assoc-in [index :y] dy)))
|
|
||||||
|
|
||||||
handler-reducer (fn [modifiers [index prefix]]
|
modifiers (get-in state [:workspace-local :edit-path id :content-modifiers] {})
|
||||||
(let [cx (d/prefix-keyword prefix :x)
|
modifiers (->> points
|
||||||
cy (d/prefix-keyword prefix :y)]
|
(reduce modifiers-reducer {}))]
|
||||||
(-> modifiers
|
|
||||||
(assoc-in [index cx] dx)
|
|
||||||
(assoc-in [index cy] dy))))
|
|
||||||
|
|
||||||
modifiers (as-> (get-in state [:workspace-local :edit-path id :content-modifiers] {}) $
|
(assoc-in state [:workspace-local :edit-path id :content-modifiers] modifiers))))))
|
||||||
(reduce point-reducer $ point-indices)
|
|
||||||
(reduce handler-reducer $ handler-indices))]
|
|
||||||
|
|
||||||
(assoc-in state [:workspace-local :edit-path id :content-modifiers] modifiers)))))
|
|
||||||
|
|
||||||
(defn start-move-path-point
|
(defn start-move-path-point
|
||||||
[position]
|
[position]
|
||||||
|
@ -641,7 +640,7 @@
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(->> ms/mouse-position
|
(->> ms/mouse-position
|
||||||
(rx/take-until stopper)
|
(rx/take-until stopper)
|
||||||
(rx/map #(move-path-point position %)))
|
(rx/map #(move-selected-path-point start-position %)))
|
||||||
(rx/of (apply-content-modifiers))))))))
|
(rx/of (apply-content-modifiers))))))))
|
||||||
|
|
||||||
(defn start-move-handler
|
(defn start-move-handler
|
||||||
|
|
|
@ -23,11 +23,11 @@
|
||||||
[:div.viewport-actions-entry {:class (when (= edit-mode :move) "is-toggled")
|
[:div.viewport-actions-entry {:class (when (= edit-mode :move) "is-toggled")
|
||||||
:on-click #(st/emit! (drp/change-edit-mode :move))} i/pointer-inner]]
|
:on-click #(st/emit! (drp/change-edit-mode :move))} i/pointer-inner]]
|
||||||
|
|
||||||
#_[:div.viewport-actions-group
|
[:div.viewport-actions-group
|
||||||
[:div.viewport-actions-entry {:class "is-disabled"} i/nodes-add]
|
[:div.viewport-actions-entry {:class "is-disabled"} i/nodes-add]
|
||||||
[:div.viewport-actions-entry {:class "is-disabled"} i/nodes-remove]]
|
[:div.viewport-actions-entry {:class "is-disabled"} i/nodes-remove]]
|
||||||
|
|
||||||
#_[:div.viewport-actions-group
|
[:div.viewport-actions-group
|
||||||
[:div.viewport-actions-entry {:class "is-disabled"} i/nodes-merge]
|
[:div.viewport-actions-entry {:class "is-disabled"} i/nodes-merge]
|
||||||
[:div.viewport-actions-entry {:class "is-disabled"} i/nodes-join]
|
[:div.viewport-actions-entry {:class "is-disabled"} i/nodes-join]
|
||||||
[:div.viewport-actions-entry {:class "is-disabled"} i/nodes-separate]]
|
[:div.viewport-actions-entry {:class "is-disabled"} i/nodes-separate]]
|
||||||
|
@ -40,5 +40,5 @@
|
||||||
:on-click #(when-not (empty? selected-points)
|
:on-click #(when-not (empty? selected-points)
|
||||||
(st/emit! (drp/make-curve)))} i/nodes-curve]]
|
(st/emit! (drp/make-curve)))} i/nodes-curve]]
|
||||||
|
|
||||||
#_[:div.viewport-actions-group
|
[:div.viewport-actions-group
|
||||||
[:div.viewport-actions-entry {:class (when snap-toggled "is-toggled")} i/nodes-snap]]]))
|
[:div.viewport-actions-entry {:class (when snap-toggled "is-toggled")} i/nodes-snap]]]))
|
||||||
|
|
|
@ -33,34 +33,32 @@
|
||||||
|
|
||||||
on-click
|
on-click
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(when-not last-p?
|
(dom/stop-propagation event)
|
||||||
(dom/stop-propagation event)
|
(dom/prevent-default event)
|
||||||
(dom/prevent-default event)
|
|
||||||
|
|
||||||
(let [shift? (kbd/shift? event)]
|
(let [shift? (kbd/shift? event)]
|
||||||
(cond
|
(cond
|
||||||
(and (= edit-mode :move) (not selected?))
|
(and (= edit-mode :move) (not selected?))
|
||||||
(st/emit! (drp/select-node position shift?))
|
(st/emit! (drp/select-node position shift?))
|
||||||
|
|
||||||
(and (= edit-mode :move) selected?)
|
(and (= edit-mode :move) selected?)
|
||||||
(st/emit! (drp/deselect-node position shift?))))))
|
(st/emit! (drp/deselect-node position shift?)))))
|
||||||
|
|
||||||
|
|
||||||
on-mouse-down
|
on-mouse-down
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(when-not last-p?
|
(dom/stop-propagation event)
|
||||||
(dom/stop-propagation event)
|
(dom/prevent-default event)
|
||||||
(dom/prevent-default event)
|
|
||||||
|
|
||||||
(cond
|
(cond
|
||||||
(= edit-mode :move)
|
(= edit-mode :move)
|
||||||
(st/emit! (drp/start-move-path-point position))
|
(st/emit! (drp/start-move-path-point position))
|
||||||
|
|
||||||
(and (= edit-mode :draw) start-path?)
|
(and (= edit-mode :draw) start-path?)
|
||||||
(st/emit! (drp/start-path-from-point position))
|
(st/emit! (drp/start-path-from-point position))
|
||||||
|
|
||||||
(and (= edit-mode :draw) (not start-path?))
|
(and (= edit-mode :draw) (not start-path?))
|
||||||
(st/emit! (drp/close-path-drag-start position)))))]
|
(st/emit! (drp/close-path-drag-start position))))]
|
||||||
|
|
||||||
[:g.path-point
|
[:g.path-point
|
||||||
[:circle.path-point
|
[:circle.path-point
|
||||||
|
@ -80,8 +78,9 @@
|
||||||
:on-mouse-down on-mouse-down
|
:on-mouse-down on-mouse-down
|
||||||
:on-mouse-enter on-enter
|
:on-mouse-enter on-enter
|
||||||
:on-mouse-leave on-leave
|
:on-mouse-leave on-leave
|
||||||
:style {:cursor (cond
|
:style {:pointer-events (when last-p? "none")
|
||||||
(and (not last-p?) (= edit-mode :draw)) cur/pen-node
|
:cursor (cond
|
||||||
|
(= edit-mode :draw) cur/pen-node
|
||||||
(= edit-mode :move) cur/pointer-node)
|
(= edit-mode :move) cur/pointer-node)
|
||||||
:fill "transparent"}}]]))
|
:fill "transparent"}}]]))
|
||||||
|
|
||||||
|
|
|
@ -468,7 +468,6 @@
|
||||||
[content]
|
[content]
|
||||||
(->> (d/with-prev content)
|
(->> (d/with-prev content)
|
||||||
(d/enumerate)
|
(d/enumerate)
|
||||||
|
|
||||||
(mapcat (fn [[index [cur-cmd pre-cmd]]]
|
(mapcat (fn [[index [cur-cmd pre-cmd]]]
|
||||||
(if (and pre-cmd (= :curve-to (:command cur-cmd)))
|
(if (and pre-cmd (= :curve-to (:command cur-cmd)))
|
||||||
(let [cur-pos (command->point cur-cmd)
|
(let [cur-pos (command->point cur-cmd)
|
||||||
|
@ -480,6 +479,25 @@
|
||||||
(group-by first)
|
(group-by first)
|
||||||
(d/mapm #(mapv second %2))))
|
(d/mapm #(mapv second %2))))
|
||||||
|
|
||||||
|
(defn point-indices
|
||||||
|
[content point]
|
||||||
|
(->> (d/enumerate content)
|
||||||
|
(filter (fn [[_ cmd]] (= point (command->point cmd))))
|
||||||
|
(mapv (fn [[index _]] index))))
|
||||||
|
|
||||||
|
(defn handler-indices
|
||||||
|
[content point]
|
||||||
|
(->> (d/with-prev content)
|
||||||
|
(d/enumerate)
|
||||||
|
(mapcat (fn [[index [cur-cmd pre-cmd]]]
|
||||||
|
(if (and (some? pre-cmd) (= :curve-to (:command cur-cmd)))
|
||||||
|
(let [cur-pos (command->point cur-cmd)
|
||||||
|
pre-pos (command->point pre-cmd)]
|
||||||
|
(cond-> []
|
||||||
|
(= pre-pos point) (conj [index :c1])
|
||||||
|
(= cur-pos point) (conj [index :c2])))
|
||||||
|
[])))))
|
||||||
|
|
||||||
(defn opposite-index
|
(defn opposite-index
|
||||||
"Calculate sthe opposite index given a prefix and an index"
|
"Calculate sthe opposite index given a prefix and an index"
|
||||||
[content index prefix]
|
[content index prefix]
|
||||||
|
|
Loading…
Add table
Reference in a new issue