From e61e76a074ce4cc6ced5cca22b4046f7a36204cd Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Mon, 7 Nov 2022 17:26:28 +0100 Subject: [PATCH] :sparkles: Fix problems with flipped layouts --- .../app/common/geom/shapes/constraints.cljc | 5 +- .../common/geom/shapes/flex_layout/lines.cljc | 10 ++-- .../geom/shapes/flex_layout/modifiers.cljc | 3 +- .../geom/shapes/flex_layout/positions.cljc | 10 ++++ .../app/common/geom/shapes/transforms.cljc | 1 - common/src/app/common/types/modifiers.cljc | 12 +++-- frontend/src/app/main/data/workspace.cljs | 3 +- .../src/app/main/ui/workspace/viewport.cljs | 10 +++- .../app/main/ui/workspace/viewport/debug.cljs | 51 +++++++++++++++++-- frontend/src/debug.cljs | 3 ++ 10 files changed, 84 insertions(+), 24 deletions(-) diff --git a/common/src/app/common/geom/shapes/constraints.cljc b/common/src/app/common/geom/shapes/constraints.cljc index c90cd179b..0b9fe0b6f 100644 --- a/common/src/app/common/geom/shapes/constraints.cljc +++ b/common/src/app/common/geom/shapes/constraints.cljc @@ -9,6 +9,7 @@ [app.common.geom.point :as gpt] [app.common.geom.shapes.common :as gco] [app.common.geom.shapes.intersect :as gsi] + [app.common.geom.shapes.points :as gpo] [app.common.geom.shapes.rect :as gre] [app.common.geom.shapes.transforms :as gst] [app.common.math :as mth] @@ -235,9 +236,7 @@ child-bb-after (gst/parent-coords-rect transformed-child transformed-parent) scale-x (/ (:width child-bb-before) (:width child-bb-after)) scale-y (/ (:height child-bb-before) (:height child-bb-after)) - - ;; TODO LAYOUT: Is the first always the origin? - resize-origin (-> transformed-parent :points first)] + resize-origin (-> transformed-parent :points gpo/origin)] (cond-> modifiers (not= :scale constraints-h) 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 e26894fa6..2a5c255b8 100644 --- a/common/src/app/common/geom/shapes/flex_layout/lines.cljc +++ b/common/src/app/common/geom/shapes/flex_layout/lines.cljc @@ -22,13 +22,8 @@ [pad-top pad-right pad-bottom pad-left] (if (= layout-padding-type :multiple) [pad-top pad-right pad-bottom pad-left] - [pad-top pad-top pad-top pad-top]) - - ;; Normalize the points to remove flips - ;; TODO LAYOUT: Need function to normalize the points - points (gst/parent-coords-points shape shape)] - - (gpo/pad-points points pad-top pad-right pad-bottom pad-left))) + [pad-top pad-top pad-top pad-top])] + (gpo/pad-points (:points shape) pad-top pad-right pad-bottom pad-left))) (defn init-layout-lines "Calculates the lines basic data and accumulated values. The positions will be calculated in a different operation" @@ -312,5 +307,6 @@ (mapv (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 2a9a04e09..039f17f98 100644 --- a/common/src/app/common/geom/shapes/flex_layout/modifiers.cljc +++ b/common/src/app/common/geom/shapes/flex_layout/modifiers.cljc @@ -22,8 +22,7 @@ child-bb-after (gst/parent-coords-rect transformed-child transformed-parent) scale-x (/ (:width child-bb-before) (:width child-bb-after)) scale-y (/ (:height child-bb-before) (:height child-bb-after)) - - resize-origin (-> transformed-parent :points first) ;; TODO LAYOUT: IS always the origin + resize-origin (-> transformed-parent :points gpo/origin) resize-vector (gpt/point scale-x scale-y)] (-> modifiers (ctm/select-child-modifiers) diff --git a/common/src/app/common/geom/shapes/flex_layout/positions.cljc b/common/src/app/common/geom/shapes/flex_layout/positions.cljc index 30437fd16..d6bc69c21 100644 --- a/common/src/app/common/geom/shapes/flex_layout/positions.cljc +++ b/common/src/app/common/geom/shapes/flex_layout/positions.cljc @@ -249,6 +249,16 @@ (some? margin-y) (gpt/add (vv margin-y))) + + ;; Fix position when layout is flipped + corner-p + (cond-> corner-p + (:flip-x parent) + (gpt/add (hv child-width)) + + (:flip-y parent) + (gpt/add (vv child-height))) + next-p (cond-> start-p row? diff --git a/common/src/app/common/geom/shapes/transforms.cljc b/common/src/app/common/geom/shapes/transforms.cljc index 3dcf61c89..564f9cf74 100644 --- a/common/src/app/common/geom/shapes/transforms.cljc +++ b/common/src/app/common/geom/shapes/transforms.cljc @@ -311,7 +311,6 @@ (cond-> (some? selrect) (assoc :selrect selrect)) - ;; TODO LAYOUT: Make sure the order of points is alright (cond-> (d/not-empty? points) (assoc :points points)) (assoc :rotation rotation)))) diff --git a/common/src/app/common/types/modifiers.cljc b/common/src/app/common/types/modifiers.cljc index e6c7943d1..8b2d27445 100644 --- a/common/src/app/common/types/modifiers.cljc +++ b/common/src/app/common/types/modifiers.cljc @@ -196,13 +196,17 @@ (defn rotation-modifiers [shape center angle] (let [shape-center (gco/center-shape shape) - rotation (-> (gmt/matrix) - (gmt/rotate angle center) - (gmt/rotate (- angle) shape-center))] + ;; Translation caused by the rotation + move-vec + (gpt/transform + (gpt/point 0 0) + (-> (gmt/matrix) + (gmt/rotate angle center) + (gmt/rotate (- angle) shape-center)))] (-> (empty) (rotation shape-center angle) - (move (gpt/transform (gpt/point 0 0) rotation))))) + (move move-vec)))) (defn remove-children-modifiers [shapes] diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index 895c5799e..bedd71065 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -1580,8 +1580,7 @@ (ptk/reify ::create-artboard-from-selection ptk/WatchEvent (watch [_ state _] - (let [page-id (:current-page-id state) - objects (wsh/lookup-page-objects state page-id) + (let [objects (wsh/lookup-page-objects state) selected (wsh/lookup-selected state) selected-objs (map #(get objects %) selected)] (when (d/not-empty? selected) diff --git a/frontend/src/app/main/ui/workspace/viewport.cljs b/frontend/src/app/main/ui/workspace/viewport.cljs index 586e1b389..80217083d 100644 --- a/frontend/src/app/main/ui/workspace/viewport.cljs +++ b/frontend/src/app/main/ui/workspace/viewport.cljs @@ -418,10 +418,16 @@ ;; DEBUG LAYOUT DROP-ZONES (when (debug? :layout-drop-zones) + [:& wvd/debug-drop-zones {:selected-shapes selected-shapes + :objects objects-modified + :hover-top-frame-id @hover-top-frame-id + :zoom zoom}]) + + (when (debug? :layout-lines) [:& wvd/debug-layout {:selected-shapes selected-shapes :objects objects-modified - :hover-top-frame-id @hover-top-frame-id}]) - + :hover-top-frame-id @hover-top-frame-id + :zoom zoom}]) (when show-selection-handlers? [:g.selection-handlers {:clipPath "url(#clip-handlers)"} diff --git a/frontend/src/app/main/ui/workspace/viewport/debug.cljs b/frontend/src/app/main/ui/workspace/viewport/debug.cljs index d338c0a71..f1fcecf0e 100644 --- a/frontend/src/app/main/ui/workspace/viewport/debug.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/debug.cljs @@ -8,13 +8,17 @@ (:require [app.common.data :as d] [app.common.data.macros :as dm] + [app.common.geom.point :as gpt] [app.common.geom.shapes :as gsh] [app.common.geom.shapes.flex-layout :as gsl] + [app.common.geom.shapes.points :as gpo] [app.common.pages.helpers :as cph] + [app.common.types.shape.layout :as ctl] + [cuerdas.core :as str] [rumext.v2 :as mf])) ;; Helper to debug the bounds when set the "hug" content property -#_(mf/defc debug-bounds +#_(mf/defc debug-layout "Debug component to show the auto-layout drop areas" {::mf/wrap-props false} [props] @@ -57,6 +61,47 @@ [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") + + selected-frame + (when (and (= (count selected-shapes) 1) (= :frame (-> selected-shapes first :type))) + (first selected-shapes)) + + shape (or selected-frame (get objects hover-top-frame-id))] + + (when (and shape (ctl/layout? shape)) + (let [row? (ctl/row? shape) + col? (ctl/col? shape) + + children (cph/get-immediate-children objects (:id shape)) + layout-data (gsl/calc-layout-data shape children) + + layout-bounds (:layout-bounds layout-data) + xv #(gpo/start-hv layout-bounds %) + yv #(gpo/start-vv layout-bounds %)] + [:g.debug-layout {:pointer-events "none"} + (for [[idx {:keys [start-p line-width line-height layout-gap-row layout-gap-col num-children]}] (d/enumerate (:layout-lines layout-data))] + (let [line-width (if row? (+ line-width (* (dec num-children) layout-gap-row)) line-width) + line-height (if col? (+ line-height (* (dec num-children) layout-gap-col)) line-height) + + points [start-p + (-> start-p (gpt/add (xv line-width))) + (-> start-p (gpt/add (xv line-width)) (gpt/add (yv line-height))) + (-> start-p (gpt/add (yv line-height))) + ]] + [:g.layout-line {:key (dm/str "line-" idx)} + [:polygon {:points (->> points (map #(dm/fmt "%, %" (:x %) (:y %))) (str/join " ")) + :style {:stroke "red" :stroke-width (/ 2 zoom) :stroke-dasharray (dm/str (/ 10 zoom) " " (/ 5 zoom))}}]]))])))) + +(mf/defc debug-drop-zones + "Debug component to show the auto-layout drop areas" + {::mf/wrap-props false} + [props] + + (let [objects (unchecked-get props "objects") + zoom (unchecked-get props "objects") selected-shapes (unchecked-get props "selected-shapes") hover-top-frame-id (unchecked-get props "hover-top-frame-id") @@ -81,8 +126,8 @@ :style {:fill "blue" :fill-opacity 0.3 :stroke "red" - :stroke-width 1 - :stroke-dasharray "3 6"}}] + :stroke-width (/ zoom 1) + :stroke-dasharray (dm/str (/ 3 zoom) " " (/ 6 zoom))}}] [:text {:x (:x drop-area) :y (:y drop-area) :width (:width drop-area) diff --git a/frontend/src/debug.cljs b/frontend/src/debug.cljs index d4856cbda..f64e98f4b 100644 --- a/frontend/src/debug.cljs +++ b/frontend/src/debug.cljs @@ -71,6 +71,9 @@ ;; Enable a widget to show the auto-layout drop-zones :layout-drop-zones + ;; Display the layout lines + :layout-lines + ;; Makes the pixel grid red so its more visibile :pixel-grid })