Carry a length as a rule beside a widget, not a widget around it
`.width()` built a `SetSize` whose whole job was to answer `size_hint`, so every declared length cost a widget, an `ActiveData` and a link of chain to say one number. It is now a `SizeRule` per axis on `WidgetData`, beside `region_node`, resolved by `Painter` where the widget is drawn. `SetSize` and `MaxSize` are gone; `MaxSize` had no caller but its own builders. That settles which of two answers is the size. A rule wins on the axis it names and the `Size` returned by `draw` answers the rest, applied once in `draw_inner` rather than by each widget that could carry one -- so the widget under a rule never learns of it. `Painter::size_hint` reads the rule first for the same reason: a rule that beats what a widget would draw has to beat what it says about itself. `declared_lens` still falls back to a non-leftover `size_hint`, which is how an image or a gap gets its own pixel size rather than the whole offer. That is the offer's business rather than a declaration's, and it falls away when a widget occupies its reported size inside the box it was offered. `known` and `declared` are separate because a share is a length to whoever divides one and not to whoever composes a box: `.width(leftover(3))` is known without drawing but cannot narrow anything. Checked: fmt, clippy, 85 tests, and 100 generated seeds agreeing warm against cold in 67.6 s. `minimal`, `text` and `view` render byte-identical at 1920x1200; `tabs` differs only in the widget count it prints about itself, which is two wrapper types smaller.
This commit is contained in:
1 parent
0283c9d6c7
commit
8220a78d4a
21 files changed
+252
-214
No files matched your search
+4
-4
@@ -236,7 +236,7 @@ fn a_parent_that_only_read_a_hint_relays_out_when_the_hint_changes() {
|
||||
h.set_root(parent);
|
||||
assert_corners!(h, inner, (0, 0), (400, 80));
|
||||
|
||||
h.rsc[inner].y = Some(Len::px(120));
|
||||
h.set_len(inner, Axis::Y, 120);
|
||||
h.frame();
|
||||
|
||||
assert_corners!(h, inner, (0, 0), (400, 120));
|
||||
@@ -484,7 +484,7 @@ fn stretching_a_subtree_carries_the_children_in_it() {
|
||||
let settled = draws.get();
|
||||
assert_corners!(h, inner, (0, 40), (400, 400));
|
||||
|
||||
h.rsc[first].y = Some(Len::px(80));
|
||||
h.set_len(first, Axis::Y, 80);
|
||||
h.frame();
|
||||
|
||||
assert_eq!(
|
||||
@@ -508,7 +508,7 @@ fn a_widened_row_redraws_what_reads_its_length_and_nothing_else() {
|
||||
h.set_root((bar, row).span(Dir::RIGHT));
|
||||
let (settled_wrap, settled_back) = (wrap_draws.get(), back_draws.get());
|
||||
|
||||
h.rsc[bar].x = Some(Len::px(200));
|
||||
h.set_len(bar, Axis::X, 200);
|
||||
h.frame();
|
||||
|
||||
// The span reads every child's size, so redrawing one takes the span
|
||||
@@ -534,7 +534,7 @@ fn a_declared_length_child_is_not_redrawn_when_the_box_around_it_grows() {
|
||||
h.set_root((bar, row).span(Dir::RIGHT));
|
||||
let settled = draws.get();
|
||||
|
||||
h.rsc[bar].x = Some(Len::px(200));
|
||||
h.set_len(bar, Axis::X, 200);
|
||||
h.frame();
|
||||
|
||||
assert_eq!(draws.get(), settled, "its own length did not change");
|
||||
|
||||
Reference in new issue
Block a user