diff --git a/common/src/app/common/features.cljc b/common/src/app/common/features.cljc index bb5340e9c7..b396e19370 100644 --- a/common/src/app/common/features.cljc +++ b/common/src/app/common/features.cljc @@ -61,7 +61,8 @@ "styles/v2" "layout/grid" "components/v2" - "plugins/runtime"}) + "plugins/runtime" + "design-tokens/v1"}) ;; A set of features which only affects on frontend and can be enabled ;; and disabled freely by the user any time. This features does not diff --git a/common/src/app/common/files/helpers.cljc b/common/src/app/common/files/helpers.cljc index 1b49099f28..3795812c34 100644 --- a/common/src/app/common/files/helpers.cljc +++ b/common/src/app/common/files/helpers.cljc @@ -283,6 +283,22 @@ :else (get-root-frame objects (:frame-id frame))))) +(defn get-parent-frame + "Similar to `get-frame, but always return the parent frame. When root + frame is provided, then itself is returned." + [objects shape-or-id] + (cond + (map? shape-or-id) + (get objects (dm/get-prop shape-or-id :frame-id)) + + (= uuid/zero shape-or-id) + (get objects uuid/zero) + + :else + (some->> shape-or-id + (get objects) + (get-frame objects)))) + (defn valid-frame-target? [objects parent-id shape-id] (let [shape (get objects shape-id)] diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index b676dc8d9e..1f353c4ac7 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -406,6 +406,7 @@ :workspace-media-objects :workspace-persistence :workspace-presence + :workspace-tokens :workspace-undo) (update :workspace-global dissoc :read-only?) (assoc-in [:workspace-global :options-mode] :design))) diff --git a/frontend/src/app/main/data/workspace/transforms.cljs b/frontend/src/app/main/data/workspace/transforms.cljs index c145c11af2..ccd166395f 100644 --- a/frontend/src/app/main/data/workspace/transforms.cljs +++ b/frontend/src/app/main/data/workspace/transforms.cljs @@ -859,42 +859,44 @@ (rx/of (reorder-selected-layout-child direction)) (rx/of (nudge-selected-shapes direction shift?))))))) -(defn- get-delta [position bbox] - (let [cpos (gpt/point (:x bbox) (:y bbox)) - pos (gpt/point (or (:x position) (:x bbox)) - (or (:y position) (:y bbox)))] - (gpt/subtract pos cpos))) - -(defn- get-relative-delta [position bbox frame] - (let [frame-bbox (-> frame :points grc/points->rect) - relative-cpos (gpt/subtract (gpt/point (:x bbox) (:y bbox)) - (gpt/point (:x frame-bbox) - (:y frame-bbox))) - cpos (gpt/point (:x relative-cpos) (:y relative-cpos)) - pos (gpt/point (or (:x position) (:x relative-cpos)) - (or (:y position) (:y relative-cpos)))] - (gpt/subtract pos cpos))) +(defn- calculate-delta + [position bbox relative-to] + (let [current (gpt/point (:x bbox) (:y bbox)) + position (gpt/point (or (some-> (:x position) (+ (dm/get-prop relative-to :x))) + (:x bbox)) + (or (some-> (:y position) (+ (dm/get-prop relative-to :y))) + (:y bbox)))] + (gpt/subtract position current))) (defn update-position - "Move shapes to a new position" + "Move shapes to a new position. It will resolve to the current frame + of the shape, unless given the absolute option. In this case it will + resolve to the root frame of the page. + + The position is a map that can have a partial position (it means it + can receive {:x 10}." ([id position] (update-position id position nil)) ([id position options] - (dm/assert! (uuid? id)) + (assert (uuid? id) "expected a valid uuid for `id`") + (assert (map? position) "expected a valid map for `position`") + (ptk/reify ::update-position ptk/WatchEvent (watch [_ state _] - (let [page-id (or (get options :page-id) - (get state :current-page-id)) - objects (dsh/lookup-page-objects state page-id) - shape (get objects id) - ;; FIXME: performance rect - bbox (-> shape :points grc/points->rect) - frame (cfh/get-frame objects shape) - delta (if (:absolute? options) - (get-delta position bbox) - (get-relative-delta position bbox frame)) - modif-tree (dwm/create-modif-tree [id] (ctm/move-modifiers delta))] - (rx/of (dwm/apply-modifiers {:modifiers modif-tree + (let [page-id (or (get options :page-id) + (get state :current-page-id)) + objects (dsh/lookup-page-objects state page-id) + shape (get objects id) + + bbox (-> shape :points grc/points->rect) + frame (if (:absolute? options) + (cfh/get-frame objects) + (cfh/get-parent-frame objects shape)) + + delta (calculate-delta position bbox frame) + modifiers (dwm/create-modif-tree [id] (ctm/move-modifiers delta))] + + (rx/of (dwm/apply-modifiers {:modifiers modifiers :page-id page-id :ignore-constraints false :ignore-touched (:ignore-touched options) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs index 4642633f1c..eb7069cb6b 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs @@ -175,7 +175,7 @@ show-in-viewer-ref (mf/use-ref nil) ;; PRESETS - preset-state* (mf/use-state false) + preset-state* (mf/use-state false) show-presets-dropdown? (deref preset-state*) open-presets @@ -205,11 +205,11 @@ ;; ORIENTATION - orientation (when (= type :frame) - (cond (> (:width values) (:height values)) - :horiz - :else - :vert)) + orientation + (when (= type :frame) + (if (> (:width values) (:height values)) + :horiz + :vert)) on-orientation-change (mf/use-fn @@ -235,10 +235,8 @@ (run! #(st/emit! (udw/set-shape-proportion-lock % new-lock)) ids)))) ;; POSITION - do-position-change (mf/use-fn - (mf/deps ids) (fn [shape' value attr] (st/emit! (udw/update-position (:id shape') {attr value})))) @@ -248,7 +246,7 @@ (fn [value attr] (st/emit! (udw/trigger-bounding-box-cloaking ids)) (binding [cts/*wasm-sync* true] - (doall (map #(do-position-change %1 value attr) shapes))))) + (run! #(do-position-change %1 value attr) shapes)))) ;; ROTATION diff --git a/frontend/src/app/main/ui/workspace/tokens/changes.cljs b/frontend/src/app/main/ui/workspace/tokens/changes.cljs index 1137b28e4a..8bdc1a67f8 100644 --- a/frontend/src/app/main/ui/workspace/tokens/changes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/changes.cljs @@ -304,13 +304,11 @@ ptk/WatchEvent (watch [_ state _] (when (number? value) - (let [page-id' (or page-id (get state :current-page-id))] - (rx/concat - (map #(dwt/update-position % (zipmap attributes (repeat value)) - {:ignore-touched true - :page-id page-id'}) - shape-ids)))))))) - + (let [page-id (or page-id (get state :current-page-id))] + (->> (rx/from shape-ids) + (rx/map #(dwt/update-position % (zipmap attributes (repeat value)) + {:ignore-touched true + :page-id page-id}))))))))) (defn update-layout-sizing-limits ([value shape-ids attributes] (update-layout-sizing-limits value shape-ids attributes nil))