mirror of
https://github.com/penpot/penpot.git
synced 2025-03-11 07:11:32 -05:00
✨ Right click options on grid editor
This commit is contained in:
parent
da358d635b
commit
9ed3ad2f3c
6 changed files with 422 additions and 112 deletions
|
@ -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."
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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}])]]))
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue