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 dede7d3315..64e2a3975e 100644 --- a/frontend/src/app/main/ui/workspace/shapes/path/editor.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/path/editor.cljs @@ -8,7 +8,6 @@ (: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] @@ -267,7 +266,6 @@ (mf/defc path-editor* [{:keys [shape zoom]}] - (let [shape-id (dm/get-prop shape :id) edit-path-ref (mf/with-memo [shape-id] (make-edit-path-ref shape-id)) @@ -293,12 +291,6 @@ 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/top_toolbar.cljs b/frontend/src/app/main/ui/workspace/top_toolbar.cljs index a904761f69..3b8b14ea9b 100644 --- a/frontend/src/app/main/ui/workspace/top_toolbar.cljs +++ b/frontend/src/app/main/ui/workspace/top_toolbar.cljs @@ -77,9 +77,8 @@ hidden?)) st/state)) -(mf/defc top-toolbar - {::mf/wrap [mf/memo] - ::mf/wrap-props false} +(mf/defc top-toolbar* + {::mf/memo true} [{:keys [layout]}] (let [selected-drawtool (mf/deref refs/selected-drawing-tool) edition (mf/deref refs/selected-edition) diff --git a/frontend/src/app/main/ui/workspace/viewport.cljs b/frontend/src/app/main/ui/workspace/viewport.cljs index 0e225599d4..dc91a6ef44 100644 --- a/frontend/src/app/main/ui/workspace/viewport.cljs +++ b/frontend/src/app/main/ui/workspace/viewport.cljs @@ -12,6 +12,7 @@ [app.common.data.macros :as dm] [app.common.files.helpers :as cfh] [app.common.geom.shapes :as gsh] + [app.common.types.path :as path] [app.common.types.shape-tree :as ctt] [app.common.types.shape.layout :as ctl] [app.main.data.workspace.modifiers :as dwm] @@ -29,6 +30,7 @@ [app.main.ui.workspace.shapes.text.text-edition-outline :refer [text-edition-outline]] [app.main.ui.workspace.shapes.text.v2-editor :as editor-v2] [app.main.ui.workspace.shapes.text.viewport-texts-html :as stvh] + [app.main.ui.workspace.top-toolbar :refer [top-toolbar*]] [app.main.ui.workspace.viewport-wasm :as viewport.wasm] [app.main.ui.workspace.viewport.actions :as actions] [app.main.ui.workspace.viewport.comments :as comments] @@ -48,7 +50,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 :as top-bar] + [app.main.ui.workspace.viewport.top-bar :refer [edition-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] @@ -88,12 +90,14 @@ vport zoom zoom-inverse - edition]} wlocal + edition]} + wlocal {:keys [options-mode tooltip show-distances? - picking-color?]} wglobal + picking-color?]} + wglobal vbox' (mf/use-debounce 100 vbox) @@ -122,23 +126,23 @@ (not-empty)) ;; STATE - alt? (mf/use-state false) - shift? (mf/use-state false) - mod? (mf/use-state false) - space? (mf/use-state false) - z? (mf/use-state false) - cursor (mf/use-state (utils/get-cursor :pointer-inner)) - hover-ids (mf/use-state nil) - hover (mf/use-state nil) - measure-hover (mf/use-state nil) - hover-disabled? (mf/use-state false) + alt? (mf/use-state false) + shift? (mf/use-state false) + mod? (mf/use-state false) + space? (mf/use-state false) + z? (mf/use-state false) + cursor (mf/use-state #(utils/get-cursor :pointer-inner)) + hover-ids (mf/use-state nil) + hover (mf/use-state nil) + measure-hover (mf/use-state nil) + hover-disabled? (mf/use-state false) hover-top-frame-id (mf/use-state nil) - frame-hover (mf/use-state nil) - active-frames (mf/use-state #{}) + frame-hover (mf/use-state nil) + active-frames (mf/use-state #{}) ;; REFS - [viewport-ref - on-viewport-ref] (create-viewport-ref) + [viewport-ref on-viewport-ref] + (create-viewport-ref) ;; VARS disable-paste (mf/use-var false) @@ -163,34 +167,43 @@ selected-frames (into #{} (map :frame-id) selected-shapes) ;; Only when we have all the selected shapes in one frame - selected-frame (when (= (count selected-frames) 1) (get base-objects (first selected-frames))) + selected-frame (when (= (count selected-frames) 1) + (get base-objects (first selected-frames))) - editing-shape (when edition (get base-objects edition)) + edit-path-state (get edit-path edition) + edit-path-mode (get edit-path-state :edit-mode) - edit-path (get edit-path edition) - edit-path-mode (get edit-path :edit-mode) + path-editing? (some? edit-path-state) + path-drawing? (or (= edit-path-mode :draw) + (and (= :path (get drawing-obj :type)) + (not= :curve drawing-tool))) + + editing-shape (when edition + (get base-objects edition)) + + editing-shape (mf/with-memo [editing-shape path-editing? base-objects] + (if path-editing? + (path/convert-to-path editing-shape base-objects) + editing-shape)) create-comment? (= :comments drawing-tool) - drawing-path? (or (= edit-path-mode :draw) - (= :path (get drawing-obj :type))) - node-editing? (cfh/path-shape? editing-shape) text-editing? (cfh/text-shape? editing-shape) grid-editing? (and edition (ctl/grid-layout? base-objects edition)) mode-inspect? (= options-mode :inspect) - on-click (actions/on-click hover selected edition drawing-path? drawing-tool space? selrect z?) + on-click (actions/on-click hover selected edition path-drawing? drawing-tool space? selrect z?) on-context-menu (actions/on-context-menu hover hover-ids read-only?) - on-double-click (actions/on-double-click hover hover-ids hover-top-frame-id drawing-path? base-objects edition drawing-tool z? read-only?) + on-double-click (actions/on-double-click hover hover-ids hover-top-frame-id path-drawing? base-objects edition drawing-tool z? read-only?) comp-inst-ref (mf/use-ref false) on-drag-enter (actions/on-drag-enter comp-inst-ref) on-drag-over (actions/on-drag-over move-stream) on-drag-end (actions/on-drag-over comp-inst-ref) on-drop (actions/on-drop file comp-inst-ref) - on-pointer-down (actions/on-pointer-down @hover selected edition drawing-tool text-editing? node-editing? grid-editing? - drawing-path? create-comment? space? panning z? read-only?) + on-pointer-down (actions/on-pointer-down @hover selected edition drawing-tool text-editing? path-editing? grid-editing? + path-drawing? create-comment? space? panning z? read-only?) on-pointer-up (actions/on-pointer-up disable-paste) @@ -236,14 +249,14 @@ (or drawing-obj transform)) show-selrect? (and selrect (empty? drawing) (not text-editing?)) show-measures? (and (not transform) - (not node-editing?) + (not path-editing?) (or show-distances? mode-inspect? read-only?)) show-artboard-names? (contains? layout :display-artboard-names) hide-ui? (contains? layout :hide-ui) show-rulers? (and (contains? layout :rulers) (not hide-ui?)) - disabled-guides? (or drawing-tool transform drawing-path? node-editing?) + disabled-guides? (or drawing-tool transform path-drawing? path-editing?) single-select? (= (count selected-shapes) 1) @@ -276,24 +289,30 @@ rule-area-size (/ rulers/ruler-area-size zoom)] - (hooks/setup-dom-events zoom disable-paste in-viewport? read-only? drawing-tool drawing-path?) + (hooks/setup-dom-events zoom disable-paste in-viewport? read-only? drawing-tool path-drawing?) (hooks/setup-viewport-size vport viewport-ref) - (hooks/setup-cursor cursor alt? mod? space? panning drawing-tool drawing-path? node-editing? z? read-only?) + (hooks/setup-cursor cursor alt? mod? space? panning drawing-tool path-drawing? path-editing? z? read-only?) (hooks/setup-keyboard alt? mod? space? z? shift?) (hooks/setup-hover-shapes page-id move-stream base-objects transform selected mod? hover measure-hover hover-ids hover-top-frame-id @hover-disabled? focus zoom show-measures?) (hooks/setup-viewport-modifiers modifiers base-objects) - (hooks/setup-shortcuts node-editing? drawing-path? text-editing? grid-editing?) + (hooks/setup-shortcuts path-editing? path-drawing? text-editing? grid-editing?) (hooks/setup-active-frames base-objects hover-ids selected active-frames zoom transform vbox) [:div {:class (stl/css :viewport) :style #js {"--zoom" zoom} :data-testid "viewport"} (when (:can-edit permissions) - [:> top-bar/top-bar* {:layout layout - :selected selected-shapes - :edit-path edit-path - :drawing drawing - :edition edition - :is-read-only read-only?}]) + [:* + (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}])]) + [:div {:class (stl/css :viewport-overlays)} ;; The behaviour inside a foreign object is a bit different that in plain HTML so we wrap ;; inside a foreign object "dummy" so this awkward behaviour is take into account diff --git a/frontend/src/app/main/ui/workspace/viewport/path_actions.cljs b/frontend/src/app/main/ui/workspace/viewport/path_actions.cljs index 0f9553d652..5930c74c12 100644 --- a/frontend/src/app/main/ui/workspace/viewport/path_actions.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/path_actions.cljs @@ -67,8 +67,8 @@ :separate-nodes segments-selected?}))) (mf/defc path-actions* - [{:keys [shape edit-path]}] - (let [{:keys [edit-mode selected-points snap-toggled]} edit-path + [{:keys [shape state]}] + (let [{:keys [edit-mode selected-points snap-toggled]} state content (:content shape) diff --git a/frontend/src/app/main/ui/workspace/viewport/top_bar.cljs b/frontend/src/app/main/ui/workspace/viewport/top_bar.cljs index 570eaad0b0..1c91d3c656 100644 --- a/frontend/src/app/main/ui/workspace/viewport/top_bar.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/top_bar.cljs @@ -7,19 +7,20 @@ (ns app.main.ui.workspace.viewport.top-bar (:require-macros [app.main.style :as stl]) (:require - [app.common.data.macros :as dm] - [app.common.files.helpers :as cfh] - [app.common.types.shape.layout :as ctl] [app.main.data.workspace :as dw] [app.main.data.workspace.common :as dwc] [app.main.store :as st] - [app.main.ui.workspace.top-toolbar :refer [top-toolbar]] [app.main.ui.workspace.viewport.grid-layout-editor :refer [grid-edition-actions]] [app.main.ui.workspace.viewport.path-actions :refer [path-actions*]] [app.util.i18n :as i18n :refer [tr]] [rumext.v2 :as mf])) +;; FIXME: this namespace should be renamed and all translation files +;; should also be renamed. But this should be done on development +;; branch. + (mf/defc view-only-actions* + {::mf/private true} [] (let [handle-close-view-mode (mf/use-fn @@ -37,44 +38,22 @@ :on-click handle-close-view-mode} (tr "workspace.top-bar.read-only.done")]]])) -(mf/defc top-bar* - [{:keys [layout drawing is-read-only edition selected edit-path]}] - (let [rulers? (contains? layout :rulers) - hide-ui? (contains? layout :hide-ui) +(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*] - drawing-obj (get drawing :object) - shape (or drawing-obj (-> selected first)) - shape-id (dm/get-prop shape :id) + ^boolean + is-path-edition - single? (= (count selected) 1) - editing? (= shape-id 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}]]) - draw-path? (and (some? drawing-obj) - (cfh/path-shape? drawing-obj) - (not= :curve (:tool drawing))) - - is-path-edition - (or (and single? editing? - (and (not (cfh/text-shape? shape)) - (not (cfh/frame-shape? shape)))) - draw-path?) - - grid-edition? - (and single? editing? (ctl/grid-layout? shape))] - - [:* - (when-not ^boolean hide-ui? - [:& top-toolbar {:layout layout}]) - - (cond - ^boolean - is-read-only - [:> view-only-actions*] - - ^boolean - is-path-edition - [:div {:class (stl/css-case :viewport-actions-path true :viewport-actions-no-rulers (not rulers?))} - [:> path-actions* {:shape shape :edit-path edit-path}]] - - grid-edition? - [:& grid-edition-actions {:shape shape}])])) + is-grid-edition + [:& grid-edition-actions {:shape shape}])) diff --git a/frontend/src/app/main/ui/workspace/viewport_wasm.cljs b/frontend/src/app/main/ui/workspace/viewport_wasm.cljs index 0f49c833ee..ecd9258cec 100644 --- a/frontend/src/app/main/ui/workspace/viewport_wasm.cljs +++ b/frontend/src/app/main/ui/workspace/viewport_wasm.cljs @@ -12,6 +12,7 @@ [app.common.data.macros :as dm] [app.common.files.helpers :as cfh] [app.common.geom.shapes :as gsh] + [app.common.types.path :as path] [app.common.types.shape :as cts] [app.common.types.shape-tree :as ctt] [app.common.types.shape.layout :as ctl] @@ -27,6 +28,7 @@ [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] + [app.main.ui.workspace.top-toolbar :refer [top-toolbar*]] [app.main.ui.workspace.viewport.actions :as actions] [app.main.ui.workspace.viewport.comments :as comments] [app.main.ui.workspace.viewport.debug :as wvd] @@ -45,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 :as top-bar] + [app.main.ui.workspace.viewport.top-bar :refer [edition-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] @@ -162,38 +164,45 @@ drawing-tool (:tool drawing) drawing-obj (:object drawing) - selected-frames (into #{} (map :frame-id) selected-shapes) ;; Only when we have all the selected shapes in one frame selected-frame (when (= (count selected-frames) 1) (get base-objects (first selected-frames))) - editing-shape (when edition (get base-objects edition)) + edit-path-state (get edit-path edition) + edit-path-mode (get edit-path-state :edit-mode) - edit-path (get edit-path edition) - edit-path-mode (get edit-path :edit-mode) + path-editing? (some? edit-path-state) + path-drawing? (or (= edit-path-mode :draw) + (and (= :path (get drawing-obj :type)) + (not= :curve drawing-tool))) + + editing-shape (when edition + (get base-objects edition)) + + editing-shape (mf/with-memo [editing-shape path-editing? base-objects] + (if path-editing? + (path/convert-to-path editing-shape base-objects) + editing-shape)) create-comment? (= :comments drawing-tool) - drawing-path? (or (= edit-path-mode :draw) - (= :path (get drawing-obj :type))) - node-editing? (cfh/path-shape? editing-shape) text-editing? (cfh/text-shape? editing-shape) grid-editing? (and edition (ctl/grid-layout? base-objects edition)) mode-inspect? (= options-mode :inspect) - on-click (actions/on-click hover selected edition drawing-path? drawing-tool space? selrect z?) + on-click (actions/on-click hover selected edition path-drawing? drawing-tool space? selrect z?) on-context-menu (actions/on-context-menu hover hover-ids read-only?) - on-double-click (actions/on-double-click hover hover-ids hover-top-frame-id drawing-path? base-objects edition drawing-tool z? read-only?) + on-double-click (actions/on-double-click hover hover-ids hover-top-frame-id path-drawing? base-objects edition drawing-tool z? read-only?) comp-inst-ref (mf/use-ref false) on-drag-enter (actions/on-drag-enter comp-inst-ref) on-drag-over (actions/on-drag-over move-stream) on-drag-end (actions/on-drag-over comp-inst-ref) on-drop (actions/on-drop file comp-inst-ref) - on-pointer-down (actions/on-pointer-down @hover selected edition drawing-tool text-editing? node-editing? grid-editing? - drawing-path? create-comment? space? panning z? read-only?) + on-pointer-down (actions/on-pointer-down @hover selected edition drawing-tool text-editing? path-editing? grid-editing? + path-drawing? create-comment? space? panning z? read-only?) on-pointer-up (actions/on-pointer-up disable-paste) @@ -239,14 +248,14 @@ (or drawing-obj transform)) show-selrect? (and selrect (empty? drawing) (not text-editing?)) show-measures? (and (not transform) - (not node-editing?) + (not path-editing?) (or show-distances? mode-inspect?)) show-artboard-names? (contains? layout :display-artboard-names) hide-ui? (contains? layout :hide-ui) show-rulers? (and (contains? layout :rulers) (not hide-ui?)) - disabled-guides? (or drawing-tool transform drawing-path? node-editing?) + disabled-guides? (or drawing-tool transform path-drawing? path-editing?) single-select? (= (count selected-shapes) 1) @@ -329,23 +338,27 @@ (when (and @canvas-init? initialized?) (wasm.api/set-canvas-background background))) - (hooks/setup-dom-events zoom disable-paste in-viewport? read-only? drawing-tool drawing-path?) + (hooks/setup-dom-events zoom disable-paste in-viewport? read-only? drawing-tool path-drawing?) (hooks/setup-viewport-size vport viewport-ref) - (hooks/setup-cursor cursor alt? mod? space? panning drawing-tool drawing-path? node-editing? z? read-only?) + (hooks/setup-cursor cursor alt? mod? space? panning drawing-tool path-drawing? path-editing? z? read-only?) (hooks/setup-keyboard alt? mod? space? z? shift?) (hooks/setup-hover-shapes page-id move-stream base-objects transform selected mod? hover measure-hover hover-ids hover-top-frame-id @hover-disabled? focus zoom show-measures?) - (hooks/setup-shortcuts node-editing? drawing-path? text-editing? grid-editing?) + (hooks/setup-shortcuts path-editing? path-drawing? text-editing? grid-editing?) (hooks/setup-active-frames base-objects hover-ids selected active-frames zoom transform vbox) [:div {:class (stl/css :viewport) :style #js {"--zoom" zoom} :data-testid "viewport"} (when (:can-edit permissions) - [:> top-bar/top-bar* {:layout layout - :selected selected-shapes - :edit-path edit-path - :drawing drawing - :edition edition - :is-read-only read-only?}]) + [:* + (when-not hide-ui? + [:> top-toolbar* {:layout layout}]) + + [:> 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