One argument says where a child goes and what its fractions are of

`Place` was a product written as a sum -- a `Part` and a fill flag -- and
`Part` named three operations the geometry already had, under words that did
not match them. `Of` was `UiSpan::within`, `From` was `UiSpan::shift`, and
`Sized` was `placement`'s own body with the length given rather than
reported. Both enums are gone.

`PlaceDescAxis` says one axis, named after the operation it performs:
`within`, `shifted`, `sized`, and `WHOLE`. What is optional is a builder --
`fills` and `rel_base` -- so a caller writes only what it decided, and the
rel base it does not write follows the constructor: a span composed into the
caller's box narrows it, a span along a cursor does not, a decided length is
it. That was the one rule a caller could get wrong with nothing failing.

`PlaceDesc` says both axes with named fields, so `axis`, `axis_mut` and
`from_axis` work the way they do on every other pair here, and the joint
work -- resolving a region, reading the fill flags -- is written once rather
than per axis. `widget_at` and `place_at` take `impl Into<PlaceDesc>`, so a
wrapper passes a `UiRegion` and says nothing else. `widget_within` and
`ActiveData::narrow_rel_base` are deleted; `asked` and `placed` carry the
rel base their ask stated.

Cold layout is byte-identical to `84dad21`.
This commit is contained in:
iris-ai committed 2026-09-19 17:59:26 -04:00
1 parent c55be21761
commit 58ce74dd7d
12 files changed
+367 -271

No files matched your search

+6 -6
View File
@@ -22,17 +22,17 @@ struct BranchesOnMeasurement {
impl Widget for BranchesOnMeasurement {
fn draw(&mut self, painter: &mut Painter) -> Size {
let cut = Len::from_parts(Rel::ZERO, Px::from_int(40));
let top = Place::Within(Part::From(UiSpan::new(Len::ZERO, cut)));
let top = PlaceDescAxis::shifted(UiSpan::new(Len::ZERO, cut));
let measured = painter
.widget_at(&self.probe, [Place::Within(Part::WHOLE), top], None)
.widget_at(&self.probe, PlaceDesc::new(PlaceDescAxis::WHOLE, top))
.len(Axis::X);
let px = painter.to_px(measured.apply_leftover(), Axis::X);
let below = Place::Within(Part::From(UiSpan::new(cut, painter.region_len(Axis::Y))));
let place = [Place::Within(Part::WHOLE), below];
let below = PlaceDescAxis::shifted(UiSpan::new(cut, painter.region_len(Axis::Y)));
let place = PlaceDesc::new(PlaceDescAxis::WHOLE, below);
match px > Px::from_f32(self.threshold) {
true => painter.widget_at(&self.wide, place, None),
false => painter.widget_at(&self.narrow, place, None),
true => painter.widget_at(&self.wide, place),
false => painter.widget_at(&self.narrow, place),
};
Size::LEFTOVER
}
+28 -33
View File
@@ -216,8 +216,7 @@ impl Widget for FromHint {
let top = UiSpan::new(Len::ZERO, Len::from_parts(Rel::ZERO, len.px));
painter.widget_at(
&self.inner,
[Place::Within(Part::WHOLE), Place::Within(Part::From(top))],
None,
PlaceDesc::new(PlaceDescAxis::WHOLE, PlaceDescAxis::shifted(top)),
);
Size::LEFTOVER
}
@@ -877,11 +876,10 @@ fn resizing_a_fixed_frame_recomposes_its_contents_without_drawing_them() {
fn draw(&mut self, painter: &mut Painter) -> Size {
painter.widget_at(
&self.child,
[
Place::Within(Part::From(self.region.x)),
Place::Within(Part::From(self.region.y)),
],
None,
PlaceDesc::new(
PlaceDescAxis::shifted(self.region.x),
PlaceDescAxis::shifted(self.region.y),
),
);
Size::LEFTOVER
}
@@ -966,11 +964,11 @@ fn glyph_origins_compose_identically_when_drawn_and_when_retained() {
fn draw(&mut self, painter: &mut Painter) -> Size {
painter.widget_at(
&self.child,
[
Place::Fill(Part::From(self.region.x)),
Place::Fill(Part::From(self.region.y)),
],
[Some(self.frame.x.len()), None],
PlaceDesc::new(
PlaceDescAxis::shifted(self.region.x).fills(),
PlaceDescAxis::shifted(self.region.y).fills(),
)
.rel_base(Axis::X, self.frame.x.len()),
);
Size::LEFTOVER
}
@@ -1136,11 +1134,10 @@ fn padding_and_stack_boxes_follow_the_region_without_drawing_again() {
fn draw(&mut self, painter: &mut Painter) -> Size {
painter.widget_at(
&self.child,
[
Place::Fill(Part::From(self.region.x)),
Place::Fill(Part::From(self.region.y)),
],
None,
PlaceDesc::new(
PlaceDescAxis::shifted(self.region.x).fills(),
PlaceDescAxis::shifted(self.region.y).fills(),
),
);
Size::LEFTOVER
}
@@ -1224,14 +1221,14 @@ fn moving_a_childs_region_preserves_the_slot_chosen_from_its_measurement() {
fn draw(&mut self, painter: &mut Painter) -> Size {
painter.widget_at(
&self.child,
[
Place::Fill(Part::From(UiSpan::new(
PlaceDesc::new(
PlaceDescAxis::shifted(UiSpan::new(
Len::px(self.start),
Len::px(self.start + 200.0),
))),
Place::Fill(Part::From(UiSpan::FULL)),
],
None,
))
.fills(),
PlaceDescAxis::shifted(UiSpan::FULL).fills(),
),
);
Size::LEFTOVER
}
@@ -1266,11 +1263,10 @@ fn changing_regions_keep_fractional_reports_and_numeric_dependencies_valid() {
painter
.widget_at(
&self.child,
[
Place::Within(Part::From(self.region.x)),
Place::Within(Part::From(self.region.y)),
],
None,
PlaceDesc::new(
PlaceDescAxis::shifted(self.region.x),
PlaceDescAxis::shifted(self.region.y),
),
)
.size()
}
@@ -1286,11 +1282,10 @@ fn changing_regions_keep_fractional_reports_and_numeric_dependencies_valid() {
painter
.widget_at(
&self.child,
[
Place::Fill(Part::From(self.region.x)),
Place::Fill(Part::From(self.region.y)),
],
None,
PlaceDesc::new(
PlaceDescAxis::shifted(self.region.x).fills(),
PlaceDescAxis::shifted(self.region.y).fills(),
),
)
.size(),
);