Allow for rotated auto-layout

This commit is contained in:
alonso.torres 2022-07-08 15:16:20 +02:00 committed by Andrey Antukh
parent 5e5355230c
commit 28abe785e8
6 changed files with 72 additions and 44 deletions

View file

@ -172,6 +172,7 @@
(dm/export gtr/modifiers->transform)
(dm/export gtr/empty-modifiers?)
(dm/export gtr/move-position-data)
(dm/export gtr/apply-transform)
;; Constratins
(dm/export gct/calc-child-modifiers)

View file

@ -8,7 +8,8 @@
(:require
[app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt]
[app.common.geom.shapes.rect :as gre]))
[app.common.geom.shapes.rect :as gre]
[app.common.geom.shapes.common :as gco]))
;; :layout ;; true if active, false if not
;; :layout-dir ;; :right, :left, :top, :bottom
@ -312,13 +313,16 @@
(defn calc-layout-modifiers
"Calculates the modifiers for the layout"
[parent child layout-data]
[parent transform child layout-data]
(let [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)))
delta-p (-> corner-p
(gpt/subtract (gpt/point bounds))
(cond-> (some? transform) (gpt/transform transform)))
modifiers {:displacement-after (gmt/translate-matrix delta-p)}]
[modifiers layout-data]))

View file

@ -112,7 +112,7 @@
child-modifiers (cond-> child-modifiers snap-pixel? (set-pixel-precision child))]
(cond-> modif-tree
(not (gtr/empty-modifiers? child-modifiers))
(update-in [(:id child) :modifiers] #(merge % child-modifiers)))))]
(update-in [(:id child) :modifiers] #(merge 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)
@ -134,18 +134,26 @@
(defn set-layout-modifiers
[modif-tree objects id]
(letfn [(transform-child [shape]
(let [modifiers (get modif-tree (:id shape))]
(cond-> shape
(not (group? shape))
(-> (merge modifiers) gtr/transform-shape)
(letfn [(transform-child [parent child]
(let [modifiers (get modif-tree (:id child))
(group? shape)
(gtr/apply-group-modifiers objects modif-tree))))
child
(cond-> child
(not (group? child))
(-> (merge modifiers) gtr/transform-shape)
(set-layout-modifiers [parent [layout-data modif-tree] child]
(group? child)
(gtr/apply-group-modifiers objects modif-tree))
child
(-> child
(gtr/apply-transform (gmt/transform-in (gco/center-shape parent) (:transform-inverse parent))))]
child))
(set-layout-modifiers [parent transform [layout-data modif-tree] child]
(let [[modifiers layout-data]
(gcl/calc-layout-modifiers parent child layout-data)
(gcl/calc-layout-modifiers parent transform child layout-data)
modif-tree
(cond-> modif-tree
@ -157,19 +165,29 @@
[layout-data modif-tree]))]
(let [shape (get objects id)
children (->> (:shapes shape)
(map (d/getf objects))
(map transform-child))
(let [modifiers (get modif-tree id)
modifiers (get-in modif-tree [id :modifiers])
shape (-> (get objects id) (merge modifiers) gtr/transform-shape)
transformed-rect (gtr/transform-selrect (:selrect shape) modifiers)
layout-data (gcl/calc-layout-data shape children transformed-rect)
children (into [] (cond-> children (:reverse? layout-data) reverse))
max-idx (dec (count children))
layout-lines (:layout-lines layout-data)]
children (->> (:shapes shape)
(map (d/getf objects))
(map (partial transform-child shape)))
center (gco/center-shape shape)
{:keys [transform transform-inverse]} shape
shape
(-> shape
(gtr/apply-transform (gmt/transform-in center transform-inverse)))
transformed-rect (:selrect shape)
layout-data (gcl/calc-layout-data shape children transformed-rect)
children (into [] (cond-> children (:reverse? layout-data) reverse))
max-idx (dec (count children))
layout-lines (:layout-lines layout-data)]
(loop [modif-tree modif-tree
layout-line (first layout-lines)
@ -180,7 +198,7 @@
children (subvec children from-idx to-idx)
[_ modif-tree]
(reduce (partial set-layout-modifiers shape) [layout-line modif-tree] children)]
(reduce (partial set-layout-modifiers shape transform) [layout-line modif-tree] children)]
(recur modif-tree (first pending) (rest pending) to-idx))
@ -209,9 +227,7 @@
;; If group or boolean or other type of group we continue with the last result
:else
(recur (:id parent) result)
))))
(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
@ -225,12 +241,14 @@
(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)
(let [set-modifiers
(fn [modif-tree id]
(assoc modif-tree id {:modifiers (get-modifier (get objects id))}))
modif-tree (reduce set-modifiers {} ids)
ids (resolve-layout-ids ids objects)
;; First: Calculate children modifiers (constraints, etc)
[modif-tree touched-layouts]
(loop [current (first ids)

View file

@ -278,7 +278,7 @@
(if transform (gmt/multiply transform matrix) matrix)
(if transform-inverse (gmt/multiply matrix-inverse transform-inverse) matrix-inverse)]))
(defn- apply-transform
(defn apply-transform
"Given a new set of points transformed, set up the rectangle so it keeps
its properties. We adjust de x,y,width,height and create a custom transform"
[shape transform-mtx]

View file

@ -32,8 +32,8 @@
:layout-wrap-type :wrap
:layout-padding-type :simple
:layout-padding {:p1 0 :p2 0 :p3 0 :p4 0}
:layout-h-orientation :top
:layout-v-orientation :left})
:layout-h-orientation :left
:layout-v-orientation :top})
(defn update-layout-positions
[ids]

View file

@ -128,7 +128,6 @@
(ptk/reify ::set-modifiers
ptk/UpdateEvent
(update [_ state]
(let [objects (wsh/lookup-page-objects state)
ids (into #{} (remove #(get-in objects [% :blocked] false)) ids)
@ -138,7 +137,7 @@
modif-tree
(gsh/set-objects-modifiers ids objects (constantly modifiers) ignore-constraints snap-pixel?)]
(assoc state :workspace-modifiers modif-tree))))))
(update state :workspace-modifiers merge modif-tree))))))
;; Rotation use different algorithm to calculate children modifiers (and do not use child constraints).
(defn- set-rotation-modifiers
@ -147,19 +146,25 @@
([angle shapes center]
(ptk/reify ::set-rotation-modifiers
ptk/WatchEvent
(watch [_ state _]
(let [objects (wsh/lookup-page-objects state)
shapes
ptk/UpdateEvent
(update [_ state]
(let [objects (wsh/lookup-page-objects state)
ids
(->> shapes
(remove #(get % :blocked false))
(mapcat #(cph/get-children objects (:id %)))
(concat shapes)
(filter #((cpc/editable-attrs (:type %)) :rotation)))]
(->> (rx/from shapes)
(rx/map (fn [shape]
(let [rotate-modifiers (gsh/rotation-modifiers shape center angle)]
(set-modifiers [(:id shape)] rotate-modifiers))))))))))
(filter #((cpc/editable-attrs (:type %)) :rotation))
(map :id))
get-modifier
(fn [shape]
(gsh/rotation-modifiers shape center angle))
modif-tree
(gsh/set-objects-modifiers ids objects get-modifier false false)]
(update state :workspace-modifiers merge modif-tree))))))
(defn- update-grow-type
[shape old-shape]