From cf4e2f91d1aa602bbac875c62a75ee8e8cf30eb9 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Tue, 23 May 2023 12:33:39 +0200 Subject: [PATCH] :sparkles: Grid layout polishing --- common/src/app/common/types/shape/layout.cljc | 2 +- .../src/app/main/data/workspace/edition.cljs | 3 +- .../main/ui/workspace/sidebar/options.cljs | 53 ++++++++++++------- .../src/app/main/ui/workspace/viewport.cljs | 40 +++++++------- .../main/ui/workspace/viewport/actions.cljs | 8 ++- .../viewport/grid_layout_editor.cljs | 29 ++++++---- 6 files changed, 82 insertions(+), 53 deletions(-) diff --git a/common/src/app/common/types/shape/layout.cljc b/common/src/app/common/types/shape/layout.cljc index 6f85b8499..1de4aed70 100644 --- a/common/src/app/common/types/shape/layout.cljc +++ b/common/src/app/common/types/shape/layout.cljc @@ -643,7 +643,7 @@ (fn [[id cell]] (let [inner-track? (or (= track-num (get cell attr)) - (and (< (get cell attr) track-num (+ (get cell attr) (get cell span-attr))))) + (< (get cell attr) track-num (+ (get cell attr) (get cell span-attr)))) displace-cell? (and (not inner-track?) (< track-num (get cell attr))) diff --git a/frontend/src/app/main/data/workspace/edition.cljs b/frontend/src/app/main/data/workspace/edition.cljs index 01be4c72e..66a33acf5 100644 --- a/frontend/src/app/main/data/workspace/edition.cljs +++ b/frontend/src/app/main/data/workspace/edition.cljs @@ -26,7 +26,8 @@ (if (contains? objects id) (-> state (assoc-in [:workspace-local :selected] #{id}) - (assoc-in [:workspace-local :edition] id)) + (assoc-in [:workspace-local :edition] id) + (dissoc :workspace-grid-edition)) state))) ptk/WatchEvent diff --git a/frontend/src/app/main/ui/workspace/sidebar/options.cljs b/frontend/src/app/main/ui/workspace/sidebar/options.cljs index 16ce75b7b..76076a7e0 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options.cljs @@ -85,6 +85,7 @@ (if (= options-mode :inspect) ;;TODO maybe move this logic to set-options-mode (st/emit! :interrupt (udw/set-workspace-read-only true)) (st/emit! :interrupt (udw/set-workspace-read-only false))))] + [:div.tool-window [:div.tool-window-content [:& tabs-container {:on-change-tab on-change-tab @@ -95,27 +96,41 @@ [:& align-options] [:& bool-options] (cond - grid-cell-selected? [:& grid-cell/options {:shape (get objects grid-id) - :cell (get-in objects [grid-id :layout-grid-cells cell-id])}] + grid-cell-selected? + [:& grid-cell/options + {:shape (get objects grid-id) + :cell (get-in objects [grid-id :layout-grid-cells cell-id])}] - (d/not-empty? drawing) [:& shape-options {:shape (:object drawing) - :page-id page-id - :file-id file-id - :shared-libs shared-libs}] - (= 0 (count selected)) [:& page/options] - (= 1 (count selected)) [:& shape-options {:shape (first selected-shapes) - :page-id page-id - :file-id file-id - :shared-libs shared-libs - :shapes-with-children shapes-with-children}] - :else [:& multiple/options {:shapes-with-children shapes-with-children - :shapes selected-shapes - :page-id page-id - :file-id file-id - :shared-libs shared-libs}])]] + (d/not-empty? drawing) + [:& shape-options + {:shape (:object drawing) + :page-id page-id + :file-id file-id + :shared-libs shared-libs}] + + (= 0 (count selected)) + [:& page/options] + + (= 1 (count selected)) + [:& shape-options + {:shape (first selected-shapes) + :page-id page-id + :file-id file-id + :shared-libs shared-libs + :shapes-with-children shapes-with-children}] + + :else + [:& multiple/options + {:shapes-with-children shapes-with-children + :shapes selected-shapes + :page-id page-id + :file-id file-id + :shared-libs shared-libs}])]] + + [:& tabs-element + {:id :prototype + :title (tr "workspace.options.prototype")} - [:& tabs-element {:id :prototype - :title (tr "workspace.options.prototype")} [:div.element-options [:& interactions-menu {:shape (first shapes)}]]] diff --git a/frontend/src/app/main/ui/workspace/viewport.cljs b/frontend/src/app/main/ui/workspace/viewport.cljs index 946bf1df0..177e3b1d5 100644 --- a/frontend/src/app/main/ui/workspace/viewport.cljs +++ b/frontend/src/app/main/ui/workspace/viewport.cljs @@ -251,7 +251,9 @@ offset-y (if selecting-first-level-frame? (:y (first selected-shapes)) - (:y selected-frame))] + (:y selected-frame)) + + rule-area-size (/ rules/rule-area-size zoom)] (hooks/setup-dom-events zoom disable-paste in-viewport? workspace-read-only?) (hooks/setup-viewport-size vport viewport-ref) @@ -349,6 +351,14 @@ :on-pointer-move on-pointer-move :on-pointer-up on-pointer-up} + [:defs + ;; This clip is so the handlers are not over the rules + [:clipPath {:id "clip-handlers"} + [:rect {:x (+ (:x vbox) rule-area-size) + :y (+ (:y vbox) rule-area-size) + :width (- (:width vbox) (* rule-area-size 2)) + :height (- (:height vbox) (* rule-area-size 2))}]]] + [:g {:style {:pointer-events (if disable-events? "none" "auto")}} (when show-text-editor? [:& editor/text-editor-svg {:shape editing-shape @@ -559,15 +569,6 @@ (when show-selection-handlers? [:g.selection-handlers {:clipPath "url(#clip-handlers)"} - [:defs - (let [rule-area-size (/ rules/rule-area-size zoom)] - ;; This clip is so the handlers are not over the rules - [:clipPath {:id "clip-handlers"} - [:rect {:x (+ (:x vbox) rule-area-size) - :y (+ (:y vbox) rule-area-size) - :width (max 0 (- (:width vbox) (* rule-area-size 2))) - :height (max 0 (- (:height vbox) (* rule-area-size 2)))}]])] - [:& selection/selection-handlers {:selected selected :shapes selected-shapes @@ -589,14 +590,13 @@ {:id (first selected) :zoom zoom}]) - (when (or show-grid-editor? hover-grid?) - [:& grid-layout/editor - {:zoom zoom - :objects objects-modified - :shape (or (get objects-modified edition) - (gsh/transform-shape - (get base-objects @hover-top-frame-id) - (dm/get-in modifiers [@hover-top-frame-id :modifiers]))) - :view-only (not show-grid-editor?)}]) - ]]])) + [:g.grid-layout-editor {:clipPath "url(#clip-handlers)"} + [:& grid-layout/editor + {:zoom zoom + :objects objects-modified + :shape (or (get objects-modified edition) + (gsh/transform-shape + (get base-objects @hover-top-frame-id) + (dm/get-in modifiers [@hover-top-frame-id :modifiers]))) + :view-only (not show-grid-editor?)}]])]]])) diff --git a/frontend/src/app/main/ui/workspace/viewport/actions.cljs b/frontend/src/app/main/ui/workspace/viewport/actions.cljs index 7c1f48565..f9ec1e96a 100644 --- a/frontend/src/app/main/ui/workspace/viewport/actions.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/actions.cljs @@ -1,4 +1,4 @@ -; This Source Code Form is subject to the terms of the Mozilla Public +;; This Source Code Form is subject to the terms of the Mozilla Public ;; License, v. 2.0. If a copy of the MPL was not distributed with this ;; file, You can obtain one at http://mozilla.org/MPL/2.0/. ;; @@ -9,6 +9,7 @@ [app.common.geom.point :as gpt] [app.common.math :as mth] [app.common.pages.helpers :as cph] + [app.common.types.shape.layout :as ctl] [app.common.uuid :as uuid] [app.config :as cfg] [app.main.data.workspace :as dw] @@ -204,7 +205,7 @@ (st/emit! (ms/->MouseEvent :double-click ctrl? shift? alt? meta?)) - ;; Emit asynchronously so the double click to exit shapes won't break + ;; Emit asynchronously so the double click to exit shapes won't break (timers/schedule (fn [] (when (and (not drawing-path?) shape) @@ -213,6 +214,9 @@ (st/emit! (dw/select-shape id) (dw/start-editing-selected)) + (ctl/grid-layout? shape) + (st/emit! (dw/start-edition-mode id)) + :else (let [;; We only get inside childrens of the hovering shape hover-ids (->> @hover-ids (filter (partial cph/is-child? objects id))) diff --git a/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.cljs b/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.cljs index 0ff2557cd..1f59f0c24 100644 --- a/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.cljs @@ -261,7 +261,8 @@ text]])) (mf/defc grid-cell - {::mf/wrap-props false} + {::mf/wrap [#(mf/memo' % (mf/check-props ["shape" "cell" "layout-data" "zoom" "hover?" "selected?"]))] + ::mf/wrap-props false} [props] (let [shape (unchecked-get props "shape") cell (unchecked-get props "cell") @@ -278,16 +279,19 @@ handle-pointer-enter (mf/use-callback + (mf/deps (:id shape) (:id cell)) (fn [] (st/emit! (dwge/hover-grid-cell (:id shape) (:id cell) true)))) handle-pointer-leave (mf/use-callback + (mf/deps (:id shape) (:id cell)) (fn [] (st/emit! (dwge/hover-grid-cell (:id shape) (:id cell) false)))) handle-pointer-down (mf/use-callback + (mf/deps (:id shape) (:id cell)) (fn [] (st/emit! (dwge/select-grid-cell (:id shape) (:id cell)))))] @@ -639,7 +643,11 @@ snap-pixel? (mf/deref refs/snap-pixel?) - grid-edition-id-ref (mf/use-memo #(refs/workspace-grid-edition-id (:id shape))) + grid-edition-id-ref + (mf/use-memo + (mf/deps (:id shape)) + #(refs/workspace-grid-edition-id (:id shape))) + grid-edition (mf/deref grid-edition-id-ref) hover-cells (:hover grid-edition) @@ -781,11 +789,12 @@ :snap-pixel? snap-pixel? :zoom zoom}]]))]) - (for [[_ cell] (:layout-grid-cells shape)] - [:& grid-cell {:key (dm/str "cell-" (:id cell)) - :shape base-shape - :layout-data layout-data - :cell cell - :zoom zoom - :hover? (contains? hover-cells (:id cell)) - :selected? (= selected-cells (:id cell))}])])) + [:g.cells + (for [cell (ctl/get-cells shape {:sort? true})] + [:& grid-cell {:key (dm/str "cell-" (:id cell)) + :shape base-shape + :layout-data layout-data + :cell cell + :zoom zoom + :hover? (contains? hover-cells (:id cell)) + :selected? (= selected-cells (:id cell))}])]]))