diff --git a/common/src/app/common/pages/changes_builder.cljc b/common/src/app/common/pages/changes_builder.cljc index e27b7f3a3..bb669eeb1 100644 --- a/common/src/app/common/pages/changes_builder.cljc +++ b/common/src/app/common/pages/changes_builder.cljc @@ -278,6 +278,7 @@ (defn changed-attrs + "Returns the list of attributes that will change when `update-fn` is applied" [object update-fn {:keys [attrs]}] (let [changed? (fn [old new attr] @@ -285,9 +286,7 @@ new-val (get new attr)] (not= old-val new-val))) new-obj (update-fn object)] - (if (= object new-obj) - '() - + (when-not (= object new-obj) (let [attrs (or attrs (d/concat-set (keys object) (keys new-obj)))] (filter (partial changed? object new-obj) attrs))))) diff --git a/frontend/src/app/main/data/workspace/shape_layout.cljs b/frontend/src/app/main/data/workspace/shape_layout.cljs index 8f1b69a9b..b0eb03812 100644 --- a/frontend/src/app/main/data/workspace/shape_layout.cljs +++ b/frontend/src/app/main/data/workspace/shape_layout.cljs @@ -8,8 +8,12 @@ (:require [app.common.colors :as clr] [app.common.data :as d] + [app.common.geom.point :as gpt] + [app.common.geom.shapes :as gsh] + [app.common.math :as mth] [app.common.pages.helpers :as cph] [app.common.types.modifiers :as ctm] + [app.common.types.shape-tree :as ctt] [app.common.types.shape.layout :as ctl] [app.common.uuid :as uuid] [app.main.data.workspace.changes :as dwc] @@ -38,7 +42,7 @@ (def initial-flex-layout {:layout :flex :layout-flex-dir :row - :layout-gap-type :simple + :layout-gap-type :multiple :layout-gap {:row-gap 0 :column-gap 0} :layout-align-items :start :layout-justify-content :start @@ -97,6 +101,41 @@ [] (ptk/reify ::finalize)) +(defn shapes->flex-params + "Given the shapes calculate its flex parameters (horizontal vs vertical etc)" + [objects shapes] + + (let [points + (->> shapes + (map :id) + (ctt/sort-z-index objects) + (map (comp gsh/center-shape (d/getf objects)))) + + start (first points) + end (reduce (fn [acc p] (gpt/add acc (gpt/to-vec start p))) points) + + angle (gpt/signed-angle-with-other + (gpt/to-vec start end) + (gpt/point 1 0)) + + angle (mod angle 360) + + t1 (min (abs (- angle 0)) (abs (- angle 360))) + t2 (abs (- angle 90)) + t3 (abs (- angle 180)) + t4 (abs (- angle 270)) + + tmin (min t1 t2 t3 t4) + + direction + (cond + (mth/close? tmin t1) :row + (mth/close? tmin t2) :reverse-column + (mth/close? tmin t3) :reverse-row + (mth/close? tmin t4) :column)] + + {:layout-flex-dir direction})) + (defn create-layout-from-selection [type] (ptk/reify ::create-layout-from-selection @@ -110,6 +149,7 @@ single? (= (count selected-shapes) 1) has-group? (->> selected-shapes (d/seek cph/group-shape?)) is-group? (and single? has-group?)] + (if is-group? (let [new-shape-id (uuid/next) parent-id (:parent-id (first selected-shapes)) @@ -123,17 +163,35 @@ (cl/remove-all-fills [new-shape-id] {:color clr/black :opacity 1}) (create-layout-from-id [new-shape-id] type) + (dwc/update-shapes + [new-shape-id] + (fn [shape] + (-> shape + (assoc :layout-item-h-sizing :auto + :layout-item-v-sizing :auto)))) + + (ptk/data-event :layout/update [new-shape-id]) (dws/delete-shapes page-id selected) (dwu/commit-undo-transaction undo-id))) (let [new-shape-id (uuid/next) - undo-id (uuid/next)] + undo-id (uuid/next) + flex-params (shapes->flex-params objects selected-shapes)] (rx/of (dwu/start-undo-transaction undo-id) (dws/create-artboard-from-selection new-shape-id) (cl/remove-all-fills [new-shape-id] {:color clr/black :opacity 1}) (create-layout-from-id [new-shape-id] type) + (dwc/update-shapes + [new-shape-id] + (fn [shape] + (-> shape + (merge flex-params) + (assoc :layout-item-h-sizing :auto + :layout-item-v-sizing :auto)))) + + (ptk/data-event :layout/update [new-shape-id]) (dwu/commit-undo-transaction undo-id)))))))) (defn remove-layout