Judge a kept contract against the box it was asked in
A local redraw keeps the narrower guarantee its parent holds when the new drawing covers it, so widening and narrowing back do not churn the parent. It checked that guarantee against `placement`, where the answer put the drawing, rather than `region`, the box the drawing was made in and the box both contracts are about. The two differ on every axis a widget reported less than it was offered, so any such widget escalated to its parent every time its contract widened -- which is the churn the retention exists to avoid. `resize` and `try_reuse` both already ask about `region`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
aea0387567
commit
713e3e747b
2 files changed
+60
-1
No files matched your search
@@ -1477,3 +1477,59 @@ fn a_redrawn_subtree_is_not_undrawn_by_the_parent_it_left() {
|
||||
assert_eq!(h.region(&leaf), before);
|
||||
}
|
||||
}
|
||||
|
||||
/// A leaf that reports less than the box it is given and states which lengths
|
||||
/// of that box its drawing holds for, so a test can widen the contract
|
||||
/// without changing the answer.
|
||||
struct Contracted {
|
||||
holds: std::ops::RangeInclusive<Px>,
|
||||
size: Size,
|
||||
}
|
||||
|
||||
impl Widget for Contracted {
|
||||
fn draw(&mut self, painter: &mut Painter) -> Size {
|
||||
painter.holds(Axis::X, self.holds.clone());
|
||||
self.size
|
||||
}
|
||||
}
|
||||
|
||||
struct CountedParent {
|
||||
inner: StrongWidget,
|
||||
draws: Rc<Cell<usize>>,
|
||||
}
|
||||
|
||||
impl Widget for CountedParent {
|
||||
fn draw(&mut self, painter: &mut Painter) -> Size {
|
||||
self.draws.set(self.draws.get() + 1);
|
||||
painter.widget(&self.inner).size()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn widening_what_a_drawing_holds_for_does_not_relay_out_the_parent() {
|
||||
let mut h = Harness::new((400, 200));
|
||||
let child = Contracted {
|
||||
holds: Px::from_int(300)..=Px::from_int(500),
|
||||
size: Size::from((100, 200)),
|
||||
}
|
||||
.add(&mut h.rsc);
|
||||
let draws = Rc::new(Cell::new(0));
|
||||
let root = CountedParent {
|
||||
inner: child.upgrade(&mut h.rsc),
|
||||
draws: draws.clone(),
|
||||
}
|
||||
.add(&mut h.rsc);
|
||||
h.set_root(root);
|
||||
let settled = draws.get();
|
||||
|
||||
// The same answer, good for more boxes than before, so the guarantee the
|
||||
// parent kept still holds.
|
||||
h.rsc[child].holds = Px::from_int(200)..=Px::from_int(600);
|
||||
h.frame();
|
||||
|
||||
assert_eq!(
|
||||
draws.get(),
|
||||
settled,
|
||||
"a wider contract for the same answer is not a change to lay out"
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user