Settle dirty layout from the leaves upward

This commit is contained in:
iris-ai committed 2026-09-14 15:56:44 -04:00
1 parent a640c6cce2
commit 84f589e364
5 files changed
+69 -68

No files matched your search

+29 -1
View File
@@ -148,6 +148,22 @@ impl<Rsc: UiRsc + 'static> Grow<'_, Rsc> {
}
}
fn align(&mut self) -> Align {
let mut axis = || match self.rng.below(4) {
0 => None,
1 => Some(AxisAlign::Neg),
2 => Some(AxisAlign::Center),
_ => Some(AxisAlign::Pos),
};
let (mut x, y) = (axis(), axis());
// Aligning on neither axis is just another transparent wrapper and
// would leave this branch unexercised.
if x.is_none() && y.is_none() {
x = Some(AxisAlign::Center);
}
Align { x, y }
}
/// A declared size over half the tree, kept where a test can change it.
fn sized(&mut self, inner: StrongWidget) -> StrongWidget {
if !self.rng.chance() {
@@ -171,7 +187,8 @@ impl<Rsc: UiRsc + 'static> Grow<'_, Rsc> {
if depth == 0 {
return self.leaf();
}
if self.rng.below(6) == 0 {
let positioned = self.rng.below(6);
if positioned == 0 {
// Scrolling reads the pixel length of its box, which nothing
// else here does, and gives its child a box longer than its own.
let inner = self.node(depth - 1);
@@ -182,6 +199,17 @@ impl<Rsc: UiRsc + 'static> Grow<'_, Rsc> {
self.tree.ids.push(id.id());
return id.add_strong(self.rsc);
}
if positioned == 1 {
let inner = self.node(depth - 1);
let inner = self.sized(inner);
let id = Aligned {
inner,
align: self.align(),
}
.add_strong(self.rsc);
self.tree.ids.push(id.id());
return id;
}
if self.rng.below(4) == 0 {
let inner = self.node(depth - 1);
let inner = self.sized(inner);
+3 -7
View File
@@ -13,13 +13,9 @@ impl Widget for Scroll {
fn draw(&mut self, painter: &mut Painter) -> Size {
let output_len = painter.output_size().axis(self.axis);
let container_len = UiScalar::abs(painter.px_size().axis(self.axis));
// Its last measured size stays valid while neither the child nor this
// container's constraints changed. Otherwise draw it in the whole
// container to learn its length, then place it at the scrolled offset.
let child = match painter.retained_size(&self.inner) {
Some(size) => size,
None => painter.place(&self.inner, UiRegion::FULL).size(),
};
// Draw in the whole container to learn the content's length, then
// place it at the scrolled offset.
let child = painter.place(&self.inner, UiRegion::FULL).size();
let content_len = child
.axis(self.axis)
.apply_rest()