Allows groups to reflow the layout on transform

This commit is contained in:
alonso.torres 2022-07-06 12:40:07 +02:00 committed by Andrey Antukh
parent 84c0825893
commit 6e5a23c190
4 changed files with 92 additions and 31 deletions

View file

@ -75,7 +75,6 @@
[children-width children-height] [children-width children-height]
(->> children (->> children
(map #(-> (merge % (get modif-tree (:id %))) gtr/transform-shape))
(reduce (fn [[acc-width acc-height] shape] (reduce (fn [[acc-width acc-height] shape]
[(+ acc-width (-> shape :points gre/points->rect :width)) [(+ acc-width (-> shape :points gre/points->rect :width))
(+ acc-height (-> shape :points gre/points->rect :height))]) [0 0])) (+ acc-height (-> shape :points gre/points->rect :height))]) [0 0]))
@ -99,7 +98,7 @@
0) 0)
margin-y (if (and (row? shape) (= :space-around layout-type)) margin-y (if (and (row? shape) (= :space-around layout-type))
(/ (- height children-height) (dec num-children) 2) (/ (- height children-height) (inc num-children))
0) 0)
children-gap (* layout-gap (dec num-children)) children-gap (* layout-gap (dec num-children))
@ -199,20 +198,17 @@
layout-data layout-data
(assoc layout-data :start-x next-x :start-y next-y)] (assoc layout-data :start-x next-x :start-y next-y)]
[corner-p layout-data]) [corner-p layout-data]))
)
(defn calc-layout-modifiers (defn calc-layout-modifiers
"Calculates the modifiers for the layout" "Calculates the modifiers for the layout"
[parent child modifiers layout-data] [parent child layout-data]
(let [modifiers (-> modifiers (dissoc :displacement-after)) (let [bounds (-> child :points gre/points->selrect)
child (-> child (assoc :modifiers modifiers) gtr/transform-shape)
bounds (-> child :points gre/points->selrect)
[corner-p layout-data] (next-p parent bounds layout-data) [corner-p layout-data] (next-p parent bounds layout-data)
delta-p (-> corner-p (gpt/subtract (gpt/point bounds))) delta-p (-> corner-p (gpt/subtract (gpt/point bounds)))
modifiers (-> modifiers (assoc :displacement-after (gmt/translate-matrix delta-p)))] modifiers {:displacement-after (gmt/translate-matrix delta-p)}]
[modifiers layout-data])) [modifiers layout-data]))

View file

