use morphorm::*;
use morphorm_ecs::*;
fn snapshot(world: &World, entities: &[Entity]) -> Vec<Option<Rect>> {
entities.iter().map(|entity| world.cache.bounds(*entity).copied()).collect()
}
fn full_layout(world: &mut World, root: Entity) {
root.layout(&mut world.cache, &world.tree, &world.store, &mut ());
}
fn incremental_layout(world: &mut World, node: Entity) {
node.layout(&mut world.cache, &world.tree, &world.store, &mut ());
}
#[test]
fn incremental_matches_full_under_fixed_parent() {
let mut world = World::default();
let root = world.add(None);
world.set_width(root, Units::Pixels(600.0));
world.set_height(root, Units::Pixels(600.0));
world.set_alignment(root, Alignment::TopLeft);
world.set_layout_type(root, LayoutType::Column);
let parent = world.add(Some(root));
world.set_width(parent, Units::Pixels(400.0));
world.set_height(parent, Units::Pixels(400.0));
world.set_layout_type(parent, LayoutType::Column);
let a = world.add(Some(parent));
world.set_width(a, Units::Pixels(100.0));
world.set_height(a, Units::Pixels(100.0));
let b = world.add(Some(parent));
world.set_width(b, Units::Pixels(100.0));
world.set_height(b, Units::Pixels(100.0));
full_layout(&mut world, root);
world.set_height(a, Units::Pixels(250.0));
incremental_layout(&mut world, a);
let incremental = snapshot(&world, &[root, parent, a, b]);
full_layout(&mut world, root);
let full = snapshot(&world, &[root, parent, a, b]);
assert_eq!(incremental, full);
assert_eq!(world.cache.bounds(b).unwrap().posy, 250.0);
}
#[test]
fn incremental_bubbles_through_auto_parent() {
let mut world = World::default();
let root = world.add(None);
world.set_width(root, Units::Pixels(600.0));
world.set_height(root, Units::Pixels(600.0));
world.set_alignment(root, Alignment::TopLeft);
world.set_layout_type(root, LayoutType::Column);
let grandparent = world.add(Some(root));
world.set_width(grandparent, Units::Pixels(500.0));
world.set_height(grandparent, Units::Pixels(500.0));
world.set_layout_type(grandparent, LayoutType::Column);
let parent = world.add(Some(grandparent));
world.set_width(parent, Units::Pixels(300.0));
world.set_height(parent, Units::Auto);
world.set_layout_type(parent, LayoutType::Column);
let sibling = world.add(Some(grandparent));
world.set_width(sibling, Units::Pixels(50.0));
world.set_height(sibling, Units::Pixels(50.0));
let child = world.add(Some(parent));
world.set_width(child, Units::Pixels(100.0));
world.set_height(child, Units::Pixels(100.0));
full_layout(&mut world, root);
assert_eq!(world.cache.bounds(sibling).unwrap().posy, 100.0);
world.set_height(child, Units::Pixels(220.0));
incremental_layout(&mut world, child);
let incremental = snapshot(&world, &[grandparent, parent, sibling, child]);
full_layout(&mut world, root);
let full = snapshot(&world, &[grandparent, parent, sibling, child]);
assert_eq!(incremental, full);
assert_eq!(world.cache.bounds(sibling).unwrap().posy, 220.0);
}
#[test]
fn incremental_restarts_at_stretch_ancestor() {
let mut world = World::default();
let root = world.add(None);
world.set_width(root, Units::Pixels(600.0));
world.set_height(root, Units::Pixels(600.0));
world.set_alignment(root, Alignment::TopLeft);
world.set_layout_type(root, LayoutType::Row);
let stretch = world.add(Some(root));
world.set_width(stretch, Units::Stretch(1.0));
world.set_height(stretch, Units::Stretch(1.0));
world.set_layout_type(stretch, LayoutType::Column);
let child = world.add(Some(stretch));
world.set_width(child, Units::Pixels(100.0));
world.set_height(child, Units::Pixels(100.0));
let child2 = world.add(Some(stretch));
world.set_width(child2, Units::Pixels(100.0));
world.set_height(child2, Units::Pixels(100.0));
full_layout(&mut world, root);
assert_eq!(world.cache.bounds(child2).unwrap().posy, 100.0);
world.set_height(child, Units::Pixels(180.0));
incremental_layout(&mut world, child);
let incremental = snapshot(&world, &[root, stretch, child, child2]);
full_layout(&mut world, root);
let full = snapshot(&world, &[root, stretch, child, child2]);
assert_eq!(incremental, full);
assert_eq!(world.cache.bounds(child2).unwrap().posy, 180.0);
}
#[test]
fn incremental_before_first_full_layout_matches_full() {
let mut world = World::default();
let root = world.add(None);
world.set_width(root, Units::Pixels(600.0));
world.set_height(root, Units::Pixels(600.0));
world.set_alignment(root, Alignment::TopLeft);
world.set_layout_type(root, LayoutType::Column);
let parent = world.add(Some(root));
world.set_width(parent, Units::Pixels(400.0));
world.set_height(parent, Units::Pixels(400.0));
world.set_layout_type(parent, LayoutType::Column);
let a = world.add(Some(parent));
world.set_width(a, Units::Pixels(100.0));
world.set_height(a, Units::Pixels(100.0));
let b = world.add(Some(parent));
world.set_width(b, Units::Pixels(100.0));
world.set_height(b, Units::Pixels(100.0));
incremental_layout(&mut world, a);
let incremental = snapshot(&world, &[root, parent, a, b]);
full_layout(&mut world, root);
let full = snapshot(&world, &[root, parent, a, b]);
assert_eq!(incremental, full);
assert_eq!(world.cache.bounds(b).unwrap().posy, 100.0);
}
#[test]
fn incremental_repositions_right_bottom_anchored_absolute_ancestor() {
let mut world = World::default();
let root = world.add(None);
world.set_width(root, Units::Pixels(400.0));
world.set_height(root, Units::Pixels(400.0));
world.set_alignment(root, Alignment::TopLeft);
world.set_layout_type(root, LayoutType::Overlay);
let absolute = world.add(Some(root));
world.set_position_type(absolute, PositionType::Absolute);
world.set_layout_type(absolute, LayoutType::Column);
world.set_width(absolute, Units::Auto);
world.set_height(absolute, Units::Auto);
world.set_right(absolute, Units::Pixels(0.0));
world.set_bottom(absolute, Units::Pixels(0.0));
let child = world.add(Some(absolute));
world.set_width(child, Units::Pixels(100.0));
world.set_height(child, Units::Pixels(100.0));
full_layout(&mut world, root);
assert_eq!(world.cache.bounds(absolute).unwrap().posx, 300.0);
assert_eq!(world.cache.bounds(absolute).unwrap().posy, 300.0);
world.set_width(child, Units::Pixels(150.0));
world.set_height(child, Units::Pixels(150.0));
incremental_layout(&mut world, child);
let incremental = snapshot(&world, &[root, absolute, child]);
full_layout(&mut world, root);
let full = snapshot(&world, &[root, absolute, child]);
assert_eq!(incremental, full);
assert_eq!(world.cache.bounds(absolute).unwrap().posx, 250.0);
assert_eq!(world.cache.bounds(absolute).unwrap().posy, 250.0);
}
#[test]
fn incremental_bubbles_through_percentage_ancestor() {
let mut world = World::default();
let root = world.add(None);
world.set_width(root, Units::Pixels(600.0));
world.set_height(root, Units::Pixels(600.0));
world.set_alignment(root, Alignment::TopLeft);
world.set_layout_type(root, LayoutType::Column);
let percent = world.add(Some(root));
world.set_width(percent, Units::Percentage(50.0));
world.set_height(percent, Units::Percentage(50.0));
world.set_layout_type(percent, LayoutType::Column);
let child = world.add(Some(percent));
world.set_width(child, Units::Pixels(100.0));
world.set_height(child, Units::Pixels(100.0));
let child2 = world.add(Some(percent));
world.set_width(child2, Units::Pixels(100.0));
world.set_height(child2, Units::Pixels(100.0));
full_layout(&mut world, root);
world.set_height(child, Units::Pixels(150.0));
incremental_layout(&mut world, child);
let incremental = snapshot(&world, &[root, percent, child, child2]);
full_layout(&mut world, root);
let full = snapshot(&world, &[root, percent, child, child2]);
assert_eq!(incremental, full);
assert_eq!(world.cache.bounds(percent).unwrap().height, 300.0);
assert_eq!(world.cache.bounds(child2).unwrap().posy, 150.0);
}
#[test]
fn incremental_on_root_is_full_layout() {
let mut world = World::default();
let root = world.add(None);
world.set_width(root, Units::Pixels(600.0));
world.set_height(root, Units::Pixels(600.0));
world.set_alignment(root, Alignment::TopLeft);
world.set_layout_type(root, LayoutType::Row);
let a = world.add(Some(root));
world.set_width(a, Units::Pixels(100.0));
world.set_height(a, Units::Pixels(150.0));
let b = world.add(Some(root));
world.set_width(b, Units::Pixels(120.0));
world.set_height(b, Units::Pixels(150.0));
incremental_layout(&mut world, root);
assert_eq!(world.cache.bounds(a), Some(&Rect { posx: 0.0, posy: 0.0, width: 100.0, height: 150.0 }));
assert_eq!(world.cache.bounds(b), Some(&Rect { posx: 100.0, posy: 0.0, width: 120.0, height: 150.0 }));
}