diff --git a/common/src/app/common/geom/shapes.cljc b/common/src/app/common/geom/shapes.cljc index ca8f40611e..31c1037795 100644 --- a/common/src/app/common/geom/shapes.cljc +++ b/common/src/app/common/geom/shapes.cljc @@ -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) diff --git a/common/src/app/common/geom/shapes/layout.cljc b/common/src/app/common/geom/shapes/layout.cljc index 3225a10ce2..1cca7ec45c 100644 --- a/common/src/app/common/geom/shapes/layout.cljc +++ b/common/src/app/common/geom/shapes/layout.cljc @@ -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])) diff --git a/common/src/app/common/geom/shapes/modifiers.cljc b/common/src/app/common/geom/shapes/modifiers.cljc index a9dffa037e..cd8a1ab021 100644 --- a/common/src/app/common/geom/shapes/modifiers.cljc +++ b/common/src/app/common/geom/shapes/modifiers.cljc @@ -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) diff --git a/common/src/app/common/geom/shapes/transforms.cljc b/common/src/app/common/geom/shapes/transforms.cljc index 0f77162522..44c87562b4 100644 --- a/common/src/app/common/geom/shapes/transforms.cljc +++ b/common/src/app/common/geom/shapes/transforms.cljc @@ -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] diff --git a/frontend/src/app/main/data/workspace/shape_layout.cljs b/frontend/src/app/main/data/workspace/shape_layout.cljs index 9055f042ac..49cb09a32a 100644 --- a/frontend/src/app/main/data/workspace/shape_layout.cljs +++ b/frontend/src/app/main/data/workspace/shape_layout.cljs @@ -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] diff --git a/frontend/src/app/main/data/workspace/transforms.cljs b/frontend/src/app/main/data/workspace/transforms.cljs index de018cb592..703a558aa4 100644 --- a/frontend/src/app/main/data/workspace/transforms.cljs +++ b/frontend/src/app/main/data/workspace/transforms.cljs @@ -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]