Skip to content

Commit

Permalink
Merge pull request #2 from Demonthos/master
Browse files Browse the repository at this point in the history
fix re-computing layout moves children of non-zero positioned parent
  • Loading branch information
jkelleyrtp authored Apr 4, 2022
2 parents cb8d73d + 50e54f5 commit 0c2cc13
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 8 deletions.
19 changes: 12 additions & 7 deletions src/algo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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);
}
Expand Down Expand Up @@ -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(),
},
);
}
Expand Down Expand Up @@ -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 },
},
Expand Down Expand Up @@ -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<NodeId>], 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 _);
Expand Down
3 changes: 2 additions & 1 deletion src/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ pub struct Layout {
pub(crate) order: u32,
pub size: Size<f32>,
pub location: Point<f32>,
pub(crate) relative_location: Point<f32>,
}

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() }
}
}

Expand Down
64 changes: 64 additions & 0 deletions tests/relayout.rs
Original file line number Diff line number Diff line change
@@ -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);
}
}

0 comments on commit 0c2cc13

Please sign in to comment.