Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 34 additions & 18 deletions src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,19 @@ fn same_f32(a: f32, b: f32) -> bool {
a.to_bits() == b.to_bits()
}

#[inline]
fn is_horizontal(layout_type: LayoutType) -> bool {
match layout_type {
LayoutType::Row | LayoutType::Overlay | LayoutType::Grid => true,
LayoutType::Column => false,
}
}

#[inline]
fn same_axis_direction(a: LayoutType, b: LayoutType) -> bool {
is_horizontal(a) == is_horizontal(b)
}

#[allow(clippy::too_many_arguments)]
fn clamp_with_aspect_ratio(
parent_layout_type: LayoutType,
Expand Down Expand Up @@ -767,8 +780,11 @@ where

// Convert parent-provided main/cross (which are in parent layout axes)
// into this node's layout axes.
let (parent_main, parent_cross) =
if parent_layout_type == layout_type { (parent_main, parent_cross) } else { (parent_cross, parent_main) };
let (parent_main, parent_cross) = if same_axis_direction(parent_layout_type, layout_type) {
(parent_main, parent_cross)
} else {
(parent_cross, parent_main)
};

let padding_main_before = node.padding_main_before(store, layout_type).to_px(parent_main, 0.0);
let padding_main_after = node.padding_main_after(store, layout_type).to_px(parent_main, 0.0);
Expand Down Expand Up @@ -1276,7 +1292,7 @@ where
cache.set_rect(abs_child.node, layout_type, child_main_pos, child_cross_pos, abs_child.main, abs_child.cross);
}

