🐛 Fix problem when moving masks, bools, groups with wasm

This commit is contained in:
alonso.torres 2025-06-18 14:51:46 +02:00
parent 58e5748b4f
commit 5b4cd9f4f1
8 changed files with 86 additions and 59 deletions

View file

@ -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."

View file

@ -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);
}
}

View file

@ -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);
}

View file

@ -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,

View file

@ -728,7 +728,11 @@ impl Shape {
self.children.first()
}
pub fn children_ids(&self) -> IndexSet<Uuid> {
pub fn children_ids(&self, include_hidden: bool) -> IndexSet<Uuid> {
if include_hidden {
return self.children.clone().into_iter().rev().collect();
}
if let Type::Bool(_) = self.shape_type {
IndexSet::<Uuid>::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<Uuid, &mut Shape>) -> IndexSet<Uuid> {
pub fn all_children_with_self(
&self,
shapes: &HashMap<Uuid, &mut Shape>,
include_hidden: bool,
) -> IndexSet<Uuid> {
once(self.id)
.chain(self.children_ids().into_iter().flat_map(|id| {
.chain(
self.children_ids(include_hidden)
.into_iter()
.flat_map(|id| {
shapes
.get(&id)
.map(|s| s.all_children_with_self(shapes))
.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<StructureEntry>>,
include_hidden: bool,
) -> IndexSet<Uuid> {
if let Some(structure) = structure {
let mut result: Vec<Uuid> = Vec::from_iter(element.children_ids().iter().copied());
let mut result: Vec<Uuid> =
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)
}
}

View file

@ -25,7 +25,7 @@ fn propagate_children(
structure: &HashMap<Uuid, Vec<StructureEntry>>,
scale_content: &HashMap<Uuid, f32>,
) -> VecDeque<Modifier> {
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::<Point>::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);

View file

@ -184,7 +184,7 @@ fn initialize_tracks(
) -> Vec<TrackData> {
let mut tracks = Vec::<TrackData>::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() {

View file

@ -634,7 +634,7 @@ pub fn reflow_grid_layout(
) -> VecDeque<Modifier> {
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,