mirror of
https://github.com/penpot/penpot.git
synced 2025-02-10 00:58:26 -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)
|
||||
:else (rx/of (finish-path "changed-content")))))))
|
||||
|
||||
(defn move-path-point [start-point end-point]
|
||||
(ptk/reify ::move-point
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [id (get-path-id state)
|
||||
content (get-in state (get-path state :content))
|
||||
(defn move-selected-path-point [from-point to-point]
|
||||
(letfn [(modify-content-point [content {dx :x dy :y} modifiers point]
|
||||
(let [point-indices (ugp/point-indices content point) ;; [indices]
|
||||
handler-indices (ugp/handler-indices content point) ;; [[index prefix]]
|
||||
|
||||
{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)
|
||||
(get start-point))
|
||||
modify-handler
|
||||
(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]]
|
||||
(let [point (ugp/command->point command)]
|
||||
(= point start-point)))
|
||||
(as-> modifiers $
|
||||
(reduce modify-point $ point-indices)
|
||||
(reduce modify-handler $ handler-indices))))]
|
||||
|
||||
point-indices (->> (d/enumerate content)
|
||||
(filter command-for-point)
|
||||
(map first))
|
||||
(ptk/reify ::move-point
|
||||
ptk/UpdateEvent
|
||||
(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]
|
||||
(-> modifiers
|
||||
(assoc-in [index :x] dx)
|
||||
(assoc-in [index :y] dy)))
|
||||
points (get-in state [:workspace-local :edit-path id :selected-points] #{})
|
||||
|
||||
handler-reducer (fn [modifiers [index prefix]]
|
||||
(let [cx (d/prefix-keyword prefix :x)
|
||||
cy (d/prefix-keyword prefix :y)]
|
||||
(-> modifiers
|
||||
(assoc-in [index cx] dx)
|
||||
(assoc-in [index cy] dy))))
|
||||
modifiers (get-in state [:workspace-local :edit-path id :content-modifiers] {})
|
||||
modifiers (->> points
|
||||
(reduce modifiers-reducer {}))]
|
||||
|
||||
modifiers (as-> (get-in state [:workspace-local :edit-path id :content-modifiers] {}) $
|
||||
(reduce point-reducer $ point-indices)
|
||||
(reduce handler-reducer $ handler-indices))]
|
||||
|
||||
(assoc-in state [:workspace-local :edit-path id :content-modifiers] modifiers)))))
|
||||
(assoc-in state [:workspace-local :edit-path id :content-modifiers] modifiers))))))
|
||||
|
||||
(defn start-move-path-point
|
||||
[position]
|
||||
|
@ -641,7 +640,7 @@
|
|||
(rx/concat
|
||||
(->> ms/mouse-position
|
||||
(rx/take-until stopper)
|
||||
(rx/map #(move-path-point position %)))
|
||||
(rx/map #(move-selected-path-point start-position %)))
|
||||
(rx/of (apply-content-modifiers))))))))
|
||||
|
||||
(defn start-move-handler
|
||||
|
|
|
@ -23,11 +23,11 @@
|
|||
[:div.viewport-actions-entry {:class (when (= edit-mode :move) "is-toggled")
|
||||
: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-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-join]
|
||||
[:div.viewport-actions-entry {:class "is-disabled"} i/nodes-separate]]
|
||||
|
@ -40,5 +40,5 @@
|
|||
:on-click #(when-not (empty? selected-points)
|
||||
(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]]]))
|
||||
|
|
|
@ -33,34 +33,32 @@
|
|||
|
||||
on-click
|
||||
(fn [event]
|
||||
(when-not last-p?
|
||||
(dom/stop-propagation event)
|
||||
(dom/prevent-default event)
|
||||
(dom/stop-propagation event)
|
||||
(dom/prevent-default event)
|
||||
|
||||
(let [shift? (kbd/shift? event)]
|
||||
(cond
|
||||
(and (= edit-mode :move) (not selected?))
|
||||
(st/emit! (drp/select-node position shift?))
|
||||
(let [shift? (kbd/shift? event)]
|
||||
(cond
|
||||
(and (= edit-mode :move) (not selected?))
|
||||
(st/emit! (drp/select-node position shift?))
|
||||
|
||||
(and (= edit-mode :move) selected?)
|
||||
(st/emit! (drp/deselect-node position shift?))))))
|
||||
(and (= edit-mode :move) selected?)
|
||||
(st/emit! (drp/deselect-node position shift?)))))
|
||||
|
||||
|
||||
on-mouse-down
|
||||
(fn [event]
|
||||
(when-not last-p?
|
||||
(dom/stop-propagation event)
|
||||
(dom/prevent-default event)
|
||||
(dom/stop-propagation event)
|
||||
(dom/prevent-default event)
|
||||
|
||||
(cond
|
||||
(= edit-mode :move)
|
||||
(st/emit! (drp/start-move-path-point position))
|
||||
(cond
|
||||
(= edit-mode :move)
|
||||
(st/emit! (drp/start-move-path-point position))
|
||||
|
||||
(and (= edit-mode :draw) start-path?)
|
||||
(st/emit! (drp/start-path-from-point position))
|
||||
(and (= edit-mode :draw) start-path?)
|
||||
(st/emit! (drp/start-path-from-point position))
|
||||
|
||||
(and (= edit-mode :draw) (not start-path?))
|
||||
(st/emit! (drp/close-path-drag-start position)))))]
|
||||
(and (= edit-mode :draw) (not start-path?))
|
||||
(st/emit! (drp/close-path-drag-start position))))]
|
||||
|
||||
[:g.path-point
|
||||
[:circle.path-point
|
||||
|
@ -80,8 +78,9 @@
|
|||
:on-mouse-down on-mouse-down
|
||||
:on-mouse-enter on-enter
|
||||
:on-mouse-leave on-leave
|
||||
:style {:cursor (cond
|
||||
(and (not last-p?) (= edit-mode :draw)) cur/pen-node
|
||||
:style {:pointer-events (when last-p? "none")
|
||||
:cursor (cond
|
||||
(= edit-mode :draw) cur/pen-node
|
||||
(= edit-mode :move) cur/pointer-node)
|
||||
:fill "transparent"}}]]))
|
||||
|
||||
|
|
|
@ -468,7 +468,6 @@
|
|||
[content]
|
||||
(->> (d/with-prev content)
|
||||
(d/enumerate)
|
||||
|
||||
(mapcat (fn [[index [cur-cmd pre-cmd]]]
|
||||
(if (and pre-cmd (= :curve-to (:command cur-cmd)))
|
||||
(let [cur-pos (command->point cur-cmd)
|
||||
|
@ -480,6 +479,25 @@
|
|||
(group-by first)
|
||||
(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
|
||||
"Calculate sthe opposite index given a prefix and an index"
|
||||
[content index prefix]
|
||||
|
|
Loading…
Add table
Reference in a new issue