if parent_layout_type == layout_type {
if same_axis_direction(parent_layout_type, layout_type) {
Size { main: final_main, cross: final_cross }
} else {
Size { main: final_cross, cross: final_main }
Expand Down Expand Up @@ -1425,7 +1441,7 @@ where

// Determine the parent_main/cross size to pass to the children based on the layout type of the parent and the node.
// i.e. if the parent layout type and the node layout type are different, swap the main and the cross axes.
let (mut parent_main, mut parent_cross) = if parent_layout_type == layout_type {
let (mut parent_main, mut parent_cross) = if same_axis_direction(parent_layout_type, layout_type) {
(computed_main, computed_cross)
} else {
(computed_cross, computed_main)
Expand Down Expand Up @@ -1550,31 +1566,31 @@ where
// Determine auto main and cross size from space and size of children.
if num_parent_directed_children != 0 {
if main.is_auto() || node.min_main(store, parent_layout_type).is_auto() {
if parent_layout_type == layout_type {
if same_axis_direction(parent_layout_type, layout_type) {
min_main = main_sum + padding_main_before + padding_main_after;
} else {
min_main = cross_max + padding_cross_before + padding_cross_after;
}
}

if node.max_main(store, parent_layout_type).is_auto() {
if parent_layout_type == layout_type && main_sum != 0.0 {
if same_axis_direction(parent_layout_type, layout_type) && main_sum != 0.0 {
max_main = main_sum + padding_main_before + padding_main_after;
} else if cross_max != 0.0 {
max_main = cross_max + padding_cross_before + padding_cross_after;
}
}

if cross.is_auto() || node.min_cross(store, parent_layout_type).is_auto() {
if parent_layout_type == layout_type {
if same_axis_direction(parent_layout_type, layout_type) {
min_cross = cross_max + padding_cross_before + padding_cross_after;
} else {
min_cross = main_sum + padding_main_before + padding_main_after;
}
}

if node.max_cross(store, parent_layout_type).is_auto() {
if parent_layout_type == layout_type && cross_max != 0.0 {
if same_axis_direction(parent_layout_type, layout_type) && cross_max != 0.0 {
max_cross = cross_max + padding_cross_before + padding_cross_after;
} else if main_sum != 0.0 {
max_cross = main_sum + padding_main_before + padding_main_after;
Expand All @@ -1595,7 +1611,7 @@ where
&mut computed_cross,
);

let (mut parent_main, mut parent_cross) = if parent_layout_type == layout_type {
let (mut parent_main, mut parent_cross) = if same_axis_direction(parent_layout_type, layout_type) {
(computed_main, computed_cross)
} else {
(computed_cross, computed_main)
Expand Down Expand Up @@ -1642,31 +1658,31 @@ where
// Determine auto main and cross size from space and size of children.
if num_parent_directed_children != 0 {
if main.is_auto() || node.min_main(store, parent_layout_type).is_auto() {
if parent_layout_type == layout_type {
if same_axis_direction(parent_layout_type, layout_type) {
min_main = main_sum + padding_main_before + padding_main_after;
} else {
min_main = cross_max + padding_cross_before + padding_cross_after;
}
}

if node.max_main(store, parent_layout_type).is_auto() {
if parent_layout_type == layout_type && main_sum != 0.0 {
if same_axis_direction(parent_layout_type, layout_type) && main_sum != 0.0 {
max_main = main_sum + padding_main_before + padding_main_after;
} else if cross_max != 0.0 {
max_main = cross_max + padding_cross_before + padding_cross_after;
}
}

if cross.is_auto() || node.min_cross(store, parent_layout_type).is_auto() {
if parent_layout_type == layout_type {
if same_axis_direction(parent_layout_type, layout_type) {
min_cross = cross_max + padding_cross_before + padding_cross_after;
} else {
min_cross = main_sum + padding_main_before + padding_main_after;
}
}

if node.max_cross(store, parent_layout_type).is_auto() {
if parent_layout_type == layout_type && cross_max != 0.0 {
if same_axis_direction(parent_layout_type, layout_type) && cross_max != 0.0 {
max_cross = cross_max + padding_cross_before + padding_cross_after;
} else if main_sum != 0.0 {
max_cross = main_sum + padding_main_before + padding_main_after;
Expand Down Expand Up @@ -1804,31 +1820,31 @@ where
// Determine auto main and cross size from space and size of children.
if num_parent_directed_children != 0 {
if main.is_auto() || node.min_main(store, parent_layout_type).is_auto() {
if parent_layout_type == layout_type {
if same_axis_direction(parent_layout_type, layout_type) {
min_main = main_sum + padding_main_before + padding_main_after;
} else {
min_main = cross_max + padding_cross_before + padding_cross_after;
}
}

if node.max_main(store, parent_layout_type).is_auto() {
if parent_layout_type == layout_type && main_sum != 0.0 {
if same_axis_direction(parent_layout_type, layout_type) && main_sum != 0.0 {
max_main = main_sum + padding_main_before + padding_main_after;
} else if cross_max != 0.0 {
max_main = cross_max + padding_cross_before + padding_cross_after;
}
}

if cross.is_auto() || node.min_cross(store, parent_layout_type).is_auto() {
if parent_layout_type == layout_type {
if same_axis_direction(parent_layout_type, layout_type) {
min_cross = cross_max + padding_cross_before + padding_cross_after;
} else {
min_cross = main_sum + padding_main_before + padding_main_after;
}
}

if node.max_cross(store, parent_layout_type).is_auto() {
if parent_layout_type == layout_type && cross_max != 0.0 {
if same_axis_direction(parent_layout_type, layout_type) && cross_max != 0.0 {
max_cross = cross_max + padding_cross_before + padding_cross_after;
} else if main_sum != 0.0 {
max_cross = main_sum + padding_main_before + padding_main_after;
Expand All @@ -1849,7 +1865,7 @@ where
&mut computed_cross,
);

let (mut parent_main, mut parent_cross) = if parent_layout_type == layout_type {
let (mut parent_main, mut parent_cross) = if same_axis_direction(parent_layout_type, layout_type) {
(computed_main, computed_cross)
} else {
(computed_cross, computed_main)
Expand Down
33 changes: 33 additions & 0 deletions tests/overlay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,36 @@ fn overlay_preserves_absolute_child_positioning() {
assert_eq!(world.cache.bounds(relative), Some(&Rect { posx: 0.0, posy: 0.0, width: 50.0, height: 50.0 }));
assert_eq!(world.cache.bounds(absolute), Some(&Rect { posx: 20.0, posy: 30.0, width: 60.0, height: 70.0 }));
}

#[test]
fn overlay_row_child_uses_horizontal_axis_for_stretch_distribution() {
let mut world = World::default();

let root = world.add(None);
world.set_width(root, Units::Pixels(1920.0));
world.set_height(root, Units::Pixels(1000.0));
world.set_layout_type(root, LayoutType::Overlay);

let row = world.add(Some(root));
world.set_width(row, Units::Stretch(1.0));
world.set_height(row, Units::Stretch(1.0));
world.set_layout_type(row, LayoutType::Row);
world.set_horizontal_gap(row, Units::Pixels(16.0));

let sidebar = world.add(Some(row));
world.set_width(sidebar, Units::Pixels(218.0));

let stage = world.add(Some(row));
world.set_width(stage, Units::Stretch(1.0));

let queue = world.add(Some(row));
world.set_width(queue, Units::Pixels(282.0));

root.layout(&mut world.cache, &world.tree, &world.store, &mut ());

assert_eq!(world.cache.width(&row), 1920.0);
assert_eq!(world.cache.width(&sidebar), 218.0);
assert_eq!(world.cache.width(&stage), 1388.0);
assert_eq!(world.cache.posx(&queue), 1638.0);
assert_eq!(world.cache.width(&queue), 282.0);
}
Loading