mirror of
https://github.com/penpot/penpot.git
synced 2025-07-25 08:07:20 +02:00
Merge pull request #6746 from penpot/niwinz-staging-path-editor-fixes
✨ Add missing fixes to the path edition mode
This commit is contained in:
commit
3d0c3013e5
5 changed files with 116 additions and 104 deletions
|
@ -31,8 +31,23 @@
|
|||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(declare close-path-drag-end)
|
||||
(declare check-changed-content)
|
||||
(declare change-edit-mode)
|
||||
|
||||
(defn- end-path-event?
|
||||
[event]
|
||||
(let [type (ptk/type event)]
|
||||
(or
|
||||
(= type ::common/finish-path)
|
||||
(= type :app.main.data.workspace.path.shortcuts/esc-pressed)
|
||||
(= type :app.main.data.workspace.common/clear-edition-mode)
|
||||
(= type :app.main.data.workspace.edition/clear-edition-mode)
|
||||
(= type :app.main.data.workspace/finalize-page)
|
||||
(= event :interrupt) ;; ESC
|
||||
(and ^boolean (mse/mouse-event? event)
|
||||
^boolean (mse/mouse-double-click-event? event)))))
|
||||
|
||||
(defn preview-next-point
|
||||
[{:keys [x y shift?]}]
|
||||
(ptk/reify ::preview-next-point
|
||||
|
@ -126,8 +141,6 @@
|
|||
(rx/of (preview-next-point handler)
|
||||
(undo/merge-head))))))
|
||||
|
||||
(declare close-path-drag-end)
|
||||
|
||||
(defn close-path-drag-start
|
||||
[position]
|
||||
(ptk/reify ::close-path-drag-start
|
||||
|
@ -146,8 +159,7 @@
|
|||
(rx/take-until
|
||||
(rx/merge
|
||||
(mse/drag-stopper stream)
|
||||
(->> stream
|
||||
(rx/filter helpers/end-path-event?)))))]
|
||||
(rx/filter end-path-event? stream))))]
|
||||
|
||||
(rx/concat
|
||||
(rx/of (add-node position))
|
||||
|
@ -171,8 +183,7 @@
|
|||
(watch [_ state stream]
|
||||
(let [stopper (rx/merge
|
||||
(mse/drag-stopper stream)
|
||||
(->> stream
|
||||
(rx/filter helpers/end-path-event?)))
|
||||
(rx/filter end-path-event? stream))
|
||||
|
||||
drag-events (->> (streams/position-stream state)
|
||||
(rx/map #(drag-handler %))
|
||||
|
@ -199,8 +210,7 @@
|
|||
|
||||
(let [stopper (rx/merge
|
||||
(mse/drag-stopper stream)
|
||||
(->> stream
|
||||
(rx/filter helpers/end-path-event?)))
|
||||
(rx/filter end-path-event? stream))
|
||||
|
||||
drag-events
|
||||
(->> (streams/position-stream state)
|
||||
|
@ -230,7 +240,7 @@
|
|||
|
||||
end-stream
|
||||
(->> stream
|
||||
(rx/filter helpers/end-path-event?)
|
||||
(rx/filter end-path-event?)
|
||||
(rx/share))
|
||||
|
||||
stoper-stream
|
||||
|
@ -241,8 +251,7 @@
|
|||
;; Mouse move preview
|
||||
mousemove-events
|
||||
(->> (streams/position-stream state)
|
||||
(rx/map #(preview-next-point %))
|
||||
(rx/take-until end-stream))
|
||||
(rx/map #(preview-next-point %)))
|
||||
|
||||
;; From mouse down we can have: click, drag and double click
|
||||
mousedown-events
|
||||
|
@ -256,18 +265,15 @@
|
|||
(make-drag-stream state stream %)))
|
||||
(rx/take-until end-stream))]
|
||||
|
||||
(rx/concat
|
||||
(rx/of (undo/start-path-undo))
|
||||
(rx/of (common/init-path))
|
||||
(->> (rx/merge mousemove-events
|
||||
mousedown-events)
|
||||
(rx/take-until stoper-stream))
|
||||
(->> (rx/concat
|
||||
(rx/of (undo/start-path-undo))
|
||||
(->> (rx/merge mousemove-events
|
||||
mousedown-events)
|
||||
(rx/take-until stoper-stream))
|
||||
(rx/of (ptk/data-event ::end-edition))))))))
|
||||
|
||||
;; This step implicitly finish path
|
||||
(rx/of (common/finish-path)
|
||||
(change-edit-mode :draw)))))))
|
||||
|
||||
(defn setup-frame []
|
||||
(defn setup-frame
|
||||
[]
|
||||
(ptk/reify ::setup-frame
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
|
@ -332,14 +338,15 @@
|
|||
(rx/concat
|
||||
(rx/of (start-edition shape-id))
|
||||
(->> stream
|
||||
(rx/filter (ptk/type? ::common/finish-path))
|
||||
(rx/filter (ptk/type? ::end-edition))
|
||||
(rx/take 1)
|
||||
(rx/observe-on :async)
|
||||
(rx/map (partial handle-drawing-end shape-id))))))))
|
||||
|
||||
(declare check-changed-content)
|
||||
(declare start-draw-mode*)
|
||||
|
||||
(defn start-draw-mode []
|
||||
(defn start-draw-mode
|
||||
[]
|
||||
(ptk/reify ::start-draw-mode
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
|
@ -350,36 +357,31 @@
|
|||
(update-in state [:workspace-local :edit-path id] assoc :old-content content)
|
||||
state)))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ _]
|
||||
(rx/of (start-draw-mode*)))))
|
||||
|
||||
(defn start-draw-mode*
|
||||
[]
|
||||
(ptk/reify ::start-draw-mode*
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [id (get-in state [:workspace-local :edition])
|
||||
edit-mode (get-in state [:workspace-local :edit-path id :edit-mode])]
|
||||
(if (= :draw edit-mode)
|
||||
(let [local (get state :workspace-local)
|
||||
id (get local :edition)
|
||||
mode (dm/get-in local [:edit-path id :edit-mode])]
|
||||
|
||||
(if (= :draw mode)
|
||||
(rx/concat
|
||||
(rx/of (dwsh/update-shapes [id] path/convert-to-path))
|
||||
(rx/of (start-edition id))
|
||||
(->> stream
|
||||
(rx/filter (ptk/type? ::common/finish-path))
|
||||
(rx/filter (ptk/type? ::end-edition))
|
||||
(rx/take 1)
|
||||
(rx/map check-changed-content)))
|
||||
(rx/mapcat (fn [_]
|
||||
(rx/of (check-changed-content)
|
||||
(start-draw-mode*))))))
|
||||
(rx/empty))))))
|
||||
|
||||
(defn check-changed-content []
|
||||
(ptk/reify ::check-changed-content
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [id (st/get-path-id state)
|
||||
content (st/get-path state :content)
|
||||
old-content (get-in state [:workspace-local :edit-path id :old-content])
|
||||
mode (get-in state [:workspace-local :edit-path id :edit-mode])
|
||||
empty-content? (empty? content)]
|
||||
(cond
|
||||
(and (not= content old-content) (not empty-content?)) (rx/of (changes/save-path-content))
|
||||
(= mode :draw) (rx/of :interrupt)
|
||||
:else (rx/of
|
||||
(common/finish-path)
|
||||
(dwdc/clear-drawing)))))))
|
||||
|
||||
(defn change-edit-mode
|
||||
[mode]
|
||||
(ptk/reify ::change-edit-mode
|
||||
|
@ -406,3 +408,25 @@
|
|||
(let [id (st/get-path-id state)]
|
||||
(assoc-in state [:workspace-local :edit-path id :prev-handler] nil)))))
|
||||
|
||||
(defn check-changed-content
|
||||
[]
|
||||
(ptk/reify ::check-changed-content
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [id (st/get-path-id state)
|
||||
content (st/get-path state :content)
|
||||
old-content (get-in state [:workspace-local :edit-path id :old-content])
|
||||
mode (get-in state [:workspace-local :edit-path id :edit-mode])
|
||||
empty-content? (empty? content)]
|
||||
|
||||
(cond
|
||||
(and (not= content old-content) (not empty-content?))
|
||||
(rx/of (changes/save-path-content))
|
||||
|
||||
(= mode :draw)
|
||||
(rx/of :interrupt)
|
||||
|
||||
:else
|
||||
(rx/of
|
||||
(common/finish-path)
|
||||
(dwdc/clear-drawing)))))))
|
||||
|
|
|
@ -10,22 +10,7 @@
|
|||
[app.common.math :as mth]
|
||||
[app.common.types.path :as path]
|
||||
[app.common.types.path.helpers :as path.helpers]
|
||||
[app.common.types.path.segment :as path.segment]
|
||||
[app.main.data.workspace.path.common :as common]
|
||||
[app.util.mouse :as mse]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(defn end-path-event?
|
||||
[event]
|
||||
(let [type (ptk/type event)]
|
||||
(or (= type ::common/finish-path)
|
||||
(= type :app.main.data.workspace.path.shortcuts/esc-pressed)
|
||||
(= type :app.main.data.workspace.common/clear-edition-mode)
|
||||
(= type :app.main.data.workspace.edition/clear-edition-mode)
|
||||
(= type :app.main.data.workspace/finalize-page)
|
||||
(= event :interrupt) ;; ESC
|
||||
(and ^boolean (mse/mouse-event? event)
|
||||
^boolean (mse/mouse-double-click-event? event)))))
|
||||
[app.common.types.path.segment :as path.segment]))
|
||||
|
||||
(defn append-node
|
||||
"Creates a new node in the path. Usually used when drawing."
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
[app.main.ui.workspace.viewport.selection :as selection]
|
||||
[app.main.ui.workspace.viewport.snap-distances :as snap-distances]
|
||||
[app.main.ui.workspace.viewport.snap-points :as snap-points]
|
||||
[app.main.ui.workspace.viewport.top-bar :refer [edition-bar*]]
|
||||
[app.main.ui.workspace.viewport.top-bar :refer [path-edition-bar* grid-edition-bar* view-only-bar*]]
|
||||
[app.main.ui.workspace.viewport.utils :as utils]
|
||||
[app.main.ui.workspace.viewport.viewport-ref :refer [create-viewport-ref]]
|
||||
[app.main.ui.workspace.viewport.widgets :as widgets]
|
||||
|
@ -302,17 +302,21 @@
|
|||
|
||||
[:div {:class (stl/css :viewport) :style #js {"--zoom" zoom} :data-testid "viewport"}
|
||||
(when (:can-edit permissions)
|
||||
[:*
|
||||
(when-not hide-ui?
|
||||
[:> top-toolbar* {:layout layout}])
|
||||
(if read-only?
|
||||
[:> view-only-bar* {}]
|
||||
[:*
|
||||
(when-not hide-ui?
|
||||
[:> top-toolbar* {:layout layout}])
|
||||
|
||||
(when single-select?
|
||||
[:> edition-bar* {:shape editing-shape
|
||||
:is-path-edition path-editing?
|
||||
:is-grid-edition grid-editing?
|
||||
:is-read-only read-only?
|
||||
:edit-path-state edit-path-state
|
||||
:layout layout}])])
|
||||
(when (and ^boolean path-editing?
|
||||
^boolean single-select?)
|
||||
[:> path-edition-bar* {:shape editing-shape
|
||||
:edit-path-state edit-path-state
|
||||
:layout layout}])
|
||||
|
||||
(when (and ^boolean grid-editing?
|
||||
^boolean single-select?)
|
||||
[:> grid-edition-bar* {:shape editing-shape}])]))
|
||||
|
||||
[:div {:class (stl/css :viewport-overlays)}
|
||||
;; The behaviour inside a foreign object is a bit different that in plain HTML so we wrap
|
||||
|
@ -637,7 +641,7 @@
|
|||
(when show-selection-handlers?
|
||||
[:g.selection-handlers {:clipPath "url(#clip-handlers)"}
|
||||
(when-not text-editing?
|
||||
(if editing-shape
|
||||
(if (and editing-shape path-editing?)
|
||||
[:> path-editor* {:shape editing-shape
|
||||
:state edit-path-state
|
||||
:zoom zoom}]
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
;; should also be renamed. But this should be done on development
|
||||
;; branch.
|
||||
|
||||
(mf/defc view-only-actions*
|
||||
(mf/defc view-only-bar*
|
||||
{::mf/private true}
|
||||
[]
|
||||
(let [handle-close-view-mode
|
||||
|
@ -38,22 +38,15 @@
|
|||
:on-click handle-close-view-mode}
|
||||
(tr "workspace.top-bar.read-only.done")]]]))
|
||||
|
||||
(mf/defc edition-bar*
|
||||
[{:keys [layout is-read-only edit-path-state is-grid-edition is-path-edition shape]}]
|
||||
(cond
|
||||
^boolean
|
||||
is-read-only
|
||||
[:> view-only-actions*]
|
||||
(mf/defc path-edition-bar*
|
||||
[{:keys [layout edit-path-state shape]}]
|
||||
(let [rulers? (contains? layout :rulers)
|
||||
class (stl/css-case
|
||||
:viewport-actions-path true
|
||||
:viewport-actions-no-rulers (not rulers?))]
|
||||
[:div {:class class}
|
||||
[:> path-actions* {:shape shape :state edit-path-state}]]))
|
||||
|
||||
^boolean
|
||||
is-path-edition
|
||||
|
||||
(let [rulers? (contains? layout :rulers)
|
||||
class (stl/css-case
|
||||
:viewport-actions-path true
|
||||
:viewport-actions-no-rulers (not rulers?))]
|
||||
[:div {:class class}
|
||||
[:> path-actions* {:shape shape :state edit-path-state}]])
|
||||
|
||||
is-grid-edition
|
||||
[:& grid-edition-actions {:shape shape}]))
|
||||
(mf/defc grid-edition-bar*
|
||||
[{:keys [shape]}]
|
||||
[:& grid-edition-actions {:shape shape}])
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
[app.main.ui.workspace.viewport.selection :as selection]
|
||||
[app.main.ui.workspace.viewport.snap-distances :as snap-distances]
|
||||
[app.main.ui.workspace.viewport.snap-points :as snap-points]
|
||||
[app.main.ui.workspace.viewport.top-bar :refer [edition-bar*]]
|
||||
[app.main.ui.workspace.viewport.top-bar :refer [path-edition-bar* grid-edition-bar* view-only-bar*]]
|
||||
[app.main.ui.workspace.viewport.utils :as utils]
|
||||
[app.main.ui.workspace.viewport.viewport-ref :refer [create-viewport-ref]]
|
||||
[app.main.ui.workspace.viewport.widgets :as widgets]
|
||||
|
@ -349,16 +349,22 @@
|
|||
|
||||
[:div {:class (stl/css :viewport) :style #js {"--zoom" zoom} :data-testid "viewport"}
|
||||
(when (:can-edit permissions)
|
||||
[:*
|
||||
(when-not hide-ui?
|
||||
[:> top-toolbar* {:layout layout}])
|
||||
(if read-only?
|
||||
[:> view-only-bar* {}]
|
||||
[:*
|
||||
(when-not hide-ui?
|
||||
[:> top-toolbar* {:layout layout}])
|
||||
|
||||
(when (and ^boolean path-editing?
|
||||
^boolean single-select?)
|
||||
[:> path-edition-bar* {:shape editing-shape
|
||||
:edit-path-state edit-path-state
|
||||
:layout layout}])
|
||||
|
||||
(when (and ^boolean grid-editing?
|
||||
^boolean single-select?)
|
||||
[:> grid-edition-bar* {:shape editing-shape}])]))
|
||||
|
||||
[:> edition-bar* {:layout layout
|
||||
:selected selected-shapes
|
||||
:edit-path edit-path-state
|
||||
:drawing drawing
|
||||
:edition edition
|
||||
:is-read-only read-only?}]])
|
||||
[:div {:class (stl/css :viewport-overlays)}
|
||||
(when show-comments?
|
||||
[:> comments/comments-layer* {:vbox vbox
|
||||
|
@ -627,7 +633,7 @@
|
|||
(when show-selection-handlers?
|
||||
[:g.selection-handlers {:clipPath "url(#clip-handlers)"}
|
||||
(when-not text-editing?
|
||||
(if editing-shape
|
||||
(if (and editing-shape path-editing?)
|
||||
[:> path-editor* {:shape editing-shape
|
||||
:state edit-path-state
|
||||
:zoom zoom}]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue