From 17f35cda15b6ed0057afe943f7f2326d5d790b3e Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Thu, 14 Sep 2023 10:57:42 +0200 Subject: [PATCH] :sparkles: Multiple cells selection and area --- .../app/common/geom/shapes/transforms.cljc | 17 +-- common/src/app/common/types/shape/layout.cljc | 106 +++++++++++++--- .../partials/sidebar-element-options.scss | 13 +- .../app/main/data/workspace/drawing/box.cljs | 17 ++- .../data/workspace/grid_layout/editor.cljs | 23 +++- .../app/main/data/workspace/shape_layout.cljs | 65 +++++++++- .../src/app/main/data/workspace/shapes.cljs | 4 +- .../app/main/data/workspace/transforms.cljs | 2 +- .../main/ui/workspace/sidebar/options.cljs | 11 +- .../sidebar/options/menus/grid_cell.cljs | 115 +++++++++++------- .../options/menus/layout_container.cljs | 10 +- .../viewport/grid_layout_editor.cljs | 14 +-- 12 files changed, 288 insertions(+), 109 deletions(-) diff --git a/common/src/app/common/geom/shapes/transforms.cljc b/common/src/app/common/geom/shapes/transforms.cljc index c5503d040..ade9d8a7e 100644 --- a/common/src/app/common/geom/shapes/transforms.cljc +++ b/common/src/app/common/geom/shapes/transforms.cljc @@ -104,14 +104,15 @@ (defn absolute-move "Move the shape to the exactly specified position." [shape pos] - (let [x (dm/get-prop pos :x) - y (dm/get-prop pos :y) - sr (dm/get-prop shape :selrect) - px (dm/get-prop sr :x) - py (dm/get-prop sr :y) - dx (- (d/check-num x) px) - dy (- (d/check-num y) py)] - (move shape (gpt/point dx dy)))) + (when shape + (let [x (dm/get-prop pos :x) + y (dm/get-prop pos :y) + sr (dm/get-prop shape :selrect) + px (dm/get-prop sr :x) + py (dm/get-prop sr :y) + dx (- (d/check-num x) px) + dy (- (d/check-num y) py)] + (move shape (gpt/point dx dy))))) ;; --- Transformation matrix operations diff --git a/common/src/app/common/types/shape/layout.cljc b/common/src/app/common/types/shape/layout.cljc index b4d526141..b5b5d9fda 100644 --- a/common/src/app/common/types/shape/layout.cljc +++ b/common/src/app/common/types/shape/layout.cljc @@ -13,8 +13,6 @@ [app.common.schema :as sm] [app.common.uuid :as uuid])) -;; FIXME: need proper schemas - ;; :layout ;; :flex, :grid in the future ;; :layout-flex-dir ;; :row, :row-reverse, :column, :column-reverse ;; :layout-gap-type ;; :simple, :multiple @@ -698,13 +696,17 @@ (defn- reorder-grid-track [prop parent from-index to-index] (-> parent - (update prop - (fn [tracks] - (let [tr (nth tracks from-index)] - (-> tracks - (assoc from-index nil) - (d/insert-at-index (inc to-index) [tr]) - (d/vec-without-nils))))))) + (update + prop + (fn [tracks] + (let [tr (nth tracks from-index)] + (mapv + second + (-> tracks + (d/enumerate) ;; make unique so the insert-at-index won't remove the value + (assoc from-index nil) + (d/insert-at-index (inc to-index) [[nil tr]]) + (d/vec-without-nils)))))))) (defn reorder-grid-column [parent from-index to-index] @@ -846,7 +848,9 @@ cells (let [next-free (first free-cells) current (first pending) - cells (update-in cells [next-free :shapes] conj current)] + cells (-> cells + (update-in [next-free :shapes] conj current) + (assoc-in [next-free :position] :auto))] (recur cells (rest free-cells) (rest pending)))))] ;; TODO: Remove after testing @@ -870,7 +874,7 @@ (let [cell-from (get cells idx) cell-to (get cells (inc idx)) - cell (assoc cell-to :shapes (:shapes cell-from)) + cell (assoc cell-to :shapes (:shapes cell-from) :position (:position cell-from)) parent (assoc-in parent [:layout-grid-cells (:id cell)] cell) result-cells (assoc result-cells (inc idx) cell)] @@ -882,7 +886,7 @@ (recur parent result-cells (inc idx))))))] [(assoc-in parent [:layout-grid-cells (get-in cells [index :id]) :shapes] []) - (assoc-in result-cells [index :shapes] [])])))) + (update result-cells index assoc :shapes [] :position :auto)])))) (defn in-cell? @@ -912,7 +916,7 @@ [start-index start-cell] (seek-indexed-cell cells row column)] (if (some? start-cell) - (let [ ;; start-index => to-index is the range where the shapes inserted will be added + (let [;; start-index => to-index is the range where the shapes inserted will be added to-index (min (+ start-index (count shape-ids)) (dec (count cells)))] ;; Move shift the `shapes` attribute between cells @@ -920,7 +924,8 @@ (map vector shape-ids) (reduce (fn [[parent cells] [shape-id idx]] (let [[parent cells] (free-cell-push parent cells idx)] - [(assoc-in parent [:layout-grid-cells (get-in cells [idx :id]) :shapes] [shape-id]) + [(update-in parent [:layout-grid-cells (get-in cells [idx :id])] + assoc :position :manual :shapes [shape-id]) cells])) [parent cells]) (first))) @@ -1044,9 +1049,17 @@ (defn swap-shapes [parent id-from id-to] - (-> parent - (assoc-in [:layout-grid-cells id-from :shapes] (dm/get-in parent [:layout-grid-cells id-to :shapes])) - (assoc-in [:layout-grid-cells id-to :shapes] (dm/get-in parent [:layout-grid-cells id-from :shapes])))) + (let [cell-to (dm/get-in parent [:layout-grid-cells id-to]) + cell-from (dm/get-in parent [:layout-grid-cells id-from])] + (-> parent + (update-in [:layout-grid-cells id-from] + assoc + :shapes (:shapes cell-to) + :podition (:position cell-to)) + (update-in [:layout-grid-cells id-to] + assoc + :shapes (:shapes cell-from) + :position (:position cell-from))))) (defn add-children-to-cell [frame children objects [row column :as cell]] @@ -1106,3 +1119,62 @@ (< (inc index) (+ column column-span))))) (map second) (mapcat :shapes))) + +(defn cells-coordinates + "Given a group of cells returns the coordinates that define" + [cells] + (loop [cells (seq cells) + result + {:first-row ##Inf + :first-column ##Inf + :last-row ##-Inf + :last-column ##-Inf + :cell-coords #{}}] + + (if (empty? cells) + result + (let [{:keys [first-row last-row first-column last-column cell-coords]} result + current (first cells) + + first-row + (if (< (:row current) first-row) + (:row current) + first-row) + + last-row + (if (> (+ (:row current) (:row-span current) -1) last-row) + (+ (:row current) (:row-span current) -1) + last-row) + + first-column + (if (< (:column current) first-column) + (:column current) + first-column) + + last-column + (if (> (+ (:column current) (:column-span current) -1) last-column) + (+ (:column current) (:column-span current) -1) + last-column) + + cell-coords + (into cell-coords + (for [r (range (:row current) (+ (:row current) (:row-span current))) + c (range (:column current) (+ (:column current) (:column-span current)))] + [r c]))] + (recur (rest cells) + (assoc result + :first-row first-row + :last-row last-row + :first-column first-column + :last-column last-column + :cell-coords cell-coords)))))) + +(defn valid-area-cells? + [cells] + + (let [{:keys [first-row last-row first-column last-column cell-coords]} (cells-coordinates cells)] + (every? + #(contains? cell-coords %) + (for [r (range first-row (inc last-row)) + c (range first-column (inc last-column))] + [r c])))) diff --git a/frontend/resources/styles/main/partials/sidebar-element-options.scss b/frontend/resources/styles/main/partials/sidebar-element-options.scss index d6cce261e..9fa16aa28 100644 --- a/frontend/resources/styles/main/partials/sidebar-element-options.scss +++ b/frontend/resources/styles/main/partials/sidebar-element-options.scss @@ -1855,13 +1855,13 @@ } } .position-wrapper { - display: grid; - grid-template-columns: 1fr 1fr 1fr; + display: flex; width: 100%; max-width: 185px; height: 26px; border-radius: 4px; border: 1px solid $color-gray-60; + .position-btn { display: flex; justify-content: center; @@ -1871,6 +1871,8 @@ cursor: pointer; color: $color-gray-20; border-right: 1px solid $color-gray-60; + flex: 1; + &:last-child { border-right: none; } @@ -1878,6 +1880,13 @@ &:hover { color: $color-primary; } + + &[disabled] { + opacity: 0.5; + &:hover { + color: $color-gray-20; + } + } } } diff --git a/frontend/src/app/main/data/workspace/drawing/box.cljs b/frontend/src/app/main/data/workspace/drawing/box.cljs index 4ac0afb2d..d6d28dd8b 100644 --- a/frontend/src/app/main/data/workspace/drawing/box.cljs +++ b/frontend/src/app/main/data/workspace/drawing/box.cljs @@ -41,7 +41,7 @@ (> dy dx) (assoc :x (- (:x point) (* sx (- dy dx))))))) -(defn resize-shape [{:keys [x y width height] :as shape} initial point lock?] +(defn resize-shape [{:keys [x y width height] :as shape} initial point lock? mod?] (if (and (some? x) (some? y) (some? width) (some? height)) (let [draw-rect (grc/make-rect initial (cond-> point lock? (adjust-ratio initial))) shape-rect (grc/make-rect x y width height) @@ -56,13 +56,14 @@ (-> shape (assoc :click-draw? false) + (vary-meta merge {:mod? mod?}) (gsh/transform-shape (-> (ctm/empty) (ctm/resize scalev (gpt/point x y)) (ctm/move movev))))) shape)) -(defn update-drawing [state initial point lock?] - (update-in state [:workspace-drawing :object] resize-shape initial point lock?)) +(defn update-drawing [state initial point lock? mod?] + (update-in state [:workspace-drawing :object] resize-shape initial point lock? mod?)) (defn move-drawing [{:keys [x y]}] @@ -105,9 +106,7 @@ (cond-> (some? drop-index) (with-meta {:index drop-index})) (cond-> (some? drop-cell) - (with-meta {:cell drop-cell}))) - - ] + (with-meta {:cell drop-cell})))] (rx/concat ;; Add shape to drawing state @@ -120,14 +119,14 @@ (->> ms/mouse-position (rx/filter #(> (gpt/distance % initial) (/ 2 zoom))) (rx/with-latest vector ms/mouse-position-shift) + (rx/with-latest conj ms/mouse-position-mod) (rx/switch-map (fn [[point :as current]] (->> (snap/closest-snap-point page-id [shape] objects layout zoom focus point) (rx/map #(conj current %))))) (rx/map - (fn [[_ shift? point]] - #(update-drawing % initial (cond-> point snap-pixel? (gpt/round-step snap-prec)) shift?))))) - + (fn [[_ shift? mod? point]] + #(update-drawing % initial (cond-> point snap-pixel? (gpt/round-step snap-prec)) shift? mod?))))) (rx/take-until stoper)) (->> (rx/of (common/handle-finish-drawing)) diff --git a/frontend/src/app/main/data/workspace/grid_layout/editor.cljs b/frontend/src/app/main/data/workspace/grid_layout/editor.cljs index bbcef7e9d..82621a7c4 100644 --- a/frontend/src/app/main/data/workspace/grid_layout/editor.cljs +++ b/frontend/src/app/main/data/workspace/grid_layout/editor.cljs @@ -25,18 +25,20 @@ (disj hover-set cell-id)))))))) (defn select-grid-cell - [grid-id cell-id] + [grid-id cell-id add?] (ptk/reify ::select-grid-cell ptk/UpdateEvent (update [_ state] - (assoc-in state [:workspace-grid-edition grid-id :selected] cell-id)))) + (if add? + (update-in state [:workspace-grid-edition grid-id :selected] (fnil conj #{}) cell-id) + (assoc-in state [:workspace-grid-edition grid-id :selected] #{cell-id}))))) (defn remove-selection - [grid-id] + [grid-id cell-id] (ptk/reify ::remove-selection ptk/UpdateEvent (update [_ state] - (update-in state [:workspace-grid-edition grid-id] dissoc :selected)))) + (update-in state [:workspace-grid-edition grid-id :selected] disj cell-id)))) (defn clear-selection [grid-id] @@ -45,6 +47,19 @@ (update [_ state] (update-in state [:workspace-grid-edition grid-id] dissoc :selected)))) +(defn clean-selection + [grid-id] + (ptk/reify ::clean-selection + ptk/UpdateEvent + (update [_ state] + (let [objects (wsh/lookup-page-objects state) + shape (get objects grid-id)] + (update-in state [:workspace-grid-edition grid-id :selected] + (fn [selected] + (into #{} + (filter #(contains? (:layout-grid-cells shape) %)) + selected))))))) + (defn stop-grid-layout-editing [grid-id] (ptk/reify ::stop-grid-layout-editing diff --git a/frontend/src/app/main/data/workspace/shape_layout.cljs b/frontend/src/app/main/data/workspace/shape_layout.cljs index 7a6006585..201b2cbdc 100644 --- a/frontend/src/app/main/data/workspace/shape_layout.cljs +++ b/frontend/src/app/main/data/workspace/shape_layout.cljs @@ -20,6 +20,7 @@ [app.common.uuid :as uuid] [app.main.data.workspace.changes :as dwc] [app.main.data.workspace.colors :as cl] + [app.main.data.workspace.grid-layout.editor :as dwge] [app.main.data.workspace.modifiers :as dwm] [app.main.data.workspace.selection :as dwse] [app.main.data.workspace.shapes :as dws] @@ -563,20 +564,72 @@ (ptk/data-event :layout/update ids) (dwu/commit-undo-transaction undo-id)))))) -(defn update-grid-cell - [layout-id cell-id props] - (ptk/reify ::update-grid-cell +(defn update-grid-cells + [layout-id ids props] + (ptk/reify ::update-grid-cells ptk/WatchEvent (watch [_ _ _] (let [undo-id (js/Symbol)] (rx/of (dwu/start-undo-transaction undo-id) + (dwc/update-shapes [layout-id] (fn [shape] - (-> shape - (d/update-in-when [:layout-grid-cells cell-id] - #(d/without-nils (merge % props)))))) + (->> ids + (reduce (fn [shape cell-id] + (-> shape + (d/update-in-when [:layout-grid-cells cell-id] + #(d/without-nils (merge % props))))) + shape)))) + (ptk/data-event :layout/update [layout-id]) + (dwu/commit-undo-transaction undo-id)))))) + +(defn change-cells-mode + [layout-id ids mode] + + (ptk/reify ::change-cells-mode + ptk/WatchEvent + (watch [_ _ _] + (let [undo-id (js/Symbol)] + (rx/of + (dwu/start-undo-transaction undo-id) + + (dwc/update-shapes + [layout-id] + (fn [shape] + (cond + (= mode :area) + ;; Create area with the selected cells + (let [{:keys [first-row first-column last-row last-column]} + (ctl/cells-coordinates (->> ids (map #(get-in shape [:layout-grid-cells %])))) + + target-cell + (ctl/get-cell-by-position shape first-row first-column) + + shape + (-> shape + (ctl/resize-cell-area + (:row target-cell) (:column target-cell) + first-row + first-column + (inc (- last-row first-row)) + (inc (- last-column first-column))) + (ctl/assign-cells))] + + (-> shape + (d/update-in-when [:layout-grid-cells (:id target-cell)] assoc :position :area))) + + (= mode :auto) + ;; change the manual cells and move to auto + (->> ids + (reduce (fn [shape cell-id] + (cond-> shape + (= :manual (get-in shape [:layout-grid-cells cell-id :position])) + (-> (d/update-in-when [:layout-grid-cells cell-id] assoc :shapes [] :position :auto) + (ctl/assign-cells)))) + shape))))) + (dwge/clean-selection layout-id) (ptk/data-event :layout/update [layout-id]) (dwu/commit-undo-transaction undo-id)))))) diff --git a/frontend/src/app/main/data/workspace/shapes.cljs b/frontend/src/app/main/data/workspace/shapes.cljs index 7c59da35b..4c65609dd 100644 --- a/frontend/src/app/main/data/workspace/shapes.cljs +++ b/frontend/src/app/main/data/workspace/shapes.cljs @@ -36,10 +36,10 @@ (defn prepare-add-shape [changes shape objects _selected] (let [index (:index (meta shape)) - ;; FIXME: revisit id (:id shape) - [row column :as cell] (:cell (meta shape)) + mod? (:mod? (meta shape)) + [row column :as cell] (when-not mod? (:cell (meta shape))) changes (-> changes (pcb/with-objects objects) diff --git a/frontend/src/app/main/data/workspace/transforms.cljs b/frontend/src/app/main/data/workspace/transforms.cljs index 71a62d861..593dcb694 100644 --- a/frontend/src/app/main/data/workspace/transforms.cljs +++ b/frontend/src/app/main/data/workspace/transforms.cljs @@ -490,7 +490,7 @@ flex-layout? (ctl/flex-layout? objects target-frame) grid-layout? (ctl/grid-layout? objects target-frame) drop-index (when flex-layout? (gslf/get-drop-index target-frame objects position)) - cell-data (when grid-layout? (gslg/get-drop-cell target-frame objects position))] + cell-data (when (and grid-layout? (not mod?)) (gslg/get-drop-cell target-frame objects position))] [move-vector target-frame drop-index cell-data]))) (rx/take-until stopper))] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options.cljs b/frontend/src/app/main/ui/workspace/sidebar/options.cljs index a7f41befb..3dda83136 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options.cljs @@ -82,7 +82,8 @@ shape-parent-frame (cph/get-frame objects (:frame-id first-selected-shape)) edit-grid? (ctl/grid-layout? objects edition) - selected-cell (dm/get-in grid-edition [edition :selected]) + selected-cells (->> (dm/get-in grid-edition [edition :selected]) + (map #(dm/get-in objects [edition :layout-grid-cells %]))) on-change-tab (fn [options-mode] @@ -105,10 +106,10 @@ [:& bool-options] (cond - (some? selected-cell) + (d/not-empty? selected-cells) [:& grid-cell/options {:shape (get objects edition) - :cell (dm/get-in objects [edition :layout-grid-cells selected-cell])}] + :cells selected-cells}] edit-grid? [:& layout-container/grid-layout-edition @@ -166,10 +167,10 @@ [:& align-options] [:& bool-options] (cond - (some? selected-cell) + (d/not-empty? selected-cells) [:& grid-cell/options {:shape (get objects edition) - :cell (dm/get-in objects [edition :layout-grid-cells selected-cell])}] + :cells selected-cells}] edit-grid? [:& layout-container/grid-layout-edition diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs index bd81743b8..d1fb4e255 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs @@ -6,17 +6,31 @@ (ns app.main.ui.workspace.sidebar.options.menus.grid-cell (:require + [app.common.attrs :as attrs] [app.common.data :as d] [app.common.data.macros :as dm] + [app.common.types.shape.layout :as ctl] + [app.main.data.workspace :as dw] [app.main.data.workspace.grid-layout.editor :as dwge] [app.main.data.workspace.shape-layout :as dwsl] [app.main.store :as st] [app.main.ui.components.numeric-input :refer [numeric-input*]] + [app.main.ui.hooks :as hooks] [app.main.ui.icons :as i] [app.main.ui.workspace.sidebar.options.menus.layout-container :as lyc] [app.util.dom :as dom] [rumext.v2 :as mf])) +(def cell-props [:id + :position + :row + :row-span + :column + :column-span + :align-self + :justify-self + :area-name]) + (mf/defc set-self-alignment [{:keys [is-col? alignment set-alignment] :as props}] (let [dir-v [:auto :start :center :end :stretch #_:baseline] @@ -35,78 +49,91 @@ (mf/defc options {::mf/wrap [mf/memo]} - [{:keys [shape cell] :as props}] + [{:keys [shape cell cells] :as props}] - (let [{:keys [mode area-name align-self justify-self column column-span row row-span]} cell - column-end (+ column column-span) - row-end (+ row row-span) + (let [cells (hooks/use-equal-memo cells) + cell (or cell (attrs/get-attrs-multi cells cell-props)) - cell-mode (or mode :auto) + multiple? (= :multiple (:id cell)) + cell-ids (if (some? cell) [(:id cell)] (->> cells (map :id))) + cell-ids (hooks/use-equal-memo cell-ids) + + {:keys [position area-name align-self justify-self column column-span row row-span]} cell + + column-end (when (and (d/num? column) (d/num? column-span)) + (+ column column-span)) + row-end (when (and (d/num? row) (d/num? row-span)) + (+ row row-span)) + + cell-mode (or position :auto) cell-mode (if (and (= :auto cell-mode) (or (> (:column-span cell) 1) (> (:row-span cell) 1))) :manual cell-mode) + valid-area-cells? (mf/use-memo + (mf/deps cells) + #(ctl/valid-area-cells? cells)) + set-alignment (mf/use-callback - (mf/deps align-self (:id shape) (:id cell)) + (mf/deps align-self (:id shape) cell-ids) (fn [value] (if (= align-self value) - (st/emit! (dwsl/update-grid-cell (:id shape) (:id cell) {:align-self nil})) - (st/emit! (dwsl/update-grid-cell (:id shape) (:id cell) {:align-self value}))))) + (st/emit! (dwsl/update-grid-cells (:id shape) cell-ids {:align-self nil})) + (st/emit! (dwsl/update-grid-cells (:id shape) cell-ids {:align-self value}))))) set-justify-self (mf/use-callback - (mf/deps justify-self (:id shape) (:id cell)) + (mf/deps justify-self (:id shape) cell-ids) (fn [value] (if (= justify-self value) - (st/emit! (dwsl/update-grid-cell (:id shape) (:id cell) {:justify-self nil})) - (st/emit! (dwsl/update-grid-cell (:id shape) (:id cell) {:justify-self value}))))) + (st/emit! (dwsl/update-grid-cells (:id shape) cell-ids {:justify-self nil})) + (st/emit! (dwsl/update-grid-cells (:id shape) cell-ids {:justify-self value}))))) - on-change + on-grid-coordinates (mf/use-callback (mf/deps column row (:id shape) (:id cell)) (fn [field type value] - (let [[property value] - (cond - (and (= type :column) (or (= field :all) (= field :start))) - [:column value] + (when-not multiple? + (let [[property value] + (cond + (and (= type :column) (or (= field :all) (= field :start))) + [:column value] - (and (= type :column) (= field :end)) - [:column-span (max 1 (- value column))] + (and (= type :column) (= field :end)) + [:column-span (max 1 (- value column))] - (and (= type :row) (or (= field :all) (= field :start))) - [:row value] + (and (= type :row) (or (= field :all) (= field :start))) + [:row value] - (and (= type :row) (= field :end)) - [:row-span (max 1 (- value row))])] + (and (= type :row) (= field :end)) + [:row-span (max 1 (- value row))])] - (st/emit! (dwsl/update-grid-cell-position (:id shape) (:id cell) {property value}))))) + (st/emit! (dwsl/update-grid-cell-position (:id shape) (:id cell) {property value})))))) on-area-name-change (mf/use-callback - (mf/deps (:id shape) (:id cell)) + (mf/deps (:id shape) cell-ids) (fn [event] (let [value (dom/get-value (dom/get-target event))] (if (= value "") - (st/emit! (dwsl/update-grid-cell (:id shape) (:id cell) {:area-name nil})) - (st/emit! (dwsl/update-grid-cell (:id shape) (:id cell) {:area-name value})))))) + (st/emit! (dwsl/update-grid-cells (:id shape) cell-ids {:area-name nil})) + (st/emit! (dwsl/update-grid-cells (:id shape) cell-ids {:area-name value})))))) set-cell-mode (mf/use-callback - (mf/deps (:id shape) (:id cell)) + (mf/deps (:id shape) cell-ids) (fn [mode] - (let [props (cond-> {:mode mode} - (not= mode :area) - (assoc :area-name nil))] - (st/emit! (dwsl/update-grid-cell (:id shape) (:id cell) props))))) + (st/emit! (dwsl/change-cells-mode (:id shape) cell-ids mode)))) toggle-edit-mode (mf/use-fn (mf/deps (:id shape)) (fn [] - (st/emit! (dwge/remove-selection (:id shape)))))] + (st/emit! (dw/start-edition-mode (:id shape)) + (dwge/clear-selection (:id shape)))))] [:div.element-set [:div.element-set-title @@ -119,15 +146,17 @@ [:button.position-btn {:on-click #(set-cell-mode :auto) :class (dom/classnames :active (= :auto cell-mode))} "Auto"] - [:button.position-btn - {:on-click #(set-cell-mode :manual) - :class (dom/classnames :active (= :manual cell-mode))} "Manual"] + (when-not multiple? + [:button.position-btn + {:on-click #(set-cell-mode :manual) + :class (dom/classnames :active (= :manual cell-mode))} "Manual"]) [:button.position-btn {:on-click #(set-cell-mode :area) + :disabled (not valid-area-cells?) :class (dom/classnames :active (= :area cell-mode))} "Area"]]] [:div.manage-grid-columns - (when (= :auto cell-mode) + (when (and (not multiple?) (= :auto cell-mode)) [:div.grid-auto [:div.grid-columns-auto [:span.icon i/layout-rows] @@ -135,7 +164,7 @@ [:> numeric-input* {:placeholder "--" :on-click #(dom/select-target %) - :on-change (partial on-change :all :column) + :on-change (partial on-grid-coordinates :all :column) :value column}]]] [:div.grid-rows-auto [:span.icon i/layout-columns] @@ -143,7 +172,7 @@ [:> numeric-input* {:placeholder "--" :on-click #(dom/select-target %) - :on-change (partial on-change :all :row) + :on-change (partial on-grid-coordinates :all :row) :value row}]]]]) (when (= :area cell-mode) @@ -158,7 +187,7 @@ :auto-complete "off" :on-change on-area-name-change}]]) - (when (or (= :manual cell-mode) (= :area cell-mode)) + (when (and (not multiple?) (or (= :manual cell-mode) (= :area cell-mode))) [:div.grid-manual [:div.grid-columns-auto [:span.icon i/layout-rows] @@ -166,12 +195,12 @@ [:> numeric-input* {:placeholder "--" :on-pointer-down #(dom/select-target %) - :on-change (partial on-change :start :column) + :on-change (partial on-grid-coordinates :start :column) :value column}] [:> numeric-input* {:placeholder "--" :on-pointer-down #(dom/select-target %) - :on-change (partial on-change :end :column) + :on-change (partial on-grid-coordinates :end :column) :value column-end}]]] [:div.grid-rows-auto [:span.icon i/layout-columns] @@ -179,12 +208,12 @@ [:> numeric-input* {:placeholder "--" :on-pointer-down #(dom/select-target %) - :on-change (partial on-change :start :row) + :on-change (partial on-grid-coordinates :start :row) :value row}] [:> numeric-input* {:placeholder "--" :on-pointer-down #(dom/select-target %) - :on-change (partial on-change :end :row) + :on-change (partial on-grid-coordinates :end :row) :value row-end}]]]])] [:div.layout-row diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs index fdb6d6274..0207f372b 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs @@ -894,7 +894,7 @@ [dprops dref] (h/use-sortable - :data-type "penpot/layer" + :data-type "penpot/grid-track" :on-drop drop-track :data {:is-col? is-col? :index index @@ -1449,8 +1449,8 @@ (mf/deps ids) (fn [value type] (if (= type :row) - (st/emit! (dwsl/update-layout ids {:layout-align-content value})) - (st/emit! (dwsl/update-layout ids {:layout-justify-content value}))))) + (st/emit! (dwsl/update-layout ids {:layout-justify-content value})) + (st/emit! (dwsl/update-layout ids {:layout-align-content value}))))) ;;Grid columns column-grid-values (:layout-grid-columns values) @@ -1544,10 +1544,10 @@ [:div.jusfiy-content-grid.row-title "Content"] [:div.btn-wrapper.align-grid-content [:& justify-grid-row {:is-col? true - :justify-items grid-justify-content-column + :justify-items grid-justify-content-row :set-justify set-content-grid}] [:& justify-grid-row {:is-col? false - :justify-items grid-justify-content-row + :justify-items grid-justify-content-column :set-justify set-content-grid}]]] [:& grid-columns-row {:is-col? true :expanded? @grid-columns-open? 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 6a1326c18..99ef08e8d 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 @@ -302,10 +302,10 @@ handle-pointer-down (mf/use-callback (mf/deps (:id shape) (:id cell) selected?) - (fn [] - (if selected? - (st/emit! (dwge/remove-selection (:id shape))) - (st/emit! (dwge/select-grid-cell (:id shape) (:id cell))))))] + (fn [event] + (if (and (kbd/shift? event) selected?) + (st/emit! (dwge/remove-selection (:id shape) (:id cell))) + (st/emit! (dwge/select-grid-cell (:id shape) (:id cell) (kbd/shift? event)) ))))] [:g.cell-editor [:rect @@ -435,11 +435,11 @@ [width height] (if (= type :column) - [(max layout-gap-col (/ 16 zoom)) + [(max 0 (- layout-gap-col (/ 10 zoom)) (/ 16 zoom)) (+ row-total-size row-total-gap)] [(+ column-total-size column-total-gap) - (max layout-gap-row (/ 16 zoom))]) + (max 0 (- layout-gap-row (/ 10 zoom)) (/ 16 zoom))]) start-p (cond-> start-p @@ -789,7 +789,7 @@ :cell cell :zoom zoom :hover? (contains? hover-cells (:id cell)) - :selected? (= selected-cells (:id cell))}])] + :selected? (contains? selected-cells (:id cell))}])] (when-not view-only [:* [:& grid-editor-frame {:zoom zoom