Read a child's report as a fraction of the containing widget

`rel(0.5)` is half the span whatever else is in it and wherever the child
sits among them (Bryan, 2026-09-17). It was half of what the span had left
at the point it asked, because a report came back composed through the box
it was offered and a span offers each child the room from its cursor -- so
a nested span taking half of what it was given took a quarter of a row
whose first half was already spoken for, where the same half written as a
rule on the child took half the row.

The offer stays the remainder: a text has to wrap at the width actually
there, and `a_text_in_a_span_wraps_at_the_room_left_rather_than_the_whole_row`
pins that. What separates from it is the base a report's fractions are of,
which the ask now carries. It is the box the child was given wherever that
box is the child's whole area -- a pad's inset, a stack child, a scroll's
content -- and a span passes its own extent along the row.

`widget_decided` becomes `widget_at`, which says both things about an ask
rather than one of them; `widget_within` is still the sugar for neither.

Two spans asking for half each now take the whole row between them and a
third overflows, which the rewritten
`a_span_reads_a_child_report_as_a_fraction_of_the_row` states outright.
The five reference renders are byte-identical at 1920x1200 and `random`
live-resized still matches a cold render, so nothing that exists reports a
fraction to a span today.
This commit is contained in:
iris-ai committed 2026-09-17 02:56:51 -04:00
1 parent 0e0d4af326
commit ffd79f32d3
6 files changed
+102 -46

No files matched your search

+14 -3
View File
@@ -20,9 +20,15 @@ impl Widget for Span {
span.flip();
}
let region = UiRegion::from_axis(axis, span, UiSpan::FULL);
let len = match painter.known_len(child, axis, region) {
// Offered the room left from the cursor, because a text has to
// wrap at the width actually there, but reporting a fraction of
// the whole row: `rel(0.5)` is half the span whatever else is in
// it and wherever this child sits among them.
let len = match painter.known_len(child, axis, region, UiVec2::FULL_SIZE) {
Some(len) => len,
None => painter.widget_within(child, region).len(axis),
None => painter
.widget_at(child, region, UiVec2::FULL_SIZE, [false; 2])
.len(axis),
};
cursor.px += len.px + self.gap;
cursor.rel += len.rel;
@@ -122,7 +128,12 @@ impl Widget for Span {
// Along the row this box is the child's own answer, so the answer
// is not placed in it again; across it the child sits where its
// alignment says.
let placed = painter.widget_decided(child, region, [axis == Axis::X, axis == Axis::Y]);
let placed = painter.widget_at(
child,
region,
UiVec2::FULL_SIZE,
[axis == Axis::X, axis == Axis::Y],
);
if shrinks {
let used = placed.len(!axis);
// Choosing between a fixed and a relative length from the