diff --git a/common/src/app/common/types/shape/layout.cljc b/common/src/app/common/types/shape/layout.cljc index 86aff113e..08645a098 100644 --- a/common/src/app/common/types/shape/layout.cljc +++ b/common/src/app/common/types/shape/layout.cljc @@ -1397,6 +1397,23 @@ (< (inc index) (+ column column-span))) (= (inc index) column))))))) +(defn cells-in-area + [parent first-row last-row first-column last-column] + (->> (:layout-grid-cells parent) + (vals) + (filter + (fn [{:keys [row column row-span column-span] :as cell}] + (and + (or (<= row first-row (+ row row-span -1)) + (<= row last-row (+ row row-span -1)) + (<= first-row row last-row) + (<= first-row (+ row row-span -1) last-row)) + + (or (<= column first-column (+ column column-span -1)) + (<= column last-column (+ column column-span -1)) + (<= first-column column last-column) + (<= first-column (+ column column-span -1) last-column))))))) + (defn shapes-by-row ([parent index] (shapes-by-row parent index true)) 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 dc6e99fa5..9af194119 100644 --- a/frontend/src/app/main/data/workspace/grid_layout/editor.cljs +++ b/frontend/src/app/main/data/workspace/grid_layout/editor.cljs @@ -6,6 +6,7 @@ (ns app.main.data.workspace.grid-layout.editor (:require + [app.common.data.macros :as dm] [app.common.geom.rect :as grc] [app.common.types.shape.layout :as ctl] [app.main.data.workspace.state-helpers :as wsh] @@ -25,14 +26,34 @@ (conj hover-set cell-id) (disj hover-set cell-id)))))))) -(defn select-grid-cell - [grid-id cell-id add?] - (ptk/reify ::select-grid-cell +(defn add-to-selection + ([grid-id cell-id] + (add-to-selection grid-id cell-id false)) + ([grid-id cell-id shift?] + (ptk/reify ::add-to-selection + ptk/UpdateEvent + (update [_ state] + (if shift? + (let [objects (wsh/lookup-page-objects state) + grid (get objects grid-id) + selected (or (dm/get-in state [:workspace-grid-edition grid-id :selected]) #{}) + selected (into selected [cell-id]) + cells (->> selected (map #(dm/get-in grid [:layout-grid-cells %]))) + + {:keys [first-row last-row first-column last-column]} (ctl/cells-coordinates cells) + new-selected + (into #{} + (map :id) + (ctl/cells-in-area grid first-row last-row first-column last-column))] + (assoc-in state [:workspace-grid-edition grid-id :selected] new-selected)) + (update-in state [:workspace-grid-edition grid-id :selected] (fnil conj #{}) cell-id)))))) + +(defn set-selection + [grid-id cell-id] + (ptk/reify ::set-selection ptk/UpdateEvent (update [_ state] - (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}))))) + (assoc-in state [:workspace-grid-edition grid-id :selected] #{cell-id})))) (defn remove-selection [grid-id cell-id] diff --git a/frontend/src/app/main/ui/workspace/context_menu.cljs b/frontend/src/app/main/ui/workspace/context_menu.cljs index 1e2296454..af84fffa6 100644 --- a/frontend/src/app/main/ui/workspace/context_menu.cljs +++ b/frontend/src/app/main/ui/workspace/context_menu.cljs @@ -576,6 +576,7 @@ (let [{:keys [grid cells]} mdata single? (= (count cells) 1) + can-merge? (mf/use-memo (mf/deps cells) @@ -603,7 +604,8 @@ :on-click do-merge-cells}]) [:& menu-entry {:title (tr "workspace.context-menu.grid-cells.create-board") - :on-click do-create-board}]])) + :on-click do-create-board + :disabled (and (not single?) (not can-merge?))}]])) (mf/defc context-menu 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 ddc740d96..7b99e9f61 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 @@ -337,10 +337,19 @@ (mf/use-callback (mf/deps (:id shape) (:id cell) selected?) (fn [event] - (when (or (dom/left-mouse? event) (not selected?)) - (if (and (kbd/shift? event) selected?) + (when (dom/left-mouse? event) + (cond + (and selected? (or (kbd/mod? event) (kbd/shift? event))) (st/emit! (dwge/remove-selection (:id shape) (:id cell))) - (st/emit! (dwge/select-grid-cell (:id shape) (:id cell) (kbd/shift? event))))))) + + (and (not selected?) (kbd/mod? event)) + (st/emit! (dwge/add-to-selection (:id shape) (:id cell))) + + (and (not selected?) (kbd/shift? event)) + (st/emit! (dwge/add-to-selection (:id shape) (:id cell) true)) + + :else + (st/emit! (dwge/set-selection (:id shape) (:id cell))))))) handle-context-menu (mf/use-callback