@ -119,27 +119,51 @@
resize-modif? (or (:resize-vector modifiers) (:resize-vector-2 modifiers))] resize-modif? (or (:resize-vector modifiers) (:resize-vector-2 modifiers))]
(reduce (partial set-child transformed-rect (and snap-pixel? resize-modif?)) modif-tree children)))) (reduce (partial set-child transformed-rect (and snap-pixel? resize-modif?)) modif-tree children))))
(defn group? [shape]
(or (= :group (:type shape))
(= :bool (:type shape))))
(defn merge-modifiers
[modif-tree ids modifiers]
(reduce
(fn [modif-tree id]
(update-in modif-tree [id :modifiers] #(merge % modifiers)))
modif-tree
ids))
(defn set-layout-modifiers (defn set-layout-modifiers
[modif-tree objects id] [modif-tree objects id]
(letfn [(set-layout-modifiers [parent [layout-data modif-tree] child] (letfn [(transform-child [shape]
(let [modifiers (get-in modif-tree [(:id child) :modifiers]) (let [modifiers (get modif-tree (:id shape))]
(cond-> shape
(not (group? shape))
(-> (merge modifiers) gtr/transform-shape)
[modifiers layout-data] (group? shape)
(gcl/calc-layout-modifiers parent child modifiers layout-data) (gtr/apply-group-modifiers objects modif-tree))))
(set-layout-modifiers [parent [layout-data modif-tree] child]
(let [[modifiers layout-data]
(gcl/calc-layout-modifiers parent child layout-data)
modif-tree modif-tree
(cond-> modif-tree (cond-> modif-tree
(not (gtr/empty-modifiers? modifiers)) (not (gtr/empty-modifiers? modifiers))
(assoc-in [(:id child) :modifiers] modifiers))] (merge-modifiers [(:id child)] modifiers)
(and (not (gtr/empty-modifiers? modifiers)) (group? child))
(merge-modifiers (:shapes child) modifiers))]
[layout-data modif-tree]))] [layout-data modif-tree]))]
(let [shape (get objects id) (let [shape (get objects id)
children (map (d/getf objects) (:shapes shape)) children (->> (:shapes shape)
(map (d/getf objects))
(map transform-child))
modifiers (get-in modif-tree [id :modifiers]) modifiers (get-in modif-tree [id :modifiers])
;;_ (.log js/console "layout" (:name shape) (clj->js modifiers))
transformed-rect (gtr/transform-selrect (:selrect shape) modifiers) transformed-rect (gtr/transform-selrect (:selrect shape) modifiers)
layout-data (gcl/calc-layout-data shape children modif-tree transformed-rect) layout-data (gcl/calc-layout-data shape children modif-tree transformed-rect)
children (cond-> children (:reverse? layout-data) reverse) children (cond-> children (:reverse? layout-data) reverse)
@ -191,21 +215,41 @@
(let [modif-tree (reduce (fn [modif-tree id] (let [modif-tree (reduce (fn [modif-tree id]
(assoc modif-tree id {:modifiers (get-modifier (get objects id))})) {} ids) (assoc modif-tree id {:modifiers (get-modifier (get objects id))})) {} ids)
ids (resolve-layout-ids ids objects)] ids (resolve-layout-ids ids objects)
(loop [current (first ids)
pending (rest ids)
modif-tree modif-tree]
(if (some? current)
(let [shape (get objects current)
pending (concat pending (:shapes shape))
modif-tree ;; First: Calculate children modifiers (constraints, etc)
(-> modif-tree [modif-tree touched-layouts]
(set-children-modifiers shape objects ignore-constraints snap-pixel?) (loop [current (first ids)
(cond-> (:layout shape) pending (rest ids)
(set-layout-modifiers objects current)))] modif-tree modif-tree
touched-layouts (d/ordered-set)]
(if (some? current)
(let [shape (get objects current)
pending (concat pending (:shapes shape))
(recur (first pending) (rest pending) modif-tree)) touched-layouts
(cond-> touched-layouts
(:layout shape)
(conj (:id shape)))
modif-tree)))) modif-tree
(-> modif-tree
(set-children-modifiers shape objects ignore-constraints snap-pixel?))]
(recur (first pending) (rest pending) modif-tree touched-layouts))
[modif-tree touched-layouts]))
;; Second: Calculate layout positioning
modif-tree
(loop [current (first touched-layouts)
pending (rest touched-layouts)
modif-tree modif-tree]
(if (some? current)
(let [modif-tree (set-layout-modifiers modif-tree objects current)]
(recur (first pending) (rest pending) modif-tree))
modif-tree))]
modif-tree))

View file

@ -670,3 +670,17 @@
(map (comp gpr/points->selrect :points transform-shape)) (map (comp gpr/points->selrect :points transform-shape))
(gpr/join-selrects))) (gpr/join-selrects)))
(defn apply-group-modifiers
"Apply the modifiers to the group children to calculate its selection rect"
[group objects modif-tree]
(let [children
(->> (:shapes group)
(map (d/getf objects))
(map (fn [shape]
(let [modifiers (get modif-tree (:id shape))
shape (-> shape (merge modifiers) transform-shape)]
(if (= :group (:type shape))
(apply-group-modifiers shape objects modif-tree)
shape)))))]
(update-group-selrect group children)))

View file

@ -353,3 +353,10 @@
(let [root-node (dom/query ".viewport .render-shapes") (let [root-node (dom/query ".viewport .render-shapes")
num-nodes (->> (dom/seq-nodes root-node) count)] num-nodes (->> (dom/seq-nodes root-node) count)]
#js {:number num-nodes})) #js {:number num-nodes}))
#_(defn modif->js
[modif-tree objects]
(clj->js (into {}
(map (fn [[k v]]
[(get-in objects [k :name]) v]))
modif-tree)))