mirror of
https://github.com/penpot/penpot.git
synced 2025-01-25 07:58:49 -05:00
🎉 Add support for nested layouts
This commit is contained in:
parent
1c8aef6fa8
commit
7176bb6f1a
7 changed files with 308 additions and 205 deletions
|
@ -15,6 +15,7 @@
|
|||
[app.common.geom.shapes.corners :as gsc]
|
||||
[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]
|
||||
[app.common.geom.shapes.transforms :as gtr]
|
||||
|
@ -201,3 +202,6 @@
|
|||
;; Corners
|
||||
(dm/export gsc/shape-corners-1)
|
||||
(dm/export gsc/shape-corners-4)
|
||||
|
||||
;; Modifiers
|
||||
(dm/export gsm/set-objects-modifiers)
|
||||
|
|
|
@ -197,6 +197,9 @@
|
|||
;; Build final child modifiers. Apply transform again to the result, to get the
|
||||
;; real modifiers that need to be applied to the child, including rotation as needed.
|
||||
(cond-> {}
|
||||
(some? (:displacement-after modifiers))
|
||||
(assoc :displacement-after (:displacement-after modifiers))
|
||||
|
||||
(or (contains? modifiers-h :displacement)
|
||||
(contains? modifiers-v :displacement))
|
||||
(assoc :displacement (cond-> (gpt/point (get-in modifiers-h [:displacement :x] 0)
|
||||
|
|
|
@ -68,11 +68,11 @@
|
|||
|
||||
(defn calc-layout-data
|
||||
"Digest the layout data to pass it to the constrains"
|
||||
[{:keys [layout-gap] :as shape} children modif-tree transformed-rect]
|
||||
[{:keys [layout-type layout-gap] :as shape} children modif-tree transformed-rect]
|
||||
|
||||
(let [transformed-rect (-> transformed-rect (add-padding shape))
|
||||
(let [{:keys [x y width height]} (-> transformed-rect (add-padding shape))
|
||||
num-children (count children)
|
||||
children-gap (* layout-gap (dec num-children) )
|
||||
|
||||
[children-width children-height]
|
||||
(->> children
|
||||
(map #(-> (merge % (get modif-tree (:id %))) gtr/transform-shape))
|
||||
|
@ -80,13 +80,39 @@
|
|||
[(+ acc-width (-> shape :points gre/points->rect :width))
|
||||
(+ acc-height (-> shape :points gre/points->rect :height))]) [0 0]))
|
||||
|
||||
{:keys [x y width height]} transformed-rect
|
||||
layout-gap
|
||||
(cond
|
||||
(= :packed layout-type)
|
||||
layout-gap
|
||||
|
||||
(= :space-around layout-type)
|
||||
0
|
||||
|
||||
(and (col? shape) (= :space-between layout-type))
|
||||
(/ (- width children-width) (dec num-children))
|
||||
|
||||
(and (row? shape) (= :space-between layout-type))
|
||||
(/ (- height children-height) (dec num-children)))
|
||||
|
||||
margin-x (if (and (col? shape) (= :space-around layout-type))
|
||||
(/ (- width children-width) (dec num-children) 2)
|
||||
0)
|
||||
|
||||
margin-y (if (and (row? shape) (= :space-around layout-type))
|
||||
(/ (- height children-height) (dec num-children) 2)
|
||||
0)
|
||||
|
||||
children-gap (* layout-gap (dec num-children))
|
||||
|
||||
start-x
|
||||
(cond
|
||||
(or (and (col? shape) (= :space-between layout-type))
|
||||
(and (col? shape) (= :space-around layout-type)))
|
||||
x
|
||||
|
||||
(and (row? shape) (h-center? shape))
|
||||
(+ x (/ width 2))
|
||||
|
||||
|
||||
(and (row? shape) (h-end? shape))
|
||||
(+ x width)
|
||||
|
||||
|
@ -97,10 +123,14 @@
|
|||
(- (+ x width) (+ children-width children-gap))
|
||||
|
||||
:else
|
||||
(:x transformed-rect))
|
||||
x)
|
||||
|
||||
start-y
|
||||
(cond
|
||||
(or (and (row? shape) (= :space-between layout-type))
|
||||
(and (row? shape) (= :space-around layout-type)))
|
||||
y
|
||||
|
||||
(and (col? shape) (v-center? shape))
|
||||
(+ y (/ height 2))
|
||||
|
||||
|
@ -114,15 +144,18 @@
|
|||
(- (+ y height) (+ children-height children-gap))
|
||||
|
||||
:else
|
||||
(:y transformed-rect) )]
|
||||
y)]
|
||||
|
||||
{:start-x start-x
|
||||
:start-y start-y
|
||||
:layout-gap layout-gap
|
||||
:margin-x margin-x
|
||||
:margin-y margin-y
|
||||
:reverse? (or (= :left (:layout-dir shape)) (= :bottom (:layout-dir shape)))}))
|
||||
|
||||
(defn next-p
|
||||
"Calculates the position for the current shape given the layout-data context"
|
||||
[{:keys [layout-gap] :as shape} {:keys [width height]} {:keys [start-x start-y] :as layout-data}]
|
||||
[shape {:keys [width height]} {:keys [start-x start-y layout-gap margin-x margin-y] :as layout-data}]
|
||||
|
||||
(let [pos-x
|
||||
(cond
|
||||
|
@ -146,8 +179,11 @@
|
|||
:else
|
||||
start-y)
|
||||
|
||||
pos-x (cond-> pos-x (some? margin-x) (+ margin-x))
|
||||
pos-y (cond-> pos-y (some? margin-y) (+ margin-y))
|
||||
|
||||
corner-p (gpt/point pos-x pos-y)
|
||||
|
||||
|
||||
next-x
|
||||
(if (col? shape)
|
||||
(+ start-x width layout-gap)
|
||||
|
@ -158,6 +194,9 @@
|
|||
(+ start-y height layout-gap)
|
||||
start-y)
|
||||
|
||||
next-x (cond-> next-x (some? margin-x) (+ margin-x))
|
||||
next-y (cond-> next-y (some? margin-y) (+ margin-y))
|
||||
|
||||
layout-data
|
||||
(assoc layout-data :start-x next-x :start-y next-y)]
|
||||
[corner-p layout-data])
|
||||
|
@ -165,15 +204,15 @@
|
|||
|
||||
(defn calc-layout-modifiers
|
||||
"Calculates the modifiers for the layout"
|
||||
[parent child current-modifier _modifiers _transformed-rect layout-data]
|
||||
[parent child modifiers layout-data]
|
||||
|
||||
(let [current-modifier (-> current-modifier (dissoc :displacement-after))
|
||||
child (-> child (assoc :modifiers current-modifier) gtr/transform-shape)
|
||||
bounds (-> child :points gre/points->selrect)
|
||||
(let [modifiers (-> modifiers (dissoc :displacement-after))
|
||||
child (-> child (assoc :modifiers modifiers) gtr/transform-shape)
|
||||
bounds (-> child :points gre/points->selrect)
|
||||
|
||||
[corner-p layout-data] (next-p parent bounds layout-data)
|
||||
|
||||
delta-p (-> corner-p (gpt/subtract (gpt/point bounds)))
|
||||
modifiers (-> current-modifier (assoc :displacement-after (gmt/translate-matrix delta-p)))]
|
||||
modifiers (-> modifiers (assoc :displacement-after (gmt/translate-matrix delta-p)))]
|
||||
|
||||
[modifiers layout-data]))
|
||||
|
|
213
common/src/app/common/geom/shapes/modifiers.cljc
Normal file
213
common/src/app/common/geom/shapes/modifiers.cljc
Normal file
|
@ -0,0 +1,213 @@
|
|||
;; 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) UXBOX Labs SL
|
||||
|
||||
(ns app.common.geom.shapes.modifiers
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.geom.matrix :as gmt]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes.common :as gco]
|
||||
[app.common.geom.shapes.constraints :as gct]
|
||||
[app.common.geom.shapes.layout :as gcl]
|
||||
[app.common.geom.shapes.rect :as gpr]
|
||||
[app.common.geom.shapes.transforms :as gtr]
|
||||
[app.common.math :as mth]
|
||||
[app.common.uuid :as uuid]))
|
||||
|
||||
(defn set-pixel-precision
|
||||
"Adjust modifiers so they adjust to the pixel grid"
|
||||
[modifiers shape]
|
||||
|
||||
(if (some? (:resize-transform modifiers))
|
||||
;; If we're working with a rotation we don't handle pixel precision because
|
||||
;; the transformation won't have the precision anyway
|
||||
modifiers
|
||||
|
||||
(let [center (gco/center-shape shape)
|
||||
base-bounds (-> (:points shape) (gpr/points->rect))
|
||||
|
||||
raw-bounds
|
||||
(-> (gtr/transform-bounds (:points shape) center modifiers)
|
||||
(gpr/points->rect))
|
||||
|
||||
flip-x? (neg? (get-in modifiers [:resize-vector :x]))
|
||||
flip-y? (or (neg? (get-in modifiers [:resize-vector :y]))
|
||||
(neg? (get-in modifiers [:resize-vector-2 :y])))
|
||||
|
||||
path? (= :path (:type shape))
|
||||
vertical-line? (and path? (<= (:width raw-bounds) 0.01))
|
||||
horizontal-line? (and path? (<= (:height raw-bounds) 0.01))
|
||||
|
||||
target-width (if vertical-line?
|
||||
(:width raw-bounds)
|
||||
(max 1 (mth/round (:width raw-bounds))))
|
||||
|
||||
target-height (if horizontal-line?
|
||||
(:height raw-bounds)
|
||||
(max 1 (mth/round (:height raw-bounds))))
|
||||
|
||||
target-p (cond-> (gpt/round (gpt/point raw-bounds))
|
||||
flip-x?
|
||||
(update :x + target-width)
|
||||
|
||||
flip-y?
|
||||
(update :y + target-height))
|
||||
|
||||
ratio-width (/ target-width (:width raw-bounds))
|
||||
ratio-height (/ target-height (:height raw-bounds))
|
||||
|
||||
modifiers
|
||||
(-> modifiers
|
||||
(d/without-nils)
|
||||
(d/update-in-when
|
||||
[:resize-vector :x] #(* % ratio-width))
|
||||
|
||||
;; If the resize-vector-2 modifier arrives means the resize-vector
|
||||
;; will only resize on the x axis
|
||||
(cond-> (nil? (:resize-vector-2 modifiers))
|
||||
(d/update-in-when
|
||||
[:resize-vector :y] #(* % ratio-height)))
|
||||
|
||||
(d/update-in-when
|
||||
[:resize-vector-2 :y] #(* % ratio-height)))
|
||||
|
||||
origin (get modifiers :resize-origin)
|
||||
origin-2 (get modifiers :resize-origin-2)
|
||||
|
||||
resize-v (get modifiers :resize-vector)
|
||||
resize-v-2 (get modifiers :resize-vector-2)
|
||||
displacement (get modifiers :displacement)
|
||||
|
||||
target-p-inv
|
||||
(-> target-p
|
||||
(gpt/transform
|
||||
(cond-> (gmt/matrix)
|
||||
(some? displacement)
|
||||
(gmt/multiply (gmt/inverse displacement))
|
||||
|
||||
(and (some? resize-v) (some? origin))
|
||||
(gmt/scale (gpt/inverse resize-v) origin)
|
||||
|
||||
(and (some? resize-v-2) (some? origin-2))
|
||||
(gmt/scale (gpt/inverse resize-v-2) origin-2))))
|
||||
|
||||
delta-v (gpt/subtract target-p-inv (gpt/point base-bounds))
|
||||
|
||||
modifiers
|
||||
(-> modifiers
|
||||
(d/update-when :displacement #(gmt/multiply (gmt/translate-matrix delta-v) %))
|
||||
(cond-> (nil? (:displacement modifiers))
|
||||
(assoc :displacement (gmt/translate-matrix delta-v))))]
|
||||
modifiers)))
|
||||
|
||||
|
||||
(defn set-children-modifiers
|
||||
[modif-tree shape objects ignore-constraints snap-pixel?]
|
||||
(letfn [(set-child [transformed-rect snap-pixel? modif-tree child]
|
||||
(let [modifiers (get-in modif-tree [(:id shape) :modifiers])
|
||||
child-modifiers (gct/calc-child-modifiers shape child modifiers ignore-constraints transformed-rect)
|
||||
child-modifiers (cond-> child-modifiers snap-pixel? (set-pixel-precision child))
|
||||
]
|
||||
(cond-> modif-tree
|
||||
(not (gtr/empty-modifiers? child-modifiers))
|
||||
(assoc (:id child) {:modifiers child-modifiers}))))]
|
||||
(let [children (map (d/getf objects) (:shapes shape))
|
||||
modifiers (get-in modif-tree [(:id shape) :modifiers])
|
||||
transformed-rect (gtr/transform-selrect (:selrect shape) modifiers)
|
||||
resize-modif? (or (:resize-vector modifiers) (:resize-vector-2 modifiers))]
|
||||
(reduce (partial set-child transformed-rect (and snap-pixel? resize-modif?)) modif-tree children))))
|
||||
|
||||
(defn set-layout-modifiers
|
||||
[modif-tree objects id]
|
||||
|
||||
(letfn [(set-layout-modifiers [parent [layout-data modif-tree] child]
|
||||
(let [modifiers (get-in modif-tree [(:id child) :modifiers])
|
||||
|
||||
[modifiers layout-data]
|
||||
(gcl/calc-layout-modifiers parent child modifiers layout-data)
|
||||
|
||||
modif-tree
|
||||
(cond-> modif-tree
|
||||
(not (gtr/empty-modifiers? modifiers))
|
||||
(assoc-in [(:id child) :modifiers] modifiers))]
|
||||
|
||||
[layout-data modif-tree]))]
|
||||
|
||||
(let [shape (get objects id)
|
||||
children (map (d/getf objects) (:shapes shape))
|
||||
modifiers (get-in modif-tree [id :modifiers])
|
||||
|
||||
;;_ (.log js/console "layout" (:name shape) (clj->js modifiers))
|
||||
transformed-rect (gtr/transform-selrect (:selrect shape) modifiers)
|
||||
layout-data (gcl/calc-layout-data shape children modif-tree transformed-rect)
|
||||
children (cond-> children (:reverse? layout-data) reverse)
|
||||
|
||||
[_ modif-tree]
|
||||
(reduce (partial set-layout-modifiers shape) [layout-data modif-tree] children)]
|
||||
|
||||
;;(.log js/console "modif-tree" modif-tree)
|
||||
modif-tree)))
|
||||
|
||||
(defn get-first-layout
|
||||
[id objects]
|
||||
|
||||
(loop [current id
|
||||
result id]
|
||||
(let [shape (get objects current)
|
||||
parent (get objects (:parent-id shape))]
|
||||
(cond
|
||||
(or (not shape) (= uuid/zero current))
|
||||
result
|
||||
|
||||
;; Frame found, but not layout we return the last layout found (or the id)
|
||||
(and (= :frame (:type parent))
|
||||
(not (:layout parent)))
|
||||
result
|
||||
|
||||
;; Layout found. We continue upward but we mark this layout
|
||||
(and (= :frame (:type parent))
|
||||
(:layout parent))
|
||||
(recur (:id parent) (:id parent))
|
||||
|
||||
;; If group or boolean or other type of group we continue with the last result
|
||||
:else
|
||||
(recur (:id parent) result)
|
||||
))))
|
||||
|
||||
|
||||
(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]
|
||||
|
||||
(into (d/ordered-set)
|
||||
(map #(get-first-layout % objects))
|
||||
ids))
|
||||
|
||||
(defn set-objects-modifiers
|
||||
[ids objects get-modifier ignore-constraints snap-pixel?]
|
||||
|
||||
(let [modif-tree (reduce (fn [modif-tree id]
|
||||
(assoc modif-tree id {:modifiers (get-modifier (get objects id))})) {} ids)
|
||||
|
||||
ids (resolve-layout-ids ids objects)]
|
||||
|
||||
(loop [current (first ids)
|
||||
pending (rest ids)
|
||||
modif-tree modif-tree]
|
||||
(if (some? current)
|
||||
(let [shape (get objects current)
|
||||
pending (concat pending (:shapes shape))
|
||||
|
||||
modif-tree
|
||||
(-> modif-tree
|
||||
(set-children-modifiers shape objects ignore-constraints snap-pixel?)
|
||||
(cond-> (:layout shape)
|
||||
(set-layout-modifiers objects current)))]
|
||||
|
||||
(recur (first pending) (rest pending) modif-tree #_touched-layouts))
|
||||
|
||||
modif-tree))))
|
|
@ -614,7 +614,7 @@
|
|||
(dissoc :modifiers))))))
|
||||
|
||||
(defn transform-bounds
|
||||
[points center {:keys [displacement resize-transform-inverse resize-vector resize-origin resize-vector-2 resize-origin-2]}]
|
||||
[points center {:keys [displacement displacement-after resize-transform-inverse resize-vector resize-origin resize-vector-2 resize-origin-2]}]
|
||||
;; FIXME: Improve Performance
|
||||
(let [resize-transform-inverse (or resize-transform-inverse (gmt/matrix))
|
||||
|
||||
|
@ -628,9 +628,10 @@
|
|||
|
||||
resize-origin-2
|
||||
(when (some? resize-origin-2)
|
||||
(transform-point-center resize-origin-2 center resize-transform-inverse))]
|
||||
(transform-point-center resize-origin-2 center resize-transform-inverse))
|
||||
]
|
||||
|
||||
(if (and (nil? displacement) (nil? resize-origin) (nil? resize-origin-2))
|
||||
(if (and (nil? displacement) (nil? resize-origin) (nil? resize-origin-2) (nil? displacement-after))
|
||||
points
|
||||
|
||||
(cond-> points
|
||||
|
@ -641,7 +642,10 @@
|
|||
(gco/transform-points resize-origin (gmt/scale-matrix resize-vector))
|
||||
|
||||
(some? resize-origin-2)
|
||||
(gco/transform-points resize-origin-2 (gmt/scale-matrix resize-vector-2))))))
|
||||
(gco/transform-points resize-origin-2 (gmt/scale-matrix resize-vector-2))
|
||||
|
||||
(some? displacement-after)
|
||||
(gco/transform-points displacement-after)))))
|
||||
|
||||
(defn transform-selrect
|
||||
[selrect modifiers]
|
||||
|
|
|
@ -218,7 +218,7 @@
|
|||
(->> (get-root-shapes objects)
|
||||
(mapv :id)))
|
||||
|
||||
(defn- get-base
|
||||
(defn get-base
|
||||
[objects id-a id-b]
|
||||
|
||||
(let [parents-a (reverse (get-parents-seq objects id-a))
|
||||
|
|
|
@ -110,7 +110,7 @@
|
|||
;; geometric attributes of the shapes.
|
||||
|
||||
(declare clear-local-transform)
|
||||
(declare set-objects-modifiers)
|
||||
|
||||
(declare get-ignore-tree)
|
||||
|
||||
(defn set-modifiers
|
||||
|
@ -128,20 +128,17 @@
|
|||
(ptk/reify ::set-modifiers
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [modifiers (or modifiers (get-in state [:workspace-local :modifiers] {}))
|
||||
page-id (:current-page-id state)
|
||||
objects (wsh/lookup-page-objects state page-id)
|
||||
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
ids (into #{} (remove #(get-in objects [% :blocked] false)) ids)
|
||||
layout (get state :workspace-layout)
|
||||
snap-pixel? (and (not ignore-snap-pixel) (contains? layout :snap-pixel-grid))
|
||||
|
||||
setup-modifiers
|
||||
(fn [state id]
|
||||
(let [shape (get objects id)]
|
||||
(update state :workspace-modifiers
|
||||
#(set-objects-modifiers % objects shape modifiers ignore-constraints snap-pixel?))))]
|
||||
snap-pixel? (and (not ignore-snap-pixel)
|
||||
(contains? (:workspace-layout state) :snap-pixel-grid))
|
||||
|
||||
(reduce setup-modifiers state ids))))))
|
||||
modif-tree
|
||||
(gsh/set-objects-modifiers ids objects (constantly modifiers) ignore-constraints snap-pixel?)]
|
||||
|
||||
(assoc state :workspace-modifiers modif-tree))))))
|
||||
|
||||
;; Rotation use different algorithm to calculate children modifiers (and do not use child constraints).
|
||||
(defn- set-rotation-modifiers
|
||||
|
@ -280,162 +277,9 @@
|
|||
|
||||
[root transformed-root ignore-geometry?]))
|
||||
|
||||
(defn set-pixel-precision
|
||||
"Adjust modifiers so they adjust to the pixel grid"
|
||||
[modifiers shape]
|
||||
|
||||
(if (some? (:resize-transform modifiers))
|
||||
;; If we're working with a rotation we don't handle pixel precision because
|
||||
;; the transformation won't have the precision anyway
|
||||
modifiers
|
||||
|
||||
(let [center (gsh/center-shape shape)
|
||||
base-bounds (-> (:points shape) (gsh/points->rect))
|
||||
|
||||
raw-bounds
|
||||
(-> (gsh/transform-bounds (:points shape) center modifiers)
|
||||
(gsh/points->rect))
|
||||
|
||||
flip-x? (neg? (get-in modifiers [:resize-vector :x]))
|
||||
flip-y? (or (neg? (get-in modifiers [:resize-vector :y]))
|
||||
(neg? (get-in modifiers [:resize-vector-2 :y])))
|
||||
|
||||
path? (= :path (:type shape))
|
||||
vertical-line? (and path? (<= (:width raw-bounds) 0.01))
|
||||
horizontal-line? (and path? (<= (:height raw-bounds) 0.01))
|
||||
|
||||
target-width (if vertical-line?
|
||||
(:width raw-bounds)
|
||||
(max 1 (mth/round (:width raw-bounds))))
|
||||
|
||||
target-height (if horizontal-line?
|
||||
(:height raw-bounds)
|
||||
(max 1 (mth/round (:height raw-bounds))))
|
||||
|
||||
target-p (cond-> (gpt/round (gpt/point raw-bounds))
|
||||
flip-x?
|
||||
(update :x + target-width)
|
||||
|
||||
flip-y?
|
||||
(update :y + target-height))
|
||||
|
||||
ratio-width (/ target-width (:width raw-bounds))
|
||||
ratio-height (/ target-height (:height raw-bounds))
|
||||
|
||||
modifiers
|
||||
(-> modifiers
|
||||
(d/without-nils)
|
||||
(d/update-in-when
|
||||
[:resize-vector :x] #(* % ratio-width))
|
||||
|
||||
;; If the resize-vector-2 modifier arrives means the resize-vector
|
||||
;; will only resize on the x axis
|
||||
(cond-> (nil? (:resize-vector-2 modifiers))
|
||||
(d/update-in-when
|
||||
[:resize-vector :y] #(* % ratio-height)))
|
||||
|
||||
(d/update-in-when
|
||||
[:resize-vector-2 :y] #(* % ratio-height)))
|
||||
|
||||
origin (get modifiers :resize-origin)
|
||||
origin-2 (get modifiers :resize-origin-2)
|
||||
|
||||
resize-v (get modifiers :resize-vector)
|
||||
resize-v-2 (get modifiers :resize-vector-2)
|
||||
displacement (get modifiers :displacement)
|
||||
|
||||
target-p-inv
|
||||
(-> target-p
|
||||
(gpt/transform
|
||||
(cond-> (gmt/matrix)
|
||||
(some? displacement)
|
||||
(gmt/multiply (gmt/inverse displacement))
|
||||
|
||||
(and (some? resize-v) (some? origin))
|
||||
(gmt/scale (gpt/inverse resize-v) origin)
|
||||
|
||||
(and (some? resize-v-2) (some? origin-2))
|
||||
(gmt/scale (gpt/inverse resize-v-2) origin-2))))
|
||||
|
||||
delta-v (gpt/subtract target-p-inv (gpt/point base-bounds))
|
||||
|
||||
modifiers
|
||||
(-> modifiers
|
||||
(d/update-when :displacement #(gmt/multiply (gmt/translate-matrix delta-v) %))
|
||||
(cond-> (nil? (:displacement modifiers))
|
||||
(assoc :displacement (gmt/translate-matrix delta-v))))]
|
||||
modifiers)))
|
||||
|
||||
(defn- set-objects-modifiers
|
||||
[modif-tree objects shape modifiers ignore-constraints snap-pixel?]
|
||||
(letfn [(set-modifiers-rec
|
||||
[modif-tree shape modifiers]
|
||||
|
||||
(let [children (map (d/getf objects) (:shapes shape))
|
||||
transformed-rect (gsh/transform-selrect (:selrect shape) modifiers)
|
||||
|
||||
set-layout-child
|
||||
(fn [snap-pixel? {:keys [modif-tree] :as layout-data} child]
|
||||
(let [current-modifier (get-in modif-tree [(:id child) :modifiers])
|
||||
|
||||
;; child (-> (merge child old-modif) gsh/transform-shape)
|
||||
|
||||
[child-modifiers next-layout-data] (gsh/calc-layout-modifiers shape child current-modifier modifiers transformed-rect layout-data)
|
||||
child-modifiers (cond-> child-modifiers snap-pixel? (set-pixel-precision child))
|
||||
|
||||
;;child-modifiers (if (some? old-modif)
|
||||
;; (d/deep-merge (:modifiers old-modif) child-modifiers)
|
||||
;; child-modifiers)
|
||||
|
||||
modif-tree
|
||||
(cond-> modif-tree
|
||||
(not (gsh/empty-modifiers? child-modifiers))
|
||||
(set-modifiers-rec child child-modifiers))]
|
||||
|
||||
(assoc next-layout-data :modif-tree modif-tree)))
|
||||
|
||||
set-child
|
||||
(fn [snap-pixel? modif-tree child]
|
||||
(let [child-modifiers (gsh/calc-child-modifiers shape child modifiers ignore-constraints transformed-rect)
|
||||
child-modifiers (cond-> child-modifiers snap-pixel? (set-pixel-precision child))]
|
||||
(cond-> modif-tree
|
||||
(not (gsh/empty-modifiers? child-modifiers))
|
||||
(set-modifiers-rec child child-modifiers))))
|
||||
|
||||
modif-tree
|
||||
(-> modif-tree
|
||||
(assoc-in [(:id shape) :modifiers] modifiers))
|
||||
|
||||
resize-modif?
|
||||
(or (:resize-vector modifiers) (:resize-vector-2 modifiers))
|
||||
|
||||
|
||||
modif-tree
|
||||
(reduce (partial set-child (and snap-pixel? resize-modif?)) modif-tree children)]
|
||||
|
||||
(cond
|
||||
(:layout shape)
|
||||
(let [layout-data (gsh/calc-layout-data shape children modif-tree transformed-rect)
|
||||
children (cond-> children (:reverse? layout-data) reverse)]
|
||||
(->> children
|
||||
(reduce (partial set-layout-child (and snap-pixel? resize-modif?))
|
||||
(merge {:modif-tree modif-tree} layout-data))
|
||||
:modif-tree))
|
||||
|
||||
:else
|
||||
modif-tree)))]
|
||||
|
||||
(let [modifiers (cond-> modifiers snap-pixel? (set-pixel-precision shape))
|
||||
modif-tree (set-modifiers-rec modif-tree shape modifiers)
|
||||
|
||||
parent (get objects (:parent-id shape))
|
||||
|
||||
modif-tree
|
||||
(cond-> modif-tree
|
||||
(:layout parent)
|
||||
(set-modifiers-rec parent nil))]
|
||||
|
||||
modif-tree)))
|
||||
|
||||
(defn- get-ignore-tree
|
||||
"Retrieves a map with the flag `ignore-geometry?` given a tree of modifiers"
|
||||
|
@ -590,18 +434,16 @@
|
|||
(ptk/reify ::update-dimensions
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
layout (get state :workspace-layout)
|
||||
snap-pixel? (contains? layout :snap-pixel-grid)
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
snap-pixel? (and (contains? (:workspace-layout state) :snap-pixel-grid)
|
||||
(int? value))
|
||||
get-modifier
|
||||
(fn [shape] (gsh/resize-modifiers shape attr value))
|
||||
|
||||
update-modifiers
|
||||
(fn [state id]
|
||||
(let [shape (get objects id)
|
||||
modifiers (gsh/resize-modifiers shape attr value)]
|
||||
(-> state
|
||||
(update :workspace-modifiers
|
||||
#(set-objects-modifiers % objects shape modifiers false (and snap-pixel? (int? value)))))))]
|
||||
(reduce update-modifiers state ids)))
|
||||
modif-tree
|
||||
(gsh/set-objects-modifiers ids objects get-modifier false snap-pixel?)]
|
||||
|
||||
(assoc state :workspace-modifiers modif-tree)))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ _]
|
||||
|
@ -617,17 +459,15 @@
|
|||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
layout (get state :workspace-layout)
|
||||
snap-pixel? (contains? layout :snap-pixel-grid)
|
||||
snap-pixel? (contains? (get state :workspace-layout) :snap-pixel-grid)
|
||||
|
||||
update-modifiers
|
||||
(fn [state id]
|
||||
(let [shape (get objects id)
|
||||
modifiers (gsh/change-orientation-modifiers shape orientation)]
|
||||
(-> state
|
||||
(update :workspace-modifiers
|
||||
#(set-objects-modifiers % objects shape modifiers false snap-pixel?)))))]
|
||||
(reduce update-modifiers state ids)))
|
||||
get-modifier
|
||||
(fn [shape] (gsh/change-orientation-modifiers shape orientation))
|
||||
|
||||
modif-tree
|
||||
(gsh/set-objects-modifiers ids objects get-modifier false snap-pixel?)]
|
||||
|
||||
(assoc state :workspace-modifiers modif-tree)))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ _]
|
||||
|
|
Loading…
Add table
Reference in a new issue