diff --git a/common/src/app/common/geom/shapes/layout.cljc b/common/src/app/common/geom/shapes/layout.cljc index d369514b7..41d219e16 100644 --- a/common/src/app/common/geom/shapes/layout.cljc +++ b/common/src/app/common/geom/shapes/layout.cljc @@ -75,7 +75,6 @@ [children-width children-height] (->> children - (map #(-> (merge % (get modif-tree (:id %))) gtr/transform-shape)) (reduce (fn [[acc-width acc-height] shape] [(+ acc-width (-> shape :points gre/points->rect :width)) (+ acc-height (-> shape :points gre/points->rect :height))]) [0 0])) @@ -99,7 +98,7 @@ 0) margin-y (if (and (row? shape) (= :space-around layout-type)) - (/ (- height children-height) (dec num-children) 2) + (/ (- height children-height) (inc num-children)) 0) children-gap (* layout-gap (dec num-children)) @@ -199,20 +198,17 @@ layout-data (assoc layout-data :start-x next-x :start-y next-y)] - [corner-p layout-data]) - ) + [corner-p layout-data])) (defn calc-layout-modifiers "Calculates the modifiers for the layout" - [parent child modifiers layout-data] + [parent child layout-data] - (let [modifiers (-> modifiers (dissoc :displacement-after)) - child (-> child (assoc :modifiers modifiers) gtr/transform-shape) - bounds (-> child :points gre/points->selrect) + (let [bounds (-> child :points gre/points->selrect) [corner-p layout-data] (next-p parent bounds layout-data) - delta-p (-> corner-p (gpt/subtract (gpt/point bounds))) - modifiers (-> modifiers (assoc :displacement-after (gmt/translate-matrix delta-p)))] + delta-p (-> corner-p (gpt/subtract (gpt/point bounds))) + modifiers {:displacement-after (gmt/translate-matrix delta-p)}] [modifiers layout-data])) diff --git a/common/src/app/common/geom/shapes/modifiers.cljc b/common/src/app/common/geom/shapes/modifiers.cljc index a548c85ce..e3faaeec3 100644 --- a/common/src/app/common/geom/shapes/modifiers.cljc +++ b/common/src/app/common/geom/shapes/modifiers.cljc @@ -119,27 +119,51 @@ resize-modif? (or (:resize-vector modifiers) (:resize-vector-2 modifiers))] (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 [modif-tree objects id] - (letfn [(set-layout-modifiers [parent [layout-data modif-tree] child] - (let [modifiers (get-in modif-tree [(:id child) :modifiers]) + (letfn [(transform-child [shape] + (let [modifiers (get modif-tree (:id shape))] + (cond-> shape + (not (group? shape)) + (-> (merge modifiers) gtr/transform-shape) - [modifiers layout-data] - (gcl/calc-layout-modifiers parent child modifiers layout-data) + (group? shape) + (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 (cond-> modif-tree (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]))] (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]) - ;;_ (.log js/console "layout" (:name shape) (clj->js modifiers)) transformed-rect (gtr/transform-selrect (:selrect shape) modifiers) layout-data (gcl/calc-layout-data shape children modif-tree transformed-rect) children (cond-> children (:reverse? layout-data) reverse) @@ -191,21 +215,41 @@ (let [modif-tree (reduce (fn [modif-tree id] (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 - (-> modif-tree - (set-children-modifiers shape objects ignore-constraints snap-pixel?) - (cond-> (:layout shape) - (set-layout-modifiers objects current)))] + ;; First: Calculate children modifiers (constraints, etc) + [modif-tree touched-layouts] + (loop [current (first ids) + pending (rest ids) + 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)) diff --git a/common/src/app/common/geom/shapes/transforms.cljc b/common/src/app/common/geom/shapes/transforms.cljc index d09e04424..0f7716252 100644 --- a/common/src/app/common/geom/shapes/transforms.cljc +++ b/common/src/app/common/geom/shapes/transforms.cljc @@ -670,3 +670,17 @@ (map (comp gpr/points->selrect :points transform-shape)) (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))) diff --git a/frontend/src/debug.cljs b/frontend/src/debug.cljs index ccf1bd49b..bef2d105d 100644 --- a/frontend/src/debug.cljs +++ b/frontend/src/debug.cljs @@ -353,3 +353,10 @@ (let [root-node (dom/query ".viewport .render-shapes") num-nodes (->> (dom/seq-nodes root-node) count)] #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)))