diff --git a/common/src/app/common/geom/shapes.cljc b/common/src/app/common/geom/shapes.cljc index 25da561f3..941e6b634 100644 --- a/common/src/app/common/geom/shapes.cljc +++ b/common/src/app/common/geom/shapes.cljc @@ -13,8 +13,8 @@ [app.common.geom.shapes.common :as gco] [app.common.geom.shapes.constraints :as gct] [app.common.geom.shapes.corners :as gsc] + [app.common.geom.shapes.flex-layout :as gcl] [app.common.geom.shapes.intersect :as gin] - [app.common.geom.shapes.layout :as gcl] [app.common.geom.shapes.modifiers :as gsm] [app.common.geom.shapes.path :as gsp] [app.common.geom.shapes.rect :as gpr] diff --git a/common/src/app/common/geom/shapes/layout.cljc b/common/src/app/common/geom/shapes/flex_layout.cljc similarity index 67% rename from common/src/app/common/geom/shapes/layout.cljc rename to common/src/app/common/geom/shapes/flex_layout.cljc index d3282b357..b67e12e4d 100644 --- a/common/src/app/common/geom/shapes/layout.cljc +++ b/common/src/app/common/geom/shapes/flex_layout.cljc @@ -4,7 +4,7 @@ ;; ;; Copyright (c) KALEIDOS INC -(ns app.common.geom.shapes.layout +(ns app.common.geom.shapes.flex-layout (:require [app.common.data :as d] [app.common.geom.matrix :as gmt] @@ -16,52 +16,95 @@ [app.common.pages.helpers :as cph] [app.common.types.modifiers :as ctm])) -;; :layout ;; true if active, false if not -;; :layout-dir ;; :right, :left, :top, :bottom -;; :layout-gap ;; number could be negative -;; :layout-type ;; :packed, :space-between, :space-around +;; :layout ;; :flex, :grid in the future +;; :layout-flex-dir ;; :row, :reverse-row, :column, :reverse-column +;; :layout-gap-type ;; :simple, :multiple +;; :layout-gap ;; {:row-gap number , :column-gap number} +;; :layout-align-items ;; :start :end :center :strech +;; :layout-justify-content ;; :start :center :end :space-between :space-around +;; :layout-align-content ;; :start :center :end :space-between :space-around :strech (by default) ;; :layout-wrap-type ;; :wrap, :no-wrap ;; :layout-padding-type ;; :simple, :multiple ;; :layout-padding ;; {:p1 num :p2 num :p3 num :p4 num} number could be negative -;; :layout-h-orientation ;; :top, :center, :bottom -;; :layout-v-orientation ;; :left, :center, :right + +;; ITEMS +;; :layout-margin ;; {:m1 0 :m2 0 :m3 0 :m4 0} +;; :layout-margin-type ;; :simple :multiple +;; :layout-h-behavior ;; :fill :fix :auto +;; :layout-v-behavior ;; :fill :fix :auto +;; :layout-max-h ;; num +;; :layout-min-h ;; num +;; :layout-max-w ;; num +;; :layout-min-w (defn col? - [{:keys [layout-dir]}] - (or (= :right layout-dir) (= :left layout-dir))) + [{:keys [layout-flex-dir]}] + (or (= :column layout-flex-dir) (= :reverse-column layout-flex-dir))) (defn row? - [{:keys [layout-dir]}] - (or (= :top layout-dir) (= :bottom layout-dir))) + [{:keys [layout-flex-dir]}] + (or (= :row layout-flex-dir) (= :reverse-row layout-flex-dir))) (defn h-start? - [{:keys [layout-h-orientation]}] - (= layout-h-orientation :left)) + [{:keys [layout-align-items layout-justify-content] :as shape}] + (or (and (col? shape) + (= layout-align-items :start)) + (and (row? shape) + (= layout-justify-content :start)))) (defn h-center? - [{:keys [layout-h-orientation]}] - (= layout-h-orientation :center)) + [{:keys [layout-align-items layout-justify-content] :as shape}] + (or (and (col? shape) + (= layout-align-items :center)) + (and (row? shape) + (= layout-justify-content :center)))) (defn h-end? - [{:keys [layout-h-orientation]}] - (= layout-h-orientation :right)) + [{:keys [layout-align-items layout-justify-content] :as shape}] + (or (and (col? shape) + (= layout-align-items :end)) + (and (row? shape) + (= layout-justify-content :end)))) (defn v-start? - [{:keys [layout-v-orientation]}] - (= layout-v-orientation :top)) + [{:keys [layout-align-items layout-justify-content] :as shape}] + (or (and (row? shape) + (= layout-align-items :start)) + (and (col? shape) + (= layout-justify-content :start)))) (defn v-center? - [{:keys [layout-v-orientation]}] - (= layout-v-orientation :center)) + [{:keys [layout-align-items layout-justify-content] :as shape}] + (or (and (row? shape) + (= layout-align-items :center)) + (and (col? shape) + (= layout-justify-content :center)))) (defn v-end? - [{:keys [layout-v-orientation]}] - (= layout-v-orientation :bottom)) + [{:keys [layout-align-items layout-justify-content] :as shape}] + (or (and (row? shape) + (= layout-align-items :end)) + (and (col? shape) + (= layout-justify-content :end)))) + +(defn gaps + [{:keys [layout-gap layout-gap-type]}] + (let [layout-gap-row (or (-> layout-gap :row-gap) 0) + layout-gap-col (if (= layout-gap-type :simple) + layout-gap-row + (or (-> layout-gap :column-gap) 0))] + [layout-gap-row layout-gap-col])) (defn calc-layout-lines - [{:keys [layout-gap layout-wrap-type] :as parent} children layout-bounds] + "Calculates the lines basic data and accumulated values. The positions will be calculated in a different operation" + [{:keys [layout-wrap-type] :as parent} children layout-bounds] (let [wrap? (= layout-wrap-type :wrap) + col? (col? parent) + row? (row? parent) + + [layout-gap-row layout-gap-col] (gaps parent) + layout-width (gpo/width-points layout-bounds) layout-height (gpo/height-points layout-bounds) @@ -71,39 +114,36 @@ child-width (gpo/width-points child-bounds) child-height (gpo/height-points child-bounds) - col? (col? parent) - row? (row? parent) - cur-child-fill? - (or (and col? (= :fill (:layout-h-behavior child))) - (and row? (= :fill (:layout-v-behavior child)))) - - cur-line-fill? (or (and row? (= :fill (:layout-h-behavior child))) (and col? (= :fill (:layout-v-behavior child)))) + cur-line-fill? + (or (and col? (= :fill (:layout-h-behavior child))) + (and row? (= :fill (:layout-v-behavior child)))) + ;; TODO LAYOUT: ADD MINWIDTH/HEIGHT - next-width (if (or (and col? cur-child-fill?) - (and row? cur-line-fill?)) + next-width (if (or (and row? cur-child-fill?) + (and col? cur-line-fill?)) 0 child-width) - next-height (if (or (and row? cur-child-fill?) - (and col? cur-line-fill?)) + next-height (if (or (and col? cur-child-fill?) + (and row? cur-line-fill?)) 0 child-height) - next-total-width (+ line-width next-width (* layout-gap (dec num-children))) - next-total-height (+ line-height next-height (* layout-gap (dec num-children)))] + next-total-width (+ line-width next-width (* layout-gap-row (dec num-children))) + next-total-height (+ line-height next-height (* layout-gap-col (dec num-children)))] (if (and (some? line-data) (or (not wrap?) - (and col? (<= next-total-width layout-width)) - (and row? (<= next-total-height layout-height)))) + (and row? (<= next-total-width layout-width)) + (and col? (<= next-total-height layout-height)))) ;; When :fill we add min width (0 by default) - [{:line-width (if col? (+ line-width next-width) (max line-width next-width)) - :line-height (if row? (+ line-height next-height) (max line-height next-height)) + [{:line-width (if row? (+ line-width next-width) (max line-width next-width)) + :line-height (if col? (+ line-height next-height) (max line-height next-height)) :num-children (inc num-children) :child-fill? (or cur-child-fill? child-fill?) :line-fill? (or cur-line-fill? line-fill?) @@ -123,14 +163,16 @@ (cond-> layout-lines (some? line-data) (conj line-data)))) (defn calc-layout-lines-position - [{:keys [layout-gap] :as parent} layout-bounds layout-lines] + [{:keys [layout-justify-content] :as parent} layout-bounds layout-lines] (let [layout-width (gpo/width-points layout-bounds) layout-height (gpo/height-points layout-bounds) + [layout-gap-row layout-gap-col] (gaps parent) + row? (row? parent) col? (col? parent) - space-between? (= :space-between (:layout-type parent)) - space-around? (= :space-around (:layout-type parent)) + space-between? (= layout-justify-content :space-between) + space-around? (= layout-justify-content :space-around) h-center? (h-center? parent) h-end? (h-end? parent) v-center? (v-center? parent) @@ -148,61 +190,62 @@ [total-width total-height] (cond-> (gpo/origin layout-bounds) - (and row? h-center?) + (and col? h-center?) (gpt/add (xv (/ (- layout-width total-width) 2))) - (and row? h-end?) + (and col? h-end?) (gpt/add (xv (- layout-width total-width))) - (and col? v-center?) + (and row? v-center?) (gpt/add (yv (/ (- layout-height total-height) 2))) - (and col? v-end?) + (and row? v-end?) (gpt/add (yv (- layout-height total-height))))) (get-start-line [{:keys [line-width line-height num-children child-fill?]} base-p] - (let [children-gap (* layout-gap (dec num-children)) + (let [children-gap-width (* layout-gap-row (dec num-children)) + children-gap-height (* layout-gap-col (dec num-children)) - line-width (if (and col? child-fill?) - (- layout-width (* layout-gap (dec num-children))) + line-width (if (and row? child-fill?) + (- layout-width (* layout-gap-row (dec num-children))) line-width) - line-height (if (and row? child-fill?) - (- layout-height (* layout-gap (dec num-children))) + line-height (if (and col? child-fill?) + (- layout-height (* layout-gap-col (dec num-children))) line-height) start-p (cond-> base-p ;; X AXIS - (and col? h-center? (not space-around?) (not space-between?)) + (and row? h-center? (not space-around?) (not space-between?)) (-> (gpt/add (xv (/ layout-width 2))) - (gpt/subtract (xv (/ (+ line-width children-gap) 2)))) + (gpt/subtract (xv (/ (+ line-width children-gap-width) 2)))) - (and col? h-end? (not space-around?) (not space-between?)) + (and row? h-end? (not space-around?) (not space-between?)) (-> (gpt/add (xv layout-width)) - (gpt/subtract (xv (+ line-width children-gap)))) + (gpt/subtract (xv (+ line-width children-gap-width)))) - (and row? h-center?) + (and col? h-center?) (gpt/add (xv (/ line-width 2))) - (and row? h-end?) + (and col? h-end?) (gpt/add (xv line-width)) ;; Y AXIS - (and row? v-center? (not space-around?) (not space-between?)) + (and col? v-center? (not space-around?) (not space-between?)) (-> (gpt/add (yv (/ layout-height 2))) - (gpt/subtract (yv (/ (+ line-height children-gap) 2)))) + (gpt/subtract (yv (/ (+ line-height children-gap-height) 2)))) - (and row? v-end? (not space-around?) (not space-between?)) + (and col? v-end? (not space-around?) (not space-between?)) (-> (gpt/add (yv layout-height)) - (gpt/subtract (yv (+ line-height children-gap)))) + (gpt/subtract (yv (+ line-height children-gap-height)))) - (and col? v-center?) + (and row? v-center?) (gpt/add (yv (/ line-height 2))) - (and col? v-end?) + (and row? v-end?) (gpt/add (yv line-height)))] start-p)) @@ -211,11 +254,11 @@ [{:keys [line-width line-height]} base-p] (cond-> base-p - row? - (gpt/add (xv (+ line-width layout-gap))) - col? - (gpt/add (yv (+ line-height layout-gap))))) + (gpt/add (xv (+ line-width layout-gap-row))) + + row? + (gpt/add (yv (+ line-height layout-gap-col))))) (add-lines [[total-width total-height] {:keys [line-width line-height]}] [(+ total-width line-width) @@ -230,24 +273,25 @@ (let [[total-width total-height] (->> layout-lines (reduce add-lines [0 0])) - total-width (+ total-width (* layout-gap (dec (count layout-lines)))) - total-height (+ total-height (* layout-gap (dec (count layout-lines)))) + total-width (+ total-width (* layout-gap-row (dec (count layout-lines)))) + total-height (+ total-height (* layout-gap-col (dec (count layout-lines)))) vertical-fill-space (- layout-height total-height) + horizontal-fill-space (- layout-width total-width) num-line-fill (count (->> layout-lines (filter :line-fill?))) layout-lines (->> layout-lines (mapv #(cond-> % - (and col? (:line-fill? %)) + (and row? (:line-fill? %)) (update :line-height + (/ vertical-fill-space num-line-fill)) - (and row? (:line-fill? %)) + (and col? (:line-fill? %)) (update :line-width + (/ horizontal-fill-space num-line-fill))))) - total-height (if (and col? (> num-line-fill 0)) layout-height total-height) - total-width (if (and row? (> num-line-fill 0)) layout-width total-width) + total-width (if (and col? (> num-line-fill 0)) layout-width total-width) + total-height (if (and row? (> num-line-fill 0)) layout-height total-height) base-p (get-base-line total-width total-height) @@ -257,40 +301,54 @@ (defn calc-layout-line-data "Calculates the baseline for a flex layout" - [{:keys [layout-type layout-gap] :as shape} + [{:keys [layout-justify-content] :as shape} layout-bounds - {:keys [num-children line-width line-height child-fill?] :as line-data}] + {:keys [num-children line-width line-height] :as line-data}] (let [width (gpo/width-points layout-bounds) height (gpo/height-points layout-bounds) - layout-gap - (cond - (or (= :packed layout-type) child-fill?) - layout-gap + row? (row? shape) + col? (col? shape) + space-between? (= layout-justify-content :space-between) + space-around? (= layout-justify-content :space-around) - (= :space-around layout-type) - 0 + [layout-gap-row layout-gap-col] (gaps shape) - (and (col? shape) (= :space-between layout-type)) - (/ (- width line-width) (dec num-children)) + layout-gap-row + (cond (and row? space-around?) + 0 - (and (row? shape) (= :space-between layout-type)) - (/ (- height line-height) (dec num-children))) + (and row? space-between?) + (/ (- width line-width) (dec num-children)) + + :else + layout-gap-row) + + layout-gap-col + (cond (and col? space-around?) + 0 + + (and col? space-between?) + (/ (- height line-height) (dec num-children)) + + :else + layout-gap-col) margin-x - (if (and (col? shape) (= :space-around layout-type)) + (if (and row? space-around?) (/ (- width line-width) (inc num-children)) 0) margin-y - (if (and (row? shape) (= :space-around layout-type)) + (if (and col? space-around?) (/ (- height line-height) (inc num-children)) 0)] (assoc line-data :layout-bounds layout-bounds - :layout-gap layout-gap + :layout-gap-row layout-gap-row + :layout-gap-col layout-gap-col :margin-x margin-x :margin-y margin-y))) @@ -298,7 +356,7 @@ "Calculates the position for the current shape given the layout-data context" [parent child-width child-height - {:keys [start-p layout-gap margin-x margin-y] :as layout-data}] + {:keys [start-p layout-gap-row layout-gap-col margin-x margin-y] :as layout-data}] (let [row? (row? parent) col? (col? parent) @@ -314,16 +372,16 @@ corner-p (cond-> start-p - (and row? h-center?) + (and col? h-center?) (gpt/add (xv (- (/ child-width 2)))) - (and row? h-end?) + (and col? h-end?) (gpt/add (xv (- child-width))) - (and col? v-center?) + (and row? v-center?) (gpt/add (yv (- (/ child-height 2)))) - (and col? v-end?) + (and row? v-end?) (gpt/add (yv (- child-height))) (some? margin-x) @@ -334,11 +392,11 @@ next-p (cond-> start-p - col? - (gpt/add (xv (+ child-width layout-gap))) - row? - (gpt/add (yv (+ child-height layout-gap))) + (gpt/add (xv (+ child-width layout-gap-row))) + + col? + (gpt/add (yv (+ child-height layout-gap-col))) (some? margin-x) (gpt/add (xv margin-x)) @@ -353,46 +411,48 @@ (defn calc-fill-width-data "Calculates the size and modifiers for the width of an auto-fill child" - [{:keys [layout-gap transform transform-inverse] :as parent} + [{:keys [transform transform-inverse] :as parent} {:keys [layout-h-behavior] :as child} child-origin child-width {:keys [num-children line-width line-fill? child-fill? layout-bounds] :as layout-data}] - (cond - (and (col? parent) (= :fill layout-h-behavior) child-fill?) - (let [layout-width (gpo/width-points layout-bounds) - fill-space (- layout-width line-width (* layout-gap (dec num-children))) - fill-width (/ fill-space (:num-child-fill layout-data)) - fill-scale (/ fill-width child-width)] + (let [[layout-gap-row _] (gaps parent)] + (cond + (and (row? parent) (= :fill layout-h-behavior) child-fill?) + (let [layout-width (gpo/width-points layout-bounds) + fill-space (- layout-width line-width (* layout-gap-row (dec num-children))) + fill-width (/ fill-space (:num-child-fill layout-data)) + fill-scale (/ fill-width child-width)] - {:width fill-width - :modifiers (ctm/resize (gpt/point fill-scale 1) child-origin transform transform-inverse)}) + {:width fill-width + :modifiers (ctm/resize (gpt/point fill-scale 1) child-origin transform transform-inverse)}) - (and (row? parent) (= :fill layout-h-behavior) line-fill?) - (let [fill-scale (/ line-width child-width)] - {:width line-width - :modifiers (ctm/resize (gpt/point fill-scale 1) child-origin transform transform-inverse)}))) + (and (col? parent) (= :fill layout-h-behavior) line-fill?) + (let [fill-scale (/ line-width child-width)] + {:width line-width + :modifiers (ctm/resize (gpt/point fill-scale 1) child-origin transform transform-inverse)})))) (defn calc-fill-height-data "Calculates the size and modifiers for the height of an auto-fill child" - [{:keys [layout-gap transform transform-inverse] :as parent} + [{:keys [transform transform-inverse] :as parent} {:keys [layout-v-behavior] :as child} child-origin child-height {:keys [num-children line-height layout-bounds line-fill? child-fill?] :as layout-data}] - (cond - (and (row? parent) (= :fill layout-v-behavior) child-fill?) - (let [layout-height (gpo/height-points layout-bounds) - fill-space (- layout-height line-height (* layout-gap (dec num-children))) - fill-height (/ fill-space (:num-child-fill layout-data)) - fill-scale (/ fill-height child-height)] - {:height fill-height - :modifiers (ctm/resize (gpt/point 1 fill-scale) child-origin transform transform-inverse)}) + (let [[_ layout-gap-col] (gaps parent)] + (cond + (and (col? parent) (= :fill layout-v-behavior) child-fill?) + (let [layout-height (gpo/height-points layout-bounds) + fill-space (- layout-height line-height (* layout-gap-col (dec num-children))) + fill-height (/ fill-space (:num-child-fill layout-data)) + fill-scale (/ fill-height child-height)] + {:height fill-height + :modifiers (ctm/resize (gpt/point 1 fill-scale) child-origin transform transform-inverse)}) - (and (col? parent) (= :fill layout-v-behavior) line-fill?) - (let [fill-scale (/ line-height child-height)] - {:height line-height - :modifiers (ctm/resize (gpt/point 1 fill-scale) child-origin transform transform-inverse)}))) + (and (row? parent) (= :fill layout-v-behavior) line-fill?) + (let [fill-scale (/ line-height child-height)] + {:height line-height + :modifiers (ctm/resize (gpt/point 1 fill-scale) child-origin transform transform-inverse)})))) (defn normalize-child-modifiers "Apply the modifiers and then normalized them against the parent coordinates" @@ -412,7 +472,7 @@ (defn calc-layout-data "Digest the layout data to pass it to the constrains" - [{:keys [layout-dir layout-padding layout-padding-type] :as parent} children] + [{:keys [layout-flex-dir layout-padding layout-padding-type] :as parent} children] (let [;; Add padding to the bounds {pad-top :p1 pad-right :p2 pad-bottom :p3 pad-left :p4} layout-padding @@ -427,7 +487,7 @@ layout-bounds (gpo/pad-points points pad-top pad-right pad-bottom pad-left) ;; Reverse - reverse? (or (= :left layout-dir) (= :bottom layout-dir)) + reverse? (or (= :reverse-row layout-flex-dir) (= :reverse-column layout-flex-dir)) children (cond->> children reverse? reverse) ;; Creates the layout lines information @@ -476,7 +536,9 @@ h-end? (and row? (h-end? frame)) v-center? (and col? (v-center? frame)) v-end? (and row? (v-end? frame)) - layout-gap (:layout-gap frame 0) + layout-gap-row (or (-> frame :layout-gap :row-gap) 0) + ;;layout-gap-col (or (-> frame :layout-gap :column-gap) 0) + layout-gap layout-gap-row ;; TODO LAYOUT: FIXME reverse? (:reverse? layout-data) children (vec (cond->> (d/enumerate children) @@ -499,31 +561,31 @@ box-width (-> child :selrect :width) box-height (-> child :selrect :height) - x (if row? (:x parent-rect) prev-x) - y (if col? (:y parent-rect) prev-y) + x (if col? (:x parent-rect) prev-x) + y (if row? (:y parent-rect) prev-y) width (cond - (and col? last?) + (and row? last?) (- (+ (:x parent-rect) (:width parent-rect)) x) - row? + col? (:width parent-rect) :else (+ box-width (- box-x prev-x) (/ layout-gap 2))) height (cond - (and row? last?) + (and col? last?) (- (+ (:y parent-rect) (:height parent-rect)) y) - col? + row? (:height parent-rect) :else (+ box-height (- box-y prev-y) (/ layout-gap 2))) [line-area-1 line-area-2] - (if col? + (if row? (let [half-point-width (+ (- box-x x) (/ box-width 2))] [(-> (gsr/make-rect x y half-point-width height) (assoc :index (if reverse? (inc index) index))) @@ -555,16 +617,16 @@ last? (nil? next) line-width - (if col? + (if row? (:width frame) (+ line-width margin-x - (if col? (* layout-gap (dec num-children)) 0))) + (if row? (* layout-gap (dec num-children)) 0))) line-height - (if row? + (if col? (:height frame) (+ line-height margin-y - (if row? + (if col? (* layout-gap (dec num-children)) 0))) @@ -582,24 +644,24 @@ v-end? line-height :else 0)) - x (if col? (:x frame) prev-x) - y (if row? (:y frame) prev-y) + x (if row? (:x frame) prev-x) + y (if col? (:y frame) prev-y) width (cond - (and row? last?) + (and col? last?) (- (+ (:x frame) (:width frame)) x) - col? + row? (:width frame) :else (+ line-width (- box-x prev-x) (/ layout-gap 2))) height (cond - (and col? last?) + (and row? last?) (- (+ (:y frame) (:height frame)) y) - row? + col? (:height frame) :else diff --git a/common/src/app/common/geom/shapes/modifiers.cljc b/common/src/app/common/geom/shapes/modifiers.cljc index 3660aec60..6f7d9a5ec 100644 --- a/common/src/app/common/geom/shapes/modifiers.cljc +++ b/common/src/app/common/geom/shapes/modifiers.cljc @@ -8,9 +8,10 @@ (:require [app.common.data :as d] [app.common.geom.shapes.constraints :as gct] - [app.common.geom.shapes.layout :as gcl] + [app.common.geom.shapes.flex-layout :as gcl] [app.common.geom.shapes.pixel-precision :as gpp] [app.common.geom.shapes.transforms :as gtr] + [app.common.pages.helpers :as cph] [app.common.types.modifiers :as ctm] [app.common.uuid :as uuid])) @@ -101,7 +102,7 @@ modif-tree))))) -(defn get-first-layout +(defn get-tree-root [id objects] (loop [current id @@ -127,24 +128,40 @@ (recur (:id parent) result))))) (defn resolve-tree-sequence - ;; TODO LAYOUT: Esta ahora puesto al zero pero tiene que mirar todas las raices "Given the ids that have changed search for layout roots to recalculate" - [_ids objects] - (->> (tree-seq - #(d/not-empty? (get-in objects [% :shapes])) - #(get-in objects [% :shapes]) - uuid/zero) + [modif-tree objects] - (map #(get objects %)))) + (let [redfn + (fn [result id] + (if (= id uuid/zero) + result + (let [root (get-tree-root id objects) -(defn resolve-layout-ids - "Given a list of ids, resolve the parent layouts that will need to update. This will go upwards - in the tree while a layout is found" - [ids objects] + ;; Remove the children from the current root + result + (into #{} (remove #(cph/is-child? objects root %)) result) - (into (d/ordered-set) - (map #(get-first-layout % objects)) - ids)) + contains-parent? + (some #(cph/is-child? objects % root) result)] + + (cond-> result + (not contains-parent?) + (conj root))))) + + generate-tree + (fn [id] + (->> (tree-seq + #(d/not-empty? (get-in objects [% :shapes])) + #(get-in objects [% :shapes]) + id) + + (map #(get objects %)))) + + roots (->> modif-tree keys (reduce redfn #{}))] + + (concat + (when (contains? modif-tree uuid/zero) [(get objects uuid/zero)]) + (mapcat generate-tree roots)))) (defn inside-layout? [objects shape] @@ -170,34 +187,31 @@ ;; modif-tree)))) (defn set-objects-modifiers - [ids objects get-modifier ignore-constraints snap-pixel?] + [modif-tree objects ignore-constraints snap-pixel?] - (let [set-modifiers - (fn [modif-tree id] - (let [root? (= uuid/zero id) - shape (get objects id) - modifiers (cond-> (get-modifier shape) - (and (not root?) snap-pixel?) - (gpp/set-pixel-precision shape))] - (-> modif-tree - (assoc id {:modifiers modifiers})))) - - modif-tree (reduce set-modifiers {} ids) - shapes-tree (resolve-tree-sequence ids objects) + (let [shapes-tree (resolve-tree-sequence modif-tree objects) modif-tree (->> shapes-tree (reduce (fn [modif-tree shape] + (let [root? (= uuid/zero (:id shape)) + modifiers (get-in modif-tree [(:id shape) :modifiers]) - has-modifiers? (some? modifiers) + modifiers (cond-> modifiers + (and (not root?) (ctm/has-geometry? modifiers) snap-pixel?) + (gpp/set-pixel-precision shape)) + + modif-tree (-> modif-tree (assoc-in [(:id shape) :modifiers] modifiers)) + + has-modifiers? (ctm/child-modifiers? modifiers) is-layout? (layout? shape) is-parent? (or (group? shape) (and (frame? shape) (not (layout? shape)))) ;; If the current child is inside the layout we ignore the constraints is-inside-layout? (inside-layout? objects shape)] - + (cond-> modif-tree (and has-modifiers? is-parent? (not root?)) (set-children-modifiers objects shape (or ignore-constraints is-inside-layout?) snap-pixel?) @@ -207,6 +221,6 @@ modif-tree))] - ;; #?(:cljs - ;; (.log js/console ">result" (modif->js modif-tree objects))) + ;;#?(:cljs + ;; (.log js/console ">result" (modif->js modif-tree objects))) modif-tree)) diff --git a/common/src/app/common/geom/shapes/pixel_precision.cljc b/common/src/app/common/geom/shapes/pixel_precision.cljc index 03aa4359a..40e32ae72 100644 --- a/common/src/app/common/geom/shapes/pixel_precision.cljc +++ b/common/src/app/common/geom/shapes/pixel_precision.cljc @@ -31,8 +31,10 @@ ratio-width (/ target-width curr-width) ratio-height (/ target-height curr-height) scalev (gpt/point ratio-width ratio-height)] - (-> modifiers - (ctm/set-resize scalev origin transform transform-inverse)))) + (cond-> modifiers + (or (not (mth/almost-zero? (- ratio-width 1))) + (not (mth/almost-zero? (- ratio-height 1)))) + (ctm/set-resize scalev origin transform transform-inverse)))) (defn position-pixel-precision [modifiers shape] @@ -41,8 +43,10 @@ corner (gpt/point bounds) target-corner (gpt/round corner) deltav (gpt/to-vec corner target-corner)] - (-> modifiers - (ctm/set-move deltav)))) + (cond-> modifiers + (or (not (mth/almost-zero? (:x deltav))) + (not (mth/almost-zero? (:y deltav)))) + (ctm/set-move deltav)))) (defn set-pixel-precision "Adjust modifiers so they adjust to the pixel grid" diff --git a/common/src/app/common/types/modifiers.cljc b/common/src/app/common/types/modifiers.cljc index bd0715aec..22c5ff636 100644 --- a/common/src/app/common/types/modifiers.cljc +++ b/common/src/app/common/types/modifiers.cljc @@ -24,7 +24,8 @@ ;; - structure-parent: Structure non recursive ;; * add-children ;; * remove-children -;; - structure-child: Structre recursive +;; * reflow +;; - structure-child: Structure recursive ;; * scale-content ;; @@ -47,44 +48,48 @@ ([modifiers vector origin] (-> modifiers (update :geometry conjv {:type :resize - :vector vector - :origin origin}))) + :vector vector + :origin origin}))) ([modifiers vector origin transform transform-inverse] (-> modifiers (update :geometry conjv {:type :resize - :vector vector - :origin origin - :transform transform - :transform-inverse transform-inverse})))) + :vector vector + :origin origin + :transform transform + :transform-inverse transform-inverse})))) (defn set-rotation [modifiers center angle] (-> modifiers (update :geometry conjv {:type :rotation - :center center - :rotation angle}))) + :center center + :rotation angle}))) (defn set-remove-children [modifiers shapes] (-> modifiers (update :structure-parent conjv {:type :remove-children - :value shapes})) + :value shapes})) ) (defn set-add-children [modifiers shapes index] (-> modifiers (update :structure-parent conjv {:type :add-children - :value shapes - :index index}))) + :value shapes + :index index}))) + +(defn set-reflow + [modifiers] + (-> modifiers + (update :structure-parent conjv {:type :reflow}))) (defn set-scale-content [modifiers value] (-> modifiers (update :structure-child conjv {:type :scale-content :value value}))) - (defn add-modifiers [modifiers new-modifiers] @@ -124,7 +129,7 @@ (-> (empty-modifiers) (set-rotation shape-center angle) - (set-move (gpt/transform (gpt/point 1 1) rotation))))) + (set-move (gpt/transform (gpt/point 0 0) rotation))))) (defn remove-children [shapes] @@ -136,11 +141,21 @@ (-> (empty-modifiers) (set-add-children shapes index))) +(defn reflow + [] + (-> (empty-modifiers) + (set-reflow))) + (defn scale-content [value] (-> (empty-modifiers) (set-scale-content value))) +(defn child-modifiers? + [{:keys [geometry structure-child]}] + (or (d/not-empty? geometry) + (d/not-empty? structure-child))) + (defn select-child-modifiers [modifiers] (select-keys modifiers [:geometry :structure-child])) @@ -337,3 +352,7 @@ (as-> shape $ (reduce apply-modifier $ (:structure-parent modifiers)) (reduce apply-modifier $ (:structure-child modifiers))))) + +(defn has-geometry? + [{:keys [geometry]}] + (d/not-empty? geometry)) diff --git a/common/test/common_tests/geom_shapes_test.cljc b/common/test/common_tests/geom_shapes_test.cljc index f86487de2..e36a487e7 100644 --- a/common/test/common_tests/geom_shapes_test.cljc +++ b/common/test/common_tests/geom_shapes_test.cljc @@ -10,6 +10,7 @@ [app.common.geom.point :as gpt] [app.common.geom.shapes :as gsh] [app.common.math :as mth :refer [close?]] + [app.common.types.modifiers :as ctm] [app.common.types.shape :as cts] [clojure.test :as t])) @@ -59,7 +60,7 @@ (t/testing "Transform shape with translation modifiers" (t/are [type] - (let [modifiers {:displacement (gmt/translate-matrix (gpt/point 10 -10))}] + (let [modifiers (ctm/move (gpt/point 10 -10))] (let [shape-before (create-test-shape type {:modifiers modifiers}) shape-after (gsh/transform-shape shape-before)] (t/is (not= shape-before shape-after)) @@ -91,9 +92,7 @@ (t/testing "Transform shape with resize modifiers" (t/are [type] - (let [modifiers {:resize-origin (gpt/point 0 0) - :resize-vector (gpt/point 2 2) - :resize-transform (gmt/matrix)} + (let [modifiers (ctm/resize (gpt/point 2 2) (gpt/point 0 0)) shape-before (create-test-shape type {:modifiers modifiers}) shape-after (gsh/transform-shape shape-before)] (t/is (not= shape-before shape-after)) @@ -113,9 +112,7 @@ (t/testing "Transform with empty resize" (t/are [type] - (let [modifiers {:resize-origin (gpt/point 0 0) - :resize-vector (gpt/point 1 1) - :resize-transform (gmt/matrix)} + (let [modifiers (ctm/resize (gpt/point 1 1) (gpt/point 0 0)) shape-before (create-test-shape type {:modifiers modifiers}) shape-after (gsh/transform-shape shape-before)] (t/are [prop] @@ -126,9 +123,7 @@ (t/testing "Transform with resize=0" (t/are [type] - (let [modifiers {:resize-origin (gpt/point 0 0) - :resize-vector (gpt/point 0 0) - :resize-transform (gmt/matrix)} + (let [modifiers (ctm/resize (gpt/point 0 0) (gpt/point 0 0)) shape-before (create-test-shape type {:modifiers modifiers}) shape-after (gsh/transform-shape shape-before)] (t/is (> (get-in shape-before [:selrect :width]) @@ -142,13 +137,13 @@ (t/testing "Transform shape with rotation modifiers" (t/are [type] - (let [modifiers {:rotation 30} - shape-before (create-test-shape type {:modifiers modifiers}) + (let [shape-before (create-test-shape type) + modifiers (ctm/rotation shape-before (gsh/center-shape shape-before) 30 ) + shape-before (assoc shape-before :modifiers modifiers) shape-after (gsh/transform-shape shape-before)] - (t/is (not= shape-before shape-after)) + (t/is (not= (:selrect shape-before) (:selrect shape-after))) - ;; Selrect won't change with a rotation, but points will (t/is (close? (get-in shape-before [:selrect :x]) (get-in shape-after [:selrect :x]))) @@ -166,9 +161,9 @@ (t/testing "Transform shape with rotation = 0 should leave equal selrect" (t/are [type] - (let [modifiers {:rotation 0} - shape-before (create-test-shape type {:modifiers modifiers}) - shape-after (gsh/transform-shape shape-before)] + (let [shape-before (create-test-shape type) + modifiers (ctm/rotation shape-before (gsh/center-shape shape-before) 0) + shape-after (gsh/transform-shape (assoc shape-before :modifiers modifiers))] (t/are [prop] (t/is (close? (get-in shape-before [:selrect prop]) (get-in shape-after [:selrect prop]))) @@ -177,12 +172,13 @@ (t/testing "Transform shape with invalid selrect fails gracefully" (t/are [type selrect] - (let [modifiers {:displacement (gmt/matrix)} + (let [modifiers (ctm/move 0 0) shape-before (-> (create-test-shape type {:modifiers modifiers}) (assoc :selrect selrect)) shape-after (gsh/transform-shape shape-before)] - (= (:selrect shape-before) - (:selrect shape-after))) + + (t/is (not= (:selrect shape-before) + (:selrect shape-after)))) :rect {:x 0.0 :y 0.0 :x1 0.0 :y1 0.0 :x2 ##Inf :y2 ##Inf :width ##Inf :height ##Inf} :path {:x 0.0 :y 0.0 :x1 0.0 :y1 0.0 :x2 ##Inf :y2 ##Inf :width ##Inf :height ##Inf} diff --git a/frontend/src/app/main/data/workspace/shape_layout.cljs b/frontend/src/app/main/data/workspace/shape_layout.cljs index cffd33827..da2262c53 100644 --- a/frontend/src/app/main/data/workspace/shape_layout.cljs +++ b/frontend/src/app/main/data/workspace/shape_layout.cljs @@ -8,6 +8,7 @@ (:require [app.common.data :as d] [app.common.pages.helpers :as cph] + [app.common.types.modifiers :as ctm] [app.main.data.workspace.changes :as dwc] [app.main.data.workspace.state-helpers :as wsh] [app.main.data.workspace.transforms :as dwt] @@ -25,8 +26,7 @@ :layout-wrap-type :layout-padding-type :layout-padding - ]) - + :layout-gap-type]) (def initial-flex-layout {:layout :flex @@ -51,8 +51,9 @@ (let [objects (wsh/lookup-page-objects state) ids (->> ids (filter #(get-in objects [% :layout])))] (if (d/not-empty? ids) - (rx/of (dwt/set-modifiers ids) - (dwt/apply-modifiers)) + (let [modif-tree (dwt/create-modif-tree ids (ctm/reflow))] + (rx/of (dwt/set-modifiers modif-tree) + (dwt/apply-modifiers))) (rx/empty)))))) ;; TODO LAYOUT: Remove constraints from children diff --git a/frontend/src/app/main/data/workspace/transforms.cljs b/frontend/src/app/main/data/workspace/transforms.cljs index f304dbe31..1769d41ae 100644 --- a/frontend/src/app/main/data/workspace/transforms.cljs +++ b/frontend/src/app/main/data/workspace/transforms.cljs @@ -11,7 +11,7 @@ [app.common.geom.matrix :as gmt] [app.common.geom.point :as gpt] [app.common.geom.shapes :as gsh] - [app.common.geom.shapes.layout :as gsl] + [app.common.geom.shapes.flex-layout :as gsl] [app.common.math :as mth] [app.common.pages.changes-builder :as pcb] [app.common.pages.common :as cpc] @@ -117,46 +117,69 @@ (declare get-ignore-tree) +(defn create-modif-tree + [ids modifiers] + (us/verify (s/coll-of uuid?) ids) + (into {} (map #(vector % {:modifiers modifiers})) ids)) + +(defn build-modif-tree + [ids objects get-modifier] + (us/verify (s/coll-of uuid?) ids) + (into {} (map #(vector % {:modifiers (get-modifier (get objects %))})) ids)) + +(defn build-change-frame-modifiers + [modif-tree objects selected target-frame position] + + (let [origin-frame-ids (->> selected (group-by #(get-in objects [% :frame-id]))) + layout? (get-in objects [target-frame :layout]) + child-set (set (get-in objects [target-frame :shapes])) + drop-index (when layout? (gsl/get-drop-index target-frame objects position)) + + update-frame-modifiers + (fn [modif-tree [original-frame shapes]] + (let [shapes (->> shapes (d/removev #(= target-frame %))) + shapes (cond->> shapes + (and layout? (= original-frame target-frame)) + ;; When movining inside a layout frame remove the shapes that are not immediate children + (filterv #(contains? child-set %)))] + (cond-> modif-tree + (not= original-frame target-frame) + (-> (update-in [original-frame :modifiers] ctm/set-remove-children shapes) + (update-in [target-frame :modifiers] ctm/set-add-children shapes drop-index)) + + (and layout? (= original-frame target-frame)) + (update-in [target-frame :modifiers] ctm/set-add-children shapes drop-index))))] + + (reduce update-frame-modifiers modif-tree origin-frame-ids))) + +(defn modif->js + [modif-tree objects] + (clj->js (into {} + (map (fn [[k v]] + [(get-in objects [k :name]) v])) + modif-tree))) + (defn set-modifiers - ([ids] - (set-modifiers ids nil false)) + ([modif-tree] + (set-modifiers modif-tree false)) - ([ids modifiers] - (set-modifiers ids modifiers false)) + ([modif-tree ignore-constraints] + (set-modifiers modif-tree ignore-constraints false)) - ([ids modifiers ignore-constraints] - (set-modifiers ids modifiers ignore-constraints false)) - - ([ids modifiers ignore-constraints ignore-snap-pixel] - (us/verify (s/coll-of uuid?) ids) + ([modif-tree ignore-constraints ignore-snap-pixel] (ptk/reify ::set-modifiers ptk/UpdateEvent (update [_ state] - (let [objects (wsh/lookup-page-objects state) - ids (into #{} (remove #(get-in objects [% :blocked] false)) ids) + (let [objects + (wsh/lookup-page-objects state) - snap-pixel? (and (not ignore-snap-pixel) - (contains? (:workspace-layout state) :snap-pixel-grid)) - - workspace-modifiers (:workspace-modifiers state) + snap-pixel? + (and (not ignore-snap-pixel) (contains? (:workspace-layout state) :snap-pixel-grid)) modif-tree - (gsh/set-objects-modifiers - ;; TODO LAYOUT: I don't like this - (concat (keys workspace-modifiers) ids) - objects - (fn [shape] - (let [ - modifiers (if (contains? ids (:id shape)) modifiers (ctm/empty-modifiers)) + (gsh/set-objects-modifiers modif-tree objects ignore-constraints snap-pixel?)] - structure-modifiers (ctm/select-structure - (get-in state [:workspace-modifiers (:id shape) :modifiers]))] - (cond-> modifiers - (some? structure-modifiers) - (ctm/add-modifiers structure-modifiers)))) - ignore-constraints snap-pixel?)] - - (update state :workspace-modifiers merge modif-tree)))))) + (assoc state :workspace-modifiers modif-tree)))))) ;; Rotation use different algorithm to calculate children modifiers (and do not use child constraints). (defn- set-rotation-modifiers @@ -171,8 +194,6 @@ ids (->> shapes (remove #(get % :blocked false)) - #_(mapcat #(cph/get-children objects (:id %))) - #_(concat shapes) (filter #((cpc/editable-attrs (:type %)) :rotation)) (map :id)) @@ -181,9 +202,10 @@ (ctm/rotation shape center angle)) modif-tree - (gsh/set-objects-modifiers ids objects get-modifier false false)] + (-> (build-modif-tree ids objects get-modifier) + (gsh/set-objects-modifiers objects false false))] - (update state :workspace-modifiers merge modif-tree)))))) + (assoc state :workspace-modifiers modif-tree)))))) (defn- update-grow-type [shape old-shape] @@ -408,9 +430,11 @@ (ctm/set-resize scalev resize-origin shape-transform shape-transform-inverse) (cond-> scale-text - (ctm/set-scale-content (:x scalev))))] + (ctm/set-scale-content (:x scalev)))) - (rx/of (set-modifiers ids modifiers)))) + modif-tree (create-modif-tree ids modifiers)] + + (rx/of (set-modifiers modif-tree)))) ;; Unifies the instantaneous proportion lock modifier ;; activated by Shift key and the shapes own proportion @@ -463,7 +487,8 @@ (fn [shape] (ctm/change-dimensions shape attr value)) modif-tree - (gsh/set-objects-modifiers ids objects get-modifier false snap-pixel?)] + (-> (build-modif-tree ids objects get-modifier) + (gsh/set-objects-modifiers objects false snap-pixel?))] (assoc state :workspace-modifiers modif-tree))) @@ -487,7 +512,8 @@ (fn [shape] (ctm/change-orientation-modifiers shape orientation)) modif-tree - (gsh/set-objects-modifiers ids objects get-modifier false snap-pixel?)] + (-> (build-modif-tree ids objects get-modifier) + (gsh/set-objects-modifiers objects false snap-pixel?))] (assoc state :workspace-modifiers modif-tree))) @@ -621,37 +647,6 @@ (rx/take 1) (rx/map #(start-move from-position)))))) -(defn set-change-frame-modifiers - [selected target-frame position] - - (ptk/reify ::set-change-frame-modifiers - ptk/UpdateEvent - (update [_ state] - (let [objects (wsh/lookup-page-objects state) - - origin-frame-ids (->> selected (group-by #(get-in objects [% :frame-id]))) - - layout? (get-in objects [target-frame :layout]) - - drop-index - (when layout? (gsl/get-drop-index target-frame objects position)) - - modif-tree - (into {} - (mapcat - (fn [original-frame] - (let [shapes (->> (get origin-frame-ids original-frame) - (d/removev #(= target-frame %)))] - (cond - (not= original-frame target-frame) - [[original-frame {:modifiers (ctm/remove-children shapes)}] - [target-frame {:modifiers (ctm/add-children shapes drop-index)}]] - - layout? - [[target-frame {:modifiers (ctm/add-children shapes drop-index)}]])))) - (keys origin-frame-ids))] - - (assoc state :workspace-modifiers modif-tree))))) (defn- start-move ([from-position] (start-move from-position nil)) @@ -699,22 +694,21 @@ (rx/of (finish-transform)) (rx/concat (rx/merge - (->> position - (rx/map (fn [delta] - (let [position (gpt/add from-position delta) - target-frame (ctst/top-nested-frame objects position)] - (set-change-frame-modifiers selected target-frame position)))) - (rx/take-until stopper)) - (->> position ;; We ask for the snap position but we continue even if the result is not available (rx/with-latest vector snap-delta) ;; We try to use the previous snap so we don't have to wait for the result of the new (rx/map snap/correct-snap-point) - (rx/map ctm/move) - (rx/map (partial set-modifiers ids)) + (rx/map + (fn [move-vector] + (let [position (gpt/add from-position move-vector) + target-frame (ctst/top-nested-frame objects position)] + (-> (create-modif-tree ids (ctm/move move-vector)) + (build-change-frame-modifiers objects selected target-frame position) + (set-modifiers))))) + (rx/take-until stopper))) (rx/of (dwu/start-undo-transaction) @@ -762,8 +756,8 @@ (rx/merge (->> move-events (rx/scan #(gpt/add %1 mov-vec) (gpt/point 0 0)) - (rx/map #(ctm/move %)) - (rx/map (partial set-modifiers selected)) + (rx/map #(create-modif-tree selected (ctm/move %))) + (rx/map (partial set-modifiers)) (rx/take-until stopper)) (rx/of (move-selected direction shift?))) @@ -793,11 +787,12 @@ cpos (gpt/point (:x bbox) (:y bbox)) pos (gpt/point (or (:x position) (:x bbox)) (or (:y position) (:y bbox))) - delta (gpt/subtract pos cpos)] + delta (gpt/subtract pos cpos) - (rx/of - (set-modifiers [id] (ctm/move delta)) - (apply-modifiers [id])))))) + modif-tree (create-modif-tree [id] (ctm/move delta))] + + (rx/of (set-modifiers modif-tree) + (apply-modifiers)))))) (defn- calculate-frame-for-move [ids] @@ -816,7 +811,11 @@ moving-shapes (cond->> shapes (not layout?) - (remove #(= (:frame-id %) frame-id))) + (remove #(= (:frame-id %) frame-id)) + + layout? + (remove #(and (= (:frame-id %) frame-id) + (not= (:parent-id %) frame-id)))) drop-index (when layout? (gsl/get-drop-index frame-id objects position)) @@ -850,13 +849,15 @@ selected (wsh/lookup-selected state {:omit-blocked? true}) shapes (map #(get objects %) selected) selrect (gsh/selection-rect shapes) - origin (gpt/point (:x selrect) (+ (:y selrect) (/ (:height selrect) 2)))] + origin (gpt/point (:x selrect) (+ (:y selrect) (/ (:height selrect) 2))) - (rx/of (set-modifiers selected - (-> (ctm/empty-modifiers) - (ctm/set-resize (gpt/point -1.0 1.0) origin) - (ctm/move (gpt/point (:width selrect) 0))) - true) + modif-tree (create-modif-tree + selected + (-> (ctm/empty-modifiers) + (ctm/set-resize (gpt/point -1.0 1.0) origin) + (ctm/move (gpt/point (:width selrect) 0))))] + + (rx/of (set-modifiers modif-tree true) (apply-modifiers)))))) (defn flip-vertical-selected [] @@ -867,11 +868,13 @@ selected (wsh/lookup-selected state {:omit-blocked? true}) shapes (map #(get objects %) selected) selrect (gsh/selection-rect shapes) - origin (gpt/point (+ (:x selrect) (/ (:width selrect) 2)) (:y selrect))] + origin (gpt/point (+ (:x selrect) (/ (:width selrect) 2)) (:y selrect)) - (rx/of (set-modifiers selected - (-> (ctm/empty-modifiers) - (ctm/set-resize (gpt/point 1.0 -1.0) origin) - (ctm/move (gpt/point 0 (:height selrect)))) - true) + modif-tree (create-modif-tree + selected + (-> (ctm/empty-modifiers) + (ctm/set-resize (gpt/point 1.0 -1.0) origin) + (ctm/move (gpt/point 0 (:height selrect)))))] + + (rx/of (set-modifiers modif-tree true) (apply-modifiers)))))) diff --git a/frontend/src/app/main/snap.cljs b/frontend/src/app/main/snap.cljs index ce2b97c24..f9585b5bf 100644 --- a/frontend/src/app/main/snap.cljs +++ b/frontend/src/app/main/snap.cljs @@ -358,7 +358,8 @@ "Snaps a position given an old snap to a different position. We use this to provide a temporal snap while the new is being processed." [[position [snap-pos snap-delta]]] - (if (some? snap-delta) + (if (nil? snap-delta) + position (let [dx (if (not= 0 (:x snap-delta)) (- (+ (:x snap-pos) (:x snap-delta)) (:x position)) 0) @@ -372,6 +373,4 @@ dy (if (> (mth/abs dy) snap-accuracy) 0 dy)] (-> position (update :x + dx) - (update :y + dy))) - - position)) + (update :y + dy))))) diff --git a/frontend/src/app/main/ui/workspace/shapes.cljs b/frontend/src/app/main/ui/workspace/shapes.cljs index a6ca1742b..0b92d475e 100644 --- a/frontend/src/app/main/ui/workspace/shapes.cljs +++ b/frontend/src/app/main/ui/workspace/shapes.cljs @@ -68,24 +68,21 @@ [:g.frame-children (for [shape shapes] - [:g.ws-shape-wrapper + [:g.ws-shape-wrapper {:key (:id shape)} (cond (not (cph/frame-shape? shape)) [:& shape-wrapper - {:shape shape - :key (:id shape)}] + {:shape shape}] (cph/root-frame? shape) [:& root-frame-wrapper {:shape shape - :key (:id shape) :objects (get frame-objects (:id shape)) :thumbnail? (not (contains? active-frames (:id shape)))}] :else [:& nested-frame-wrapper {:shape shape - :key (:id shape) :objects (get frame-objects (:id shape))}])])]]])) (mf/defc shape-wrapper diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs index d27cb93a5..e0b8fd357 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs @@ -84,38 +84,38 @@ [:div.layout-behavior.horizontal [:button.behavior-btn.tooltip.tooltip-bottom {:alt "Fix width" - :class (dom/classnames :activated (= layout-h-behavior :fix)) + :class (dom/classnames :active (= layout-h-behavior :fix)) :on-click #(on-change-behavior :h :fix)} i/auto-fix-layout] (when fill? [:button.behavior-btn.tooltip.tooltip-bottom {:alt "Width 100%" - :class (dom/classnames :activated (= layout-h-behavior :fill)) + :class (dom/classnames :active (= layout-h-behavior :fill)) :on-click #(on-change-behavior :h :fill)} i/auto-fill]) (when auto? [:button.behavior-btn.tooltip.tooltip-bottom {:alt "Fit content" - :class (dom/classnames :activated (= layout-v-behavior :auto)) + :class (dom/classnames :active (= layout-v-behavior :auto)) :on-click #(on-change-behavior :h :auto)} i/auto-hug])] [:div.layout-behavior [:button.behavior-btn.tooltip.tooltip-bottom {:alt "Fix height" - :class (dom/classnames :activated (= layout-v-behavior :fix)) + :class (dom/classnames :active (= layout-v-behavior :fix)) :on-click #(on-change-behavior :v :fix)} i/auto-fix-layout] (when fill? [:button.behavior-btn.tooltip.tooltip-bottom {:alt "Height 100%" - :class (dom/classnames :activated (= layout-v-behavior :fill)) + :class (dom/classnames :active (= layout-v-behavior :fill)) :on-click #(on-change-behavior :v :fill)} i/auto-fill]) (when auto? [:button.behavior-btn.tooltip.tooltip-bottom-left {:alt "Fit content" - :class (dom/classnames :activated (= layout-v-behavior :auto)) + :class (dom/classnames :active (= layout-v-behavior :auto)) :on-click #(on-change-behavior :v :auto)} i/auto-hug])]])) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs index bd9df2411..048fff5c0 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs @@ -47,7 +47,7 @@ [:* [:& layout-container-menu {:type type :ids [(:id shape)] :values layout-container-values}] - (when (or (:layout shape) is-layout-child?) + (when is-layout-child? [:& layout-item-menu {:ids ids :type type diff --git a/frontend/src/app/main/ui/workspace/viewport/debug.cljs b/frontend/src/app/main/ui/workspace/viewport/debug.cljs index ef81d5fa9..869caa8ca 100644 --- a/frontend/src/app/main/ui/workspace/viewport/debug.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/debug.cljs @@ -9,7 +9,7 @@ [app.common.data :as d] [app.common.data.macros :as dm] [app.common.geom.shapes :as gsh] - [app.common.geom.shapes.layout :as gsl] + [app.common.geom.shapes.flex-layout :as gsl] [app.common.pages.helpers :as cph] [rumext.v2 :as mf]))