Say rel base, and give containers back a box to hand over

`frame` named a length, not a rectangle, which was the one word in the
layout vocabulary that lied about its own shape. It is `rel_base`: what a
fraction a widget declares or reports is a fraction of.

Three API changes with it, all for containers that do one simple thing:

- `widget_within(id, region)` returns, taking a box in the widget's own
  coordinates and deriving the child's rel base from it. `Offset` and `Pad`
  are one call each again. `Offset` also stops reading `region_len`, which
  pinned its drawing to a box length it does not care about.
- `place_at` takes the rel base, returns the answer, and asks the child
  where there is no answer to re-express. Which of the two happens is the
  painter's to work out, so `Span`'s second pass is one call and its
  `drawn_across` bookkeeping is gone.
- `Part::All` is a `Part::WHOLE` constant rather than a variant, since it
  was exactly `Of(UiSpan::FULL)` and bought a separate arm in two matches.
  Measured at 0.07% of instructions retired against 0.04% run-to-run noise.

Cold layout is byte-identical to `84dad21` over 400 depth-5 trees.
This commit is contained in:
iris-ai committed 2026-09-19 16:33:49 -04:00
1 parent a904cf4f36
commit aeb60e50f5
16 files changed
+246 -238

No files matched your search

+6 -5
View File
@@ -3,14 +3,12 @@ use crate::{AxisAlign, Len, PrimitiveHandle, UiRegion, UiSpan};
/// What of a widget's own box a child is given, along one axis.
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Part {
/// The whole of it.
All,
/// Window lengths from where the box starts, which is what a container
/// dividing room among its children speaks: a child's report is a window
/// length, so the cursor that sums those reports is one too. A moved box
/// re-places every child by re-adding its start, exactly. A fraction
/// here is a fraction of the window and not of the box -- the whole of a
/// box is [`Self::All`], not a `rel(1.0)` span.
/// box is `Of(UiSpan::FULL)`, not a `rel(1.0)` span.
From(UiSpan),
/// A part of the box in its own coordinates, which is what a container
/// that insets one speaks: taking eleven pixels off the end needs no
@@ -19,7 +17,7 @@ pub enum Part {
/// then feeds back into the answer.
Of(UiSpan),
/// A box of this length, wherever in the parent's box the child's own
/// alignment puts it, and that same length as its frame. Unlike `From`,
/// alignment puts it, and that same length as its rel base. Unlike `From`,
/// it is a length decided from above rather than a place along a
/// container's cursor -- what a stack's sizing child decides for the
/// rest.
@@ -27,10 +25,13 @@ pub enum Part {
}
impl Part {
/// The whole of the box. Not a variant of its own: it composes and
/// inverts through the same expressions every other `Of` does.
pub const WHOLE: Self = Self::Of(UiSpan::FULL);
/// Where it lands in the coordinates `own` is in.
pub(crate) fn of(self, own: UiSpan, align: AxisAlign) -> UiSpan {
match self {
Self::All => own,
Self::From(span) => UiSpan::new(own.start + span.start, own.start + span.end),
Self::Of(span) => span.within(&own),
Self::Sized(len) => {