From 18445ea5f435d95c7dcdc89df812e914f65290af Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Mon, 30 Jan 2023 19:53:42 +0100 Subject: [PATCH] :bug: Fix problem with size 100% and auto parent --- .../app/common/geom/shapes/flex_layout.cljc | 1 + .../geom/shapes/flex_layout/bounds.cljc | 86 +++++++++++-------- .../common/geom/shapes/flex_layout/lines.cljc | 38 +++++--- .../geom/shapes/flex_layout/modifiers.cljc | 2 +- common/src/app/common/geom/shapes/points.cljc | 6 ++ .../app/main/ui/workspace/viewport/debug.cljs | 14 ++- 6 files changed, 98 insertions(+), 49 deletions(-) diff --git a/common/src/app/common/geom/shapes/flex_layout.cljc b/common/src/app/common/geom/shapes/flex_layout.cljc index 6addec0af..3d196204b 100644 --- a/common/src/app/common/geom/shapes/flex_layout.cljc +++ b/common/src/app/common/geom/shapes/flex_layout.cljc @@ -13,6 +13,7 @@ [app.common.geom.shapes.flex-layout.modifiers :as fmo])) (dm/export fbo/layout-content-bounds) +(dm/export fbo/layout-content-points) (dm/export fbo/child-layout-bound-points) (dm/export fdr/get-drop-index) (dm/export fdr/get-drop-areas) 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 f0ce544ec..31f0317a1 100644 --- a/common/src/app/common/geom/shapes/flex_layout/bounds.cljc +++ b/common/src/app/common/geom/shapes/flex_layout/bounds.cljc @@ -6,6 +6,7 @@ (ns app.common.geom.shapes.flex-layout.bounds (:require + [app.common.data :as d] [app.common.geom.point :as gpt] [app.common.geom.shapes.points :as gpo] [app.common.types.shape.layout :as ctl])) @@ -27,16 +28,19 @@ 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 (ctl/fill-width? child) + min-width (if fill-w? (ctl/child-min-width child) width) - min-height (if (ctl/fill-height? child) + min-height (if fill-h? (ctl/child-min-height child) height) @@ -60,26 +64,49 @@ min-width (max min-width 0.01) min-height (max min-height 0.01)] - (-> [base-p] - (conj (cond-> base-p - (or row? h-start?) - (gpt/add (hv min-width)) + (cond-> [base-p] + (or col? h-start?) + (conj (gpt/add base-p (hv min-width))) - (and col? h-center?) - (gpt/add (hv (/ min-width 2))) + (and col? h-center?) + (conj (gpt/add base-p (hv (/ min-width 2)))) - (and col? h-center?) - (gpt/subtract (hv min-width)))) + (and col? h-center?) + (conj (gpt/subtract base-p (hv min-width))) - (conj (cond-> base-p - (or col? v-start?) - (gpt/add (vv min-height)) + (or row? v-start?) + (conj (gpt/add base-p (vv min-height))) - (and row? v-center?) - (gpt/add (vv (/ min-height 2))) + (and row? v-center?) + (conj (gpt/add base-p (vv (/ min-height 2)))) - (and row? v-end?) - (gpt/subtract (vv min-height))))))) + (and row? v-end?) + (conj (gpt/subtract base-p (vv min-height)))))) + +(defn layout-content-points + [bounds parent children] + + (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) + [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-bounds) + + child-bounds + (when (d/not-empty? child-bounds) + (-> (gpo/parent-coords-bounds child-bounds parent-bounds) + (gpo/pad-points (- margin-top) (- margin-right) (- margin-bottom) (- margin-left))))] + + child-bounds))] + + (->> children (map get-child-bounds)))) (defn layout-content-bounds [bounds {:keys [layout-padding] :as parent} children] @@ -109,21 +136,12 @@ pad-bottom (+ (or pad-bottom 0) row-pad) pad-left (+ (or pad-left 0) col-pad) - child-bounds - (fn [child] - (let [child-id (:id child) - child-bounds @(get bounds child-id) - child-bounds - (if (or (ctl/fill-height? child) (ctl/fill-height? child)) - (child-layout-bound-points parent child parent-bounds child-bounds) - child-bounds) - - [margin-top margin-right margin-bottom margin-left] (ctl/child-margins child)] - (-> (gpo/parent-coords-bounds child-bounds parent-bounds) - (gpo/pad-points (- margin-top) (- margin-right) (- margin-bottom) (- margin-left)))))] - - (as-> children $ - (map child-bounds $) - (gpo/merge-parent-coords-bounds $ parent-bounds) - (gpo/pad-points $ (- pad-top) (- pad-right) (- pad-bottom) (- pad-left))))) + layout-points + (layout-content-points bounds parent children)] + (if (d/not-empty? layout-points) + (-> layout-points + (gpo/merge-parent-coords-bounds parent-bounds) + (gpo/pad-points (- pad-top) (- pad-right) (- pad-bottom) (- pad-left))) + ;; Cannot create some bounds from the children so we return the parent's + parent-bounds))) diff --git a/common/src/app/common/geom/shapes/flex_layout/lines.cljc b/common/src/app/common/geom/shapes/flex_layout/lines.cljc index 669dec6fa..a31e13ca5 100644 --- a/common/src/app/common/geom/shapes/flex_layout/lines.cljc +++ b/common/src/app/common/geom/shapes/flex_layout/lines.cljc @@ -154,6 +154,7 @@ col? (ctl/col? parent) auto-width? (ctl/auto-width? parent) auto-height? (ctl/auto-height? parent) + space-around? (ctl/space-around? parent) [layout-gap-row layout-gap-col] (ctl/gaps parent) @@ -181,8 +182,12 @@ (let [[total-min-width total-min-height total-max-width total-max-height] (->> layout-lines (reduce add-ranges [0 0 0 0])) - get-layout-width (fn [{:keys [num-children]}] (- layout-width (* layout-gap-col (dec num-children)))) - get-layout-height (fn [{:keys [num-children]}] (- layout-height (* layout-gap-row (dec num-children)))) + get-layout-width (fn [{:keys [num-children]}] + (let [num-gap (if space-around? (inc num-children) (dec num-children))] + (- layout-width (* layout-gap-col num-gap)))) + get-layout-height (fn [{:keys [num-children]}] + (let [num-gap (if space-around? (inc num-children) (dec num-children))] + (- layout-height (* layout-gap-row num-gap)))) num-lines (count layout-lines) @@ -197,32 +202,41 @@ (/ (- layout-height (* layout-gap-row (dec num-lines)) total-max-height) num-lines) 0) + rest-layout-height (- layout-height (* (dec num-lines) layout-gap-row)) + rest-layout-width (- layout-width (* (dec num-lines) layout-gap-col)) + ;; Distributes the space between the layout lines based on its max/min constraints layout-lines (cond->> layout-lines row? - (map #(assoc % :line-width (max (:line-min-width %) (min (get-layout-width %) (:line-max-width %))))) + (map #(assoc % :line-width + (if (ctl/auto-width? parent) + (:line-min-width %) + (max (:line-min-width %) (min (get-layout-width %) (:line-max-width %)))))) col? - (map #(assoc % :line-height (max (:line-min-height %) (min (get-layout-height %) (:line-max-height %))))) + (map #(assoc % :line-height + (if (ctl/auto-height? parent) + (:line-min-height %) + (max (:line-min-height %) (min (get-layout-height %) (:line-max-height %)))))) - (and row? (>= total-min-height layout-height)) + (and row? (or (>= total-min-height rest-layout-height) (ctl/auto-height? parent))) (map #(assoc % :line-height (:line-min-height %))) - (and row? (<= total-max-height layout-height)) + (and row? (<= total-max-height rest-layout-height) (not (ctl/auto-height? parent))) (map #(assoc % :line-height (+ (:line-max-height %) stretch-height-fix))) - (and row? (< total-min-height layout-height total-max-height)) - (distribute-space :line-height :line-min-height :line-max-height total-min-height (- layout-height (* (dec num-lines) layout-gap-row))) + (and row? (< total-min-height rest-layout-height total-max-height) (not (ctl/auto-height? parent))) + (distribute-space :line-height :line-min-height :line-max-height total-min-height rest-layout-height) - (and col? (>= total-min-width layout-width)) + (and col? (or (>= total-min-width rest-layout-width) (ctl/auto-width? parent))) (map #(assoc % :line-width (:line-min-width %))) - (and col? (<= total-max-width layout-width)) + (and col? (<= total-max-width rest-layout-width) (not (ctl/auto-width? parent))) (map #(assoc % :line-width (+ (:line-max-width %) stretch-width-fix))) - (and col? (< total-min-width layout-width total-max-width)) - (distribute-space :line-width :line-min-width :line-max-width total-min-width (- layout-width (* (dec num-lines) layout-gap-col)))) + (and col? (< total-min-width rest-layout-width total-max-width) (not (ctl/auto-width? parent))) + (distribute-space :line-width :line-min-width :line-max-width total-min-width rest-layout-width)) [total-width total-height] (->> layout-lines (reduce add-lines [0 0])) 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 ccf70dcda..072eed1b3 100644 --- a/common/src/app/common/geom/shapes/flex_layout/modifiers.cljc +++ b/common/src/app/common/geom/shapes/flex_layout/modifiers.cljc @@ -68,7 +68,7 @@ child-height (gpo/height-points child-bounds) [_ transform transform-inverse] - (when (or (ctl/fill-width? child) (ctl/fill-width? child)) + (when (or (ctl/fill-width? child) (ctl/fill-height? child)) (gtr/calculate-geometry @parent-bounds)) fill-width (when (ctl/fill-width? child) (calc-fill-width-data parent transform transform-inverse child child-origin child-width layout-line)) diff --git a/common/src/app/common/geom/shapes/points.cljc b/common/src/app/common/geom/shapes/points.cljc index dba17591e..d04ad06a0 100644 --- a/common/src/app/common/geom/shapes/points.cljc +++ b/common/src/app/common/geom/shapes/points.cljc @@ -131,6 +131,7 @@ i2 (gsi/line-line-intersect minv-start minv-end maxh-start maxh-end) i3 (gsi/line-line-intersect maxv-start maxv-end maxh-start maxh-end) i4 (gsi/line-line-intersect maxv-start maxv-end minh-start minh-end)] + [i1 i2 i3 i4]))) (defn merge-parent-coords-bounds @@ -143,3 +144,8 @@ height (height-points points) center (gco/center-points points)] (gre/center->selrect center width height))) + +(defn move + [bounds vector] + (->> bounds + (map #(gpt/add % vector)))) diff --git a/frontend/src/app/main/ui/workspace/viewport/debug.cljs b/frontend/src/app/main/ui/workspace/viewport/debug.cljs index 567a0f016..1fb9b6d02 100644 --- a/frontend/src/app/main/ui/workspace/viewport/debug.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/debug.cljs @@ -25,6 +25,7 @@ [props] (let [objects (unchecked-get props "objects") + zoom (unchecked-get props "zoom") selected-shapes (unchecked-get props "selected-shapes") hover-top-frame-id (unchecked-get props "hover-top-frame-id") @@ -37,10 +38,19 @@ (when (and shape (:layout shape)) (let [children (->> (cph/get-immediate-children objects (:id shape)) (remove :hidden)) - layout-bounds (gsl/layout-content-bounds (d/lazy-map (keys objects) #(dm/get-in objects [% :points])) shape children)] + bounds (d/lazy-map (keys objects) #(dm/get-in objects [% :points])) + layout-bounds (gsl/layout-content-bounds bounds shape children) + layout-points (flatten (gsl/layout-content-points bounds shape children))] [:g.debug-layout {:pointer-events "none"} [:polygon {:points (->> layout-bounds (map #(dm/fmt "%, %" (:x %) (:y %))) (str/join " ")) - :style {:stroke "red" :fill "none"}}]])))) + :style {:stroke "red" :fill "none"}}] + + [:* + (for [p layout-points] + [:circle {:cx (:x p) + :cy (:y p) + :r (/ 4 zoom) + :style {:fill "red"}}])]])))) (mf/defc debug-layout-lines "Debug component to show the auto-layout drop areas"