From 785b58a6c433a5f7714997771de6019ee2c77905 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Thu, 5 Oct 2023 12:55:35 +0200 Subject: [PATCH] :sparkles: Change behaviour of fill to respect minimum content size --- .../app/common/geom/shapes/flex_layout.cljc | 5 +- .../geom/shapes/flex_layout/bounds.cljc | 38 +- .../geom/shapes/flex_layout/drop_area.cljc | 9 +- .../{lines.cljc => layout_data.cljc} | 102 +++--- .../geom/shapes/flex_layout/modifiers.cljc | 6 +- .../geom/shapes/grid_layout/bounds.cljc | 14 +- .../geom/shapes/grid_layout/layout_data.cljc | 344 +++++++++--------- .../geom/shapes/grid_layout/positions.cljc | 5 +- .../common/geom/shapes/min_size_layout.cljc | 81 +++++ .../src/app/common/geom/shapes/modifiers.cljc | 13 +- frontend/src/app/main/ui/measurements.cljs | 4 +- .../main/ui/shapes/grid_layout_viewer.cljs | 10 +- .../app/main/ui/workspace/viewport/debug.cljs | 36 +- .../viewport/grid_layout_editor.cljs | 4 +- 14 files changed, 402 insertions(+), 269 deletions(-) rename common/src/app/common/geom/shapes/flex_layout/{lines.cljc => layout_data.cljc} (84%) create mode 100644 common/src/app/common/geom/shapes/min_size_layout.cljc diff --git a/common/src/app/common/geom/shapes/flex_layout.cljc b/common/src/app/common/geom/shapes/flex_layout.cljc index 3d196204b..3be7382da 100644 --- a/common/src/app/common/geom/shapes/flex_layout.cljc +++ b/common/src/app/common/geom/shapes/flex_layout.cljc @@ -9,7 +9,7 @@ [app.common.data.macros :as dm] [app.common.geom.shapes.flex-layout.bounds :as fbo] [app.common.geom.shapes.flex-layout.drop-area :as fdr] - [app.common.geom.shapes.flex-layout.lines :as fli] + [app.common.geom.shapes.flex-layout.layout-data :as fld] [app.common.geom.shapes.flex-layout.modifiers :as fmo])) (dm/export fbo/layout-content-bounds) @@ -17,6 +17,5 @@ (dm/export fbo/child-layout-bound-points) (dm/export fdr/get-drop-index) (dm/export fdr/get-drop-areas) -(dm/export fli/calc-layout-data) +(dm/export fld/calc-layout-data) (dm/export fmo/layout-child-modifiers) - diff --git a/common/src/app/common/geom/shapes/flex_layout/bounds.cljc b/common/src/app/common/geom/shapes/flex_layout/bounds.cljc index 358dbe34e..a8a268436 100644 --- a/common/src/app/common/geom/shapes/flex_layout/bounds.cljc +++ b/common/src/app/common/geom/shapes/flex_layout/bounds.cljc @@ -11,9 +11,23 @@ [app.common.geom.shapes.points :as gpo] [app.common.types.shape.layout :as ctl])) +;; Setted in app.common.geom.shapes.common-layout +;; We do it this way because circular dependencies +(def -child-min-width nil) + +(defn child-min-width + [child child-bounds bounds objects] + (-child-min-width child child-bounds bounds objects)) + +(def -child-min-height nil) + +(defn child-min-height + [child child-bounds bounds objects] + (-child-min-height child child-bounds bounds objects)) + (defn child-layout-bound-points "Returns the bounds of the children as points" - [parent child parent-bounds child-bounds] + [parent child parent-bounds child-bounds bounds objects] (let [row? (ctl/row? parent) col? (ctl/col? parent) @@ -28,21 +42,13 @@ h-center? (ctl/h-center? parent) h-end? (ctl/h-end? parent) - fill-w? (ctl/fill-width? child) - fill-h? (ctl/fill-height? child) - base-p (gpo/origin child-bounds) width (gpo/width-points child-bounds) height (gpo/height-points child-bounds) - min-width (if fill-w? - (ctl/child-min-width child) - width) - - min-height (if fill-h? - (ctl/child-min-height child) - height) + min-width (child-min-width child child-bounds bounds objects) + min-height (child-min-height child child-bounds bounds objects) ;; This is the leftmost (when row) or topmost (when col) point ;; Will be added always to the bounds and then calculated the other limits @@ -95,19 +101,19 @@ (conj (gpt/subtract base-p (vv min-height)))))) (defn layout-content-points - [bounds parent children] + [bounds parent children objects] (let [parent-id (:id parent) parent-bounds @(get bounds parent-id) get-child-bounds (fn [child] (let [child-id (:id child) - child-bounds @(get bounds child-id) + child-bounds @(get bounds child-id) [margin-top margin-right margin-bottom margin-left] (ctl/child-margins child) child-bounds (if (or (ctl/fill-width? child) (ctl/fill-height? child)) - (child-layout-bound-points parent child parent-bounds child-bounds) + (child-layout-bound-points parent child parent-bounds child-bounds bounds objects) child-bounds) child-bounds @@ -122,7 +128,7 @@ (map get-child-bounds)))) (defn layout-content-bounds - [bounds {:keys [layout-padding] :as parent} children] + [bounds {:keys [layout-padding] :as parent} children objects] (let [parent-id (:id parent) parent-bounds @(get bounds parent-id) @@ -153,7 +159,7 @@ pad-left (+ (or pad-left 0) col-pad) layout-points - (layout-content-points bounds parent children)] + (layout-content-points bounds parent children objects)] (if (d/not-empty? layout-points) (-> layout-points diff --git a/common/src/app/common/geom/shapes/flex_layout/drop_area.cljc b/common/src/app/common/geom/shapes/flex_layout/drop_area.cljc index 8a050b0f0..ce7177ced 100644 --- a/common/src/app/common/geom/shapes/flex_layout/drop_area.cljc +++ b/common/src/app/common/geom/shapes/flex_layout/drop_area.cljc @@ -11,7 +11,7 @@ [app.common.geom.point :as gpt] [app.common.geom.rect :as grc] [app.common.geom.shapes.common :as gco] - [app.common.geom.shapes.flex-layout.lines :as fli] + [app.common.geom.shapes.flex-layout.layout-data :as fld] [app.common.geom.shapes.points :as gpo] [app.common.geom.shapes.transforms :as gtr] [app.common.pages.helpers :as cph] @@ -197,21 +197,22 @@ [shape nil])) (defn get-drop-areas - [frame objects] + [frame objects bounds] (let [[frame modifiers] (get-flip-modifiers frame) children (->> (cph/get-immediate-children objects (:id frame)) (remove :hidden) (map #(cond-> % (some? modifiers) (gtr/transform-shape modifiers))) (map #(vector (gpo/parent-coords-bounds (:points %) (:points frame)) %))) - layout-data (fli/calc-layout-data frame children (:points frame)) + layout-data (fld/calc-layout-data frame (:points frame) children bounds objects) drop-areas (layout-drop-areas frame layout-data children)] drop-areas)) (defn get-drop-index [frame-id objects position] (let [frame (get objects frame-id) - drop-areas (get-drop-areas frame objects) + bounds (d/lazy-map (keys objects) #(gco/shape->points (get objects %))) + drop-areas (get-drop-areas frame objects bounds) position (gmt/transform-point-center position (gco/shape->center frame) (:transform-inverse frame)) area (d/seek #(grc/contains-point? % position) drop-areas)] (:index area))) diff --git a/common/src/app/common/geom/shapes/flex_layout/lines.cljc b/common/src/app/common/geom/shapes/flex_layout/layout_data.cljc similarity index 84% rename from common/src/app/common/geom/shapes/flex_layout/lines.cljc rename to common/src/app/common/geom/shapes/flex_layout/layout_data.cljc index 14b4d110d..d0cacd31d 100644 --- a/common/src/app/common/geom/shapes/flex_layout/lines.cljc +++ b/common/src/app/common/geom/shapes/flex_layout/layout_data.cljc @@ -4,7 +4,7 @@ ;; ;; Copyright (c) KALEIDOS INC -(ns app.common.geom.shapes.flex-layout.lines +(ns app.common.geom.shapes.flex-layout.layout-data (:require [app.common.data :as d] [app.common.geom.shapes.flex-layout.positions :as flp] @@ -14,6 +14,20 @@ (def conjv (fnil conj [])) +;; Setted in app.common.geom.shapes.common-layout +;; We do it this way because circular dependencies +(def -child-min-width nil) + +(defn child-min-width + [child child-bounds bounds objects] + (-child-min-width child child-bounds bounds objects)) + +(def -child-min-height nil) + +(defn child-min-height + [child child-bounds bounds objects] + (-child-min-height child child-bounds bounds objects)) + (defn layout-bounds [parent shape-bounds] (let [[pad-top pad-right pad-bottom pad-left] (ctl/paddings parent)] @@ -21,16 +35,17 @@ (defn init-layout-lines "Calculates the lines basic data and accumulated values. The positions will be calculated in a different operation" - [shape children layout-bounds] + [shape children layout-bounds bounds objects auto?] (let [col? (ctl/col? shape) row? (ctl/row? shape) space-around? (ctl/space-around? shape) space-evenly? (ctl/space-evenly? shape) - wrap? (and (ctl/wrap? shape) - (or col? (not (ctl/auto-width? shape))) - (or row? (not (ctl/auto-height? shape)))) + auto-width? (or (ctl/auto-width? shape) auto?) + auto-height? (or (ctl/auto-height? shape) auto?) + + wrap? (and (ctl/wrap? shape) (or col? (not auto-width?)) (or row? (not auto-height?))) [layout-gap-row layout-gap-col] (ctl/gaps shape) @@ -52,8 +67,6 @@ child-width (gpo/width-points child-bounds) child-height (gpo/height-points child-bounds) - child-min-width (ctl/child-min-width child) - child-min-height (ctl/child-min-height child) child-max-width (ctl/child-max-width child) child-max-height (ctl/child-max-height child) @@ -68,15 +81,15 @@ ;; We need this info later to calculate the child resizes when fill child-data {:id (:id child) - :child-min-width (if fill-width? child-min-width child-width) - :child-min-height (if fill-height? child-min-height child-height) + :child-min-width (child-min-width child child-bounds bounds objects) + :child-min-height (child-min-height child child-bounds bounds objects) :child-max-width (if fill-width? child-max-width child-width) :child-max-height (if fill-height? child-max-height child-height)} - next-min-width (+ child-margin-width (if fill-width? child-min-width child-width)) - next-min-height (+ child-margin-height (if fill-height? child-min-height child-height)) - next-max-width (+ child-margin-width (if fill-width? child-max-width child-width)) - next-max-height (+ child-margin-height (if fill-height? child-max-height child-height)) + next-min-width (+ child-margin-width (:child-min-width child-data)) + next-min-height (+ child-margin-height (:child-min-height child-data)) + next-max-width (+ child-margin-width (:child-max-width child-data)) + next-max-height (+ child-margin-height (:child-max-height child-data)) total-gap-col (cond space-evenly? @@ -160,11 +173,11 @@ (recur remainder items)))))) (defn add-lines-positions - [parent layout-bounds layout-lines] + [parent layout-bounds auto? layout-lines] (let [row? (ctl/row? parent) col? (ctl/col? parent) - auto-width? (ctl/auto-width? parent) - auto-height? (ctl/auto-height? parent) + auto-width? (or (ctl/auto-width? parent) auto?) + auto-height? (or (ctl/auto-height? parent) auto?) space-evenly? (ctl/space-evenly? parent) space-around? (ctl/space-around? parent) @@ -178,7 +191,7 @@ [(+ total-width line-width) (+ total-height line-height)]) (add-ranges [[total-min-width total-min-height total-max-width total-max-height] - {:keys [line-min-width line-min-height line-max-width line-max-height]}] + {:keys [line-min-width line-min-height line-max-width line-max-height]}] [(+ total-min-width line-min-width) (+ total-min-height line-min-height) (+ total-max-width line-max-width) @@ -238,32 +251,32 @@ (cond->> layout-lines row? (map #(assoc % :line-width - (if (ctl/auto-width? parent) + (if auto-width? (:line-min-width %) (max (:line-min-width %) (min (get-layout-width %) (:line-max-width %)))))) col? (map #(assoc % :line-height - (if (ctl/auto-height? parent) + (if auto-height? (:line-min-height %) (max (:line-min-height %) (min (get-layout-height %) (:line-max-height %)))))) - (and row? (or (>= total-min-height rest-layout-height) (ctl/auto-height? parent))) + (and row? (or (>= total-min-height rest-layout-height) auto-height?)) (map #(assoc % :line-height (:line-min-height %))) - (and row? (<= total-max-height rest-layout-height) (not (ctl/auto-height? parent))) + (and row? (<= total-max-height rest-layout-height) (not auto-height?)) (map #(assoc % :line-height (+ (:line-max-height %) stretch-height-fix))) - (and row? (< total-min-height rest-layout-height total-max-height) (not (ctl/auto-height? parent))) + (and row? (< total-min-height rest-layout-height total-max-height) (not auto-height?)) (distribute-space :line-height :line-min-height :line-max-height total-min-height rest-layout-height) - (and col? (or (>= total-min-width rest-layout-width) (ctl/auto-width? parent))) + (and col? (or (>= total-min-width rest-layout-width) auto-width?)) (map #(assoc % :line-width (:line-min-width %))) - (and col? (<= total-max-width rest-layout-width) (not (ctl/auto-width? parent))) + (and col? (<= total-max-width rest-layout-width) (not auto-width?)) (map #(assoc % :line-width (+ (:line-max-width %) stretch-width-fix))) - (and col? (< total-min-width rest-layout-width total-max-width) (not (ctl/auto-width? parent))) + (and col? (< total-min-width rest-layout-width total-max-width) (not auto-width?)) (distribute-space :line-width :line-min-width :line-max-width total-min-width rest-layout-width)) ;; Add information to limit the growth of width: 100% shapes to the bounds of the layout @@ -298,15 +311,15 @@ (defn add-line-spacing "Calculates the baseline for a flex layout" - [shape layout-bounds {:keys [num-children line-width line-height] :as line-data}] + [shape layout-bounds auto? {:keys [num-children line-width line-height] :as line-data}] (let [width (gpo/width-points layout-bounds) height (gpo/height-points layout-bounds) row? (ctl/row? shape) col? (ctl/col? shape) - auto-height? (ctl/auto-height? shape) - auto-width? (ctl/auto-width? shape) + auto-height? (or (ctl/auto-height? shape) auto?) + auto-width? (or (ctl/auto-width? shape) auto?) space-between? (ctl/space-between? shape) space-evenly? (ctl/space-evenly? shape) space-around? (ctl/space-around? shape) @@ -402,22 +415,25 @@ (defn calc-layout-data "Digest the layout data to pass it to the constrains" - [shape children shape-bounds] + ([shape shape-bounds children bounds objects] + (calc-layout-data shape shape-bounds children bounds objects false)) - (let [layout-bounds (layout-bounds shape shape-bounds) - reverse? (ctl/reverse? shape) - children (cond->> children (not reverse?) reverse) + ([shape shape-bounds children bounds objects auto?] - ;; Don't take into account absolute children - children (->> children (remove (comp ctl/layout-absolute? second))) + (let [layout-bounds (layout-bounds shape shape-bounds) + reverse? (ctl/reverse? shape) + children (cond->> children (not reverse?) reverse) - ;; Creates the layout lines information - layout-lines - (->> (init-layout-lines shape children layout-bounds) - (add-lines-positions shape layout-bounds) - (into [] (comp (map (partial add-line-spacing shape layout-bounds)) - (map (partial add-children-resizes shape)))))] + ;; Don't take into account absolute children + children (->> children (remove (comp ctl/layout-absolute? second))) - {:layout-lines layout-lines - :layout-bounds layout-bounds - :reverse? reverse?})) + ;; Creates the layout lines information + layout-lines + (->> (init-layout-lines shape children layout-bounds bounds objects auto?) + (add-lines-positions shape layout-bounds auto?) + (into [] (comp (map (partial add-line-spacing shape layout-bounds auto?)) + (map (partial add-children-resizes shape)))))] + + {:layout-lines layout-lines + :layout-bounds layout-bounds + :reverse? reverse?}))) diff --git a/common/src/app/common/geom/shapes/flex_layout/modifiers.cljc b/common/src/app/common/geom/shapes/flex_layout/modifiers.cljc index 7f0d5ee5b..4d95c38c4 100644 --- a/common/src/app/common/geom/shapes/flex_layout/modifiers.cljc +++ b/common/src/app/common/geom/shapes/flex_layout/modifiers.cljc @@ -34,7 +34,8 @@ (let [line-width (min line-width (or to-bound-width line-width)) target-width (max (- line-width (ctl/child-width-margin child)) 0.01) max-width (max (ctl/child-max-width child) 0.01) - target-width (mth/clamp target-width (ctl/child-min-width child) max-width) + child-min-width (get-in children-data [(:id child) :child-min-width]) + target-width (mth/clamp target-width child-min-width max-width) fill-scale (/ target-width child-width)] {:width target-width :modifiers (ctm/resize-modifiers (gpt/point fill-scale 1) child-origin transform transform-inverse)}))) @@ -58,7 +59,8 @@ (let [line-height (min line-height (or to-bound-height line-height)) target-height (max (- line-height (ctl/child-height-margin child)) 0.01) max-height (max (ctl/child-max-height child) 0.01) - target-height (mth/clamp target-height (ctl/child-min-height child) max-height) + child-min-height (get-in children-data [(:id child) :child-min-height]) + target-height (mth/clamp target-height child-min-height max-height) fill-scale (/ target-height child-height)] {:height target-height :modifiers (ctm/resize-modifiers (gpt/point 1 fill-scale) child-origin transform transform-inverse)}))) diff --git a/common/src/app/common/geom/shapes/grid_layout/bounds.cljc b/common/src/app/common/geom/shapes/grid_layout/bounds.cljc index 57ee71868..6f1b0d3f2 100644 --- a/common/src/app/common/geom/shapes/grid_layout/bounds.cljc +++ b/common/src/app/common/geom/shapes/grid_layout/bounds.cljc @@ -8,21 +8,15 @@ (:require [app.common.data :as d] [app.common.geom.point :as gpt] - [app.common.geom.shapes.grid-layout.layout-data :as ld] [app.common.geom.shapes.points :as gpo])) (defn layout-content-points - [bounds parent children] + [bounds parent {:keys [row-tracks column-tracks]}] (let [parent-id (:id parent) parent-bounds @(get bounds parent-id) hv #(gpo/start-hv parent-bounds %) - vv #(gpo/start-vv parent-bounds %) - - children (->> children - (map #(vector @(get bounds (:id %)) %))) - - {:keys [row-tracks column-tracks]} (ld/calc-layout-data parent children parent-bounds)] + vv #(gpo/start-vv parent-bounds %)] (d/concat-vec (->> row-tracks (mapcat #(vector (:start-p %) @@ -32,7 +26,7 @@ (gpt/add (:start-p %) (hv (:size %))))))))) (defn layout-content-bounds - [bounds {:keys [layout-padding] :as parent} children] + [bounds {:keys [layout-padding] :as parent} layout-data] (let [parent-id (:id parent) parent-bounds @(get bounds parent-id) @@ -43,7 +37,7 @@ pad-bottom (or pad-bottom 0) pad-left (or pad-left 0) - layout-points (layout-content-points bounds parent children)] + layout-points (layout-content-points bounds parent layout-data)] (if (d/not-empty? layout-points) (-> layout-points diff --git a/common/src/app/common/geom/shapes/grid_layout/layout_data.cljc b/common/src/app/common/geom/shapes/grid_layout/layout_data.cljc index 5e3595ee2..881bf1c8e 100644 --- a/common/src/app/common/geom/shapes/grid_layout/layout_data.cljc +++ b/common/src/app/common/geom/shapes/grid_layout/layout_data.cljc @@ -55,25 +55,25 @@ [app.common.math :as mth] [app.common.types.shape.layout :as ctl])) +;; Setted in app.common.geom.shapes.common-layout +;; We do it this way because circular dependencies +(def -child-min-width nil) + +(defn child-min-width + [child child-bounds bounds objects] + (-child-min-width child child-bounds bounds objects)) + +(def -child-min-height nil) + +(defn child-min-height + [child child-bounds bounds objects] + (-child-min-height child child-bounds bounds objects)) + (defn layout-bounds [parent shape-bounds] (let [[pad-top pad-right pad-bottom pad-left] (ctl/paddings parent)] (gpo/pad-points shape-bounds pad-top pad-right pad-bottom pad-left))) -(defn child-min-width - [child bounds] - (+ (if (ctl/fill-width? child) - (ctl/child-min-width child) - (gpo/width-points bounds)) - (ctl/child-width-margin child))) - -(defn child-min-height - [child bounds] - (+ (if (ctl/fill-height? child) - (ctl/child-min-height child) - (gpo/height-points bounds)) - (ctl/child-height-margin child))) - (defn calculate-initial-track-size [total-value {:keys [type value] :as track}] @@ -91,12 +91,12 @@ (assoc track :size size :max-size max-size))) (defn set-auto-base-size - [track-list children shape-cells type] + [track-list children shape-cells bounds objects type] (let [[prop prop-span size-fn] (if (= type :column) - [:column :column-span child-min-width] - [:row :row-span child-min-height])] + [:column :column-span child-min-width] + [:row :row-span child-min-height])] (reduce (fn [tracks [child-bounds child-shape]] (let [cell (get shape-cells (:id child-shape)) @@ -105,7 +105,7 @@ (cond-> tracks (and (= (get cell prop-span) 1) (contains? #{:flex :auto} (:type track))) - (update-in [idx :size] max (size-fn child-shape child-bounds))))) + (update-in [idx :size] max (size-fn child-shape child-bounds bounds objects))))) track-list children))) @@ -216,14 +216,14 @@ (some? (->> tracks (d/seek #(= :flex (:type %))))))) (defn size-to-allocate - [type parent [child-bounds child] cell] + [type parent [child-bounds child] cell bounds objects] (let [[row-gap column-gap] (ctl/gaps parent) [sfn gap prop-span] (if (= type :column) [child-min-width column-gap :column-span] [child-min-height row-gap :row-span]) span (get cell prop-span)] - (- (sfn child child-bounds) (* gap (dec span))))) + (- (sfn child child-bounds bounds objects) (* gap (dec span))))) (defn allocate-auto-tracks [allocations indexed-tracks to-allocate] @@ -271,7 +271,7 @@ fr-value)))) (defn set-auto-multi-span - [parent track-list children-map shape-cells type] + [parent track-list children-map shape-cells bounds objects type] (let [[prop prop-span] (if (= type :column) @@ -293,7 +293,7 @@ to-idx (+ (dec (get cell prop)) (get cell prop-span)) indexed-tracks (subvec (d/enumerate track-list) from-idx to-idx) - to-allocate (size-to-allocate type parent (get children-map shape-id) cell) + to-allocate (size-to-allocate type parent (get children-map shape-id) cell bounds objects) ;; Remove the size and the tracks that are not allocated [to-allocate indexed-tracks] @@ -307,10 +307,9 @@ [(- to-allocate (:size track)) result])) [to-allocate []])) - non-assigned-indexed-tracks (->> indexed-tracks - (remove (fn [[idx track]] (contains? allocated idx)))) + (remove (fn [[idx _]] (contains? allocated idx)))) ;; First we try to assign into the non-assigned tracks [allocated to-allocate] @@ -331,7 +330,7 @@ track-list)) (defn set-flex-multi-span - [parent track-list children-map shape-cells type] + [parent track-list children-map shape-cells bounds objects type] (let [[prop prop-span] (if (= type :column) @@ -352,7 +351,7 @@ to-idx (+ (dec (get cell prop)) (get cell prop-span)) indexed-tracks (subvec (d/enumerate track-list) from-idx to-idx) - to-allocate (size-to-allocate type parent (get children-map shape-id) cell) + to-allocate (size-to-allocate type parent (get children-map shape-id) cell bounds objects) ;; Remove the size and the tracks that are not allocated [to-allocate total-frs indexed-tracks] @@ -390,197 +389,202 @@ (recur (rest tracks) min-fr))))) (defn calc-layout-data - [parent children transformed-parent-bounds] + ([parent transformed-parent-bounds children bounds objects] + (calc-layout-data parent transformed-parent-bounds children bounds objects false)) - (let [hv #(gpo/start-hv transformed-parent-bounds %) - vv #(gpo/start-vv transformed-parent-bounds %) + ([parent transformed-parent-bounds children bounds objects auto?] + (let [hv #(gpo/start-hv transformed-parent-bounds %) + vv #(gpo/start-vv transformed-parent-bounds %) - layout-bounds (layout-bounds parent transformed-parent-bounds) + layout-bounds (layout-bounds parent transformed-parent-bounds) - bound-height (gpo/height-points layout-bounds) - bound-width (gpo/width-points layout-bounds) - bound-corner (gpo/origin layout-bounds) + bound-height (gpo/height-points layout-bounds) + bound-width (gpo/width-points layout-bounds) + bound-corner (gpo/origin layout-bounds) - [row-gap column-gap] (ctl/gaps parent) - auto-height? (ctl/auto-height? parent) - auto-width? (ctl/auto-width? parent) + [row-gap column-gap] (ctl/gaps parent) + auto-height? (or (ctl/auto-height? parent) auto?) + auto-width? (or (ctl/auto-width? parent) auto?) - {:keys [layout-grid-columns layout-grid-rows layout-grid-cells]} parent - num-columns (count layout-grid-columns) - num-rows (count layout-grid-rows) + {:keys [layout-grid-columns layout-grid-rows layout-grid-cells]} parent + num-columns (count layout-grid-columns) + num-rows (count layout-grid-rows) - column-total-gap (* column-gap (dec num-columns)) - row-total-gap (* row-gap (dec num-rows)) + column-total-gap (* column-gap (dec num-columns)) + row-total-gap (* row-gap (dec num-rows)) - ;; Map shape->cell - shape-cells - (into {} - (mapcat (fn [[_ cell]] - (->> (:shapes cell) (map #(vector % cell))))) - layout-grid-cells) + ;; Map shape->cell + shape-cells + (into {} + (mapcat (fn [[_ cell]] + (->> (:shapes cell) (map #(vector % cell))))) + layout-grid-cells) - children (->> children (remove #(ctl/layout-absolute? (second %)))) - children-map - (into {} - (map #(vector (:id (second %)) %)) - children) + children + (->> children + (remove #(ctl/layout-absolute? (second %)))) - ;; Initialize tracks - column-tracks - (->> layout-grid-columns - (mapv (partial calculate-initial-track-size bound-width))) + children-map + (into {} + (map #(vector (:id (second %)) %)) + children) - row-tracks - (->> layout-grid-rows - (mapv (partial calculate-initial-track-size bound-height))) + ;; Initialize tracks + column-tracks + (->> layout-grid-columns + (mapv (partial calculate-initial-track-size bound-width))) - ;; Go through cells to adjust auto sizes for span=1. Base is the max of its children - column-tracks (set-auto-base-size column-tracks children shape-cells :column) - row-tracks (set-auto-base-size row-tracks children shape-cells :row) + row-tracks + (->> layout-grid-rows + (mapv (partial calculate-initial-track-size bound-height))) - ;; Adjust multi-spaned cells with no flex columns - column-tracks (set-auto-multi-span parent column-tracks children-map shape-cells :column) - row-tracks (set-auto-multi-span parent row-tracks children-map shape-cells :row) + ;; Go through cells to adjust auto sizes for span=1. Base is the max of its children + column-tracks (set-auto-base-size column-tracks children shape-cells bounds objects :column) + row-tracks (set-auto-base-size row-tracks children shape-cells bounds objects :row) - ;; Calculate the `fr` unit and adjust the size - column-total-size-nofr (tracks-total-size (->> column-tracks (remove #(= :flex (:type %))))) - row-total-size-nofr (tracks-total-size (->> row-tracks (remove #(= :flex (:type %))))) + ;; Adjust multi-spaned cells with no flex columns + column-tracks (set-auto-multi-span parent column-tracks children-map shape-cells bounds objects :column) + row-tracks (set-auto-multi-span parent row-tracks children-map shape-cells bounds objects :row) - column-frs (tracks-total-frs column-tracks) - row-frs (tracks-total-frs row-tracks) + ;; Calculate the `fr` unit and adjust the size + column-total-size-nofr (tracks-total-size (->> column-tracks (remove #(= :flex (:type %))))) + row-total-size-nofr (tracks-total-size (->> row-tracks (remove #(= :flex (:type %))))) - ;; Assign minimum size to the multi-span flex tracks. We do this after calculating - ;; the fr size because will affect only the minimum. The maximum will be set by the - ;; fracion - column-tracks (set-flex-multi-span parent column-tracks children-map shape-cells :column) - row-tracks (set-flex-multi-span parent row-tracks children-map shape-cells :row) + column-frs (tracks-total-frs column-tracks) + row-frs (tracks-total-frs row-tracks) - ;; Once auto sizes have been calculated we get calculate the `fr` unit with the remainining size and adjust the size - free-column-space (max 0 (- bound-width (+ column-total-size-nofr column-total-gap))) - free-row-space (max 0 (- bound-height (+ row-total-size-nofr row-total-gap))) + ;; Assign minimum size to the multi-span flex tracks. We do this after calculating + ;; the fr size because will affect only the minimum. The maximum will be set by the + ;; fracion + column-tracks (set-flex-multi-span parent column-tracks children-map shape-cells bounds objects :column) + row-tracks (set-flex-multi-span parent row-tracks children-map shape-cells bounds objects :row) - ;; Get the minimum values for fr's - min-column-fr (min-fr-value column-tracks) - min-row-fr (min-fr-value row-tracks) + ;; Once auto sizes have been calculated we get calculate the `fr` unit with the remainining size and adjust the size + free-column-space (max 0 (- bound-width (+ column-total-size-nofr column-total-gap))) + free-row-space (max 0 (- bound-height (+ row-total-size-nofr row-total-gap))) - column-fr (if auto-width? min-column-fr (mth/finite (/ free-column-space column-frs) 0)) - row-fr (if auto-height? min-row-fr (mth/finite (/ free-row-space row-frs) 0)) + ;; Get the minimum values for fr's + min-column-fr (min-fr-value column-tracks) + min-row-fr (min-fr-value row-tracks) - column-tracks (set-fr-value column-tracks column-fr auto-width?) - row-tracks (set-fr-value row-tracks row-fr auto-height?) + column-fr (if auto-width? min-column-fr (mth/finite (/ free-column-space column-frs) 0)) + row-fr (if auto-height? min-row-fr (mth/finite (/ free-row-space row-frs) 0)) - ;; Distribute free space between `auto` tracks - column-total-size (tracks-total-size column-tracks) - row-total-size (tracks-total-size row-tracks) + column-tracks (set-fr-value column-tracks column-fr auto-width?) + row-tracks (set-fr-value row-tracks row-fr auto-height?) - free-column-space (max 0 (if auto-width? 0 (- bound-width (+ column-total-size column-total-gap)))) - free-row-space (max 0 (if auto-height? 0 (- bound-height (+ row-total-size row-total-gap)))) - column-autos (tracks-total-autos column-tracks) - row-autos (tracks-total-autos row-tracks) + ;; Distribute free space between `auto` tracks + column-total-size (tracks-total-size column-tracks) + row-total-size (tracks-total-size row-tracks) - column-add-auto (/ free-column-space column-autos) - row-add-auto (/ free-row-space row-autos) + free-column-space (max 0 (if auto-width? 0 (- bound-width (+ column-total-size column-total-gap)))) + free-row-space (max 0 (if auto-height? 0 (- bound-height (+ row-total-size row-total-gap)))) + column-autos (tracks-total-autos column-tracks) + row-autos (tracks-total-autos row-tracks) - column-tracks (cond-> column-tracks - (= :stretch (:layout-justify-content parent)) - (add-auto-size column-add-auto)) + column-add-auto (/ free-column-space column-autos) + row-add-auto (/ free-row-space row-autos) - row-tracks (cond-> row-tracks - (= :stretch (:layout-align-content parent)) - (add-auto-size row-add-auto)) + column-tracks (cond-> column-tracks + (= :stretch (:layout-justify-content parent)) + (add-auto-size column-add-auto)) - column-total-size (tracks-total-size column-tracks) - row-total-size (tracks-total-size row-tracks) + row-tracks (cond-> row-tracks + (= :stretch (:layout-align-content parent)) + (add-auto-size row-add-auto)) - num-columns (count column-tracks) - column-gap - (case (:layout-justify-content parent) - auto-width? - column-gap + column-total-size (tracks-total-size column-tracks) + row-total-size (tracks-total-size row-tracks) - :space-evenly - (max column-gap (/ (- bound-width column-total-size) (inc num-columns))) + num-columns (count column-tracks) + column-gap + (case (:layout-justify-content parent) + auto-width? + column-gap - :space-around - (max column-gap (/ (- bound-width column-total-size) num-columns)) + :space-evenly + (max column-gap (/ (- bound-width column-total-size) (inc num-columns))) - :space-between - (max column-gap (if (= num-columns 1) column-gap (/ (- bound-width column-total-size) (dec num-columns)))) + :space-around + (max column-gap (/ (- bound-width column-total-size) num-columns)) - column-gap) + :space-between + (max column-gap (if (= num-columns 1) column-gap (/ (- bound-width column-total-size) (dec num-columns)))) - num-rows (count row-tracks) - row-gap - (case (:layout-align-content parent) - auto-height? - row-gap + column-gap) - :space-evenly - (max row-gap (/ (- bound-height row-total-size) (inc num-rows))) + num-rows (count row-tracks) + row-gap + (case (:layout-align-content parent) + auto-height? + row-gap - :space-around - (max row-gap (/ (- bound-height row-total-size) num-rows)) + :space-evenly + (max row-gap (/ (- bound-height row-total-size) (inc num-rows))) - :space-between - (max row-gap (if (= num-rows 1) row-gap (/ (- bound-height row-total-size) (dec num-rows)))) + :space-around + (max row-gap (/ (- bound-height row-total-size) num-rows)) - row-gap) + :space-between + (max row-gap (if (= num-rows 1) row-gap (/ (- bound-height row-total-size) (dec num-rows)))) - start-p - (cond-> bound-corner - (and (not auto-width?) (= :end (:layout-justify-content parent))) - (gpt/add (hv (- bound-width (+ column-total-size column-total-gap)))) + row-gap) - (and (not auto-width?) (= :center (:layout-justify-content parent))) - (gpt/add (hv (/ (- bound-width (+ column-total-size column-total-gap)) 2))) + start-p + (cond-> bound-corner + (and (not auto-width?) (= :end (:layout-justify-content parent))) + (gpt/add (hv (- bound-width (+ column-total-size column-total-gap)))) - (and (not auto-height?) (= :end (:layout-align-content parent))) - (gpt/add (vv (- bound-height (+ row-total-size row-total-gap)))) + (and (not auto-width?) (= :center (:layout-justify-content parent))) + (gpt/add (hv (/ (- bound-width (+ column-total-size column-total-gap)) 2))) - (and (not auto-height?) (= :center (:layout-align-content parent))) - (gpt/add (vv (/ (- bound-height (+ row-total-size row-total-gap)) 2))) + (and (not auto-height?) (= :end (:layout-align-content parent))) + (gpt/add (vv (- bound-height (+ row-total-size row-total-gap)))) - (and (not auto-width?) (= :space-around (:layout-justify-content parent))) - (gpt/add (hv (/ column-gap 2))) + (and (not auto-height?) (= :center (:layout-align-content parent))) + (gpt/add (vv (/ (- bound-height (+ row-total-size row-total-gap)) 2))) - (and (not auto-width?) (= :space-evenly (:layout-justify-content parent))) - (gpt/add (hv column-gap)) + (and (not auto-width?) (= :space-around (:layout-justify-content parent))) + (gpt/add (hv (/ column-gap 2))) - (and (not auto-height?) (= :space-around (:layout-align-content parent))) - (gpt/add (vv (/ row-gap 2))) + (and (not auto-width?) (= :space-evenly (:layout-justify-content parent))) + (gpt/add (hv column-gap)) - (and (not auto-height?) (= :space-evenly (:layout-align-content parent))) - (gpt/add (vv row-gap))) + (and (not auto-height?) (= :space-around (:layout-align-content parent))) + (gpt/add (vv (/ row-gap 2))) - column-tracks - (->> column-tracks - (reduce (fn [[tracks start-p] {:keys [size] :as track}] - [(conj tracks (assoc track :start-p start-p)) - (gpt/add start-p (hv (+ size column-gap)))]) - [[] start-p]) - (first)) + (and (not auto-height?) (= :space-evenly (:layout-align-content parent))) + (gpt/add (vv row-gap))) - row-tracks - (->> row-tracks - (reduce (fn [[tracks start-p] {:keys [size] :as track}] - [(conj tracks (assoc track :start-p start-p)) - (gpt/add start-p (vv (+ size row-gap)))]) - [[] start-p]) - (first))] + column-tracks + (->> column-tracks + (reduce (fn [[tracks start-p] {:keys [size] :as track}] + [(conj tracks (assoc track :start-p start-p)) + (gpt/add start-p (hv (+ size column-gap)))]) + [[] start-p]) + (first)) - {:origin start-p - :layout-bounds layout-bounds - :row-tracks row-tracks - :column-tracks column-tracks - :shape-cells shape-cells - :column-gap column-gap - :row-gap row-gap + row-tracks + (->> row-tracks + (reduce (fn [[tracks start-p] {:keys [size] :as track}] + [(conj tracks (assoc track :start-p start-p)) + (gpt/add start-p (vv (+ size row-gap)))]) + [[] start-p]) + (first))] - ;; Convenient informaton for visualization - :column-total-size column-total-size - :column-total-gap column-total-gap - :row-total-size row-total-size - :row-total-gap row-total-gap})) + {:origin start-p + :layout-bounds layout-bounds + :row-tracks row-tracks + :column-tracks column-tracks + :shape-cells shape-cells + :column-gap column-gap + :row-gap row-gap + + ;; Convenient informaton for visualization + :column-total-size column-total-size + :column-total-gap column-total-gap + :row-total-size row-total-size + :row-total-gap row-total-gap}))) (defn get-cell-data [{:keys [origin row-tracks column-tracks shape-cells]} _transformed-parent-bounds [_ child]] diff --git a/common/src/app/common/geom/shapes/grid_layout/positions.cljc b/common/src/app/common/geom/shapes/grid_layout/positions.cljc index 435d66218..eb7695615 100644 --- a/common/src/app/common/geom/shapes/grid_layout/positions.cljc +++ b/common/src/app/common/geom/shapes/grid_layout/positions.cljc @@ -9,6 +9,7 @@ [app.common.data :as d] [app.common.data.macros :as dm] [app.common.geom.point :as gpt] + [app.common.geom.shapes.common :as gco] [app.common.geom.shapes.grid-layout.layout-data :as ld] [app.common.geom.shapes.points :as gpo] [app.common.geom.shapes.transforms :as gtr] @@ -254,6 +255,8 @@ children (->> (cph/get-immediate-children objects (:id frame)) (remove :hidden) (map #(vector (gpo/parent-coords-bounds (:points %) (:points frame)) %))) - layout-data (ld/calc-layout-data frame children (:points frame))] + + bounds (d/lazy-map (keys objects) #(gco/shape->points (get objects %))) + layout-data (ld/calc-layout-data frame (:points frame) children bounds objects)] (get-position-grid-coord layout-data position))) diff --git a/common/src/app/common/geom/shapes/min_size_layout.cljc b/common/src/app/common/geom/shapes/min_size_layout.cljc new file mode 100644 index 000000000..7bd3b088a --- /dev/null +++ b/common/src/app/common/geom/shapes/min_size_layout.cljc @@ -0,0 +1,81 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; Copyright (c) KALEIDOS INC + +(ns app.common.geom.shapes.min-size-layout + (:require + [app.common.data :as d] + [app.common.geom.shapes.common :as gco] + [app.common.geom.shapes.flex-layout.bounds :as fb] + [app.common.geom.shapes.flex-layout.layout-data :as fd] + [app.common.geom.shapes.grid-layout.bounds :as gb] + [app.common.geom.shapes.grid-layout.layout-data :as gd] + [app.common.geom.shapes.points :as gpo] + [app.common.pages.helpers :as cph] + [app.common.types.shape.layout :as ctl])) + +(defn child-min-width + [child child-bounds bounds objects] + (let [min-width + (cond + (and (ctl/fill-width? child) + (ctl/flex-layout? child)) + (gpo/width-points (fb/layout-content-bounds bounds child (->> child :shapes (map (d/getf objects))) objects)) + + (and (ctl/fill-width? child) + (ctl/grid-layout? child)) + (let [children + (->> (cph/get-immediate-children objects (:id child)) + (remove :hidden) + (remove gco/invalid-geometry?) + (map (fn [child] [@(get bounds (:id child)) child]))) + layout-data (gd/calc-layout-data child @(get bounds (:id child)) children bounds objects true)] + (gpo/width-points (gb/layout-content-bounds bounds child layout-data))) + + (ctl/fill-width? child) + (ctl/child-min-width child) + + :else + (gpo/width-points child-bounds))] + (+ min-width (ctl/child-width-margin child)))) + +(defn child-min-height + [child child-bounds bounds objects] + (let [min-height + (cond + (and (ctl/fill-height? child) (ctl/flex-layout? child)) + (gpo/height-points (fb/layout-content-bounds bounds child (->> child :shapes (map (d/getf objects))) objects)) + + (and (ctl/fill-height? child) (ctl/grid-layout? child)) + (let [children (->> child :shapes + (map (d/getf objects)) + (map (fn [child] [@(get bounds (:id child)) child]))) + layout-data (gd/calc-layout-data child (:points child) children bounds objects true) + auto-bounds (gb/layout-content-bounds bounds child layout-data)] + (gpo/height-points auto-bounds)) + + (ctl/fill-height? child) + (ctl/child-min-height child) + + :else + (gpo/height-points child-bounds))] + (+ min-height (ctl/child-height-margin child)))) + +#?(:cljs + (do (set! fd/-child-min-width child-min-width) + (set! fd/-child-min-height child-min-height) + (set! fb/-child-min-width child-min-width) + (set! fb/-child-min-height child-min-height) + (set! gd/-child-min-width child-min-width) + (set! gd/-child-min-height child-min-height)) + + :clj + (do (alter-var-root #'fd/-child-min-width (constantly child-min-width)) + (alter-var-root #'fd/-child-min-height (constantly child-min-height)) + (alter-var-root #'fb/-child-min-width (constantly child-min-width)) + (alter-var-root #'fb/-child-min-height (constantly child-min-height)) + (alter-var-root #'gd/-child-min-width (constantly child-min-width)) + (alter-var-root #'gd/-child-min-height (constantly child-min-height)))) + diff --git a/common/src/app/common/geom/shapes/modifiers.cljc b/common/src/app/common/geom/shapes/modifiers.cljc index b87f93593..c082e9ab9 100644 --- a/common/src/app/common/geom/shapes/modifiers.cljc +++ b/common/src/app/common/geom/shapes/modifiers.cljc @@ -13,6 +13,7 @@ [app.common.geom.shapes.constraints :as gct] [app.common.geom.shapes.flex-layout :as gcfl] [app.common.geom.shapes.grid-layout :as gcgl] + [app.common.geom.shapes.min-size-layout] [app.common.geom.shapes.pixel-precision :as gpp] [app.common.geom.shapes.points :as gpo] [app.common.geom.shapes.transforms :as gtr] @@ -181,7 +182,8 @@ (remove :hidden) (remove gco/invalid-geometry?) (map apply-modifiers)) - layout-data (gcfl/calc-layout-data parent children @transformed-parent-bounds) + + layout-data (gcfl/calc-layout-data parent @transformed-parent-bounds children bounds objects) children (into [] (cond-> children (not (:reverse? layout-data)) reverse)) max-idx (dec (count children)) layout-lines (:layout-lines layout-data)] @@ -220,7 +222,7 @@ (remove :hidden) (remove gco/invalid-geometry?) (map apply-modifiers)) - grid-data (gcgl/calc-layout-data parent children @transformed-parent-bounds)] + grid-data (gcgl/calc-layout-data parent @transformed-parent-bounds children bounds objects)] (loop [modif-tree modif-tree bound+child (first children) pending (rest children)] @@ -260,10 +262,13 @@ (when (and (d/not-empty? children) (or (ctl/auto-height? parent) (ctl/auto-width? parent))) (cond (ctl/flex-layout? parent) - (gcfl/layout-content-bounds bounds parent children) + (gcfl/layout-content-bounds bounds parent children objects) (ctl/grid-layout? parent) - (gcgl/layout-content-bounds bounds parent children))) + (let [children (->> children + (map (fn [child] [@(get bounds (:id child)) child]))) + layout-data (gcgl/calc-layout-data parent @parent-bounds children bounds objects)] + (gcgl/layout-content-bounds bounds parent layout-data)))) auto-width (when content-bounds (gpo/width-points content-bounds)) auto-height (when content-bounds (gpo/height-points content-bounds))] diff --git a/frontend/src/app/main/ui/measurements.cljs b/frontend/src/app/main/ui/measurements.cljs index 5a47afa4b..9643580b9 100644 --- a/frontend/src/app/main/ui/measurements.cljs +++ b/frontend/src/app/main/ui/measurements.cljs @@ -706,7 +706,9 @@ wrap-blocks (let [block-children (->> children (map #(vector (gpo/parent-coords-bounds (:points %) (:points frame)) %))) - layout-data (gsl/calc-layout-data frame block-children (:points frame)) + bounds (d/lazy-map (keys objects) #(gsh/shape->points (get objects %))) + + layout-data (gsl/calc-layout-data frame (:points frame) block-children bounds objects) layout-bounds (:layout-bounds layout-data) xv #(gpo/start-hv layout-bounds %) yv #(gpo/start-vv layout-bounds %)] diff --git a/frontend/src/app/main/ui/shapes/grid_layout_viewer.cljs b/frontend/src/app/main/ui/shapes/grid_layout_viewer.cljs index 6f7373cda..ee6b50067 100644 --- a/frontend/src/app/main/ui/shapes/grid_layout_viewer.cljs +++ b/frontend/src/app/main/ui/shapes/grid_layout_viewer.cljs @@ -6,13 +6,16 @@ (ns app.main.ui.shapes.grid-layout-viewer (:require + [app.common.data :as d] [app.common.data.macros :as dm] [app.common.geom.matrix :as gmt] [app.common.geom.point :as gpt] [app.common.geom.shapes :as gsh] [app.common.geom.shapes.grid-layout :as gsg] [app.common.geom.shapes.points :as gpo] + [app.common.pages.helpers :as cph] [app.common.types.shape.layout :as ctl] + [app.main.refs :as refs] [rumext.v2 :as mf])) (mf/defc grid-cell-area-label @@ -82,14 +85,15 @@ {::mf/wrap-props false} [props] (let [shape (unchecked-get props "shape") - childs (unchecked-get props "childs") + objects (mf/deref refs/workspace-page-objects) + bounds (d/lazy-map (keys objects) #(gsh/shape->points (get objects %))) children - (->> childs + (->> (cph/get-immediate-children objects (:id shape)) (remove :hidden) (map #(vector (gpo/parent-coords-bounds (:points %) (:points shape)) %))) - layout-data (gsg/calc-layout-data shape children (:points shape))] + layout-data (gsg/calc-layout-data shape (:points shape) children bounds objects)] [:g.cells (for [cell (ctl/get-cells shape {:sort? true})] diff --git a/frontend/src/app/main/ui/workspace/viewport/debug.cljs b/frontend/src/app/main/ui/workspace/viewport/debug.cljs index 67116f624..0e870a275 100644 --- a/frontend/src/app/main/ui/workspace/viewport/debug.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/debug.cljs @@ -40,18 +40,23 @@ (let [children (->> (cph/get-immediate-children objects (:id shape)) (remove :hidden)) bounds (d/lazy-map (keys objects) #(dm/get-in objects [% :points])) + + grid-layout-data + (when (ctl/grid-layout? shape) + (gsg/calc-layout-data shape (:points shape) children bounds objects)) + layout-bounds (cond (ctl/flex-layout? shape) - (gsl/layout-content-bounds bounds shape children) + (gsl/layout-content-bounds bounds shape children objects) (ctl/grid-layout? shape) - (gsg/layout-content-bounds bounds shape children)) + (gsg/layout-content-bounds bounds shape grid-layout-data)) layout-points (cond (ctl/flex-layout? shape) - (flatten (gsl/layout-content-points bounds shape children)) + (flatten (gsl/layout-content-points bounds shape children objects)) (ctl/grid-layout? shape) - (flatten (gsg/layout-content-points bounds shape children)))] + (flatten (gsg/layout-content-points bounds shape grid-layout-data)))] [:g.debug-layout {:pointer-events "none"} [:polygon {:points (->> layout-bounds (map #(dm/fmt "%, %" (:x %) (:y %))) (str/join " ")) @@ -87,7 +92,10 @@ children (->> (cph/get-immediate-children objects (:id shape)) (remove :hidden) (map #(vector (gpo/parent-coords-bounds (:points %) (:points shape)) %))) - layout-data (gsl/calc-layout-data shape children (:points shape)) + + bounds (d/lazy-map (keys objects) #(dm/get-in objects [% :points])) + + layout-data (gsl/calc-layout-data shape (:points shape) children bounds objects) layout-bounds (:layout-bounds layout-data) xv #(gpo/start-hv layout-bounds %) @@ -121,10 +129,12 @@ (when (and (= (count selected-shapes) 1) (= :frame (-> selected-shapes first :type))) (first selected-shapes)) - shape (or selected-frame (get objects hover-top-frame-id))] + shape (or selected-frame (get objects hover-top-frame-id)) + + bounds (d/lazy-map (keys objects) #(dm/get-in objects [% :points]))] (when (and shape (:layout shape)) - (let [drop-areas (gsl/get-drop-areas shape objects)] + (let [drop-areas (gsl/get-drop-areas shape objects bounds)] [:g.debug-layout {:pointer-events "none" :transform (gsh/transform-str shape)} (for [[idx drop-area] (d/enumerate drop-areas)] @@ -184,7 +194,9 @@ (first selected-shapes)) parent (or selected-frame (get objects hover-top-frame-id)) - parent-bounds (:points parent)] + parent-bounds (:points parent) + + bounds (d/lazy-map (keys objects) #(dm/get-in objects [% :points]))] (when (and (some? parent) (not= uuid/zero (:id parent))) (let [children (->> (cph/get-immediate-children objects (:id parent)) @@ -200,7 +212,7 @@ (let [child-bounds (:points child) points (if (or (ctl/fill-height? child) (ctl/fill-height? child)) - (gsl/child-layout-bound-points parent child parent-bounds child-bounds) + (gsl/child-layout-bound-points parent child parent-bounds child-bounds bounds objects) child-bounds)] (for [point points] [:circle {:cx (:x point) @@ -222,7 +234,9 @@ (first selected-shapes)) parent (or selected-frame (get objects hover-top-frame-id)) - parent-bounds (:points parent)] + parent-bounds (:points parent) + + bounds (d/lazy-map (keys objects) #(dm/get-in objects [% :points]))] (when (and (some? parent) (not= uuid/zero (:id parent))) (let [children (->> (cph/get-immediate-children objects (:id parent)) @@ -237,7 +251,7 @@ origin (gpo/origin parent-bounds) {:keys [row-tracks column-tracks]} - (gsg/calc-layout-data parent children parent-bounds)] + (gsg/calc-layout-data parent parent-bounds children bounds objects)] [:* (for [row-data row-tracks] diff --git a/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.cljs b/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.cljs index 70c935b82..7f96444da 100644 --- a/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.cljs @@ -762,10 +762,12 @@ height (gpo/height-points bounds) origin (gpo/origin bounds) + all-bounds (d/lazy-map (keys objects) #(gsh/shape->points (get objects %))) + {:keys [row-tracks column-tracks] :as layout-data} (mf/use-memo (mf/deps shape children) - #(gsg/calc-layout-data shape children bounds)) + #(gsg/calc-layout-data shape bounds children all-bounds objects)) handle-pointer-down (mf/use-callback