From 7cb2f307d891c99e3fcd85df93bc32f5779a4470 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 29 Apr 2025 12:31:20 +0200 Subject: [PATCH] :sparkles: Move path-editor from selection handlers --- .../main/ui/workspace/shapes/path/editor.cljs | 11 +- .../src/app/main/ui/workspace/viewport.cljs | 28 +++-- .../main/ui/workspace/viewport/selection.cljs | 108 +++++++----------- .../app/main/ui/workspace/viewport_wasm.cljs | 29 +++-- 4 files changed, 87 insertions(+), 89 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/shapes/path/editor.cljs b/frontend/src/app/main/ui/workspace/shapes/path/editor.cljs index b166f7db1..1c8e91fcb 100644 --- a/frontend/src/app/main/ui/workspace/shapes/path/editor.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/path/editor.cljs @@ -8,6 +8,7 @@ (:require [app.common.data :as d] [app.common.data.macros :as dm] + [app.common.files.helpers :as cfh] [app.common.geom.point :as gpt] [app.common.types.path :as path] [app.common.types.path.helpers :as path.helpers] @@ -289,8 +290,14 @@ :as edit-path} (mf/deref edit-path-ref) - selected-points (or selected-points #{}) - shape (hooks/use-equal-memo shape) + selected-points + (or selected-points #{}) + + shape + (mf/with-memo [shape] + (cond-> shape + (not (cfh/path-shape? shape)) + (path/convert-to-path))) base-content (get shape :content) diff --git a/frontend/src/app/main/ui/workspace/viewport.cljs b/frontend/src/app/main/ui/workspace/viewport.cljs index 24802656e..0e225599d 100644 --- a/frontend/src/app/main/ui/workspace/viewport.cljs +++ b/frontend/src/app/main/ui/workspace/viewport.cljs @@ -24,6 +24,7 @@ [app.main.ui.measurements :as msr] [app.main.ui.shapes.export :as use] [app.main.ui.workspace.shapes :as shapes] + [app.main.ui.workspace.shapes.path.editor :refer [path-editor*]] [app.main.ui.workspace.shapes.text.editor :as editor-v1] [app.main.ui.workspace.shapes.text.text-edition-outline :refer [text-edition-outline]] [app.main.ui.workspace.shapes.text.v2-editor :as editor-v2] @@ -116,7 +117,9 @@ objects-modified (mf/with-memo [base-objects text-modifiers modifiers] (apply-modifiers-to-selected selected base-objects text-modifiers modifiers)) - selected-shapes (keep (d/getf objects-modified) selected) + selected-shapes (->> selected + (into [] (keep (d/getf objects-modified))) + (not-empty)) ;; STATE alt? (mf/use-state false) @@ -436,12 +439,13 @@ :zoom zoom :modifiers modifiers}]) - (when show-selection-handlers? - [:& selection/selection-area + (when (and show-selection-handlers? + selected-shapes) + [:> selection/area* {:shapes selected-shapes :zoom zoom :edition edition - :disable-handlers (or drawing-tool edition @space? @mod?) + :disabled (or drawing-tool edition @space? @mod?) :on-move-selected on-move-selected :on-context-menu on-menu-selected}]) @@ -611,12 +615,16 @@ (when show-selection-handlers? [:g.selection-handlers {:clipPath "url(#clip-handlers)"} - [:& selection/selection-handlers - {:selected selected - :shapes selected-shapes - :zoom zoom - :edition edition - :disable-handlers (or drawing-tool edition @space?)}] + (when-not text-editing? + (if editing-shape + [:> path-editor* {:shape editing-shape + :zoom zoom}] + (when selected-shapes + [:> selection/handlers* + {:selected selected + :shapes selected-shapes + :zoom zoom + :disabled (or drawing-tool @space?)}]))) (when show-prototypes? [:& interactions/interactions diff --git a/frontend/src/app/main/ui/workspace/viewport/selection.cljs b/frontend/src/app/main/ui/workspace/viewport/selection.cljs index 9da8423b8..7f6f47d32 100644 --- a/frontend/src/app/main/ui/workspace/viewport/selection.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/selection.cljs @@ -20,7 +20,6 @@ [app.main.store :as st] [app.main.ui.context :as ctx] [app.main.ui.css-cursors :as cur] - [app.main.ui.workspace.shapes.path.editor :refer [path-editor*]] [app.util.array :as array] [app.util.debug :as dbg] [app.util.dom :as dom] @@ -314,9 +313,8 @@ :style {:fill (if (dbg/enabled? :handlers) "yellow" "none") :stroke-width 0}}]])) -(mf/defc controls-selection - {::mf/wrap-props false} - [{:keys [shape zoom color on-move-selected on-context-menu disable-handlers]}] +(mf/defc controls-selection* + [{:keys [shape zoom color on-move-selected on-context-menu disabled]}] (let [selrect (dm/get-prop shape :selrect) transform-type (mf/deref refs/current-transform) sr-transform (mf/deref refs/workspace-selrect-transform) @@ -330,7 +328,7 @@ (when (and (some? selrect) (not (or (= transform-type :move) (= transform-type :rotate)))) - [:g.controls {:pointer-events (if ^boolean disable-handlers "none" "visible")} + [:g.controls {:pointer-events (if ^boolean disabled "none" "visible")} ;; Selection rect [:& selection-rect {:rect selrect :transform transform @@ -339,9 +337,9 @@ :on-move-selected on-move-selected :on-context-menu on-context-menu}]]))) -(mf/defc controls-handlers - {::mf/wrap-props false} - [{:keys [shape zoom color on-resize on-rotate disable-handlers]}] +(mf/defc controls-handlers* + {::mf/private true} + [{:keys [shape zoom color on-resize on-rotate disabled]}] (let [transform-type (mf/deref refs/current-transform) sr-transform (mf/deref refs/workspace-selrect-transform) @@ -370,7 +368,7 @@ (not (or (= transform-type :move) (= transform-type :rotate)))) - [:g.controls {:pointer-events (if ^boolean disable-handlers "none" "visible")} + [:g.controls {:pointer-events (if ^boolean disabled "none" "visible")} (for [handler (calculate-handlers selrect shape zoom)] (let [type (obj/get handler "type") position (obj/get handler "position") @@ -425,9 +423,9 @@ :stroke-opacity 1 :fill "none"}}]])) -(mf/defc multiple-handlers - {::mf/wrap-props false} - [{:keys [shapes selected zoom color disable-handlers]}] +(mf/defc multiple-handlers* + {::mf/private true} + [{:keys [shapes selected zoom color disabled]}] (let [shape (mf/with-memo [shapes] (-> shapes (gsh/shapes->rect) @@ -452,34 +450,34 @@ (dom/stop-propagation event) (st/emit! (dw/start-rotate shapes)))))] - [:& controls-handlers + [:> controls-handlers* {:shape shape :zoom zoom :color color - :disable-handlers disable-handlers + :disabled disabled :on-resize on-resize :on-rotate on-rotate}])) -(mf/defc multiple-selection - {::mf/wrap-props false} - [{:keys [shapes zoom color disable-handlers on-move-selected on-context-menu]}] +(mf/defc multiple-selection* + {::mf/private true} + [{:keys [shapes zoom color disabled on-move-selected on-context-menu]}] (let [shape (mf/with-memo [shapes] (-> shapes (gsh/shapes->rect) (assoc :type :multiple) (cts/setup-shape)))] - [:& controls-selection + [:> controls-selection* {:shape shape :zoom zoom :color color - :disable-handlers disable-handlers + :disabled disabled :on-move-selected on-move-selected :on-context-menu on-context-menu}])) -(mf/defc single-handlers - {::mf/wrap-props false} - [{:keys [shape zoom color disable-handlers]}] +(mf/defc single-handlers* + {::mf/private true} + [{:keys [shape zoom color disabled]}] (let [shape-id (dm/get-prop shape :id) on-resize @@ -501,28 +499,27 @@ (dom/stop-propagation event) (st/emit! (dw/start-rotate [shape])))))] - [:& controls-handlers + [:> controls-handlers* {:shape shape :zoom zoom :color color - :disable-handlers disable-handlers + :disabled disabled :on-rotate on-rotate :on-resize on-resize}])) -(mf/defc single-selection - {::mf/wrap-props false} - [{:keys [shape zoom color disable-handlers on-move-selected on-context-menu]}] - [:& controls-selection +(mf/defc single-selection* + {::mf/private true} + [{:keys [shape zoom color disabled on-move-selected on-context-menu]}] + [:> controls-selection* {:shape shape :zoom zoom :color color - :disable-handlers disable-handlers + :disabled disabled :on-move-selected on-move-selected :on-context-menu on-context-menu}]) -(mf/defc selection-area - {::mf/wrap-props false} - [{:keys [shapes edition zoom disable-handlers on-move-selected on-context-menu]}] +(mf/defc area* + [{:keys [shapes edition zoom disabled on-move-selected on-context-menu]}] (let [total (count shapes) shape (first shapes) @@ -538,15 +535,12 @@ selection-rect-color-normal)] (cond - (zero? total) - nil - (> total 1) - [:& multiple-selection + [:> multiple-selection* {:shapes shapes :zoom zoom :color color - :disable-handlers disable-handlers + :disabled disabled :on-move-selected on-move-selected :on-context-menu on-context-menu}] @@ -561,56 +555,38 @@ nil :else - [:& single-selection + [:> single-selection* {:shape shape :zoom zoom :color color - :disable-handlers disable-handlers + :disabled disabled :on-move-selected on-move-selected :on-context-menu on-context-menu}]))) -(mf/defc selection-handlers - {::mf/wrap-props false} - [{:keys [shapes selected edition zoom disable-handlers]}] +(mf/defc handlers* + [{:keys [shapes selected zoom disabled]}] (let [total (count shapes) - shape (first shapes) - shape-id (dm/get-prop shape :id) ;; Note that we don't use mf/deref to avoid a repaint dependency here objects (deref refs/workspace-page-objects) - color (if (and (= total 1) ^boolean + color (if (and (= total 1) + ^boolean (or (ctn/in-any-component? objects shape) (ctk/is-variant-container? shape))) selection-rect-color-component selection-rect-color-normal)] - (cond - (zero? total) - nil - - (> total 1) - [:& multiple-handlers + (if (> total 1) + [:> multiple-handlers* {:shapes shapes :selected selected :zoom zoom :color color - :disable-handlers disable-handlers}] - - (and (cfh/text-shape? shape) - (= edition shape-id)) - nil - - (and (= edition shape-id) - (cfh/path-shape? shape)) - [:> path-editor* - {:zoom zoom - :shape shape}] - - :else - [:& single-handlers + :disabled disabled}] + [:> single-handlers* {:shape shape :zoom zoom :color color - :disable-handlers disable-handlers}]))) + :disabled disabled}]))) diff --git a/frontend/src/app/main/ui/workspace/viewport_wasm.cljs b/frontend/src/app/main/ui/workspace/viewport_wasm.cljs index da5263e1b..1222000fa 100644 --- a/frontend/src/app/main/ui/workspace/viewport_wasm.cljs +++ b/frontend/src/app/main/ui/workspace/viewport_wasm.cljs @@ -23,6 +23,7 @@ [app.main.ui.flex-controls :as mfc] [app.main.ui.hooks :as ui-hooks] [app.main.ui.measurements :as msr] + [app.main.ui.workspace.shapes.path.editor :refer [path-editor*]] [app.main.ui.workspace.shapes.text.editor :as editor-v1] [app.main.ui.workspace.shapes.text.text-edition-outline :refer [text-edition-outline]] [app.main.ui.workspace.shapes.text.v2-editor :as editor-v2] @@ -119,8 +120,9 @@ (binding [cts/*wasm-sync* false] (apply-modifiers-to-selected selected base-objects text-modifiers modifiers))) - selected-shapes (keep (d/getf objects-modified) selected) - + selected-shapes (->> selected + (into [] (keep (d/getf objects-modified))) + (not-empty)) ;; STATE alt? (mf/use-state false) shift? (mf/use-state false) @@ -443,12 +445,13 @@ :zoom zoom :modifiers modifiers}]) - (when show-selection-handlers? - [:& selection/selection-area + (when (and show-selection-handlers? + selected-shapes) + [:> selection/area* {:shapes selected-shapes :zoom zoom :edition edition - :disable-handlers (or drawing-tool edition @space? @mod?) + :disabled (or drawing-tool edition @space? @mod?) :on-move-selected on-move-selected :on-context-menu on-menu-selected}]) @@ -618,12 +621,16 @@ (when show-selection-handlers? [:g.selection-handlers {:clipPath "url(#clip-handlers)"} - [:& selection/selection-handlers - {:selected selected - :shapes selected-shapes - :zoom zoom - :edition edition - :disable-handlers (or drawing-tool edition @space?)}] + (when-not text-editing? + (if editing-shape + [:> path-editor* {:shape editing-shape + :zoom zoom}] + (when selected-shapes + [:> selection/handlers* + {:selected selected + :shapes selected-shapes + :zoom zoom + :disabled (or drawing-tool @space?)}]))) (when show-prototypes? [:& interactions/interactions