mirror of
https://github.com/penpot/penpot.git
synced 2025-07-08 08:27:18 +02:00
✨ Allow for rotated auto-layout
This commit is contained in:
parent
5e5355230c
commit
28abe785e8
6 changed files with 72 additions and 44 deletions
|
@ -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)
|
||||||
|
|
|
@ -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]))
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue