0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-04-14 16:01:24 -05:00

Grid layers order

This commit is contained in:
alonso.torres 2023-06-05 18:07:41 +02:00
parent e86939b8ee
commit 9b8ef35603
8 changed files with 125 additions and 54 deletions

View file

@ -17,6 +17,7 @@
[app.common.pages.helpers :as cph]
[app.common.types.component :as ctk]
[app.common.types.file :as ctf]
[app.common.types.shape.layout :as ctl]
[app.common.uuid :as uuid]))
;; Auxiliary functions to help create a set of changes (undo + redo)
@ -712,3 +713,42 @@
(-> changes
(update :redo-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))

View file

@ -595,7 +595,7 @@
layout-grid-cells
(->> (d/enumerate rows)
(reduce (fn [result [row-idx _row]]
(reduce (fn [result [row-idx _]]
(let [id (uuid/next)]
(assoc result id
(merge {:id id
@ -618,7 +618,7 @@
layout-grid-cells
(->> (d/enumerate cols)
(reduce (fn [result [col-idx _col]]
(reduce (fn [result [col-idx _]]
(let [id (uuid/next)]
(assoc result id
(merge {:id id
@ -699,16 +699,20 @@
([parent]
(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)
(juxt :row :column)
(juxt :column :row))
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
(maybe-sort?)
(maybe-remove?)
(map (fn [[id cell]] (assoc cell :id id)))))))
(defn get-free-cells
@ -739,7 +743,35 @@
(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
;; 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
@ -798,6 +830,8 @@
cells (update-in cells [next-free :shapes] conj current)]
(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)))))
(defn free-cell-push
@ -1009,3 +1043,29 @@
(cond-> (some? cell)
(push-into-cell children row column))
(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)))))

View file

@ -785,11 +785,17 @@
parent)))
;; 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
(fn [parent]
(cond-> parent
(ctl/grid-layout? parent)
(ctl/assign-cells))))
(pcb/reorder-grid-children parents)
;; Resize parent containers that need to
(pcb/resize-parents parents))))

View file

@ -80,6 +80,7 @@
(pcb/set-stack-undo? stack-undo?)
(pcb/with-objects objects))
ids)
changes (pcb/reorder-grid-children changes ids)
changes (add-undo-group changes state)]
(rx/concat
(if (seq (:redo-changes changes))

View file

@ -450,7 +450,8 @@
changes (-> (pcb/add-object changes new-obj)
(pcb/amend-last-change #(assoc % :old-id (: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
(and is-component-root? is-component-main?)

View file

@ -196,7 +196,9 @@
(assoc :layout-item-h-sizing :auto
:layout-item-v-sizing :auto))
(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)
(dwc/update-shapes children-ids #(dissoc % :constraints-h :constraints-v))
(dwu/commit-undo-transaction undo-id))))))
@ -370,48 +372,6 @@
(ptk/data-event :layout/update ids)
(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
[ids type value]
(assert (#{:row :column} type))

View file

@ -95,8 +95,8 @@
(cond-> (some? cell)
(pcb/update-shapes [(:parent-id shape)] #(ctl/push-into-cell % [id] row column)))
(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]))
(defn add-shape
@ -144,7 +144,8 @@
(pcb/update-shapes ordered-indexes #(cond-> % (cph/frame-shape? %) (assoc :hide-in-viewer true)))
(pcb/change-parent frame-id to-move-shapes 0)
(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
[frame-id shapes]

View file

@ -539,8 +539,8 @@
(fn [[_ target-frame drop-index]]
(let [undo-id (js/Symbol)]
(rx/of (dwu/start-undo-transaction undo-id)
(move-shapes-to-frame ids target-frame drop-index)
(dwm/apply-modifiers {:undo-transation? false})
(move-shapes-to-frame ids target-frame drop-index)
(finish-transform)
(dwu/commit-undo-transaction undo-id))))))))))))))
@ -608,7 +608,8 @@
(ctl/swap-shapes id (:id next-cell)))))
parent))]
(-> 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
(->> selected
@ -812,6 +813,7 @@
(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/change-parent frame-id moving-shapes drop-index)
(pcb/reorder-grid-children [frame-id])
(pcb/remove-objects empty-parents))]
(when (and (some? frame-id) (d/not-empty? changes))