mirror of
https://github.com/penpot/penpot.git
synced 2025-08-07 14:38:33 +02:00
✨ Grid layers order
This commit is contained in:
parent
e86939b8ee
commit
9b8ef35603
8 changed files with 125 additions and 54 deletions
|
@ -17,6 +17,7 @@
|
||||||
[app.common.pages.helpers :as cph]
|
[app.common.pages.helpers :as cph]
|
||||||
[app.common.types.component :as ctk]
|
[app.common.types.component :as ctk]
|
||||||
[app.common.types.file :as ctf]
|
[app.common.types.file :as ctf]
|
||||||
|
[app.common.types.shape.layout :as ctl]
|
||||||
[app.common.uuid :as uuid]))
|
[app.common.uuid :as uuid]))
|
||||||
|
|
||||||
;; Auxiliary functions to help create a set of changes (undo + redo)
|
;; Auxiliary functions to help create a set of changes (undo + redo)
|
||||||
|
@ -712,3 +713,42 @@
|
||||||
(-> changes
|
(-> changes
|
||||||
(update :redo-changes add-ignore-remote)
|
(update :redo-changes add-ignore-remote)
|
||||||
(update :undo-changes add-ignore-remote))))
|
(update :undo-changes add-ignore-remote))))
|
||||||
|
|
||||||
|
(defn reorder-grid-children
|
||||||
|
[changes ids]
|
||||||
|
(assert-page-id changes)
|
||||||
|
(assert-objects changes)
|
||||||
|
|
||||||
|
(let [page-id (::page-id (meta changes))
|
||||||
|
objects (lookup-objects changes)
|
||||||
|
|
||||||
|
reorder-grid
|
||||||
|
(fn [changes grid]
|
||||||
|
(let [old-shapes (:shapes grid)
|
||||||
|
grid (ctl/reorder-grid-children grid)
|
||||||
|
|
||||||
|
redo-change
|
||||||
|
{:type :mov-objects
|
||||||
|
:parent-id (:id grid)
|
||||||
|
:page-id page-id
|
||||||
|
:shapes (:shapes grid)
|
||||||
|
:index 0}
|
||||||
|
|
||||||
|
undo-change
|
||||||
|
{:type :mov-objects
|
||||||
|
:parent-id (:id grid)
|
||||||
|
:page-id page-id
|
||||||
|
:shapes old-shapes
|
||||||
|
:index 0}]
|
||||||
|
(-> changes
|
||||||
|
(update :redo-changes conj redo-change)
|
||||||
|
(update :undo-changes d/preconj undo-change)
|
||||||
|
(apply-changes-local))))
|
||||||
|
|
||||||
|
changes
|
||||||
|
(->> ids
|
||||||
|
(map (d/getf objects))
|
||||||
|
(filter ctl/grid-layout?)
|
||||||
|
(reduce reorder-grid changes))]
|
||||||
|
|
||||||
|
changes))
|
||||||
|
|
|
@ -595,7 +595,7 @@
|
||||||
|
|
||||||
layout-grid-cells
|
layout-grid-cells
|
||||||
(->> (d/enumerate rows)
|
(->> (d/enumerate rows)
|
||||||
(reduce (fn [result [row-idx _row]]
|
(reduce (fn [result [row-idx _]]
|
||||||
(let [id (uuid/next)]
|
(let [id (uuid/next)]
|
||||||
(assoc result id
|
(assoc result id
|
||||||
(merge {:id id
|
(merge {:id id
|
||||||
|
@ -618,7 +618,7 @@
|
||||||
|
|
||||||
layout-grid-cells
|
layout-grid-cells
|
||||||
(->> (d/enumerate cols)
|
(->> (d/enumerate cols)
|
||||||
(reduce (fn [result [col-idx _col]]
|
(reduce (fn [result [col-idx _]]
|
||||||
(let [id (uuid/next)]
|
(let [id (uuid/next)]
|
||||||
(assoc result id
|
(assoc result id
|
||||||
(merge {:id id
|
(merge {:id id
|
||||||
|
@ -699,16 +699,20 @@
|
||||||
([parent]
|
([parent]
|
||||||
(get-cells parent nil))
|
(get-cells parent nil))
|
||||||
|
|
||||||
([{:keys [layout-grid-cells layout-grid-dir]} {:keys [sort?] :or {sort? false}}]
|
([{:keys [layout-grid-cells layout-grid-dir]} {:keys [sort? remove-empty?] :or {sort? false remove-empty? false}}]
|
||||||
(let [comp-fn (if (= layout-grid-dir :row)
|
(let [comp-fn (if (= layout-grid-dir :row)
|
||||||
(juxt :row :column)
|
(juxt :row :column)
|
||||||
(juxt :column :row))
|
(juxt :column :row))
|
||||||
|
|
||||||
maybe-sort?
|
maybe-sort?
|
||||||
(if sort? (partial sort-by (comp comp-fn second)) identity)]
|
(if sort? (partial sort-by (comp comp-fn second)) identity)
|
||||||
|
|
||||||
|
maybe-remove?
|
||||||
|
(if remove-empty? (partial remove #(empty? (:shapes (second %)))) identity)]
|
||||||
|
|
||||||
(->> layout-grid-cells
|
(->> layout-grid-cells
|
||||||
(maybe-sort?)
|
(maybe-sort?)
|
||||||
|
(maybe-remove?)
|
||||||
(map (fn [[id cell]] (assoc cell :id id)))))))
|
(map (fn [[id cell]] (assoc cell :id id)))))))
|
||||||
|
|
||||||
(defn get-free-cells
|
(defn get-free-cells
|
||||||
|
@ -739,7 +743,35 @@
|
||||||
|
|
||||||
(assoc parent :layout-grid-cells cells)))
|
(assoc parent :layout-grid-cells cells)))
|
||||||
|
|
||||||
;; TODO
|
(defn overlapping-cells
|
||||||
|
"Find overlapping cells"
|
||||||
|
[parent]
|
||||||
|
(let [cells (->> parent
|
||||||
|
:layout-grid-cells
|
||||||
|
(map (fn [[id cell]]
|
||||||
|
[id (sga/make-area cell)])))
|
||||||
|
find-overlaps
|
||||||
|
(fn [result [id area]]
|
||||||
|
(let [[fid _]
|
||||||
|
(d/seek #(and (not= (first %) id)
|
||||||
|
(sga/intersects? (second %) area))
|
||||||
|
cells)]
|
||||||
|
(cond-> result
|
||||||
|
(some? fid)
|
||||||
|
(conj #{id fid}))))]
|
||||||
|
(reduce find-overlaps #{} cells)))
|
||||||
|
|
||||||
|
;; FIXME: This is only for development
|
||||||
|
#_(defn fix-overlaps
|
||||||
|
[parent overlaps]
|
||||||
|
(reduce (fn [parent ids]
|
||||||
|
(let [id (if (empty? (get-in parent [:layout-grid-cells (first ids)]))
|
||||||
|
(first ids)
|
||||||
|
(second ids))]
|
||||||
|
(update parent :layout-grid-cells dissoc id)))
|
||||||
|
parent
|
||||||
|
overlaps))
|
||||||
|
|
||||||
;; Assign cells takes the children and move them into the allotted cells. If there are not enough cells it creates
|
;; Assign cells takes the children and move them into the allotted cells. If there are not enough cells it creates
|
||||||
;; not-tracked rows/columns and put the shapes there
|
;; not-tracked rows/columns and put the shapes there
|
||||||
;; Non-tracked tracks need to be deleted when they are empty and there are no more shapes unallocated
|
;; Non-tracked tracks need to be deleted when they are empty and there are no more shapes unallocated
|
||||||
|
@ -798,6 +830,8 @@
|
||||||
cells (update-in cells [next-free :shapes] conj current)]
|
cells (update-in cells [next-free :shapes] conj current)]
|
||||||
(recur cells (rest free-cells) (rest pending)))))]
|
(recur cells (rest free-cells) (rest pending)))))]
|
||||||
|
|
||||||
|
;; TODO: Remove after testing
|
||||||
|
(assert (empty? (overlapping-cells parent)) (dm/str (overlapping-cells parent)))
|
||||||
(assoc parent :layout-grid-cells cells)))))
|
(assoc parent :layout-grid-cells cells)))))
|
||||||
|
|
||||||
(defn free-cell-push
|
(defn free-cell-push
|
||||||
|
@ -1009,3 +1043,29 @@
|
||||||
(cond-> (some? cell)
|
(cond-> (some? cell)
|
||||||
(push-into-cell children row column))
|
(push-into-cell children row column))
|
||||||
(assign-cells))))
|
(assign-cells))))
|
||||||
|
|
||||||
|
(defn add-children-to-index
|
||||||
|
[parent ids objects to-index]
|
||||||
|
(let [ids (into (d/ordered-set) ids)
|
||||||
|
cells (get-cells parent {:sort? true :remove-empty? true})
|
||||||
|
to-index (- (count cells) to-index)
|
||||||
|
target-cell (nth cells to-index nil)]
|
||||||
|
|
||||||
|
(cond-> parent
|
||||||
|
(some? target-cell)
|
||||||
|
(add-children-to-cell ids objects [(:row target-cell) (:column target-cell)]))))
|
||||||
|
|
||||||
|
(defn reorder-grid-children
|
||||||
|
[parent]
|
||||||
|
(let [cells (get-cells parent {:sort? true})
|
||||||
|
child? (set (:shapes parent))
|
||||||
|
new-shapes
|
||||||
|
(into (d/ordered-set)
|
||||||
|
(comp (keep (comp first :shapes))
|
||||||
|
(filter child?))
|
||||||
|
cells)
|
||||||
|
|
||||||
|
;; Add the children that are not in cells (absolute positioned for example)
|
||||||
|
new-shapes (into new-shapes (:shapes parent))]
|
||||||
|
|
||||||
|
(assoc parent :shapes (into [] (reverse new-shapes)))))
|
||||||
|
|
|
@ -785,11 +785,17 @@
|
||||||
parent)))
|
parent)))
|
||||||
|
|
||||||
;; Update grid layout
|
;; Update grid layout
|
||||||
|
(cond-> (ctl/grid-layout? objects parent-id)
|
||||||
|
(pcb/update-shapes [parent-id] #(ctl/add-children-to-index % ids objects to-index)))
|
||||||
|
|
||||||
(pcb/update-shapes parents
|
(pcb/update-shapes parents
|
||||||
(fn [parent]
|
(fn [parent]
|
||||||
(cond-> parent
|
(cond-> parent
|
||||||
(ctl/grid-layout? parent)
|
(ctl/grid-layout? parent)
|
||||||
(ctl/assign-cells))))
|
(ctl/assign-cells))))
|
||||||
|
|
||||||
|
(pcb/reorder-grid-children parents)
|
||||||
|
|
||||||
;; Resize parent containers that need to
|
;; Resize parent containers that need to
|
||||||
(pcb/resize-parents parents))))
|
(pcb/resize-parents parents))))
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,7 @@
|
||||||
(pcb/set-stack-undo? stack-undo?)
|
(pcb/set-stack-undo? stack-undo?)
|
||||||
(pcb/with-objects objects))
|
(pcb/with-objects objects))
|
||||||
ids)
|
ids)
|
||||||
|
changes (pcb/reorder-grid-children changes ids)
|
||||||
changes (add-undo-group changes state)]
|
changes (add-undo-group changes state)]
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(if (seq (:redo-changes changes))
|
(if (seq (:redo-changes changes))
|
||||||
|
|
|
@ -450,7 +450,8 @@
|
||||||
changes (-> (pcb/add-object changes new-obj)
|
changes (-> (pcb/add-object changes new-obj)
|
||||||
(pcb/amend-last-change #(assoc % :old-id (:id obj)))
|
(pcb/amend-last-change #(assoc % :old-id (:id obj)))
|
||||||
(cond-> (ctl/grid-layout? objects (:parent-id obj))
|
(cond-> (ctl/grid-layout? objects (:parent-id obj))
|
||||||
(pcb/update-shapes [(:parent-id obj)] ctl/assign-cells)))
|
(-> (pcb/update-shapes [(:parent-id obj)] ctl/assign-cells)
|
||||||
|
(pcb/reorder-grid-children [(:parent-id obj)]))))
|
||||||
|
|
||||||
changes (cond-> changes
|
changes (cond-> changes
|
||||||
(and is-component-root? is-component-main?)
|
(and is-component-root? is-component-main?)
|
||||||
|
|
|
@ -196,7 +196,9 @@
|
||||||
(assoc :layout-item-h-sizing :auto
|
(assoc :layout-item-h-sizing :auto
|
||||||
:layout-item-v-sizing :auto))
|
:layout-item-v-sizing :auto))
|
||||||
(merge layout-params)
|
(merge layout-params)
|
||||||
(cond-> (= type :grid) (ctl/assign-cells)))))
|
(cond-> (= type :grid)
|
||||||
|
(-> (ctl/assign-cells)
|
||||||
|
(ctl/reorder-grid-children))))))
|
||||||
(ptk/data-event :layout/update ids)
|
(ptk/data-event :layout/update ids)
|
||||||
(dwc/update-shapes children-ids #(dissoc % :constraints-h :constraints-v))
|
(dwc/update-shapes children-ids #(dissoc % :constraints-h :constraints-v))
|
||||||
(dwu/commit-undo-transaction undo-id))))))
|
(dwu/commit-undo-transaction undo-id))))))
|
||||||
|
@ -370,48 +372,6 @@
|
||||||
(ptk/data-event :layout/update ids)
|
(ptk/data-event :layout/update ids)
|
||||||
(dwu/commit-undo-transaction undo-id))))))
|
(dwu/commit-undo-transaction undo-id))))))
|
||||||
|
|
||||||
#_(defn update-grid-cells
|
|
||||||
[parent objects]
|
|
||||||
(let [children (cph/get-immediate-children objects (:id parent))
|
|
||||||
layout-grid-rows (:layout-grid-rows parent)
|
|
||||||
layout-grid-columns (:layout-grid-columns parent)
|
|
||||||
num-rows (count layout-grid-columns)
|
|
||||||
num-columns (count layout-grid-columns)
|
|
||||||
layout-grid-cells (:layout-grid-cells parent)
|
|
||||||
|
|
||||||
allocated-shapes
|
|
||||||
(into #{} (mapcat :shapes) (:layout-grid-cells parent))
|
|
||||||
|
|
||||||
no-cell-shapes
|
|
||||||
(->> children (:shapes parent) (remove allocated-shapes))
|
|
||||||
|
|
||||||
layout-grid-cells
|
|
||||||
(for [[row-idx row] (d/enumerate layout-grid-rows)
|
|
||||||
[col-idx col] (d/enumerate layout-grid-columns)]
|
|
||||||
|
|
||||||
(let [shape (nth children (+ (* row-idx num-columns) col-idx) nil)
|
|
||||||
cell-data {:id (uuid/next)
|
|
||||||
:row (inc row-idx)
|
|
||||||
:column (inc col-idx)
|
|
||||||
:row-span 1
|
|
||||||
:col-span 1
|
|
||||||
:shapes (when shape [(:id shape)])}]
|
|
||||||
[(:id cell-data) cell-data]))]
|
|
||||||
(assoc parent :layout-grid-cells (into {} layout-grid-cells))))
|
|
||||||
|
|
||||||
#_(defn check-grid-cells-update
|
|
||||||
[ids]
|
|
||||||
(ptk/reify ::check-grid-cells-update
|
|
||||||
ptk/WatchEvent
|
|
||||||
(watch [_ state _]
|
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
|
||||||
undo-id (js/Symbol)]
|
|
||||||
(rx/of (dwc/update-shapes
|
|
||||||
ids
|
|
||||||
(fn [shape]
|
|
||||||
(-> shape
|
|
||||||
(update-grid-cells objects)))))))))
|
|
||||||
|
|
||||||
(defn add-layout-track
|
(defn add-layout-track
|
||||||
[ids type value]
|
[ids type value]
|
||||||
(assert (#{:row :column} type))
|
(assert (#{:row :column} type))
|
||||||
|
|
|
@ -95,8 +95,8 @@
|
||||||
(cond-> (some? cell)
|
(cond-> (some? cell)
|
||||||
(pcb/update-shapes [(:parent-id shape)] #(ctl/push-into-cell % [id] row column)))
|
(pcb/update-shapes [(:parent-id shape)] #(ctl/push-into-cell % [id] row column)))
|
||||||
(cond-> (ctl/grid-layout? objects (:parent-id shape))
|
(cond-> (ctl/grid-layout? objects (:parent-id shape))
|
||||||
(pcb/update-shapes [(:parent-id shape)] ctl/assign-cells)))]
|
(-> (pcb/update-shapes [(:parent-id shape)] ctl/assign-cells)
|
||||||
|
(pcb/reorder-grid-children [(:parent-id shape)]))))]
|
||||||
[shape changes]))
|
[shape changes]))
|
||||||
|
|
||||||
(defn add-shape
|
(defn add-shape
|
||||||
|
@ -144,7 +144,8 @@
|
||||||
(pcb/update-shapes ordered-indexes #(cond-> % (cph/frame-shape? %) (assoc :hide-in-viewer true)))
|
(pcb/update-shapes ordered-indexes #(cond-> % (cph/frame-shape? %) (assoc :hide-in-viewer true)))
|
||||||
(pcb/change-parent frame-id to-move-shapes 0)
|
(pcb/change-parent frame-id to-move-shapes 0)
|
||||||
(cond-> (ctl/grid-layout? objects frame-id)
|
(cond-> (ctl/grid-layout? objects frame-id)
|
||||||
(pcb/update-shapes [frame-id] ctl/assign-cells))))))
|
(pcb/update-shapes [frame-id] ctl/assign-cells))
|
||||||
|
(pcb/reorder-grid-children [frame-id])))))
|
||||||
|
|
||||||
(defn move-shapes-into-frame
|
(defn move-shapes-into-frame
|
||||||
[frame-id shapes]
|
[frame-id shapes]
|
||||||
|
|
|
@ -539,8 +539,8 @@
|
||||||
(fn [[_ target-frame drop-index]]
|
(fn [[_ target-frame drop-index]]
|
||||||
(let [undo-id (js/Symbol)]
|
(let [undo-id (js/Symbol)]
|
||||||
(rx/of (dwu/start-undo-transaction undo-id)
|
(rx/of (dwu/start-undo-transaction undo-id)
|
||||||
(move-shapes-to-frame ids target-frame drop-index)
|
|
||||||
(dwm/apply-modifiers {:undo-transation? false})
|
(dwm/apply-modifiers {:undo-transation? false})
|
||||||
|
(move-shapes-to-frame ids target-frame drop-index)
|
||||||
(finish-transform)
|
(finish-transform)
|
||||||
(dwu/commit-undo-transaction undo-id))))))))))))))
|
(dwu/commit-undo-transaction undo-id))))))))))))))
|
||||||
|
|
||||||
|
@ -608,7 +608,8 @@
|
||||||
(ctl/swap-shapes id (:id next-cell)))))
|
(ctl/swap-shapes id (:id next-cell)))))
|
||||||
parent))]
|
parent))]
|
||||||
(-> changes
|
(-> changes
|
||||||
(pcb/update-shapes [(:id parent)] (fn [shape] (assoc shape :layout-grid-cells layout-grid-cells))))))
|
(pcb/update-shapes [(:id parent)] (fn [shape] (assoc shape :layout-grid-cells layout-grid-cells)))
|
||||||
|
(pcb/reorder-grid-children [(:id parent)]))))
|
||||||
|
|
||||||
changes
|
changes
|
||||||
(->> selected
|
(->> selected
|
||||||
|
@ -812,6 +813,7 @@
|
||||||
(pcb/update-shapes moving-shapes-ids #(cond-> % (cph/frame-shape? %) (assoc :hide-in-viewer true)))
|
(pcb/update-shapes moving-shapes-ids #(cond-> % (cph/frame-shape? %) (assoc :hide-in-viewer true)))
|
||||||
(pcb/update-shapes shape-ids-to-detach ctk/detach-shape)
|
(pcb/update-shapes shape-ids-to-detach ctk/detach-shape)
|
||||||
(pcb/change-parent frame-id moving-shapes drop-index)
|
(pcb/change-parent frame-id moving-shapes drop-index)
|
||||||
|
(pcb/reorder-grid-children [frame-id])
|
||||||
(pcb/remove-objects empty-parents))]
|
(pcb/remove-objects empty-parents))]
|
||||||
|
|
||||||
(when (and (some? frame-id) (d/not-empty? changes))
|
(when (and (some? frame-id) (d/not-empty? changes))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue