0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-13 10:38:13 -05:00

Add move path points with keyboard

This commit is contained in:
alonso.torres 2021-04-26 18:30:56 +02:00
parent 21cf845c02
commit 14475fdc67
3 changed files with 195 additions and 78 deletions

View file

@ -24,6 +24,7 @@
(d/export edition/start-move-path-point)
(d/export edition/start-path-edit)
(d/export edition/create-node-at-position)
(d/export edition/move-selected)
;; Selection
(d/export selection/handle-selection)

View file

@ -64,8 +64,8 @@
(selection/update-selection point-change)
(fn [state] (update-in state [:workspace-local :edit-path id] dissoc :content-modifiers :moving-nodes :moving-handler)))))))
(defn move-selected-path-point [from-point to-point]
(letfn [(modify-content-point [content {dx :x dy :y} modifiers point]
(defn modify-content-point
[content {dx :x dy :y} modifiers point]
(let [point-indices (upc/point-indices content point) ;; [indices]
handler-indices (upc/handler-indices content point) ;; [[index prefix]]
@ -83,8 +83,24 @@
(as-> modifiers $
(reduce modify-point $ point-indices)
(reduce modify-handler $ handler-indices))))]
(reduce modify-handler $ handler-indices))))
(defn set-move-modifier
[points move-modifier]
(ptk/reify ::set-modifiers
ptk/UpdateEvent
(update [_ state]
(let [id (st/get-path-id state)
content (get-in state (st/get-path state :content))
modifiers-reducer (partial modify-content-point content move-modifier)
content-modifiers (get-in state [:workspace-local :edit-path id :content-modifiers] {})
content-modifiers (->> points
(reduce modifiers-reducer content-modifiers))]
(-> state
(assoc-in [:workspace-local :edit-path id :content-modifiers] content-modifiers))))))
(defn move-selected-path-point [from-point to-point]
(ptk/reify ::move-point
ptk/UpdateEvent
(update [_ state]
@ -98,11 +114,11 @@
modifiers (get-in state [:workspace-local :edit-path id :content-modifiers] {})
modifiers (->> points
(reduce modifiers-reducer {}))]
(reduce modifiers-reducer modifiers))]
(-> state
(assoc-in [:workspace-local :edit-path id :moving-nodes] true)
(assoc-in [:workspace-local :edit-path id :content-modifiers] modifiers)))))))
(assoc-in [:workspace-local :edit-path id :content-modifiers] modifiers))))))
(declare drag-selected-points)
@ -126,7 +142,6 @@
ptk/WatchEvent
(watch [_ state stream]
(let [stopper (->> stream (rx/filter ms/mouse-up?))
zoom (get-in state [:workspace-local :zoom])
id (get-in state [:workspace-local :edition])
snap-toggled (get-in state [:workspace-local :edit-path id :snap-toggled])
@ -143,6 +158,73 @@
(rx/map #(move-selected-path-point start-position %)))
(rx/of (apply-content-modifiers)))))))
(defn- get-displacement
"Retrieve the correct displacement delta point for the
provided direction speed and distances thresholds."
[direction]
(case direction
:up (gpt/point 0 (- 1))
:down (gpt/point 0 1)
:left (gpt/point (- 1) 0)
:right (gpt/point 1 0)))
(defn finish-move-selected []
(ptk/reify ::move-selected
ptk/UpdateEvent
(update [_ state]
(let [id (get-in state [:workspace-local :edition])]
(-> state
(update-in [:workspace-local :edit-path id] dissoc :current-move))))))
(defn move-selected
[direction shift?]
(let [same-event (js/Symbol "same-event")]
(ptk/reify ::move-selected
IDeref
(-deref [_] direction)
ptk/UpdateEvent
(update [_ state]
(let [id (get-in state [:workspace-local :edition])
current-move (get-in state [:workspace-local :edit-path id :current-move])]
(if (nil? current-move)
(-> state
(assoc-in [:workspace-local :edit-path id :moving-nodes] true)
(assoc-in [:workspace-local :edit-path id :current-move] same-event))
state)))
ptk/WatchEvent
(watch [_ state stream]
(let [id (get-in state [:workspace-local :edition])
current-move (get-in state [:workspace-local :edit-path id :current-move])]
(if (= same-event current-move)
(let [points (get-in state [:workspace-local :edit-path id :selected-points] #{})
move-events (->> stream
(rx/filter (ptk/type? ::move-selected))
(rx/filter #(= direction (deref %))))
stopper (->> move-events (rx/debounce 100) (rx/take 1))
scale (if shift? (gpt/point 10) (gpt/point 1))
mov-vec (gpt/multiply (get-displacement direction) scale)]
(rx/concat
(rx/merge
(->> move-events
(rx/take-until stopper)
(rx/scan #(gpt/add %1 mov-vec) (gpt/point 0 0))
(rx/map #(set-move-modifier points %)))
;; First event is not read by the stream so we need to send it again
(rx/of (move-selected direction shift?)))
(rx/of (apply-content-modifiers)
(finish-move-selected))))
(rx/empty)))))))
(defn start-move-handler
[index prefix]
(ptk/reify ::start-move-handler

View file

@ -87,6 +87,40 @@
:redo {:tooltip (ds/meta "Y")
:command [(ds/c-mod "shift+z") (ds/c-mod "y")]
:fn #(st/emit! (drp/redo-path))}
;; Arrow movement
:move-fast-up {:tooltip (ds/shift ds/up-arrow)
:command "shift+up"
:fn #(st/emit! (drp/move-selected :up true))}
:move-fast-down {:tooltip (ds/shift ds/down-arrow)
:command "shift+down"
:fn #(st/emit! (drp/move-selected :down true))}
:move-fast-right {:tooltip (ds/shift ds/right-arrow)
:command "shift+right"
:fn #(st/emit! (drp/move-selected :right true))}
:move-fast-left {:tooltip (ds/shift ds/left-arrow)
:command "shift+left"
:fn #(st/emit! (drp/move-selected :left true))}
:move-unit-up {:tooltip ds/up-arrow
:command "up"
:fn #(st/emit! (drp/move-selected :up false))}
:move-unit-down {:tooltip ds/down-arrow
:command "down"
:fn #(st/emit! (drp/move-selected :down false))}
:move-unit-left {:tooltip ds/right-arrow
:command "right"
:fn #(st/emit! (drp/move-selected :right false))}
:move-unit-right {:tooltip ds/left-arrow
:command "left"
:fn #(st/emit! (drp/move-selected :left false))}
})
(defn get-tooltip [shortcut]