0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-08 16:18:11 -05:00

Multiple cells selection and area

This commit is contained in:
alonso.torres 2023-09-14 10:57:42 +02:00
parent 322767701c
commit 17f35cda15
12 changed files with 288 additions and 109 deletions

View file

@ -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

View file

@ -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]))))

View file

@ -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;
}
}
}
}

View file

@ -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))

View file

@ -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

View file

@ -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))))))

View file

@ -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)

View file

@ -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))]

View file

@ -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

View file

@ -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

View file

@ -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?

View file

@ -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