diff --git a/pax-compiler/files/interfaces/web/src/classes/native-element-pool.ts b/pax-compiler/files/interfaces/web/src/classes/native-element-pool.ts index 9179c5c1e..563fe4bbd 100644 --- a/pax-compiler/files/interfaces/web/src/classes/native-element-pool.ts +++ b/pax-compiler/files/interfaces/web/src/classes/native-element-pool.ts @@ -710,7 +710,7 @@ export class NativeElementPool { } } - if (start_listening != null) { + if (start_listening) { this.resizeObserver.observe(leaf); } diff --git a/pax-designer/src/glass/control_point.rs b/pax-designer/src/glass/control_point.rs index 51fe26202..a7a0b5bfe 100644 --- a/pax-designer/src/glass/control_point.rs +++ b/pax-designer/src/glass/control_point.rs @@ -162,13 +162,6 @@ impl ControlPoint { if let Some(funcs) = funcs { let pos = Point2::new(args.mouse.x, args.mouse.y); let behavior = model::with_action_context(ctx, |ac| { - // save-point before we start executing control point behavior - let before_undo_id = borrow!(ac.engine_context.designtime) - .get_orm() - .get_last_undo_id() - .unwrap_or(0); - ac.undo_stack.push(before_undo_id); - (funcs[self.ind.get().to_int() as usize].tool_factory)( ac, ac.glass_transform().get() * pos, diff --git a/pax-designer/src/math/boolean_path_operations/circular_range.rs b/pax-designer/src/math/boolean_path_operations/circular_range.rs index 247869b1c..2e64c7810 100644 --- a/pax-designer/src/math/boolean_path_operations/circular_range.rs +++ b/pax-designer/src/math/boolean_path_operations/circular_range.rs @@ -53,7 +53,10 @@ mod tests { #[test] fn test_edge_cases() { assert_eq!(circular_range(0, 0, 1, false).collect::>(), vec![0]); - assert_eq!(circular_range(0, 0, 1, true).collect::>(), vec![0]); + assert_eq!( + circular_range(0, 0, 1, true).collect::>(), + vec![0, 0] + ); assert_eq!( circular_range(0, 4, 5, false).collect::>(), vec![0, 1, 2, 3, 4] diff --git a/pax-designer/src/model/action/mod.rs b/pax-designer/src/model/action/mod.rs index e9c1df083..439118a26 100644 --- a/pax-designer/src/model/action/mod.rs +++ b/pax-designer/src/model/action/mod.rs @@ -51,18 +51,24 @@ impl UndoRedoStack { } fn undo(&self, orm: &mut PaxManifestORM) -> Option<()> { - let curr_id = orm.get_last_undo_id()?; - let undo_id = borrow_mut!(self.undo_stack).pop()?; + let curr_id = orm.get_last_undo_id(); + let undo_id = borrow_mut!(self.undo_stack).pop(); + log::trace!("undo from {:?} to {:?} (non-inclusive)", curr_id, undo_id); orm.undo_until(undo_id).ok()?; - borrow_mut!(self.redo_stack).push(curr_id); + if let Some(curr_id) = curr_id { + borrow_mut!(self.redo_stack).push(curr_id); + } Some(()) } fn redo(&self, orm: &mut PaxManifestORM) -> Option<()> { - let curr_id = orm.get_last_undo_id()?; + let curr_id = orm.get_last_undo_id(); let redo_id = borrow_mut!(self.redo_stack).pop()?; + log::trace!("redo from {:?} to {} (inclusive)", curr_id, redo_id); orm.redo_including(redo_id).ok()?; - borrow_mut!(self.undo_stack).push(curr_id); + if let Some(curr_id) = curr_id { + borrow_mut!(self.undo_stack).push(curr_id); + } Some(()) } } @@ -76,10 +82,24 @@ pub struct ActionContext<'a> { pub engine_context: &'a NodeContext, pub app_state: &'a mut AppState, pub derived_state: &'a DerivedAppState, - pub undo_stack: &'a Rc, + undo_stack: &'a Rc, } -impl ActionContext<'_> { +impl<'a> ActionContext<'a> { + pub fn new( + engine_context: &'a NodeContext, + app_state: &'a mut AppState, + derived_state: &'a DerivedAppState, + undo_stack: &'a Rc, + ) -> Self { + Self { + engine_context, + app_state, + derived_state, + undo_stack, + } + } + pub fn world_transform(&self) -> Transform2 { self.app_state.glass_to_world_transform.get() } @@ -207,7 +227,7 @@ impl ActionContext<'_> { } pub struct Transaction { - before_undo_id: usize, + before_undo_id: Option, design_time: Rc>, component_id: Property, undo_stack: Rc, @@ -217,11 +237,9 @@ pub struct Transaction { impl Transaction { pub fn new(ctx: &ActionContext, user_action_message: &str) -> Self { + log::trace!("transaction {:?} created", user_action_message); let design_time = Rc::clone(&ctx.engine_context.designtime); - let before_undo_id = borrow!(design_time) - .get_orm() - .get_last_undo_id() - .unwrap_or(0); + let before_undo_id = borrow!(design_time).get_orm().get_last_undo_id(); let component_id = ctx.app_state.selected_component_id.clone(); Self { undo_stack: Rc::clone(&ctx.undo_stack), @@ -263,8 +281,11 @@ impl Transaction { impl Drop for Transaction { fn drop(&mut self) { + log::trace!("transaction {:?} finished", self.user_action_message); if borrow!(self.result).is_ok() { - self.undo_stack.push(self.before_undo_id); + if let Some(undo_before) = self.before_undo_id { + self.undo_stack.push(undo_before); + } let mut dt = borrow_mut!(self.design_time); if let Err(e) = dt.send_component_update(&self.component_id.get()) { pax_engine::log::error!("failed to save component to file: {:?}", e); diff --git a/pax-designer/src/model/action/orm/tree_movement.rs b/pax-designer/src/model/action/orm/tree_movement.rs index 2c9eb540d..23f32ada7 100644 --- a/pax-designer/src/model/action/orm/tree_movement.rs +++ b/pax-designer/src/model/action/orm/tree_movement.rs @@ -68,12 +68,28 @@ impl Action for MoveNode<'_, S> { .perform(ctx)?; } - let parent_location = ctx.location(self.new_parent_uid, &self.index); { + let mut new_location = ctx.location(self.new_parent_uid, &self.index); let mut dt = borrow_mut!(ctx.engine_context.designtime); + let old_location = dt + .get_orm() + .get_node_location(self.node_id) + .ok_or_else(|| anyhow!("failed to get old node location"))?; + if old_location.tree_location == new_location.tree_location { + if let TreeIndexPosition::At(old_index) = old_location.index { + let index = match new_location.index { + TreeIndexPosition::Top => 0, + TreeIndexPosition::Bottom => usize::MAX, + TreeIndexPosition::At(i) => i, + }; + if old_index < index { + new_location.index = TreeIndexPosition::At(index.saturating_sub(1)); + } + } + } let _undo_id = dt .get_orm_mut() - .move_node(self.node_id.clone(), parent_location.clone()) + .move_node(self.node_id.clone(), new_location.clone()) .map_err(|e| anyhow!("couldn't move child node {:?}", e))?; } diff --git a/pax-designer/src/model/mod.rs b/pax-designer/src/model/mod.rs index 6932c154d..cfe6e89e5 100644 --- a/pax-designer/src/model/mod.rs +++ b/pax-designer/src/model/mod.rs @@ -352,12 +352,12 @@ pub fn with_action_context( ref mut derived_state, .. } = model.as_mut().expect(INITIALIZED); - func(&mut ActionContext { - undo_stack, - engine_context: ctx, + func(&mut ActionContext::new( + ctx, app_state, derived_state, - }) + undo_stack, + )) }) } diff --git a/pax-designtime/src/orm/mod.rs b/pax-designtime/src/orm/mod.rs index 6a10eef5a..12a3ec215 100644 --- a/pax-designtime/src/orm/mod.rs +++ b/pax-designtime/src/orm/mod.rs @@ -369,9 +369,9 @@ impl PaxManifestORM { self.undo_stack.last().map(|l| l.0) } - pub fn undo_until(&mut self, command_id: usize) -> Result<(), String> { + pub fn undo_until(&mut self, command_id: Option) -> Result<(), String> { while let Some((id, _)) = self.undo_stack.last() { - if *id == command_id { + if command_id.is_some_and(|c_id| c_id == *id) { break; } self.undo()?; diff --git a/pax-manifest/src/lib.rs b/pax-manifest/src/lib.rs index f02782949..0e6b802f6 100644 --- a/pax-manifest/src/lib.rs +++ b/pax-manifest/src/lib.rs @@ -1233,7 +1233,7 @@ impl ComponentTemplate { } pub fn move_node(&mut self, id: &TemplateNodeId, new_location: NodeLocation) { - let old_location = self.detach_node(id); + self.detach_node(id); let (target_list, index) = match new_location.get_tree_location() { TreeLocation::Root => (&mut self.root, new_location.index), TreeLocation::Parent(p) => ( @@ -1241,19 +1241,11 @@ impl ComponentTemplate { new_location.index, ), }; - let mut index = match index { + let index = match index { TreeIndexPosition::Top => 0, TreeIndexPosition::Bottom => target_list.len(), TreeIndexPosition::At(i) => i, }; - // Adjust index if moving within the same parent - if old_location.tree_location == new_location.tree_location { - if let TreeIndexPosition::At(old_index) = old_location.index { - if old_index < index { - index = index.saturating_sub(1); - } - } - } target_list.insert(index.clamp(0, target_list.len()), id.clone()); } diff --git a/pax-runtime/src/engine/expanded_node.rs b/pax-runtime/src/engine/expanded_node.rs index 56790ca9f..afb84ce49 100644 --- a/pax-runtime/src/engine/expanded_node.rs +++ b/pax-runtime/src/engine/expanded_node.rs @@ -264,7 +264,6 @@ impl ExpandedNode { _context: &Rc, ) { *borrow_mut!(self.instance_node) = Rc::clone(&template); - log::debug!("recreate"); (&template .base() .instance_prototypical_common_properties_factory)(