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/modifiers->transform)
(dm/export gtr/empty-modifiers?) (dm/export gtr/empty-modifiers?)
(dm/export gtr/move-position-data) (dm/export gtr/move-position-data)
(dm/export gtr/apply-transform)
;; Constratins ;; Constratins
(dm/export gct/calc-child-modifiers) (dm/export gct/calc-child-modifiers)

View file

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

View file

@ -112,7 +112,7 @@
child-modifiers (cond-> child-modifiers snap-pixel? (set-pixel-precision child))] child-modifiers (cond-> child-modifiers snap-pixel? (set-pixel-precision child))]
(cond-> modif-tree (cond-> modif-tree
(not (gtr/empty-modifiers? child-modifiers)) (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)) (let [children (map (d/getf objects) (:shapes shape))
modifiers (get-in modif-tree [(:id shape) :modifiers]) modifiers (get-in modif-tree [(:id shape) :modifiers])
transformed-rect (gtr/transform-selrect (:selrect shape) modifiers) transformed-rect (gtr/transform-selrect (:selrect shape) modifiers)
@ -134,18 +134,26 @@
(defn set-layout-modifiers (defn set-layout-modifiers
[modif-tree objects id] [modif-tree objects id]
(letfn [(transform-child [shape] (letfn [(transform-child [parent child]
(let [modifiers (get modif-tree (:id shape))] (let [modifiers (get modif-tree (:id child))
(cond-> shape
(not (group? shape)) child
(cond-> child
(not (group? child))
(-> (merge modifiers) gtr/transform-shape) (-> (merge modifiers) gtr/transform-shape)
(group? shape) (group? child)
(gtr/apply-group-modifiers objects modif-tree)))) (gtr/apply-group-modifiers objects modif-tree))
(set-layout-modifiers [parent [layout-data modif-tree] child] 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] (let [[modifiers layout-data]
(gcl/calc-layout-modifiers parent child layout-data) (gcl/calc-layout-modifiers parent transform child layout-data)
modif-tree modif-tree
(cond-> modif-tree (cond-> modif-tree
@ -157,14 +165,24 @@
[layout-data modif-tree]))] [layout-data modif-tree]))]
(let [shape (get objects id) (let [modifiers (get modif-tree id)
shape (-> (get objects id) (merge modifiers) gtr/transform-shape)
children (->> (:shapes shape) children (->> (:shapes shape)
(map (d/getf objects)) (map (d/getf objects))
(map transform-child)) (map (partial transform-child shape)))
modifiers (get-in modif-tree [id :modifiers]) 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)
transformed-rect (gtr/transform-selrect (:selrect shape) modifiers)
layout-data (gcl/calc-layout-data shape children transformed-rect) layout-data (gcl/calc-layout-data shape children transformed-rect)
children (into [] (cond-> children (:reverse? layout-data) reverse)) children (into [] (cond-> children (:reverse? layout-data) reverse))
@ -180,7 +198,7 @@
children (subvec children from-idx to-idx) children (subvec children from-idx to-idx)
[_ modif-tree] [_ 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)) (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 ;; If group or boolean or other type of group we continue with the last result
:else :else
(recur (:id parent) result) (recur (:id parent) result)))))
))))
(defn resolve-layout-ids (defn resolve-layout-ids
"Given a list of ids, resolve the parent layouts that will need to update. This will go upwards "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 (defn set-objects-modifiers
[ids objects get-modifier ignore-constraints snap-pixel?] [ids objects get-modifier ignore-constraints snap-pixel?]
(let [modif-tree (reduce (fn [modif-tree id] (let [set-modifiers
(assoc modif-tree id {:modifiers (get-modifier (get objects id))})) {} ids) (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) ids (resolve-layout-ids ids objects)
;; First: Calculate children modifiers (constraints, etc) ;; First: Calculate children modifiers (constraints, etc)
[modif-tree touched-layouts] [modif-tree touched-layouts]
(loop [current (first ids) (loop [current (first ids)

View file

@ -278,7 +278,7 @@
(if transform (gmt/multiply transform matrix) matrix) (if transform (gmt/multiply transform matrix) matrix)
(if transform-inverse (gmt/multiply matrix-inverse transform-inverse) matrix-inverse)])) (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 "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" its properties. We adjust de x,y,width,height and create a custom transform"
[shape transform-mtx] [shape transform-mtx]

View file

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

View file

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