diff --git a/frontend/src/app/main/refs.cljs b/frontend/src/app/main/refs.cljs index 2561557367..c4454c430a 100644 --- a/frontend/src/app/main/refs.cljs +++ b/frontend/src/app/main/refs.cljs @@ -372,6 +372,9 @@ (def workspace-modifiers (l/derived :workspace-modifiers st/state)) +(def workspace-wasm-modifiers + (l/derived :workspace-wasm-modifiers st/state)) + (def ^:private workspace-modifiers-with-objects (l/derived (fn [state] diff --git a/frontend/src/app/main/ui/flex_controls/gap.cljs b/frontend/src/app/main/ui/flex_controls/gap.cljs index 1f6f44ab29..1e8df2c1e8 100644 --- a/frontend/src/app/main/ui/flex_controls/gap.cljs +++ b/frontend/src/app/main/ui/flex_controls/gap.cljs @@ -7,6 +7,7 @@ (ns app.main.ui.flex-controls.gap (:require [app.common.data :as d] + [app.common.data.macros :as dm] [app.common.files.helpers :as cfh] [app.common.geom.point :as gpt] [app.common.geom.shapes :as gsh] @@ -29,7 +30,7 @@ (mf/defc gap-display [{:keys [frame-id zoom gap-type gap on-pointer-enter on-pointer-leave rect-data hover? selected? mouse-pos hover-value - on-move-selected on-context-menu]}] + on-move-selected on-context-menu on-change]}] (let [resizing (mf/use-var nil) start (mf/use-var nil) original-value (mf/use-var 0) @@ -50,12 +51,18 @@ (mf/use-fn (mf/deps frame-id gap-type gap) (fn [pos] - (let [delta (-> (gpt/to-vec @start pos) - (cond-> negate? gpt/negate) - (get axis)) - val (int (max (+ @original-value (/ delta zoom)) 0)) + (let [delta + (-> (gpt/to-vec @start pos) + (cond-> negate? gpt/negate) + (get axis)) + val + (int (max (+ @original-value (/ delta zoom)) 0)) + layout-gap (assoc gap gap-type val)] - [val (dwm/create-modif-tree [frame-id] (ctm/change-property (ctm/empty) :layout-gap layout-gap))]))) + [val + (dwm/create-modif-tree + [frame-id] + (ctm/change-property (ctm/empty) :layout-gap layout-gap))]))) on-lost-pointer-capture (mf/use-fn @@ -76,7 +83,7 @@ on-pointer-move (mf/use-fn - (mf/deps calc-modifiers) + (mf/deps calc-modifiers on-change) (fn [event] (let [pos (dom/get-client-position event)] (reset! last-pos pos) @@ -86,7 +93,9 @@ (reset! hover-value val) (if (features/active-feature? @st/state "render-wasm/v1") (st/emit! (dwm/set-wasm-modifiers modifiers)) - (st/emit! (dwm/set-modifiers modifiers))))))))] + (st/emit! (dwm/set-modifiers modifiers))) + (when on-change + (on-change modifiers)))))))] [:g.gap-rect [:rect.info-area @@ -138,10 +147,17 @@ pill-width (/ fcc/flex-display-pill-width zoom) pill-height (/ fcc/flex-display-pill-height zoom) workspace-modifiers (mf/deref refs/workspace-modifiers) + workspace-wasm-modifiers (mf/deref refs/workspace-wasm-modifiers) + gap-selected (mf/deref refs/workspace-gap-selected) hover (mf/use-state nil) hover-value (mf/use-state 0) mouse-pos (mf/use-state nil) + current-modifiers (mf/use-state nil) + + frame + (ctm/apply-structure-modifiers frame (dm/get-in @current-modifiers [frame-id :modifiers])) + padding (:layout-padding frame) gap (:layout-gap frame) {:keys [width height x1 y1]} (:selrect frame) @@ -150,6 +166,12 @@ (reset! hover-value val)) on-pointer-leave #(reset! hover nil) + + on-change + (mf/use-fn + (fn [modifiers] + (reset! current-modifiers modifiers))) + negate {:column-gap (if flip-x true false) :row-gap (if flip-y true false)} @@ -161,8 +183,16 @@ (= :column-reverse saved-dir)) (drop-last children) (rest children)) - children-to-display (->> children-to-display - (map #(gsh/transform-shape % (get-in workspace-modifiers [(:id %) :modifiers])))) + children-to-display + (if (features/active-feature? @st/state "render-wasm/v1") + (let [modifiers (into {} workspace-wasm-modifiers)] + (->> children-to-display + ;;(map #(gsh/transform-shape % (get-in workspace-modifiers [(:id %) :modifiers]))) + (map (fn [shape] + (gsh/apply-transform shape (get modifiers (:id shape))))))) + + (->> children-to-display + (map #(gsh/transform-shape % (get-in workspace-modifiers [(:id %) :modifiers]))))) wrap-blocks (let [block-children (->> children @@ -290,20 +320,22 @@ [:g.gaps {:pointer-events "visible"} (for [[index display-item] (d/enumerate (concat display-blocks display-children))] (let [gap-type (:gap-type display-item)] - [:& gap-display {:key (str frame-id index) - :frame-id frame-id - :zoom zoom - :gap-type gap-type - :gap gap - :on-pointer-enter (partial on-pointer-enter gap-type (get gap gap-type)) - :on-pointer-leave on-pointer-leave - :on-move-selected on-move-selected - :on-context-menu on-context-menu - :rect-data display-item - :hover? (= @hover gap-type) - :selected? (= gap-selected gap-type) - :mouse-pos mouse-pos - :hover-value hover-value}])) + [:& gap-display + {:key (str frame-id index) + :frame-id frame-id + :zoom zoom + :gap-type gap-type + :gap gap + :on-pointer-enter (partial on-pointer-enter gap-type (get gap gap-type)) + :on-pointer-leave on-pointer-leave + :on-move-selected on-move-selected + :on-context-menu on-context-menu + :on-change on-change + :rect-data display-item + :hover? (= @hover gap-type) + :selected? (= gap-selected gap-type) + :mouse-pos mouse-pos + :hover-value hover-value}])) (when @hover [:& fcc/flex-display-pill diff --git a/frontend/src/app/main/ui/flex_controls/margin.cljs b/frontend/src/app/main/ui/flex_controls/margin.cljs index d8f2650206..9cb2223432 100644 --- a/frontend/src/app/main/ui/flex_controls/margin.cljs +++ b/frontend/src/app/main/ui/flex_controls/margin.cljs @@ -6,6 +6,7 @@ (ns app.main.ui.flex-controls.margin (:require + [app.common.data.macros :as dm] [app.common.geom.point :as gpt] [app.common.types.modifiers :as ctm] [app.main.data.workspace.modifiers :as dwm] @@ -19,8 +20,10 @@ [app.util.dom :as dom] [rumext.v2 :as mf])) -(mf/defc margin-display [{:keys [shape-id zoom hover-all? hover-v? hover-h? margin-num margin on-pointer-enter on-pointer-leave - rect-data hover? selected? mouse-pos hover-value]}] +(mf/defc margin-display + [{:keys [shape-id zoom hover-all? hover-v? hover-h? margin-num margin + on-pointer-enter on-pointer-leave on-change + rect-data hover? selected? mouse-pos hover-value]}] (let [resizing? (mf/use-var false) start (mf/use-var nil) original-value (mf/use-var 0) @@ -39,6 +42,7 @@ calc-modifiers (mf/use-fn + (mf/deps shape-id margin-num margin hover-all? hover-v? hover-h?) (fn [pos] (let [delta (-> (gpt/to-vec @start pos) @@ -67,7 +71,7 @@ on-lost-pointer-capture (mf/use-fn - (mf/deps shape-id margin-num margin) + (mf/deps calc-modifiers) (fn [event] (dom/release-pointer event) @@ -85,7 +89,7 @@ on-pointer-move (mf/use-fn - (mf/deps shape-id margin-num margin hover-all? hover-v? hover-h?) + (mf/deps calc-modifiers on-change) (fn [event] (let [pos (dom/get-client-position event)] (reset! mouse-pos (point->viewport pos)) @@ -95,7 +99,10 @@ (reset! hover-value val) (if (features/active-feature? @st/state "render-wasm/v1") (st/emit! (dwm/set-wasm-modifiers modifiers)) - (st/emit! (dwm/set-modifiers modifiers))))))))] + (st/emit! (dwm/set-modifiers modifiers))) + + (when on-change + (on-change modifiers)))))))] [:rect.margin-rect {:x (:x rect-data) @@ -118,6 +125,11 @@ pill-width (/ fcc/flex-display-pill-width zoom) pill-height (/ fcc/flex-display-pill-height zoom) margins-selected (mf/deref refs/workspace-margins-selected) + current-modifiers (mf/use-state nil) + + shape + (ctm/apply-structure-modifiers shape (dm/get-in @current-modifiers [shape-id :modifiers])) + hover-value (mf/use-state 0) mouse-pos (mf/use-state nil) hover (mf/use-state nil) @@ -126,50 +138,67 @@ hover-h? (and (or (= @hover :m2) (= @hover :m4)) shift?) margin (:layout-item-margin shape) {:keys [width height x1 x2 y1 y2]} (:selrect shape) - on-pointer-enter (fn [hover-type val] - (reset! hover hover-type) - (reset! hover-value val)) - on-pointer-leave #(reset! hover nil) - hover? #(or hover-all? - (and (or (= % :m1) (= % :m3)) hover-v?) - (and (or (= % :m2) (= % :m4)) hover-h?) - (= @hover %)) - margin-display-data {:m1 {:key (str shape-id "-m1") - :x x1 - :y (if (:flip-y frame) y2 (- y1 (:m1 margin))) - :width width - :height (:m1 margin) - :initial-value (:m1 margin) - :resize-type :top - :resize-axis :y - :resize-negate? (:flip-y frame)} - :m2 {:key (str shape-id "-m2") - :x (if (:flip-x frame) (- x1 (:m2 margin)) x2) - :y y1 - :width (:m2 margin) - :height height - :initial-value (:m2 margin) - :resize-type :left - :resize-axis :x - :resize-negate? (:flip-x frame)} - :m3 {:key (str shape-id "-m3") - :x x1 - :y (if (:flip-y frame) (- y1 (:m3 margin)) y2) - :width width - :height (:m3 margin) - :initial-value (:m3 margin) - :resize-type :top - :resize-axis :y - :resize-negate? (:flip-y frame)} - :m4 {:key (str shape-id "-m4") - :x (if (:flip-x frame) x2 (- x1 (:m4 margin))) - :y y1 - :width (:m4 margin) - :height height - :initial-value (:m4 margin) - :resize-type :left - :resize-axis :x - :resize-negate? (:flip-x frame)}}] + + on-pointer-enter + (mf/use-fn + (fn [hover-type val] + (reset! hover hover-type) + (reset! hover-value val))) + + on-pointer-leave + (mf/use-fn + (fn [] + (reset! hover nil))) + + on-change + (mf/use-fn + (fn [modifiers] + (reset! current-modifiers modifiers))) + + hover? + (fn [value] + (or hover-all? + (and (or (= value :m1) (= value :m3)) hover-v?) + (and (or (= value :m2) (= value :m4)) hover-h?) + (= @hover value))) + + margin-display-data + {:m1 {:key (str shape-id "-m1") + :x x1 + :y (if (:flip-y frame) y2 (- y1 (:m1 margin))) + :width width + :height (:m1 margin) + :initial-value (:m1 margin) + :resize-type :top + :resize-axis :y + :resize-negate? (:flip-y frame)} + :m2 {:key (str shape-id "-m2") + :x (if (:flip-x frame) (- x1 (:m2 margin)) x2) + :y y1 + :width (:m2 margin) + :height height + :initial-value (:m2 margin) + :resize-type :left + :resize-axis :x + :resize-negate? (:flip-x frame)} + :m3 {:key (str shape-id "-m3") + :x x1 + :y (if (:flip-y frame) (- y1 (:m3 margin)) y2) + :width width + :height (:m3 margin) + :initial-value (:m3 margin) + :resize-type :top + :resize-axis :y + :resize-negate? (:flip-y frame)} + :m4 {:key (str shape-id "-m4") + :x (if (:flip-x frame) x2 (- x1 (:m4 margin))) + :y y1 + :width (:m4 margin) + :height height + :initial-value (:m4 margin) + :resize-type :left + :resize-axis :x + :resize-negate? (:flip-x frame)}}] [:g.margins {:pointer-events "visible"} (for [[margin-num rect-data] margin-display-data] @@ -184,6 +213,7 @@ :margin margin :on-pointer-enter (partial on-pointer-enter margin-num (get margin margin-num)) :on-pointer-leave on-pointer-leave + :on-change on-change :rect-data rect-data :hover? (hover? margin-num) :selected? (get margins-selected margin-num) diff --git a/frontend/src/app/main/ui/flex_controls/padding.cljs b/frontend/src/app/main/ui/flex_controls/padding.cljs index 5c63ecaf12..9992219086 100644 --- a/frontend/src/app/main/ui/flex_controls/padding.cljs +++ b/frontend/src/app/main/ui/flex_controls/padding.cljs @@ -6,6 +6,7 @@ (ns app.main.ui.flex-controls.padding (:require + [app.common.data.macros :as dm] [app.common.geom.point :as gpt] [app.common.types.modifiers :as ctm] [app.main.data.workspace.modifiers :as dwm] @@ -20,8 +21,9 @@ [rumext.v2 :as mf])) (mf/defc padding-display - [{:keys [frame-id zoom hover-all? hover-v? hover-h? padding-num padding on-pointer-enter on-pointer-leave - rect-data hover? selected? mouse-pos hover-value on-move-selected on-context-menu]}] + [{:keys [frame-id zoom hover-all? hover-v? hover-h? padding-num padding on-pointer-enter + on-pointer-leave rect-data hover? selected? mouse-pos hover-value on-move-selected + on-context-menu on-change]}] (let [resizing? (mf/use-var false) start (mf/use-var nil) original-value (mf/use-var 0) @@ -61,10 +63,11 @@ layout-padding-type (if (= (:p1 padding) (:p2 padding) (:p3 padding) (:p4 padding)) :simple :multiple)] [val - (dwm/create-modif-tree [frame-id] - (-> (ctm/empty) - (ctm/change-property :layout-padding layout-padding) - (ctm/change-property :layout-padding-type layout-padding-type)))]))) + (dwm/create-modif-tree + [frame-id] + (-> (ctm/empty) + (ctm/change-property :layout-padding layout-padding) + (ctm/change-property :layout-padding-type layout-padding-type)))]))) on-lost-pointer-capture (mf/use-fn @@ -86,7 +89,7 @@ on-pointer-move (mf/use-fn - (mf/deps calc-modifiers) + (mf/deps calc-modifiers on-change) (fn [event] (let [pos (dom/get-client-position event)] (reset! mouse-pos (point->viewport pos)) @@ -96,7 +99,10 @@ (reset! hover-value val) (if (features/active-feature? @st/state "render-wasm/v1") (st/emit! (dwm/set-wasm-modifiers modifiers)) - (st/emit! (dwm/set-modifiers modifiers))))))))] + (st/emit! (dwm/set-modifiers modifiers))) + + (when on-change + (on-change modifiers)))))))] [:g.padding-rect [:rect.info-area @@ -132,77 +138,108 @@ :on-lost-pointer-capture on-lost-pointer-capture :on-pointer-move on-pointer-move :on-context-menu on-context-menu - :class (when (or hover? selected?) - (if (= (:resize-axis rect-data) :x) (cur/get-dynamic "resize-ew" 0) (cur/get-dynamic "resize-ew" 90))) - :style {:fill (if (or hover? selected?) fcc/distance-color "none") - :opacity (if selected? 0 1)}}])])) + :class + (when (or hover? selected?) + (if (= (:resize-axis rect-data) :x) + (cur/get-dynamic "resize-ew" 0) + (cur/get-dynamic "resize-ew" 90))) + + :style + {:fill (if (or hover? selected?) fcc/distance-color "none") + :opacity (if selected? 0 1)}}])])) (mf/defc padding-rects [{:keys [frame zoom alt? shift? on-move-selected on-context-menu]}] (let [frame-id (:id frame) paddings-selected (mf/deref refs/workspace-paddings-selected) + current-modifiers (mf/use-state nil) + + frame + (ctm/apply-structure-modifiers frame (dm/get-in @current-modifiers [frame-id :modifiers])) + hover-value (mf/use-state 0) mouse-pos (mf/use-state nil) hover (mf/use-state nil) + hover-all? (and (not (nil? @hover)) alt?) hover-v? (and (or (= @hover :p1) (= @hover :p3)) shift?) hover-h? (and (or (= @hover :p2) (= @hover :p4)) shift?) padding (:layout-padding frame) {:keys [width height x1 x2 y1 y2]} (:selrect frame) - on-pointer-enter (fn [hover-type val] - (reset! hover hover-type) - (reset! hover-value val)) - on-pointer-leave #(reset! hover nil) pill-width (/ fcc/flex-display-pill-width zoom) pill-height (/ fcc/flex-display-pill-height zoom) - hover? #(or hover-all? - (and (or (= % :p1) (= % :p3)) hover-v?) - (and (or (= % :p2) (= % :p4)) hover-h?) - (= @hover %)) - negate {:p1 (if (:flip-y frame) true false) - :p2 (if (:flip-x frame) true false) - :p3 (if (:flip-y frame) true false) - :p4 (if (:flip-x frame) true false)} - negate (cond-> negate - (not= :auto (:layout-item-h-sizing frame)) (assoc :p2 (not (:p2 negate))) - (not= :auto (:layout-item-v-sizing frame)) (assoc :p3 (not (:p3 negate)))) - padding-rect-data {:p1 {:key (str frame-id "-p1") - :x x1 - :y (if (:flip-y frame) (- y2 (:p1 padding)) y1) - :width width - :height (:p1 padding) - :initial-value (:p1 padding) - :resize-type (if (:flip-y frame) :bottom :top) - :resize-axis :y - :resize-negate? (:p1 negate)} - :p2 {:key (str frame-id "-p2") - :x (if (:flip-x frame) x1 (- x2 (:p2 padding))) - :y y1 - :width (:p2 padding) - :height height - :initial-value (:p2 padding) - :resize-type :left - :resize-axis :x - :resize-negate? (:p2 negate)} - :p3 {:key (str frame-id "-p3") - :x x1 - :y (if (:flip-y frame) y1 (- y2 (:p3 padding))) - :width width - :height (:p3 padding) - :initial-value (:p3 padding) - :resize-type :bottom - :resize-axis :y - :resize-negate? (:p3 negate)} - :p4 {:key (str frame-id "-p4") - :x (if (:flip-x frame) (- x2 (:p4 padding)) x1) - :y y1 - :width (:p4 padding) - :height height - :initial-value (:p4 padding) - :resize-type (if (:flip-x frame) :right :left) - :resize-axis :x - :resize-negate? (:p4 negate)}}] + negate + {:p1 (if (:flip-y frame) true false) + :p2 (if (:flip-x frame) true false) + :p3 (if (:flip-y frame) true false) + :p4 (if (:flip-x frame) true false)} + + negate + (cond-> negate + (not= :auto (:layout-item-h-sizing frame)) (assoc :p2 (not (:p2 negate))) + (not= :auto (:layout-item-v-sizing frame)) (assoc :p3 (not (:p3 negate)))) + + padding-rect-data + {:p1 {:key (str frame-id "-p1") + :x x1 + :y (if (:flip-y frame) (- y2 (:p1 padding)) y1) + :width width + :height (:p1 padding) + :initial-value (:p1 padding) + :resize-type (if (:flip-y frame) :bottom :top) + :resize-axis :y + :resize-negate? (:p1 negate)} + :p2 {:key (str frame-id "-p2") + :x (if (:flip-x frame) x1 (- x2 (:p2 padding))) + :y y1 + :width (:p2 padding) + :height height + :initial-value (:p2 padding) + :resize-type :left + :resize-axis :x + :resize-negate? (:p2 negate)} + :p3 {:key (str frame-id "-p3") + :x x1 + :y (if (:flip-y frame) y1 (- y2 (:p3 padding))) + :width width + :height (:p3 padding) + :initial-value (:p3 padding) + :resize-type :bottom + :resize-axis :y + :resize-negate? (:p3 negate)} + :p4 {:key (str frame-id "-p4") + :x (if (:flip-x frame) (- x2 (:p4 padding)) x1) + :y y1 + :width (:p4 padding) + :height height + :initial-value (:p4 padding) + :resize-type (if (:flip-x frame) :right :left) + :resize-axis :x + :resize-negate? (:p4 negate)}} + + on-pointer-enter + (mf/use-fn + (fn [hover-type val] + (reset! hover hover-type) + (reset! hover-value val))) + + on-pointer-leave + (mf/use-fn + (fn [] + (reset! hover nil))) + + on-change + (mf/use-fn + (fn [modifiers] + (reset! current-modifiers modifiers))) + + hover? + (fn [value] + (or hover-all? + (and (or (= value :p1) (= value :p3)) hover-v?) + (and (or (= value :p2) (= value :p4)) hover-h?) + (= @hover value)))] [:g.paddings {:pointer-events "visible"} (for [[padding-num rect-data] padding-rect-data] @@ -221,9 +258,11 @@ :on-pointer-leave on-pointer-leave :on-move-selected on-move-selected :on-context-menu on-context-menu + :on-change on-change :hover? (hover? padding-num) :selected? (get paddings-selected padding-num) :rect-data rect-data}]) + (when @hover [:& fcc/flex-display-pill {:height pill-height diff --git a/frontend/src/app/main/ui/workspace/viewport_wasm.cljs b/frontend/src/app/main/ui/workspace/viewport_wasm.cljs index 54dde7688d..4bed31f127 100644 --- a/frontend/src/app/main/ui/workspace/viewport_wasm.cljs +++ b/frontend/src/app/main/ui/workspace/viewport_wasm.cljs @@ -54,15 +54,11 @@ [app.util.debug :as dbg] [app.util.text-editor :as ted] [beicon.v2.core :as rx] - [okulary.core :as l] [promesa.core :as p] [rumext.v2 :as mf])) ;; --- Viewport -(def workspace-wasm-modifiers - (l/derived :workspace-wasm-modifiers st/state)) - (defn apply-modifiers-to-selected [selected objects modifiers] (->> modifiers @@ -98,7 +94,7 @@ ;; DEREFS drawing (mf/deref refs/workspace-drawing) focus (mf/deref refs/workspace-focus-selected) - wasm-modifiers (mf/deref workspace-wasm-modifiers) + wasm-modifiers (mf/deref refs/workspace-wasm-modifiers) workspace-editor-state (mf/deref refs/workspace-editor-state) diff --git a/render-wasm/src/shapes/modifiers.rs b/render-wasm/src/shapes/modifiers.rs index f090cf98a7..07c5230ce8 100644 --- a/render-wasm/src/shapes/modifiers.rs +++ b/render-wasm/src/shapes/modifiers.rs @@ -290,7 +290,7 @@ fn propagate_reflow( let mut skip_reflow = false; if shape.is_layout_horizontal_fill() || shape.is_layout_vertical_fill() { if let Some(parent_id) = shape.parent_id { - if !reflown.contains(&parent_id) { + if parent_id != Uuid::nil() && !reflown.contains(&parent_id) { // If this is a fill layout but the parent has not been reflown yet // we wait for the next iteration for reflow skip_reflow = true;