Settle dirty layout from the leaves upward
This commit is contained in:
1 parent
a640c6cce2
commit
84f589e364
5 files changed
+69
-68
No files matched your search
+29
-1
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in new issue
Block a user