Give a slot to the children a container places, and nothing else
A widget's region is now held in the coordinates of the slot it draws in rather than the window's, and `Painter::place` is how a container asks for a slot: it draws a child it decides the box of and may decide again. Everything under that slot is a fraction of its box, so placing the child a second time is one entry to write whether it moved or changed length. A child drawn any other way has no slot and shares its nearest ancestor's. That is what keeps the chain short. `chain_cost` measured depth as the cost -- free to 8, +42.6% at 16 -- and a slot per widget put a transcript's glyphs past that for nothing, since almost every slot was zero. `Span`, `Aligned` and `Scroll` are the containers that re-place a child after drawing it, and `tests/layout.rs` pins that four widgets between a span and a leaf leave the leaf's chain one deep. `UiRegion::stretch`, `UiRegion::stretchable` and `UiScalar::stretch` are gone. Nothing is inverted any more: a box that changed length is written to its slot, and the descendants recompose against it in the shader. That also retires the case the guard existed for, where a fixed length has no fraction to recover -- `tests/layout.rs` now stretches a 40-tall row on its other axis, which `stretchable` refused outright. What still walks the CPU is deciding who must draw again, which no chain can answer: `mark_resized` descends from the widget whose box changed and marks anything whose own box changed length and whose drawing reads it. A part of a box with no relative extent on an axis is a fixed length, and composing into it leaves none either, so the walk stops where a length did not change -- an 80-wide child in a widened row is not redrawn though it says `Redraw`. `Span`, `Pad`, `Stack`, `Offset`, `Aligned`, `SetSize` and `LayerOffset` say `Scale`: each places in fractions and offsets of its own box and none reads the box's pixel length. `Scroll` and `MaxSize` do read pixels and stay `Redraw`. 45 tests pass, five of them new. Render verification comes after the CPU side, per the owner. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1f9dc48b80
commit
d98969158f
18 files changed
+332
-181
No files matched your search
@@ -202,17 +202,6 @@ impl UiScalar {
|
||||
}
|
||||
}
|
||||
|
||||
/// `within` undone against `from` and redone against `to`, for one axis.
|
||||
/// `from`'s relative extent is the denominator, so it must not be zero.
|
||||
fn stretch(&self, from: &UiSpan, to: &UiSpan) -> Self {
|
||||
let frac = (self.rel - from.start.rel) / (from.end.rel - from.start.rel);
|
||||
Self {
|
||||
rel: frac.lerp(to.start.rel, to.end.rel),
|
||||
abs: self.abs - frac.lerp(from.start.abs, from.end.abs)
|
||||
+ frac.lerp(to.start.abs, to.end.abs),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn within_len(&self, len: UiScalar) -> Self {
|
||||
self.within(&UiSpan {
|
||||
start: UiScalar::ZERO,
|
||||
@@ -391,30 +380,6 @@ impl UiRegion {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether a stretch out of this box can be expressed. Each part inside a
|
||||
/// box is held as a fraction of it, and a fixed length has no fraction to
|
||||
/// hold one by -- every part of it is just an offset from its start.
|
||||
pub fn stretchable(&self) -> bool {
|
||||
self.x.start.rel != self.x.end.rel && self.y.start.rel != self.y.end.rel
|
||||
}
|
||||
|
||||
/// Re-expresses a region inside `from` as the same fractions of `to`.
|
||||
/// `from` must be `stretchable`; a translation is `shift` instead, which
|
||||
/// needs no fractions and works out of any box.
|
||||
pub fn stretch(&self, from: &UiRegion, to: &UiRegion) -> UiRegion {
|
||||
debug_assert!(from.stretchable(), "a fixed length has no fraction");
|
||||
UiRegion {
|
||||
x: UiSpan {
|
||||
start: self.x.start.stretch(&from.x, &to.x),
|
||||
end: self.x.end.stretch(&from.x, &to.x),
|
||||
},
|
||||
y: UiSpan {
|
||||
start: self.y.start.stretch(&from.y, &to.y),
|
||||
end: self.y.end.stretch(&from.y, &to.y),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for UiRegion {
|
||||
|
||||
Reference in new issue
Block a user