From 9ed3ad2f3c7bc64052c8c82037f6f79799b4a66d Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Fri, 29 Dec 2023 15:55:59 +0100 Subject: [PATCH] :sparkles: Right click options on grid editor --- common/src/app/common/data.cljc | 7 + common/src/app/common/types/shape/layout.cljc | 310 +++++++++++++----- frontend/src/app/main/data/workspace.cljs | 23 ++ .../app/main/data/workspace/shape_layout.cljs | 89 ++++- .../app/main/ui/workspace/context_menu.cljs | 61 ++++ .../viewport/grid_layout_editor.cljs | 44 ++- 6 files changed, 422 insertions(+), 112 deletions(-) diff --git a/common/src/app/common/data.cljc b/common/src/app/common/data.cljc index c997c05c0f..4068839865 100644 --- a/common/src/app/common/data.cljc +++ b/common/src/app/common/data.cljc @@ -517,6 +517,13 @@ (->> (apply c/iteration args) (concat-all))) +(defn add-at-index + "Insert an element in a vector at an arbitrary index" + [coll index element] + (assert (vector? coll)) + (let [[before after] (split-at index coll)] + (concat-vec [] before [element] after))) + (defn insert-at-index "Insert a list of elements at the given index of a previous list. Replace all existing elems." diff --git a/common/src/app/common/types/shape/layout.cljc b/common/src/app/common/types/shape/layout.cljc index 58ccb6a0a3..c6aa7cb55b 100644 --- a/common/src/app/common/types/shape/layout.cljc +++ b/common/src/app/common/types/shape/layout.cljc @@ -329,14 +329,14 @@ (defn h-padding [{:keys [layout-padding-type layout-padding]}] - (let [{pad-top :p1 pad-right :p2 pad-bottom :p3 pad-left :p4} layout-padding] + (let [{pad-right :p2 pad-left :p4} layout-padding] (if (= :simple layout-padding-type) (+ pad-right pad-right) (+ pad-right pad-left)))) (defn v-padding [{:keys [layout-padding-type layout-padding]}] - (let [{pad-top :p1 pad-right :p2 pad-bottom :p3 pad-left :p4} layout-padding] + (let [{pad-top :p1 pad-bottom :p3} layout-padding] (if (= :simple layout-padding-type) (+ pad-top pad-top) (+ pad-top pad-bottom)))) @@ -615,53 +615,201 @@ :justify-self :auto :shapes []}) +(declare resize-cell-area) +(declare cells-by-column) +(declare cells-by-row) + +(defn remove-cell-areas + "Remove the areas in the given `index` before and after the index" + [parent prop index] + (let [prop-span (if (= prop :column) :row-span :column-span) + cells (if (= prop :column) (cells-by-column parent index) (cells-by-row parent index))] + (->> cells + (filter #(> (get % prop-span) 1)) + (reduce + (fn [parent cell] + (let [changed-cells + (cond + ;; New track at the beginning + (= (get cell prop) (inc index)) + [(assoc cell prop-span 1) + (assoc cell :id (uuid/next) :shapes [] prop (inc (get cell prop)) prop-span (dec (get cell prop-span)))] + + ;; New track at the middle + (< (get cell prop) (inc index) (+ (get cell prop) (dec (get cell prop-span)))) + [(assoc cell prop-span (- (inc index) (get cell prop))) + (assoc cell :id (uuid/next) :shapes [] prop (inc index) prop-span 1) + (assoc cell :id (uuid/next) :shapes [] prop (+ index 2) prop-span (- (+ (get cell prop) (dec (get cell prop-span))) (inc index)))] + + ;; New track at the end + (= (+ (get cell prop) (dec (get cell prop-span))) (inc index)) + [(assoc cell prop-span (- (inc index) (get cell prop))) + (assoc cell :id (uuid/next) :shapes [] prop (inc index) prop-span 1)])] + + (->> changed-cells + (reduce #(update %1 :layout-grid-cells assoc (:id %2) %2) parent)))) + parent)))) + +(defn remove-cell-areas-after + "Remove the areas in the given `index` but only after the index." + [parent prop index] + (let [prop-span (if (= prop :column) :column-span :row-span) + cells (if (= type :column) (cells-by-column parent index) (cells-by-row parent index))] + (->> cells + (filter #(> (get % prop-span) 1)) + (reduce + (fn [parent cell] + (let [changed-cells + (cond + ;; New track at the beginning + (= (get cell prop) (inc index)) + [(assoc cell prop-span 1) + (assoc cell :id (uuid/next) :shapes [] prop (inc (get cell prop)) prop-span (dec (get cell prop-span)))] + + ;; New track at the middle + (< (get cell prop) (inc index) (+ (get cell prop) (dec (get cell prop-span)))) + [(assoc cell prop-span (- (+ index 2) (get cell prop))) + (assoc cell :id (uuid/next) :shapes [] prop (+ index 2) prop-span (- (+ (get cell prop) (dec (get cell prop-span))) (inc index)))])] + (->> changed-cells + (reduce #(update %1 :layout-grid-cells assoc (:id %2) %2) parent)))) + parent)))) + ;; Adding a track creates the cells. We should check the shapes that are not tracked (with default values) and assign to the correct tracked values + +(defn add-grid-track + ([type parent value] + (add-grid-track type parent value nil)) + ([type parent value index] + (dm/assert! + "expected a valid grid definition for `value`" + (check-grid-track! value)) + + (let [[tracks-prop tracks-prop-other prop prop-other prop-span prop-span-other] + (if (= type :column) + [:layout-grid-columns :layout-grid-rows :column :row :column-span :row-span] + [:layout-grid-rows :layout-grid-columns :row :column :row-span :column-span]) + + new-index (d/nilv index (count (get parent tracks-prop))) + new-track-num (inc new-index) + + ;; Increase the values for the existing cells + layout-grid-cells + (-> (:layout-grid-cells parent) + (update-vals + (fn [cell] + (cond-> cell + (>= (get cell prop) new-track-num) + (update prop inc) + + (and (< (get cell prop) new-track-num) + (> (get cell prop-span) 1) + (>= (+ (get cell prop) (dec (get cell prop-span))) new-track-num)) + (update prop-span inc))))) + + ;; Search for the cells already created + exist-cells? + (into #{} + (comp (filter + (fn [cell] + (and (>= new-track-num (get cell prop)) + (< new-track-num (+ (get cell prop) (get cell prop-span)))))) + (mapcat #(range (get % prop-other) (+ (get % prop-other) (get % prop-span-other))))) + (vals layout-grid-cells)) + + ;; Create the new cells as necesary + layout-grid-cells + (->> (d/enumerate (get parent tracks-prop-other)) + (remove (fn [[idx _]] (exist-cells? (inc idx)))) + (reduce + (fn [result [idx _]] + (let [id (uuid/next)] + (assoc result id + (merge {:id id + prop-other (inc idx) + prop new-track-num} + grid-cell-defaults)))) + layout-grid-cells))] + + (-> parent + (update tracks-prop d/add-at-index new-index value) + (assoc :layout-grid-cells layout-grid-cells))))) + (defn add-grid-column - [parent value] - (dm/assert! - "expected a valid grid definition for `value`" - (check-grid-track! value)) - - (let [rows (:layout-grid-rows parent) - new-col-num (inc (count (:layout-grid-columns parent))) - - layout-grid-cells - (->> (d/enumerate rows) - (reduce (fn [result [row-idx _]] - (let [id (uuid/next)] - (assoc result id - (merge {:id id - :row (inc row-idx) - :column new-col-num} - grid-cell-defaults)))) - (:layout-grid-cells parent)))] - (-> parent - (update :layout-grid-columns (fnil conj []) value) - (assoc :layout-grid-cells layout-grid-cells)))) + ([parent value] + (add-grid-column parent value nil)) + ([parent value index] + (add-grid-track :column parent value index))) (defn add-grid-row - [parent value] - (dm/assert! - "expected a valid grid definition for `value`" - (check-grid-track! value)) + ([parent value] + (add-grid-row parent value nil)) + ([parent value index] + (add-grid-track :row parent value index))) - (let [cols (:layout-grid-columns parent) - new-row-num (inc (count (:layout-grid-rows parent))) +(defn- duplicate-cells + [shape prop from-index to-index ids-map] - layout-grid-cells - (->> (d/enumerate cols) - (reduce (fn [result [col-idx _]] - (let [id (uuid/next)] - (assoc result id - (merge {:id id - :column (inc col-idx) - :row new-row-num} - grid-cell-defaults)))) - (:layout-grid-cells parent)))] - (-> parent - (update :layout-grid-rows (fnil conj []) value) - (assoc :layout-grid-cells layout-grid-cells)))) + (let [[prop-span prop-other prop-other-span] + (if (= prop :column) + [:column-span :row :row-span] + [:row-span :column :column-span]) + from-cells + (if (= prop :column) + (cells-by-column shape from-index) + (cells-by-row shape from-index)) + + to-cells + (if (= prop :column) + (cells-by-column shape to-index) + (cells-by-row shape to-index)) + + to-cells-idx (d/index-by prop-other to-cells) + + ;; This loop will go throught the original cells and copy their data to the target cell + ;; After this some cells could have no correspondence and should be removed + [shape matched] + (loop [from-cells (seq from-cells) + matched #{} + result shape] + (if-let [cell (first from-cells)] + (let [match-cell + (-> (get to-cells-idx (get cell prop-other)) + (d/patch-object (select-keys cell [prop-other-span :position :align-self :justify-self])) + (cond-> (= (get cell prop-span) 1) + (assoc :shapes (mapv ids-map (:shapes cell)))))] + (recur (rest from-cells) + (conj matched (:id match-cell)) + (assoc-in result [:layout-grid-cells (:id match-cell)] match-cell))) + + [result matched])) + + ;; Remove cells that haven't been matched + shape + (->> to-cells + (remove (fn [{:keys [id]}] (contains? matched id))) + (reduce (fn [shape cell] + (update shape :layout-grid-cells dissoc (:id cell))) + shape))] + + shape)) + + +(defn duplicate-row + [shape index ids-map] + (let [value (dm/get-in shape [:layout-grid-rows index])] + (-> shape + (remove-cell-areas-after :row index) + (add-grid-row value (inc index)) + (duplicate-cells :row index (inc index) ids-map)))) + +(defn duplicate-column + [shape index ids-map] + (let [value (dm/get-in shape [:layout-grid-columns index])] + (-> shape + (remove-cell-areas-after :column index) + (add-grid-column value (inc index)) + (duplicate-cells :column index (inc index) ids-map)))) (defn make-remove-cell [attr span-attr track-num] @@ -762,12 +910,9 @@ update-vals (fn [cell] (update cell prop #(get remap-tracks % %))))))) -(declare resize-cell-area) -(declare cells-by-column) -(declare cells-by-row) (defn- reorder-grid-track - [parent from-index to-index move-content? cells-by tracks-props prop prop-span] + [parent from-index to-index move-content? tracks-props prop] (let [from-track (inc from-index) to-track (if (< to-index from-index) (+ to-index 2) @@ -776,23 +921,10 @@ (and move-content? (not= from-track to-track)) parent - (if move-content? - (->> (concat (cells-by parent (dec from-track)) - (cells-by parent (dec to-track))) - (reduce (fn [parent cell] - (cond-> parent - (and (> (get cell prop-span) 1) - (or (> to-track from-track) (not (= to-track (get cell prop)))) - (or (< to-track from-track) (not (= to-track (+ (get cell prop) (dec (get cell prop-span))))))) - (resize-cell-area - (:row cell) - (:column cell) - (:row cell) - (:column cell) - (if (= prop :row) 1 (:row-span cell)) - (if (= prop :column) 1 (:column-span cell))))) - parent)) - parent) + (cond-> parent + move-content? + (-> (remove-cell-areas prop (dec from-track)) + (remove-cell-areas prop (dec to-track)))) parent (reorder-grid-tracks parent tracks-props from-index to-index)] @@ -803,11 +935,11 @@ (defn reorder-grid-column [parent from-index to-index move-content?] - (reorder-grid-track parent from-index to-index move-content? cells-by-column :layout-grid-columns :column :column-span)) + (reorder-grid-track parent from-index to-index move-content? :layout-grid-columns :column)) (defn reorder-grid-row [parent from-index to-index move-content?] - (reorder-grid-track parent from-index to-index move-content? cells-by-row :layout-grid-rows :row :row-span)) + (reorder-grid-track parent from-index to-index move-content? :layout-grid-rows :row)) (defn cells-seq [{:keys [layout-grid-cells layout-grid-dir]} & {:keys [sort?] :or {sort? false}}] @@ -1239,30 +1371,42 @@ (assoc parent :shapes (into [] (reverse new-shapes))))) (defn cells-by-row - [parent index] - (->> (:layout-grid-cells parent) - (filter (fn [[_ {:keys [row row-span]}]] - (and (>= (inc index) row) - (< (inc index) (+ row row-span))))) - (map second))) + ([parent index] + (cells-by-row parent index true)) + ([parent index check-span?] + (->> (:layout-grid-cells parent) + (filter (fn [[_ {:keys [row row-span]}]] + (if check-span? + (and (>= (inc index) row) + (< (inc index) (+ row row-span))) + (= (inc index) row)))) + (map second)))) (defn cells-by-column - [parent index] - (->> (:layout-grid-cells parent) - (filter (fn [[_ {:keys [column column-span]}]] - (and (>= (inc index) column) - (< (inc index) (+ column column-span))))) - (map second))) + ([parent index] + (cells-by-column parent index true)) + ([parent index check-span?] + (->> (:layout-grid-cells parent) + (filter (fn [[_ {:keys [column column-span]}]] + (if check-span? + (and (>= (inc index) column) + (< (inc index) (+ column column-span))) + (= (inc index) column)))) + (map second)))) (defn shapes-by-row - [parent index] - (->> (cells-by-row parent index) - (mapcat :shapes))) + ([parent index] + (shapes-by-row parent index true)) + ([parent index check-span?] + (->> (cells-by-row parent index check-span?) + (mapcat :shapes)))) (defn shapes-by-column - [parent index] - (->> (cells-by-column parent index) - (mapcat :shapes))) + ([parent index] + (shapes-by-column parent index true)) + ([parent index check-span?] + (->> (cells-by-column parent index check-span?) + (mapcat :shapes)))) (defn cells-coordinates "Given a group of cells returns the coordinates that define" diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index b711b1ead4..0eee768b7b 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -1490,6 +1490,27 @@ (rx/of (show-context-menu (-> params (assoc :kind :page :selected (:id page)))))))) +(defn show-track-context-menu + [{:keys [grid-id type index] :as params}] + (ptk/reify ::show-track-context-menu + ptk/WatchEvent + (watch [_ _ _] + (rx/of (show-context-menu + (-> params (assoc :kind :grid-track + :grid-id grid-id + :type type + :index index))))))) + +(defn show-grid-cell-context-menu + [{:keys [grid-id] :as params}] + (ptk/reify ::show-grid-cell-context-menu + ptk/WatchEvent + (watch [_ state _] + (let [cells (get-in state [:workspace-grid-edition grid-id :selected])] + (rx/of (show-context-menu + (-> params (assoc :kind :grid-cells + :grid-id grid-id + :cells cells)))))))) (def hide-context-menu (ptk/reify ::hide-context-menu ptk/UpdateEvent @@ -1497,6 +1518,8 @@ (assoc-in state [:workspace-local :context-menu] nil)))) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Clipboard ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/frontend/src/app/main/data/workspace/shape_layout.cljs b/frontend/src/app/main/data/workspace/shape_layout.cljs index e89f415ea7..98624d1286 100644 --- a/frontend/src/app/main/data/workspace/shape_layout.cljs +++ b/frontend/src/app/main/data/workspace/shape_layout.cljs @@ -9,7 +9,9 @@ [app.common.colors :as clr] [app.common.data :as d] [app.common.data.macros :as dm] + [app.common.files.changes-builder :as pcb] [app.common.files.helpers :as cfh] + [app.common.geom.point :as gpt] [app.common.geom.shapes.flex-layout :as flex] [app.common.geom.shapes.grid-layout :as grid] [app.common.types.component :as ctc] @@ -247,27 +249,29 @@ (dwu/commit-undo-transaction undo-id)))))) (defn add-layout-track - [ids type value] - (assert (#{:row :column} type)) - (ptk/reify ::add-layout-column - ptk/WatchEvent - (watch [_ _ _] - (let [undo-id (js/Symbol)] - (rx/of (dwu/start-undo-transaction undo-id) - (dwc/update-shapes - ids - (fn [shape] - (case type - :row (ctl/add-grid-row shape value) - :column (ctl/add-grid-column shape value)))) - (ptk/data-event :layout/update ids) - (dwu/commit-undo-transaction undo-id)))))) + ([ids type value] + (add-layout-track ids type value nil)) + ([ids type value index] + (assert (#{:row :column} type)) + (ptk/reify ::add-layout-track + ptk/WatchEvent + (watch [_ _ _] + (let [undo-id (js/Symbol)] + (rx/of (dwu/start-undo-transaction undo-id) + (dwc/update-shapes + ids + (fn [shape] + (case type + :row (ctl/add-grid-row shape value index) + :column (ctl/add-grid-column shape value index)))) + (ptk/data-event :layout/update ids) + (dwu/commit-undo-transaction undo-id))))))) (defn remove-layout-track [ids type index] (assert (#{:row :column} type)) - (ptk/reify ::remove-layout-column + (ptk/reify ::remove-layout-track ptk/WatchEvent (watch [_ _ _] (let [undo-id (js/Symbol)] @@ -281,6 +285,59 @@ (ptk/data-event :layout/update ids) (dwu/commit-undo-transaction undo-id)))))) +(defn duplicate-layout-track + [ids type index] + (assert (#{:row :column} type)) + + (ptk/reify ::duplicate-layout-track + ptk/WatchEvent + (watch [it state _] + (let [file-id (:current-file-id state) + page (wsh/lookup-page state) + objects (:objects page) + libraries (wsh/get-libraries state) + library-data (wsh/get-file state file-id) + shape-id (first ids) + base-shape (get objects shape-id) + + shapes-by-track + (if (= type :column) + (ctl/shapes-by-column base-shape index false) + (ctl/shapes-by-row base-shape index false)) + + ;; Change to set in order to use auxiliary functions + selected (set shapes-by-track) + + changes + (->> (dwse/prepare-duplicate-changes objects page selected (gpt/point 0 0) it libraries library-data file-id) + (dwse/duplicate-changes-update-indices objects selected)) + + ;; Creates a map with shape-id => duplicated-shape-id + ids-map + (->> changes + :redo-changes + (filter #(= (:type %) :add-obj)) + (filter #(selected (:old-id %))) + (map #(vector (:old-id %) (get-in % [:obj :id]))) + (into {})) + + changes + (-> changes + (pcb/update-shapes + ids + (fn [shape] + ;; The duplication could have altered the grid so we restore the values, we'll calculate the good ones now + (let [shape (merge shape (select-keys base-shape [:layout-grid-cells :layout-grid-columns :layout-grid-rows]))] + (case type + :row (ctl/duplicate-row shape index ids-map) + :column (ctl/duplicate-column shape index ids-map)))))) + + undo-id (js/Symbol)] + (rx/of (dwu/start-undo-transaction undo-id) + (dwc/commit-changes changes) + (ptk/data-event :layout/update ids) + (dwu/commit-undo-transaction undo-id)))))) + (defn reorder-layout-track [ids type from-index to-index move-content?] (assert (#{:row :column} type)) diff --git a/frontend/src/app/main/ui/workspace/context_menu.cljs b/frontend/src/app/main/ui/workspace/context_menu.cljs index b028ad0014..7107b5a47f 100644 --- a/frontend/src/app/main/ui/workspace/context_menu.cljs +++ b/frontend/src/app/main/ui/workspace/context_menu.cljs @@ -14,6 +14,7 @@ [app.common.types.component :as ctk] [app.common.types.container :as ctn] [app.common.types.page :as ctp] + [app.common.types.shape.layout :as ctl] [app.common.uuid :as uuid] [app.main.data.events :as ev] [app.main.data.modal :as modal] @@ -549,6 +550,64 @@ :shortcut (sc/get-tooltip :toggle-focus-mode) :on-click do-toggle-focus-mode}])])) +(mf/defc grid-track-context-menu + [{:keys [mdata] :as props}] + (let [{:keys [type index grid-id]} mdata + do-delete-track + (mf/use-callback + (mf/deps grid-id type index) + (fn [] + (st/emit! (dwsl/remove-layout-track [grid-id] type index)))) + + do-add-track-before + (mf/use-callback + (mf/deps grid-id type index) + (fn [] + (st/emit! (dwsl/add-layout-track [grid-id] type ctl/default-track-value index)))) + + do-add-track-after + (mf/use-callback + (mf/deps grid-id type index) + (fn [] + (st/emit! (dwsl/add-layout-track [grid-id] type ctl/default-track-value (inc index))))) + + do-duplicate-track + (mf/use-callback + (mf/deps grid-id type index) + (fn [] + (st/emit! (dwsl/duplicate-layout-track [grid-id] type index))))] + + (if (= type :column) + [:* + [:& menu-entry {:title "Duplicate column" :on-click do-duplicate-track}] + [:& menu-entry {:title "Add 1 column to the left" :on-click do-add-track-before}] + [:& menu-entry {:title "Add 1 column to the right" :on-click do-add-track-after}] + [:& menu-entry {:title "Delete column" :on-click do-delete-track}]] + + [:* + [:& menu-entry {:title "Duplicate row" :on-click do-duplicate-track}] + [:& menu-entry {:title "Add 1 row above" :on-click do-add-track-before}] + [:& menu-entry {:title "Add 1 row bellow" :on-click do-add-track-after}] + [:& menu-entry {:title "Delete row" :on-click do-delete-track}]]))) + +(mf/defc grid-cells-context-menu + [{:keys [mdata] :as props}] + (let [{:keys [grid-id cells]} mdata + + do-merge-cells + (mf/use-callback + (mf/deps grid-id cells) + (fn [])) + + do-create-board + (mf/use-callback + (mf/deps grid-id cells) + (fn []))] + [:* + [:& menu-entry {:title "Merge cells" :on-click do-merge-cells}] + [:& menu-entry {:title "Create board" :on-click do-create-board}]])) + + (mf/defc context-menu [] (let [mdata (mf/deref menu-ref) @@ -583,6 +642,8 @@ (case (:kind mdata) :shape [:& shape-context-menu {:mdata mdata}] :page [:& page-item-context-menu {:mdata mdata}] + :grid-track [:& grid-track-context-menu {:mdata mdata}] + :grid-cells [:& grid-cells-context-menu {:mdata mdata}] [:& viewport-context-menu {:mdata mdata}])]])) 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 ddac9377a5..ddc740d96d 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,9 +337,18 @@ (mf/use-callback (mf/deps (:id shape) (:id cell) selected?) (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)) ))))] + (when (or (dom/left-mouse? event) (not selected?)) + (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))))))) + + handle-context-menu + (mf/use-callback + (fn [event] + (dom/prevent-default event) + (dom/stop-propagation event) + (let [position (dom/get-client-position event)] + (st/emit! (dw/show-grid-cell-context-menu {:position position :grid-id (:id shape)})))))] [:g.cell-editor [:rect @@ -352,6 +361,7 @@ :width cell-width :height cell-height + :on-context-menu handle-context-menu :on-pointer-enter handle-pointer-enter :on-pointer-leave handle-pointer-leave :on-pointer-down handle-pointer-down}] @@ -746,12 +756,6 @@ (fn [] (st/emit! (dwsl/hover-layout-track [(:id shape)] type index false)))) - handle-remove-track - (mf/use-callback - (mf/deps (:id shape) type index) - (fn [] - (st/emit! (dwsl/remove-layout-track [(:id shape)] type index)))) - track-list-prop (if (= type :column) :column-tracks :row-tracks) [text-x text-y text-width text-height] (if (= type :column) @@ -776,6 +780,19 @@ (fn [_ position] (on-move-reorder-track type index position))) + handle-show-track-menu + (mf/use-callback + (fn [event] + (dom/stop-propagation event) + (dom/prevent-default event) + (let [position (cond-> (dom/get-client-position event) + (= type :column) (update :y + 40) + (= type :row) (update :x + 30))] + (st/emit! (dw/show-track-context-menu {:position position + :grid-id (:id shape) + :type type + :index index}))))) + trackwidth (* text-width zoom) medium? (and (>= trackwidth small-size-limit) (< trackwidth medium-size-limit)) small? (< trackwidth small-size-limit) @@ -811,6 +828,7 @@ (when (not small?) [:foreignObject {:x text-x :y text-y :width text-width :height text-height} [:div {:class (stl/css :grid-editor-wrapper) + :on-context-menu handle-show-track-menu :on-pointer-down handle-pointer-down :on-lost-pointer-capture handle-lost-pointer-capture :on-pointer-move handle-pointer-move} @@ -825,7 +843,7 @@ :on-blur handle-blur-track-input}] (when (and hovering? (not medium?) (not small?)) [:button {:class (stl/css :grid-editor-button) - :on-click handle-remove-track} i/delete-refactor])]])] + :on-click handle-show-track-menu} i/menu-refactor])]])] [:g {:transform (when (= type :row) (dm/fmt "rotate(-90 % %)" (:x marker-p) (:y marker-p)))} [:& track-marker @@ -952,7 +970,7 @@ handle-start-reorder-track (mf/use-callback (mf/deps layout-data) - (fn [type from-idx] + (fn [type _from-idx] ;; Initialize target-tracks (let [line-vec (if (= type :column) (vv 1) (hv 1)) @@ -979,7 +997,7 @@ handle-move-reorder-track (mf/use-callback - (fn [type from-idx position] + (fn [_type _from-idx position] (let [index (->> (mf/ref-val target-tracks*) (d/seek (fn [[[p1 p2 v] _]] @@ -991,7 +1009,7 @@ handle-end-reorder-track (mf/use-callback (mf/deps base-shape @drop-track-target*) - (fn [type from-index position move-content?] + (fn [type from-index _position move-content?] (when-let [to-index @drop-track-target*] (let [ids [(:id base-shape)]] (cond