diff --git a/frontend/src/app/main/data/workspace/modifiers.cljs b/frontend/src/app/main/data/workspace/modifiers.cljs index d40041fc3b..c438cf8815 100644 --- a/frontend/src/app/main/data/workspace/modifiers.cljs +++ b/frontend/src/app/main/data/workspace/modifiers.cljs @@ -649,7 +649,7 @@ (propagate-structure-modifiers modif-tree (dsh/lookup-page-objects state)) ids - (into [] xf:without-uuid-zero (keys transforms)) + (into (set (keys modif-tree)) xf:without-uuid-zero (keys transforms)) update-shape (fn [shape] diff --git a/frontend/src/app/main/ui/flex_controls/gap.cljs b/frontend/src/app/main/ui/flex_controls/gap.cljs index 963f9442d7..1f6f44ab29 100644 --- a/frontend/src/app/main/ui/flex_controls/gap.cljs +++ b/frontend/src/app/main/ui/flex_controls/gap.cljs @@ -16,6 +16,8 @@ [app.common.types.shape.layout :as ctl] [app.main.data.helpers :as dsh] [app.main.data.workspace.modifiers :as dwm] + [app.main.data.workspace.transforms :as dwt] + [app.main.features :as features] [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.css-cursors :as cur] @@ -31,6 +33,7 @@ (let [resizing (mf/use-var nil) start (mf/use-var nil) original-value (mf/use-var 0) + last-pos (mf/use-var nil) negate? (:resize-negate? rect-data) axis (:resize-axis rect-data) @@ -43,32 +46,47 @@ (reset! start (dom/get-client-position event)) (reset! original-value (:initial-value rect-data)))) - on-lost-pointer-capture + calc-modifiers (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)) + layout-gap (assoc gap gap-type val)] + [val (dwm/create-modif-tree [frame-id] (ctm/change-property (ctm/empty) :layout-gap layout-gap))]))) + + on-lost-pointer-capture + (mf/use-fn + (mf/deps calc-modifiers) (fn [event] (dom/release-pointer event) + + (when (and (features/active-feature? @st/state "render-wasm/v1") (= @resizing gap-type)) + (let [[_ modifiers] (calc-modifiers @last-pos)] + (st/emit! (dwm/apply-wasm-modifiers modifiers) + (dwt/finish-transform)))) + (reset! resizing nil) (reset! start nil) (reset! original-value 0) - (st/emit! (dwm/apply-modifiers)))) + (when (not (features/active-feature? @st/state "render-wasm/v1")) + (st/emit! (dwm/apply-modifiers))))) on-pointer-move (mf/use-fn - (mf/deps frame-id gap-type gap) + (mf/deps calc-modifiers) (fn [event] (let [pos (dom/get-client-position event)] + (reset! last-pos pos) (reset! mouse-pos (point->viewport pos)) (when (= @resizing gap-type) - (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) - modifiers (dwm/create-modif-tree [frame-id] (ctm/change-property (ctm/empty) :layout-gap layout-gap))] - + (let [[val modifiers] (calc-modifiers pos)] (reset! hover-value val) - (st/emit! (dwm/set-modifiers modifiers)))))))] + (if (features/active-feature? @st/state "render-wasm/v1") + (st/emit! (dwm/set-wasm-modifiers modifiers)) + (st/emit! (dwm/set-modifiers modifiers))))))))] [:g.gap-rect [:rect.info-area diff --git a/frontend/src/app/main/ui/flex_controls/margin.cljs b/frontend/src/app/main/ui/flex_controls/margin.cljs index dee2900b39..d8f2650206 100644 --- a/frontend/src/app/main/ui/flex_controls/margin.cljs +++ b/frontend/src/app/main/ui/flex_controls/margin.cljs @@ -9,6 +9,8 @@ [app.common.geom.point :as gpt] [app.common.types.modifiers :as ctm] [app.main.data.workspace.modifiers :as dwm] + [app.main.data.workspace.transforms :as dwt] + [app.main.features :as features] [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.css-cursors :as cur] @@ -22,6 +24,7 @@ (let [resizing? (mf/use-var false) start (mf/use-var nil) original-value (mf/use-var 0) + last-pos (mf/use-var nil) negate? (true? (:resize-negate? rect-data)) axis (:resize-axis rect-data) @@ -34,15 +37,51 @@ (reset! start (dom/get-client-position event)) (reset! original-value (:initial-value rect-data)))) + calc-modifiers + (mf/use-fn + (fn [pos] + (let [delta + (-> (gpt/to-vec @start pos) + (cond-> negate? gpt/negate) + (get axis)) + + val + (int (max (+ @original-value (/ delta zoom)) 0)) + + layout-item-margin + (cond + hover-all? (assoc margin :m1 val :m2 val :m3 val :m4 val) + hover-v? (assoc margin :m1 val :m3 val) + hover-h? (assoc margin :m2 val :m4 val) + :else (assoc margin margin-num val)) + + layout-item-margin-type + (if (= (:m1 margin) (:m2 margin) (:m3 margin) (:m4 margin)) :simple :multiple)] + + [val + (dwm/create-modif-tree + [shape-id] + (-> (ctm/empty) + (ctm/change-property :layout-item-margin layout-item-margin) + (ctm/change-property :layout-item-margin-type layout-item-margin-type)))]))) + on-lost-pointer-capture (mf/use-fn (mf/deps shape-id margin-num margin) (fn [event] (dom/release-pointer event) + + (when (features/active-feature? @st/state "render-wasm/v1") + (let [[_ modifiers] (calc-modifiers @last-pos)] + (st/emit! (dwm/apply-wasm-modifiers modifiers) + (dwt/finish-transform)))) + (reset! resizing? false) (reset! start nil) (reset! original-value 0) - (st/emit! (dwm/apply-modifiers)))) + + (when (not (features/active-feature? @st/state "render-wasm/v1")) + (st/emit! (dwm/apply-modifiers))))) on-pointer-move (mf/use-fn @@ -50,23 +89,13 @@ (fn [event] (let [pos (dom/get-client-position event)] (reset! mouse-pos (point->viewport pos)) + (reset! last-pos pos) (when @resizing? - (let [delta (-> (gpt/to-vec @start pos) - (cond-> negate? gpt/negate) - (get axis)) - val (int (max (+ @original-value (/ delta zoom)) 0)) - layout-item-margin (cond - hover-all? (assoc margin :m1 val :m2 val :m3 val :m4 val) - hover-v? (assoc margin :m1 val :m3 val) - hover-h? (assoc margin :m2 val :m4 val) - :else (assoc margin margin-num val)) - layout-item-margin-type (if (= (:m1 margin) (:m2 margin) (:m3 margin) (:m4 margin)) :simple :multiple) - modifiers (dwm/create-modif-tree [shape-id] - (-> (ctm/empty) - (ctm/change-property :layout-item-margin layout-item-margin) - (ctm/change-property :layout-item-margin-type layout-item-margin-type)))] + (let [[val modifiers] (calc-modifiers pos)] (reset! hover-value val) - (st/emit! (dwm/set-modifiers modifiers)))))))] + (if (features/active-feature? @st/state "render-wasm/v1") + (st/emit! (dwm/set-wasm-modifiers modifiers)) + (st/emit! (dwm/set-modifiers modifiers))))))))] [:rect.margin-rect {:x (:x rect-data) diff --git a/frontend/src/app/main/ui/flex_controls/padding.cljs b/frontend/src/app/main/ui/flex_controls/padding.cljs index 96e0c07d8f..5c63ecaf12 100644 --- a/frontend/src/app/main/ui/flex_controls/padding.cljs +++ b/frontend/src/app/main/ui/flex_controls/padding.cljs @@ -9,6 +9,8 @@ [app.common.geom.point :as gpt] [app.common.types.modifiers :as ctm] [app.main.data.workspace.modifiers :as dwm] + [app.main.data.workspace.transforms :as dwt] + [app.main.features :as features] [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.css-cursors :as cur] @@ -23,6 +25,7 @@ (let [resizing? (mf/use-var false) start (mf/use-var nil) original-value (mf/use-var 0) + last-pos (mf/use-var nil) negate? (true? (:resize-negate? rect-data)) axis (:resize-axis rect-data) @@ -35,41 +38,65 @@ (reset! start (dom/get-client-position event)) (reset! original-value (:initial-value rect-data)))) + calc-modifiers + (mf/use-fn + (mf/deps frame-id padding-num padding hover-all? hover-v? hover-h?) + (fn [pos] + (let [delta + (-> (gpt/to-vec @start pos) + (cond-> negate? gpt/negate) + (get axis)) + + val + (int (max (+ @original-value (/ delta zoom)) 0)) + + layout-padding + (cond + hover-all? (assoc padding :p1 val :p2 val :p3 val :p4 val) + hover-v? (assoc padding :p1 val :p3 val) + hover-h? (assoc padding :p2 val :p4 val) + :else (assoc padding padding-num val)) + + + 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)))]))) + on-lost-pointer-capture (mf/use-fn - (mf/deps frame-id padding-num padding) + (mf/deps calc-modifiers) (fn [event] (dom/release-pointer event) + + (when (features/active-feature? @st/state "render-wasm/v1") + (let [[_ modifiers] (calc-modifiers @last-pos)] + (st/emit! (dwm/apply-wasm-modifiers modifiers) + (dwt/finish-transform)))) + (reset! resizing? false) (reset! start nil) (reset! original-value 0) - (st/emit! (dwm/apply-modifiers)))) + + (when (not (features/active-feature? @st/state "render-wasm/v1")) + (st/emit! (dwm/apply-modifiers))))) on-pointer-move (mf/use-fn - (mf/deps frame-id padding-num padding hover-all? hover-v? hover-h?) + (mf/deps calc-modifiers) (fn [event] (let [pos (dom/get-client-position event)] (reset! mouse-pos (point->viewport pos)) + (reset! last-pos pos) (when @resizing? - (let [delta (-> (gpt/to-vec @start pos) - (cond-> negate? gpt/negate) - (get axis)) - val (int (max (+ @original-value (/ delta zoom)) 0)) - layout-padding (cond - hover-all? (assoc padding :p1 val :p2 val :p3 val :p4 val) - hover-v? (assoc padding :p1 val :p3 val) - hover-h? (assoc padding :p2 val :p4 val) - :else (assoc padding padding-num val)) - - - layout-padding-type (if (= (:p1 padding) (:p2 padding) (:p3 padding) (:p4 padding)) :simple :multiple) - modifiers (dwm/create-modif-tree [frame-id] - (-> (ctm/empty) - (ctm/change-property :layout-padding layout-padding) - (ctm/change-property :layout-padding-type layout-padding-type)))] + (let [[val modifiers] (calc-modifiers pos)] (reset! hover-value val) - (st/emit! (dwm/set-modifiers modifiers)))))))] + (if (features/active-feature? @st/state "render-wasm/v1") + (st/emit! (dwm/set-wasm-modifiers modifiers)) + (st/emit! (dwm/set-modifiers modifiers))))))))] [:g.padding-rect [:rect.info-area diff --git a/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.cljs b/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.cljs index 2b5085bf8f..869fc0f178 100644 --- a/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.cljs @@ -23,6 +23,7 @@ [app.main.data.workspace.grid-layout.editor :as dwge] [app.main.data.workspace.modifiers :as dwm] [app.main.data.workspace.shape-layout :as dwsl] + [app.main.data.workspace.transforms :as dwt] [app.main.features :as features] [app.main.refs :as refs] [app.main.store :as st] @@ -257,7 +258,8 @@ (let [modifiers (calculate-drag-modifiers position) modif-tree (dwm/create-modif-tree [(:id shape)] modifiers)] (when on-clear-modifiers (on-clear-modifiers modifiers)) - (st/emit! (dwm/apply-wasm-modifiers modif-tree))) + (st/emit! (dwm/apply-wasm-modifiers modif-tree) + (dwt/finish-transform))) (st/emit! (dwm/apply-modifiers))))) {:keys [handle-pointer-down handle-lost-pointer-capture handle-pointer-move]} @@ -506,7 +508,8 @@ (let [modifiers (calculate-modifiers position) modif-tree (dwm/create-modif-tree [(:id shape)] modifiers)] (when on-clear-modifiers (on-clear-modifiers)) - (st/emit! (dwm/apply-wasm-modifiers modif-tree))) + (st/emit! (dwm/apply-wasm-modifiers modif-tree) + (dwt/finish-transform))) (st/emit! (dwm/apply-modifiers))) (reset! start-size-before nil) (reset! start-size-after nil)))] diff --git a/frontend/src/app/render_wasm/api.cljs b/frontend/src/app/render_wasm/api.cljs index be85dc1fd7..4b6d389217 100644 --- a/frontend/src/app/render_wasm/api.cljs +++ b/frontend/src/app/render_wasm/api.cljs @@ -1246,9 +1246,15 @@ (defn clear-canvas [] - ;; TODO: perform corresponding cleaning - (set! wasm/context-initialized? false) - (h/call wasm/internal-module "_clean_up")) + (try + ;; TODO: perform corresponding cleaning + (set! wasm/context-initialized? false) + (h/call wasm/internal-module "_clean_up") + + ;; If this calls panics we don't want to crash. This happens sometimes + ;; with hot-reload in develop + (catch :default error + (.error js/console error)))) (defn show-grid [id] diff --git a/frontend/src/app/render_wasm/shape.cljs b/frontend/src/app/render_wasm/shape.cljs index fbb45cd4a3..e182094bca 100644 --- a/frontend/src/app/render_wasm/shape.cljs +++ b/frontend/src/app/render_wasm/shape.cljs @@ -291,7 +291,8 @@ (api/set-grid-layout-data shape) (ctl/flex-layout? shape) - (api/set-flex-layout shape))) + (api/set-flex-layout shape)) + (api/set-layout-child shape)) ;; Property not in WASM nil)))) diff --git a/render-wasm/src/shapes/modifiers/flex_layout.rs b/render-wasm/src/shapes/modifiers/flex_layout.rs index d3ed26b1db..7246d167e6 100644 --- a/render-wasm/src/shapes/modifiers/flex_layout.rs +++ b/render-wasm/src/shapes/modifiers/flex_layout.rs @@ -53,15 +53,6 @@ struct LayoutAxis { is_auto_across: bool, } -impl LayoutAxis { - fn main_space(&self) -> f32 { - self.main_size - self.padding_main_start - self.padding_main_end - } - fn across_space(&self) -> f32 { - self.across_size - self.padding_across_start - self.padding_across_end - } -} - impl LayoutAxis { fn new( shape: &Shape, @@ -101,6 +92,13 @@ impl LayoutAxis { } } } + + fn main_space(&self) -> f32 { + self.main_size - self.padding_main_start - self.padding_main_end + } + fn across_space(&self) -> f32 { + self.across_size - self.padding_across_start - self.padding_across_end + } } #[derive(Debug, Copy, Clone)] @@ -624,6 +622,9 @@ pub fn reflow_flex_layout( } result.push_back(Modifier::transform_propagate(child.id, transform)); + if child.has_layout() { + result.push_back(Modifier::reflow(child.id)); + } shape_anchor = next_anchor( layout_data, @@ -654,7 +655,11 @@ pub fn reflow_flex_layout( .iter() .map(|track| { let nshapes = usize::max(track.shapes.len(), 1); - track.shapes.iter().map(|s| s.main_size).sum::() + track + .shapes + .iter() + .map(|s| s.margin_main_start + s.margin_main_end + s.main_size) + .sum::() + (nshapes as f32 - 1.0) * layout_axis.gap_main }) .reduce(f32::max) diff --git a/render-wasm/src/shapes/modifiers/grid_layout.rs b/render-wasm/src/shapes/modifiers/grid_layout.rs index 083d89d0f6..3fe8e8f6bf 100644 --- a/render-wasm/src/shapes/modifiers/grid_layout.rs +++ b/render-wasm/src/shapes/modifiers/grid_layout.rs @@ -792,6 +792,9 @@ pub fn reflow_grid_layout( } result.push_back(Modifier::transform_propagate(child.id, transform)); + if child.has_layout() { + result.push_back(Modifier::reflow(child.id)); + } } if shape.is_layout_horizontal_auto() || shape.is_layout_vertical_auto() { diff --git a/render-wasm/src/wasm/layouts.rs b/render-wasm/src/wasm/layouts.rs index a97812b519..4e97222ca3 100644 --- a/render-wasm/src/wasm/layouts.rs +++ b/render-wasm/src/wasm/layouts.rs @@ -59,18 +59,19 @@ pub extern "C" fn set_layout_child_data( is_absolute: bool, z_index: i32, ) { - let h_sizing = RawSizing::from(h_sizing); - let v_sizing = RawSizing::from(v_sizing); - let max_h = if has_max_h { Some(max_h) } else { None }; - let min_h = if has_min_h { Some(min_h) } else { None }; - let max_w = if has_max_w { Some(max_w) } else { None }; - let min_w = if has_min_w { Some(min_w) } else { None }; - - let raw_align_self = align::RawAlignSelf::from(align_self); - - let align_self = raw_align_self.try_into().ok(); - with_current_shape_mut!(state, |shape: &mut Shape| { + let h_sizing = RawSizing::from(h_sizing); + let v_sizing = RawSizing::from(v_sizing); + + let max_h = if has_max_h { Some(max_h) } else { None }; + let min_h = if has_min_h { Some(min_h) } else { None }; + let max_w = if has_max_w { Some(max_w) } else { None }; + let min_w = if has_min_w { Some(min_w) } else { None }; + + let raw_align_self = align::RawAlignSelf::from(align_self); + + let align_self = raw_align_self.try_into().ok(); + shape.set_flex_layout_child_data( margin_top, margin_right,