0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-24 23:49:45 -05:00

Show tools on path creation. Change snap while drawing

This commit is contained in:
alonso.torres 2023-01-19 13:34:13 +01:00
parent 0632111e96
commit 75d6e21af8
7 changed files with 79 additions and 80 deletions

View file

@ -60,7 +60,7 @@
(point v v)
(point-like? v)
(map->Point v)
(Point. (:x v) (:y v))
:else
(ex/raise :hint "invalid arguments (on pointer constructor)" :value v)))

View file

@ -8,7 +8,6 @@
(:require
[app.common.geom.point :as gpt]
[app.common.geom.shapes.flex-layout :as gsl]
[app.common.geom.shapes.path :as upg]
[app.common.path.commands :as upc]
[app.common.path.shapes-to-path :as upsp]
[app.common.spec :as us]
@ -125,14 +124,11 @@
(ptk/reify ::close-path-drag-start
ptk/WatchEvent
(watch [_ state stream]
(let [id (st/get-path-id state)
stop-stream
(let [stop-stream
(->> stream (rx/filter #(or (helpers/end-path-event? %)
(ms/mouse-up? %))))
content (st/get-path state :content)
snap-toggled (get-in state [:workspace-local :edit-path id :snap-toggled])
points (upg/content->points content)
handlers (-> (upc/content->handlers content)
(get position))
@ -141,7 +137,7 @@
(first handlers))
drag-events-stream
(->> (streams/position-stream snap-toggled points)
(->> (streams/position-stream)
(rx/take-until stop-stream)
(rx/map #(drag-handler position idx prefix %)))]
@ -164,16 +160,10 @@
(defn start-path-from-point [position]
(ptk/reify ::start-path-from-point
ptk/WatchEvent
(watch [_ state stream]
(watch [_ _ stream]
(let [mouse-up (->> stream (rx/filter #(or (helpers/end-path-event? %)
(ms/mouse-up? %))))
content (st/get-path state :content)
points (upg/content->points content)
id (st/get-path-id state)
snap-toggled (get-in state [:workspace-local :edit-path id :snap-toggled])
drag-events (->> (streams/position-stream snap-toggled points)
drag-events (->> (streams/position-stream)
(rx/take-until mouse-up)
(rx/map #(drag-handler %)))]
@ -192,11 +182,11 @@
(rx/merge-map #(rx/empty))))
(defn make-drag-stream
[stream snap-toggled _zoom points down-event]
[stream down-event]
(let [mouse-up (->> stream (rx/filter #(or (helpers/end-path-event? %)
(ms/mouse-up? %))))
drag-events (->> (streams/position-stream snap-toggled points)
drag-events (->> (streams/position-stream)
(rx/take-until mouse-up)
(rx/map #(drag-handler %)))]
@ -217,20 +207,13 @@
(assoc-in [:workspace-local :edit-path id :edit-mode] :draw))))
ptk/WatchEvent
(watch [_ state stream]
(let [zoom (get-in state [:workspace-local :zoom])
mouse-down (->> stream (rx/filter ms/mouse-down?))
(watch [_ _ stream]
(let [mouse-down (->> stream (rx/filter ms/mouse-down?))
end-path-events (->> stream (rx/filter helpers/end-path-event?))
content (st/get-path state :content)
points (upg/content->points content)
id (st/get-path-id state)
snap-toggled (get-in state [:workspace-local :edit-path id :snap-toggled])
;; Mouse move preview
mousemove-events
(->> (streams/position-stream snap-toggled points)
(->> (streams/position-stream)
(rx/take-until end-path-events)
(rx/map #(preview-next-point %)))
@ -238,12 +221,12 @@
mousedown-events
(->> mouse-down
(rx/take-until end-path-events)
(rx/with-latest merge (streams/position-stream snap-toggled points))
(rx/with-latest merge (streams/position-stream))
;; We change to the stream that emits the first event
(rx/switch-map
#(rx/race (make-node-events-stream stream)
(make-drag-stream stream snap-toggled zoom points %))))]
(make-drag-stream stream %))))]
(rx/concat
(rx/of (undo/start-path-undo))

View file

@ -7,6 +7,7 @@
(ns app.main.data.workspace.path.edition
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.geom.point :as gpt]
[app.common.geom.shapes.path :as upg]
[app.common.path.commands :as upc]
@ -35,8 +36,8 @@
(let [content (st/get-path state :content)
modifiers (helpers/move-handler-modifiers content index prefix false match-opposite? dx dy)
[cx cy] (if (= prefix :c1) [:c1x :c1y] [:c2x :c2y])
point (gpt/point (+ (get-in content [index :params cx]) dx)
(+ (get-in content [index :params cy]) dy))]
point (gpt/point (+ (dm/get-in content [index :params cx]) dx)
(+ (dm/get-in content [index :params cy]) dy))]
(-> state
(update-in [:workspace-local :edit-path id :content-modifiers] merge modifiers)
@ -51,7 +52,7 @@
id (st/get-path-id state)
page-id (:current-page-id state)
shape (st/get-path state)
content-modifiers (get-in state [:workspace-local :edit-path id :content-modifiers])
content-modifiers (dm/get-in state [:workspace-local :edit-path id :content-modifiers])
content (:content shape)
new-content (upc/apply-content-modifiers content content-modifiers)
@ -98,7 +99,7 @@
(let [id (st/get-path-id state)
content (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 (dm/get-in state [:workspace-local :edit-path id :content-modifiers] {})
content-modifiers (->> points
(reduce modifiers-reducer content-modifiers))]
@ -115,9 +116,9 @@
modifiers-reducer (partial modify-content-point content delta)
points (get-in state [:workspace-local :edit-path id :selected-points] #{})
points (dm/get-in state [:workspace-local :edit-path id :selected-points] #{})
modifiers (get-in state [:workspace-local :edit-path id :content-modifiers] {})
modifiers (dm/get-in state [:workspace-local :edit-path id :content-modifiers] {})
modifiers (->> points
(reduce modifiers-reducer modifiers))]
@ -132,8 +133,8 @@
(ptk/reify ::start-move-path-point
ptk/WatchEvent
(watch [_ state _]
(let [id (get-in state [:workspace-local :edition])
selected-points (get-in state [:workspace-local :edit-path id :selected-points] #{})
(let [id (dm/get-in state [:workspace-local :edition])
selected-points (dm/get-in state [:workspace-local :edit-path id :selected-points] #{})
selected? (contains? selected-points position)]
(streams/drag-stream
(rx/of
@ -148,10 +149,9 @@
ptk/WatchEvent
(watch [_ state stream]
(let [stopper (->> stream (rx/filter ms/mouse-up?))
id (get-in state [:workspace-local :edition])
snap-toggled (get-in state [:workspace-local :edit-path id :snap-toggled])
id (dm/get-in state [:workspace-local :edition])
selected-points (get-in state [:workspace-local :edit-path id :selected-points] #{})
selected-points (dm/get-in state [:workspace-local :edit-path id :selected-points] #{})
content (st/get-path state :content)
points (upg/content->points content)]
@ -159,7 +159,7 @@
(rx/concat
;; This stream checks the consecutive mouse positions to do the dragging
(->> points
(streams/move-points-stream snap-toggled start-position selected-points)
(streams/move-points-stream start-position selected-points)
(rx/map #(move-selected-path-point start-position %))
(rx/take-until stopper))
(rx/of (apply-content-modifiers)))))))
@ -178,7 +178,7 @@
(ptk/reify ::finish-move-selected
ptk/UpdateEvent
(update [_ state]
(let [id (get-in state [:workspace-local :edition])]
(let [id (dm/get-in state [:workspace-local :edition])]
(-> state
(update-in [:workspace-local :edit-path id] dissoc :current-move))))))
@ -192,8 +192,8 @@
ptk/UpdateEvent
(update [_ state]
(let [id (get-in state [:workspace-local :edition])
current-move (get-in state [:workspace-local :edit-path id :current-move])]
(let [id (dm/get-in state [:workspace-local :edition])
current-move (dm/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)
@ -202,11 +202,11 @@
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])]
(let [id (dm/get-in state [:workspace-local :edition])
current-move (dm/get-in state [:workspace-local :edit-path id :current-move])]
;; id can be null if we just selected the tool but we didn't start drawing
(if (and id (= same-event current-move))
(let [points (get-in state [:workspace-local :edit-path id :selected-points] #{})
(let [points (dm/get-in state [:workspace-local :edit-path id :selected-points] #{})
move-events (->> stream
(rx/filter (ptk/type? ::move-selected))
@ -238,13 +238,13 @@
(ptk/reify ::start-move-handler
ptk/WatchEvent
(watch [_ state stream]
(let [id (get-in state [:workspace-local :edition])
(let [id (dm/get-in state [:workspace-local :edition])
cx (d/prefix-keyword prefix :x)
cy (d/prefix-keyword prefix :y)
start-point @ms/mouse-position
modifiers (get-in state [:workspace-local :edit-path id :content-modifiers])
start-delta-x (get-in modifiers [index cx] 0)
start-delta-y (get-in modifiers [index cy] 0)
modifiers (dm/get-in state [:workspace-local :edit-path id :content-modifiers])
start-delta-x (dm/get-in modifiers [index cx] 0)
start-delta-y (dm/get-in modifiers [index cy] 0)
content (st/get-path state :content)
points (upg/content->points content)
@ -253,14 +253,12 @@
handler (-> content (get index) (upc/get-handler prefix))
[op-idx op-prefix] (upc/opposite-index content index prefix)
opposite (upc/handler->point content op-idx op-prefix)
snap-toggled (get-in state [:workspace-local :edit-path id :snap-toggled])]
opposite (upc/handler->point content op-idx op-prefix)]
(streams/drag-stream
(rx/concat
(rx/of (dch/update-shapes [id] upsp/convert-to-path))
(->> (streams/move-handler-stream snap-toggled start-point point handler opposite points)
(->> (streams/move-handler-stream start-point point handler opposite points)
(rx/take-until (->> stream (rx/filter #(or (ms/mouse-up? %)
(streams/finish-edition? %)))))
(rx/map
@ -283,7 +281,7 @@
(ptk/reify ::start-path-edit
ptk/UpdateEvent
(update [_ state]
(let [edit-path (get-in state [:workspace-local :edit-path id])
(let [edit-path (dm/get-in state [:workspace-local :edit-path id])
content (st/get-path state :content)
state (st/set-content state (ups/close-subpaths content))]
(cond-> state
@ -297,7 +295,7 @@
ptk/WatchEvent
(watch [_ state stream]
(let [mode (get-in state [:workspace-local :edit-path id :edit-mode])
(let [mode (dm/get-in state [:workspace-local :edit-path id :edit-mode])
stopper (->> stream
(rx/filter #(or
(= (ptk/type %) ::dwe/clear-edition-mode)

View file

@ -6,10 +6,11 @@
(ns app.main.data.workspace.path.streams
(:require
[app.common.data.macros :as dm]
[app.common.geom.point :as gpt]
[app.common.geom.shapes.path :as upg]
[app.main.constants :refer [zoom-half-pixel-precision]]
[app.main.data.workspace.path.state :as state]
[app.main.data.workspace.path.state :as pst]
[app.main.snap :as snap]
[app.main.store :as st]
[app.main.streams :as ms]
@ -71,15 +72,23 @@
(->> position-stream
(rx/merge-map (fn [] to-stream)))))))
(defn snap-toggled-stream
[]
(let [get-snap (fn [state]
(let [id (pst/get-path-id state)]
(dm/get-in state [:workspace-local :edit-path id :snap-toggled])))]
(-> (l/derived get-snap st/state)
(rx/from-atom {:emit-current-value? true}))))
(defn move-points-stream
[snap-toggled start-point selected-points points]
[start-point selected-points points]
(let [zoom (get-in @st/state [:workspace-local :zoom] 1)
ranges (snap/create-ranges points selected-points)
d-pos (/ snap/snap-path-accuracy zoom)
check-path-snap
(fn [position]
(fn [[position snap-toggled]]
(if snap-toggled
(let [delta (gpt/subtract position start-point)
moved-points (->> selected-points (mapv #(gpt/add % delta)))
@ -88,6 +97,7 @@
position))]
(->> ms/mouse-position
(rx/map to-pixel-snap)
(rx/with-latest-from (snap-toggled-stream))
(rx/map check-path-snap))))
(defn get-angle [node handler opposite]
@ -99,7 +109,7 @@
[rot-angle rot-sign])))
(defn move-handler-stream
[snap-toggled start-point node handler opposite points]
[start-point node handler opposite points]
(let [zoom (get-in @st/state [:workspace-local :zoom] 1)
ranges (snap/create-ranges points)
@ -108,7 +118,7 @@
[initial-angle] (get-angle node handler opposite)
check-path-snap
(fn [position]
(fn [[position snap-toggled]]
(if snap-toggled
(let [delta (gpt/subtract position start-point)
handler (gpt/add handler delta)
@ -134,13 +144,14 @@
(rx/map to-pixel-snap)
(rx/with-latest merge (->> ms/mouse-position-shift (rx/map #(hash-map :shift? %))))
(rx/with-latest merge (->> ms/mouse-position-alt (rx/map #(hash-map :alt? %))))
(rx/with-latest-from (snap-toggled-stream))
(rx/map check-path-snap))))
(defn position-stream
[snap-toggled _points]
[]
(let [zoom (get-in @st/state [:workspace-local :zoom] 1)
d-pos (/ snap/snap-path-accuracy zoom)
get-content #(state/get-path % :content)
get-content #(pst/get-path % :content)
content-stream
(-> (l/derived get-content st/state)
@ -154,7 +165,8 @@
(->> ms/mouse-position
(rx/map to-pixel-snap)
(rx/with-latest vector ranges-stream)
(rx/map (fn [[position ranges]]
(rx/with-latest-from (snap-toggled-stream))
(rx/map (fn [[[position ranges] snap-toggled]]
(if snap-toggled
(let [snap (snap/get-snap-delta [position] ranges d-pos)]
(gpt/add position snap))

View file

@ -6,7 +6,10 @@
(ns app.main.ui.workspace.shapes.path.common
(:require
[app.common.data.macros :as dm]
[app.main.data.workspace.path.state :as pst]
[app.main.refs :as refs]
[app.main.store :as st]
[okulary.core :as l]
[rumext.v2 :as mf]))
@ -17,10 +20,11 @@
(def gray-color "var(--color-gray-20)")
(def current-edit-path-ref
(let [selfn (fn [local]
(let [id (:edition local)]
(get-in local [:edit-path id])))]
(l/derived selfn refs/workspace-local)))
(l/derived
(fn [state]
(let [id (pst/get-path-id state)]
(dm/get-in state [:workspace-local :edit-path id])))
st/state))
(defn make-edit-path-ref [id]
(mf/use-memo

View file

@ -327,14 +327,15 @@
[:g.path-node {:key (dm/str index "-" (:x position) "-" (:y position))}
[:g.point-handlers {:pointer-events (when (= edit-mode :draw) "none")}
(for [[index prefix] pos-handlers]
(let [handler-position (upc/handler->point content index prefix)
handler-hover? (contains? hover-handlers [index prefix])
(for [[hindex prefix] pos-handlers]
(let [handler-position (upc/handler->point content hindex prefix)
handler-hover? (contains? hover-handlers [hindex prefix])
moving-handler? (= handler-position moving-handler)
matching-handler? (matching-handler? content position pos-handlers)]
[:& path-handler {:point position
[:& path-handler {:key (dm/str (dm/str index "-" (:x position) "-" (:y position)) "-" hindex "-" (d/name prefix))
:point position
:handler handler-position
:index index
:index hindex
:prefix prefix
:zoom zoom
:hover? handler-hover?

View file

@ -50,12 +50,13 @@
(mf/defc viewport-actions
{::mf/wrap [mf/memo]}
[]
(let [edition (mf/deref refs/selected-edition)
selected (mf/deref refs/selected-objects)
shape (-> selected first)]
(when (and (= (count selected) 1)
(= (:id shape) edition)
(not= :text (:type shape)))
(let [edition (mf/deref refs/selected-edition)
selected (mf/deref refs/selected-objects)
drawing (mf/deref refs/workspace-drawing)
drawing-obj (:object drawing)
shape (or drawing-obj (-> selected first))]
(when (or (and (= (count selected) 1) (= (:id shape) edition) (not= :text (:type shape)))
(and (some? drawing-obj) (= :path (:type drawing-obj))))
[:div.viewport-actions
[:& path-actions {:shape shape}]])))