From 5b4cd9f4f168153a5b6c633dfacbfbbcca049a02 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Wed, 18 Jun 2025 14:51:46 +0200 Subject: [PATCH] :bug: Fix problem when moving masks, bools, groups with wasm --- .../app/main/data/workspace/modifiers.cljs | 88 +++++++++++-------- render-wasm/src/main.rs | 2 +- render-wasm/src/render.rs | 9 +- render-wasm/src/render/grid_layout.rs | 2 +- render-wasm/src/shapes.rs | 34 ++++--- render-wasm/src/shapes/modifiers.rs | 6 +- .../src/shapes/modifiers/flex_layout.rs | 2 +- .../src/shapes/modifiers/grid_layout.rs | 2 +- 8 files changed, 86 insertions(+), 59 deletions(-) diff --git a/frontend/src/app/main/data/workspace/modifiers.cljs b/frontend/src/app/main/data/workspace/modifiers.cljs index 6f8ffb5b21..b83085e354 100644 --- a/frontend/src/app/main/data/workspace/modifiers.cljs +++ b/frontend/src/app/main/data/workspace/modifiers.cljs @@ -39,6 +39,43 @@ (def ^:private xf:without-uuid-zero (remove #(= % uuid/zero))) +(def ^:private transform-attrs + #{:selrect + :points + :x + :y + :r1 + :r2 + :r3 + :r4 + :shadow + :blur + :strokes + :width + :height + :content + :transform + :transform-inverse + :rotation + :flip-x + :flip-y + :grow-type + :position-data + :layout-gap + :layout-padding + :layout-item-h-sizing + :layout-item-max-h + :layout-item-max-w + :layout-item-min-h + :layout-item-min-w + :layout-item-v-sizing + :layout-padding-type + :layout-item-margin + :layout-item-margin-type + :layout-grid-cells + :layout-grid-columns + :layout-grid-rows}) + ;; -- temporary modifiers ------------------------------------------- ;; During an interactive transformation of shapes (e.g. when resizing or rotating @@ -598,6 +635,18 @@ ptk/WatchEvent (watch [_ state _] (let [objects (dsh/lookup-page-objects state) + + ignore-tree + (calculate-ignore-tree modif-tree objects) + + options + (-> params + (assoc :reg-objects? true) + (assoc :ignore-tree ignore-tree) + ;; Attributes that can change in the transform. This + ;; way we don't have to check all the attributes + (assoc :attrs transform-attrs)) + geometry-entries (parse-geometry-modifiers modif-tree) snap-pixel? @@ -627,7 +676,7 @@ (clear-local-transform) (ptk/event ::dwg/move-frame-guides {:ids ids :transforms transforms}) (ptk/event ::dwcm/move-frame-comment-threads transforms) - (dwsh/update-shapes ids update-shape)))))) + (dwsh/update-shapes ids update-shape options)))))) (def ^:private xf-rotation-shape @@ -714,43 +763,6 @@ (assoc state :workspace-modifiers modif-tree))))) -(def ^:private transform-attrs - #{:selrect - :points - :x - :y - :r1 - :r2 - :r3 - :r4 - :shadow - :blur - :strokes - :width - :height - :content - :transform - :transform-inverse - :rotation - :flip-x - :flip-y - :grow-type - :position-data - :layout-gap - :layout-padding - :layout-item-h-sizing - :layout-item-max-h - :layout-item-max-w - :layout-item-min-h - :layout-item-min-w - :layout-item-v-sizing - :layout-padding-type - :layout-item-margin - :layout-item-margin-type - :layout-grid-cells - :layout-grid-columns - :layout-grid-rows}) - (defn apply-modifiers* "A lower-level version of apply-modifiers, that expects receive ready to use objects, object-modifiers and text-modifiers." diff --git a/render-wasm/src/main.rs b/render-wasm/src/main.rs index 91fd754491..ef6e1867f4 100644 --- a/render-wasm/src/main.rs +++ b/render-wasm/src/main.rs @@ -457,7 +457,7 @@ pub extern "C" fn set_structure_modifiers() { let Some(shape) = state.shapes.get(&entry.id) else { continue; }; - for id in shape.all_children_with_self(&state.shapes) { + for id in shape.all_children_with_self(&state.shapes, true) { state.scale_content.insert(id, entry.value); } } diff --git a/render-wasm/src/render.rs b/render-wasm/src/render.rs index 135225c1a3..7139846c05 100644 --- a/render-wasm/src/render.rs +++ b/render-wasm/src/render.rs @@ -930,7 +930,8 @@ impl RenderState { let children_clip_bounds = node_render_state.get_children_clip_bounds(element, modifiers.get(&element.id)); - let mut children_ids = modified_children_ids(element, structure.get(&element.id)); + let mut children_ids = + modified_children_ids(element, structure.get(&element.id), false); // Z-index ordering on Layouts if element.has_layout() { @@ -1020,7 +1021,7 @@ impl RenderState { let Some(root) = tree.get(&Uuid::nil()) else { return Err(String::from("Root shape not found")); }; - let root_ids = modified_children_ids(root, structure.get(&root.id)); + let root_ids = modified_children_ids(root, structure.get(&root.id), false); // If we finish processing every node rendering is complete // let's check if there are more pending nodes @@ -1119,7 +1120,7 @@ impl RenderState { self.update_tile_for(&shape); } else { // We only need to rebuild tiles from the first level. - let children = modified_children_ids(&shape, structure.get(&shape.id)); + let children = modified_children_ids(&shape, structure.get(&shape.id), false); for child_id in children.iter() { nodes.push(*child_id); } @@ -1149,7 +1150,7 @@ impl RenderState { self.update_tile_for(&shape); } - let children = modified_children_ids(&shape, structure.get(&shape.id)); + let children = modified_children_ids(&shape, structure.get(&shape.id), false); for child_id in children.iter() { nodes.push(*child_id); } diff --git a/render-wasm/src/render/grid_layout.rs b/render-wasm/src/render/grid_layout.rs index c617854287..23e7a0bba0 100644 --- a/render-wasm/src/render/grid_layout.rs +++ b/render-wasm/src/render/grid_layout.rs @@ -30,7 +30,7 @@ pub fn render_overlay( } let layout_bounds = shape.bounds(); - let children = modified_children_ids(shape, structure.get(&shape.id)); + let children = modified_children_ids(shape, structure.get(&shape.id), false); let column_tracks = calculate_tracks( true, diff --git a/render-wasm/src/shapes.rs b/render-wasm/src/shapes.rs index da6e5dcda7..27e21047e3 100644 --- a/render-wasm/src/shapes.rs +++ b/render-wasm/src/shapes.rs @@ -728,7 +728,11 @@ impl Shape { self.children.first() } - pub fn children_ids(&self) -> IndexSet { + pub fn children_ids(&self, include_hidden: bool) -> IndexSet { + if include_hidden { + return self.children.clone().into_iter().rev().collect(); + } + if let Type::Bool(_) = self.shape_type { IndexSet::::new() } else if let Type::Group(group) = self.shape_type { @@ -747,14 +751,22 @@ impl Shape { } } - pub fn all_children_with_self(&self, shapes: &HashMap) -> IndexSet { + pub fn all_children_with_self( + &self, + shapes: &HashMap, + include_hidden: bool, + ) -> IndexSet { once(self.id) - .chain(self.children_ids().into_iter().flat_map(|id| { - shapes - .get(&id) - .map(|s| s.all_children_with_self(shapes)) - .unwrap_or_default() - })) + .chain( + self.children_ids(include_hidden) + .into_iter() + .flat_map(|id| { + shapes + .get(&id) + .map(|s| s.all_children_with_self(shapes, include_hidden)) + .unwrap_or_default() + }), + ) .collect() } @@ -935,9 +947,11 @@ impl Shape { pub fn modified_children_ids( element: &Shape, structure: Option<&Vec>, + include_hidden: bool, ) -> IndexSet { if let Some(structure) = structure { - let mut result: Vec = Vec::from_iter(element.children_ids().iter().copied()); + let mut result: Vec = + Vec::from_iter(element.children_ids(include_hidden).iter().copied()); let mut to_remove = HashSet::<&Uuid>::new(); for st in structure { @@ -960,7 +974,7 @@ pub fn modified_children_ids( ret } else { - element.children_ids() + element.children_ids(include_hidden) } } diff --git a/render-wasm/src/shapes/modifiers.rs b/render-wasm/src/shapes/modifiers.rs index 92fd7e69e0..e5ce7cc3a1 100644 --- a/render-wasm/src/shapes/modifiers.rs +++ b/render-wasm/src/shapes/modifiers.rs @@ -25,7 +25,7 @@ fn propagate_children( structure: &HashMap>, scale_content: &HashMap, ) -> VecDeque { - let children_ids = modified_children_ids(shape, structure.get(&shape.id)); + let children_ids = modified_children_ids(shape, structure.get(&shape.id), true); if children_ids.is_empty() || identitish(transform) { return VecDeque::new(); @@ -95,7 +95,7 @@ fn calculate_group_bounds( let shape_bounds = bounds.find(shape); let mut result = Vec::::new(); - let children_ids = modified_children_ids(shape, structure.get(&shape.id)); + let children_ids = modified_children_ids(shape, structure.get(&shape.id), true); for child_id in children_ids.iter() { let Some(child) = shapes.get(child_id) else { continue; @@ -272,7 +272,7 @@ pub fn propagate_modifiers( } Type::Group(Group { masked: true }) => { let children_ids = - modified_children_ids(shape, state.structure.get(&shape.id)); + modified_children_ids(shape, state.structure.get(&shape.id), true); if let Some(child) = shapes.get(&children_ids[0]) { let child_bounds = bounds.find(child); bounds.insert(shape.id, child_bounds); diff --git a/render-wasm/src/shapes/modifiers/flex_layout.rs b/render-wasm/src/shapes/modifiers/flex_layout.rs index 1d26392146..acaa118de1 100644 --- a/render-wasm/src/shapes/modifiers/flex_layout.rs +++ b/render-wasm/src/shapes/modifiers/flex_layout.rs @@ -184,7 +184,7 @@ fn initialize_tracks( ) -> Vec { let mut tracks = Vec::::new(); let mut current_track = TrackData::default(); - let mut children = modified_children_ids(shape, structure.get(&shape.id)); + let mut children = modified_children_ids(shape, structure.get(&shape.id), true); let mut first = true; if flex_data.is_reverse() { diff --git a/render-wasm/src/shapes/modifiers/grid_layout.rs b/render-wasm/src/shapes/modifiers/grid_layout.rs index 5ac85911d9..fca6203059 100644 --- a/render-wasm/src/shapes/modifiers/grid_layout.rs +++ b/render-wasm/src/shapes/modifiers/grid_layout.rs @@ -634,7 +634,7 @@ pub fn reflow_grid_layout( ) -> VecDeque { let mut result = VecDeque::new(); let layout_bounds = bounds.find(shape); - let children = modified_children_ids(shape, structure.get(&shape.id)); + let children = modified_children_ids(shape, structure.get(&shape.id), true); let column_tracks = calculate_tracks( true,