mirror of
https://github.com/penpot/penpot.git
synced 2025-08-01 05:08:21 +02:00
🐛 Fix problem when moving masks, bools, groups with wasm
This commit is contained in:
parent
58e5748b4f
commit
5b4cd9f4f1
8 changed files with 86 additions and 59 deletions
|
@ -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."
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue