diff --git a/src/algo.rs b/src/algo.rs index 758a3a862..e40e1cb0b 100644 --- a/src/algo.rs +++ b/src/algo.rs @@ -89,7 +89,8 @@ impl Forest { self.compute_internal(root, style.size.resolve(size), size, true, true) }; - self.nodes[root].layout = result::Layout { order: 0, size: result.size, location: Point::zero() }; + self.nodes[root].layout = + result::Layout { order: 0, size: result.size, location: Point::zero(), relative_location: Point::zero() }; Self::round_layout(&mut self.nodes, &self.children, root, 0.0, 0.0); } @@ -102,15 +103,15 @@ impl Forest { abs_y: f32, ) { let layout = &mut nodes[root].layout; - let abs_x = abs_x + layout.location.x; - let abs_y = abs_y + layout.location.y; + let abs_x = abs_x + layout.relative_location.x; + let abs_y = abs_y + layout.relative_location.y; layout.location.x = sys::round(abs_x); layout.location.y = sys::round(abs_y); layout.size.width = sys::round(abs_x + layout.size.width) - sys::round(abs_x); layout.size.height = sys::round(abs_y + layout.size.height) - sys::round(abs_y); - + for child in &children[root] { Self::round_layout(nodes, children, *child, abs_x, abs_y); } @@ -748,6 +749,7 @@ impl Forest { order: self.children[node].iter().position(|n| *n == child.node).unwrap() as u32, size: result.size, location: Point::zero(), + relative_location: Point::zero(), }, ); } @@ -1154,7 +1156,8 @@ impl Forest { self.nodes[child.node].layout = result::Layout { order: self.children[node].iter().position(|n| *n == child.node).unwrap() as u32, size: result.size, - location: Point { + location: Point::zero(), + relative_location: Point { x: if is_row { offset_main } else { offset_cross }, y: if is_column { offset_main } else { offset_cross }, }, @@ -1303,16 +1306,18 @@ impl Forest { self.nodes[child].layout = result::Layout { order: order as u32, size: result.size, - location: Point { + relative_location: Point { x: if is_row { offset_main } else { offset_cross }, y: if is_column { offset_main } else { offset_cross }, }, + location: Point::zero(), }; } } fn hidden_layout(nodes: &mut [NodeData], children: &[sys::ChildrenVec], node: NodeId, order: u32) { - nodes[node].layout = result::Layout { order, size: Size::zero(), location: Point::zero() }; + nodes[node].layout = + result::Layout { order, size: Size::zero(), location: Point::zero(), relative_location: Point::zero() }; for (order, child) in children[node].iter().enumerate() { hidden_layout(nodes, children, *child, order as _); diff --git a/src/result.rs b/src/result.rs index ff3619fe3..3ca8da767 100644 --- a/src/result.rs +++ b/src/result.rs @@ -8,11 +8,12 @@ pub struct Layout { pub(crate) order: u32, pub size: Size, pub location: Point, + pub(crate) relative_location: Point, } impl Layout { pub(crate) fn new() -> Self { - Self { order: 0, size: Size::zero(), location: Point::zero() } + Self { order: 0, size: Size::zero(), location: Point::zero(), relative_location: Point::zero() } } } diff --git a/tests/relayout.rs b/tests/relayout.rs new file mode 100644 index 000000000..2ed73901a --- /dev/null +++ b/tests/relayout.rs @@ -0,0 +1,64 @@ +use stretch::style::Dimension; +use stretch2 as stretch; + +#[test] +fn relayout() { + let mut stretch = stretch::Stretch::new(); + let node1 = stretch + .new_node( + stretch::style::Style { + size: stretch::geometry::Size { width: Dimension::Points(8f32), height: Dimension::Points(80f32) }, + ..Default::default() + }, + &[], + ) + .unwrap(); + let node0 = stretch + .new_node( + stretch::style::Style { + align_self: stretch::prelude::AlignSelf::Center, + size: stretch::geometry::Size { width: Dimension::Auto, height: Dimension::Auto }, + // size: stretch::geometry::Size { width: Dimension::Percent(1.0), height: Dimension::Percent(1.0) }, + ..Default::default() + }, + &[node1], + ) + .unwrap(); + let node = stretch + .new_node( + stretch::style::Style { + size: stretch::geometry::Size { width: Dimension::Percent(1f32), height: Dimension::Percent(1f32) }, + ..Default::default() + }, + &[node0], + ) + .unwrap(); + println!("0:"); + stretch + .compute_layout( + node, + stretch::geometry::Size { + width: stretch::prelude::Number::Defined(100f32), + height: stretch::prelude::Number::Defined(100f32), + }, + ) + .unwrap(); + let initial = stretch.layout(node).unwrap().location; + let initial0 = stretch.layout(node0).unwrap().location; + let initial1 = stretch.layout(node1).unwrap().location; + for i in 1..10 { + println!("\n\n{i}:"); + stretch + .compute_layout( + node, + stretch::geometry::Size { + width: stretch::prelude::Number::Defined(100f32), + height: stretch::prelude::Number::Defined(100f32), + }, + ) + .unwrap(); + assert_eq!(stretch.layout(node).unwrap().location, initial); + assert_eq!(stretch.layout(node0).unwrap().location, initial0); + assert_eq!(stretch.layout(node1).unwrap().location, initial1); + } +}