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:
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.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))
|
||||
|
|
|
@ -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)))))
|
||||
|
|
|
@ -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))))
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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?)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Add table
Reference in a new issue