From a8898aaa5496753bbc8981f104222778282ff90e Mon Sep 17 00:00:00 2001 From: iris-ai <4+iris-ai@noreply.localhost> Date: Wed, 16 Sep 2026 13:40:15 -0400 Subject: [PATCH] Give a length with no share in it its own type again `UiScalar` was `Len` without the `leftover` weight, which is the separation canonical `main` already had as `Len` beside `LayoutLen` and this branch collapsed. It is needed back for the queued clamp: a cap may not contain a share, because a cap has to read the report a rule otherwise makes moot, and a share puts the container's division into the same equation -- two self-consistent assignments, which is the multiple-fixed-point failure generated seed 13 punished for orthogonal sizing. `min(report, cap)` is not a `LayoutLen` either: it is a sum of parts, and the smaller of two of them is not one. So `UiScalar` is `Len`, what was `Len` is `LayoutLen`, and the two say in their docs which is which: a `Len` is pixels plus a fraction of a box -- a position being the length from the box's start, which is why a span is two of them -- and a `LayoutLen` is a `Len` plus a claim only a container dividing its room can answer. `From for LayoutLen` is the one-way step between them. Names only; the shader's `UiScalar` is renamed with them. Checked: fmt, clippy, 105 tests, and `tabs`, `minimal`, `view`, `text` and `random` byte-identical at 1920x1200. Co-Authored-By: Claude Opus 5 --- core/src/layout_diagnostics.rs | 6 +- core/src/orientation/align.rs | 12 ++-- core/src/orientation/len.rs | 91 +++++++++++++++++------------ core/src/orientation/pos.rs | 80 +++++++++++++------------ core/src/render/shader/prelude.wgsl | 20 +++---- core/src/ui/active.rs | 4 +- core/src/ui/holds.rs | 8 +-- core/src/ui/painter.rs | 22 +++---- core/src/ui/render_state.rs | 28 ++++----- core/src/widget/mod.rs | 8 +-- core/src/widget/size_rule.rs | 18 +++--- src/harness.rs | 2 +- src/random.rs | 10 ++-- src/widget/image.rs | 4 +- src/widget/position/pad.rs | 4 +- src/widget/position/scroll.rs | 4 +- src/widget/position/span.rs | 22 +++---- src/widget/rect.rs | 4 +- src/widget/trait_fns.rs | 4 +- tests/cases/layout.rs | 10 ++-- tests/cases/retained.rs | 11 ++-- tests/cases/unsettled.rs | 10 ++-- tests/chain_cost.rs | 6 +- tests/generated.rs | 4 +- tests/layout_diagnostics.rs | 2 +- tests/revision_cost.rs | 6 +- tests/shrink.rs | 20 +++---- 27 files changed, 218 insertions(+), 202 deletions(-) diff --git a/core/src/layout_diagnostics.rs b/core/src/layout_diagnostics.rs index 5886307..3e9e0e6 100644 --- a/core/src/layout_diagnostics.rs +++ b/core/src/layout_diagnostics.rs @@ -15,7 +15,7 @@ //! reuse, size, placement, and text events for one suspicious widget. The //! selection is a set and survives [`take`] until cleared. -use crate::{Axis, Len, PxVec2, Size, UiRegion, WidgetId}; +use crate::{Axis, LayoutLen, PxVec2, Size, UiRegion, WidgetId}; use std::{ cell::RefCell, collections::{HashMap, HashSet}, @@ -287,7 +287,7 @@ pub enum TraceEvent { id: WidgetId, reader: WidgetId, axis: Axis, - hint: Option, + hint: Option, }, TextRendered { id: WidgetId, @@ -389,7 +389,7 @@ pub(crate) fn size_read(id: WidgetId, reader: WidgetId, size: Size) { trace(id, TraceEvent::SizeRead { id, reader, size }); } -pub(crate) fn hint_read(id: WidgetId, reader: WidgetId, axis: Axis, hint: Option) { +pub(crate) fn hint_read(id: WidgetId, reader: WidgetId, axis: Axis, hint: Option) { trace( id, TraceEvent::HintRead { diff --git a/core/src/orientation/align.rs b/core/src/orientation/align.rs index d2e873b..c611cde 100644 --- a/core/src/orientation/align.rs +++ b/core/src/orientation/align.rs @@ -172,14 +172,14 @@ impl Vec2 { } } -impl UiScalar { +impl Len { pub const fn align(&self, align: AxisAlign) -> UiSpan { let rel = align.rel(); let rest = Rel::ONE.sub(rel); - let at = UiScalar::from_parts(rel, Px::ZERO); + let at = Len::from_parts(rel, Px::ZERO); UiSpan { - start: UiScalar::from_parts(at.rel.sub(self.rel.mul(rel)), at.px.sub(self.px.mul(rel))), - end: UiScalar::from_parts(at.rel.add(self.rel.mul(rest)), at.px.add(self.px.mul(rest))), + start: Len::from_parts(at.rel.sub(self.rel.mul(rel)), at.px.sub(self.px.mul(rel))), + end: Len::from_parts(at.rel.add(self.rel.mul(rest)), at.px.add(self.px.mul(rest))), } } } @@ -221,8 +221,8 @@ impl From for Align { const impl From for UiVec2 { fn from(align: RegionAlign) -> Self { Self::new( - UiScalar::from_parts(align.x.rel(), Px::ZERO), - UiScalar::from_parts(align.y.rel(), Px::ZERO), + Len::from_parts(align.x.rel(), Px::ZERO), + Len::from_parts(align.y.rel(), Px::ZERO), ) } } diff --git a/core/src/orientation/len.rs b/core/src/orientation/len.rs index 72b1b5e..fd58850 100644 --- a/core/src/orientation/len.rs +++ b/core/src/orientation/len.rs @@ -3,23 +3,28 @@ use crate::{Px, PxVec2, Rel, UiNum, Weight, util::impl_op}; #[derive(Debug, Default, Clone, Copy, PartialEq)] pub struct Size { - pub x: Len, - pub y: Len, + pub x: LayoutLen, + pub y: LayoutLen, } -/// What a widget asks for along one axis: pixels, a fraction of the box it -/// is given, and a share of whatever is left over once everything fixed has -/// been taken. The three add up rather than choosing between one another. +/// What a widget asks for along one axis: a [`Len`] -- pixels and a fraction +/// of the box it is given -- plus a share of whatever is left over once +/// everything fixed has been taken. The parts add up rather than choosing +/// between one another. +/// +/// Only a container dividing its room can answer a share, so a length nobody +/// divides is a `Len`: a position, a padding, a cap, anything already +/// resolved. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct Len { +pub struct LayoutLen { pub px: Px, pub rel: Rel, pub leftover: Weight, } -impl From for Len { +impl From for LayoutLen { fn from(value: N) -> Self { - Len::px(value.to_f32()) + LayoutLen::px(value.to_f32()) } } @@ -32,21 +37,33 @@ impl From<(Nx, Ny)> for Size { } } -impl From for Size { - fn from(value: Len) -> Self { +/// A length with no share in it is a length a container does not have to +/// divide, which is one it can always give. +impl From for LayoutLen { + fn from(len: Len) -> Self { + Self { + px: len.px, + rel: len.rel, + leftover: Weight::ZERO, + } + } +} + +impl From for Size { + fn from(value: LayoutLen) -> Self { Self { x: value, y: value } } } impl Size { pub const ZERO: Self = Self { - x: Len::ZERO, - y: Len::ZERO, + x: LayoutLen::ZERO, + y: LayoutLen::ZERO, }; pub const LEFTOVER: Self = Self { - x: Len::LEFTOVER, - y: Len::LEFTOVER, + x: LayoutLen::LEFTOVER, + y: LayoutLen::LEFTOVER, }; /// From something measured outside layout -- a texture, a shaped line -- @@ -57,28 +74,28 @@ impl Size { pub const fn from_px(v: PxVec2) -> Self { Self { - x: Len { + x: LayoutLen { px: v.x, - ..Len::ZERO + ..LayoutLen::ZERO }, - y: Len { + y: LayoutLen { px: v.y, - ..Len::ZERO + ..LayoutLen::ZERO }, } } pub fn rel(v: Vec2) -> Self { Self { - x: Len::rel(v.x), - y: Len::rel(v.y), + x: LayoutLen::rel(v.x), + y: LayoutLen::rel(v.y), } } pub fn leftover(v: Vec2) -> Self { Self { - x: Len::leftover(v.x), - y: Len::leftover(v.y), + x: LayoutLen::leftover(v.x), + y: LayoutLen::leftover(v.y), } } @@ -89,7 +106,7 @@ impl Size { } } - pub fn from_axis(axis: Axis, aligned: Len, ortho: Len) -> Self { + pub fn from_axis(axis: Axis, aligned: LayoutLen, ortho: LayoutLen) -> Self { match axis { Axis::X => Self { x: aligned, @@ -102,7 +119,7 @@ impl Size { } } - pub fn axis(&self, axis: Axis) -> Len { + pub fn axis(&self, axis: Axis) -> LayoutLen { match axis { Axis::X => self.x, Axis::Y => self.y, @@ -110,7 +127,7 @@ impl Size { } } -impl Len { +impl LayoutLen { pub const ZERO: Self = Self { px: Px::ZERO, rel: Rel::ZERO, @@ -126,12 +143,12 @@ impl Len { /// The whole of what is left over counts as the whole box, which is what /// a length means to something that is not dividing a box between /// siblings -- a scroll asking how long its content is. - pub fn apply_leftover(&self) -> UiScalar { + pub fn apply_leftover(&self) -> Len { let share = match self.leftover > Weight::ZERO { true => Rel::ONE, false => Rel::ZERO, }; - UiScalar::from_parts(self.rel.add(share), self.px) + Len::from_parts(self.rel.add(share), self.px) } pub fn px(px: impl UiNum) -> Self { @@ -157,24 +174,24 @@ impl Len { pub mod len_fns { use super::*; - pub fn px(px: impl UiNum) -> Len { - Len::px(px) + pub fn px(px: impl UiNum) -> LayoutLen { + LayoutLen::px(px) } - pub fn rel(rel: impl UiNum) -> Len { - Len::rel(rel) + pub fn rel(rel: impl UiNum) -> LayoutLen { + LayoutLen::rel(rel) } - pub fn leftover(ratio: impl UiNum) -> Len { - Len::leftover(ratio) + pub fn leftover(ratio: impl UiNum) -> LayoutLen { + LayoutLen::leftover(ratio) } } -impl_op!(same Len Add add; px rel leftover); -impl_op!(same Len Sub sub; px rel leftover); +impl_op!(same LayoutLen Add add; px rel leftover); +impl_op!(same LayoutLen Sub sub; px rel leftover); impl_op!(same Size Add add; x y); impl_op!(same Size Sub sub; x y); -impl Default for Len { +impl Default for LayoutLen { fn default() -> Self { Self::leftover(1.0) } @@ -186,7 +203,7 @@ impl std::fmt::Display for Size { } } -impl std::fmt::Display for Len { +impl std::fmt::Display for LayoutLen { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { if self.px != Px::ZERO { write!(f, "{} px;", self.px)?; diff --git a/core/src/orientation/pos.rs b/core/src/orientation/pos.rs index e9afd75..566274b 100644 --- a/core/src/orientation/pos.rs +++ b/core/src/orientation/pos.rs @@ -6,41 +6,41 @@ use crate::{Px, PxVec2, Rel, UiNum, util::impl_op}; #[repr(C)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, bytemuck::Pod, bytemuck::Zeroable, Default)] pub struct UiVec2 { - pub x: UiScalar, - pub y: UiScalar, + pub x: Len, + pub y: Len, } impl UiVec2 { pub const ZERO: Self = Self { - x: UiScalar::ZERO, - y: UiScalar::ZERO, + x: Len::ZERO, + y: Len::ZERO, }; - pub const fn new(x: UiScalar, y: UiScalar) -> Self { + pub const fn new(x: Len, y: Len) -> Self { Self { x, y } } pub const fn px(px: impl const Into) -> Self { let px = px.into(); Self { - x: UiScalar::px(px.x), - y: UiScalar::px(px.y), + x: Len::px(px.x), + y: Len::px(px.y), } } /// From lengths already on the grid, with no fraction of a box. pub const fn from_px(px: PxVec2) -> Self { Self { - x: UiScalar::from_parts(Rel::ZERO, px.x), - y: UiScalar::from_parts(Rel::ZERO, px.y), + x: Len::from_parts(Rel::ZERO, px.x), + y: Len::from_parts(Rel::ZERO, px.y), } } pub const fn rel(rel: impl const Into) -> Self { let rel = rel.into(); Self { - x: UiScalar::rel(rel.x), - y: UiScalar::rel(rel.y), + x: Len::rel(rel.x), + y: Len::rel(rel.y), } } @@ -61,14 +61,14 @@ impl UiVec2 { } } - pub fn axis_mut(&mut self, axis: Axis) -> &mut UiScalar { + pub fn axis_mut(&mut self, axis: Axis) -> &mut Len { match axis { Axis::X => &mut self.x, Axis::Y => &mut self.y, } } - pub fn axis(&self, axis: Axis) -> UiScalar { + pub fn axis(&self, axis: Axis) -> Len { match axis { Axis::X => self.x, Axis::Y => self.y, @@ -83,7 +83,7 @@ impl UiVec2 { pub const FULL_SIZE: Self = Self::rel(Vec2::ONE); - pub const fn from_axis(axis: Axis, aligned: UiScalar, ortho: UiScalar) -> Self { + pub const fn from_axis(axis: Axis, aligned: Len, ortho: Len) -> Self { match axis { Axis::X => Self { x: aligned, @@ -129,21 +129,27 @@ where } } -/// A position along one axis, as a fraction of the box it sits in plus an -/// offset: `rel * len + px`. Both parts are fixed point, so composing one -/// through a chain of boxes rounds only where it multiplies and lands on the -/// same number as any other route to the same place. +/// A length along one axis: a fraction of the box it is measured in plus an +/// offset, `rel * box + px`. A position is the same number -- the length from +/// the start of the box to the point -- which is why a [`UiSpan`] is two of +/// these. Both parts are fixed point, so composing one through a chain of +/// boxes rounds only where it multiplies, and lands on the same number as any +/// other route to the same place. +/// +/// It carries no claim on what a container has left over. That is +/// [`crate::LayoutLen`], which is this plus a weight, and which means nothing +/// to anyone but whoever divides the room. #[repr(C)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, bytemuck::Pod, Default, bytemuck::Zeroable)] -pub struct UiScalar { +pub struct Len { pub rel: Rel, pub px: Px, } -impl_op!(same UiScalar Add add; rel px); -impl_op!(same UiScalar Sub sub; rel px); +impl_op!(same Len Add add; rel px); +impl_op!(same Len Sub sub; rel px); -impl UiScalar { +impl Len { pub const ZERO: Self = Self { rel: Rel::ZERO, px: Px::ZERO, @@ -192,10 +198,8 @@ impl UiScalar { } } - /// Both channels by the same factor, which is what a fraction of a - /// length means when the length is part pixels and part a share. - /// Both channels by the same fraction, which is what a part of a length - /// means when the length is part pixels and part a share. + /// Both parts by the same fraction, which is what a part of a length + /// means when the length is part pixels and part a fraction of a box. pub const fn scale(&self, by: Rel) -> Self { Self { rel: self.rel.mul(by), @@ -215,14 +219,14 @@ impl UiScalar { } } - pub fn within_len(&self, len: UiScalar) -> Self { + pub fn within_len(&self, len: Len) -> Self { self.within(&UiSpan { - start: UiScalar::ZERO, + start: Len::ZERO, end: len, }) } - pub fn select_len(&self, len: UiScalar) -> Self { + pub fn select_len(&self, len: Len) -> Self { len.within_len(*self) } @@ -245,24 +249,24 @@ impl UiScalar { #[repr(C)] #[derive(Debug, Copy, Clone, PartialEq, bytemuck::Pod, bytemuck::Zeroable)] pub struct UiSpan { - pub start: UiScalar, - pub end: UiScalar, + pub start: Len, + pub end: Len, } impl UiSpan { pub const FULL: Self = Self { - start: UiScalar::ZERO, - end: UiScalar::FULL, + start: Len::ZERO, + end: Len::FULL, }; pub const fn rel(rel: f32) -> Self { Self { - start: UiScalar::rel(rel), - end: UiScalar::rel(rel), + start: Len::rel(rel), + end: Len::rel(rel), } } - pub const fn new(start: UiScalar, end: UiScalar) -> Self { + pub const fn new(start: Len, end: Len) -> Self { Self { start, end } } @@ -273,7 +277,7 @@ impl UiSpan { std::mem::swap(&mut self.start.px, &mut self.end.px); } - pub const fn shift(&mut self, offset: UiScalar) { + pub const fn shift(&mut self, offset: Len) { self.start += offset; self.end += offset; } @@ -285,7 +289,7 @@ impl UiSpan { } } - pub const fn len(&self) -> UiScalar { + pub const fn len(&self) -> Len { self.end - self.start } } diff --git a/core/src/render/shader/prelude.wgsl b/core/src/render/shader/prelude.wgsl index 413eb47..30e80e0 100644 --- a/core/src/render/shader/prelude.wgsl +++ b/core/src/render/shader/prelude.wgsl @@ -49,16 +49,16 @@ struct RawSpan { end: RawScalar, } -fn scalar_of(raw: RawScalar) -> UiScalar { - return UiScalar(f32(raw.rel) * REL_STEP, f32(raw.px) * PX_STEP); +fn scalar_of(raw: RawScalar) -> Len { + return Len(f32(raw.rel) * REL_STEP, f32(raw.px) * PX_STEP); } fn span_of(raw: RawSpan) -> UiSpan { return UiSpan(scalar_of(raw.start), scalar_of(raw.end)); } -fn scalar_of_pair(raw: vec2) -> UiScalar { - return UiScalar(f32(raw.x) * REL_STEP, f32(raw.y) * PX_STEP); +fn scalar_of_pair(raw: vec2) -> Len { + return Len(f32(raw.x) * REL_STEP, f32(raw.y) * PX_STEP); } struct Region { @@ -72,12 +72,12 @@ const MOVE_NONE: u32 = 4294967295u; // resolve a deep one the same way. const CHAIN_LIMIT: u32 = 64u; -// The same expression `UiScalar::within` uses, in floats rather than on the +// The same expression `Len::within` uses, in floats rather than on the // CPU's grid: a move is resolved here so that scrolling a subtree writes one // entry instead of walking it. What has to hold is that this agrees with // itself frame to frame, not that it matches the CPU to the last bit. -fn scalar_within(s: UiScalar, p: UiSpan) -> UiScalar { - return UiScalar( +fn scalar_within(s: Len, p: UiSpan) -> Len { + return Len( p.start.rel + (p.end.rel - p.start.rel) * s.rel, s.px + (p.start.px + (p.end.px - p.start.px) * s.rel), ); @@ -102,11 +102,11 @@ fn resolve_move(idx: u32, local: Region) -> Region { } struct UiSpan { - start: UiScalar, - end: UiScalar, + start: Len, + end: Len, } -struct UiScalar { +struct Len { rel: f32, px: f32, } diff --git a/core/src/ui/active.rs b/core/src/ui/active.rs index 9da0a0b..3f09791 100644 --- a/core/src/ui/active.rs +++ b/core/src/ui/active.rs @@ -1,5 +1,5 @@ use crate::{ - Holds, LayerId, Len, MaskIdx, MoveIdx, PrimitiveHandle, RegionAlign, Size, TextureHandle, + Holds, LayerId, LayoutLen, MaskIdx, MoveIdx, PrimitiveHandle, RegionAlign, Size, TextureHandle, UiRegion, WidgetId, }; @@ -40,7 +40,7 @@ pub struct ActiveData { /// The declared lengths whoever drew this widget resolved into its box. /// A change to one moves a box this widget cannot fix by drawing again, /// and comparing them is what says so. - pub declared: [Option; 2], + pub declared: [Option; 2], /// The alignment its parent asked it with. A local redraw repeats that /// question, including an override chosen by a container. pub align: RegionAlign, diff --git a/core/src/ui/holds.rs b/core/src/ui/holds.rs index 975bc8b..25e142c 100644 --- a/core/src/ui/holds.rs +++ b/core/src/ui/holds.rs @@ -1,4 +1,4 @@ -use crate::{Px, REL_SHIFT, UiScalar, fixed::div_toward, fixed::narrow}; +use crate::{Len, Px, REL_SHIFT, fixed::div_toward, fixed::narrow}; use std::ops::RangeInclusive; /// The lengths of a box, in pixels, that one drawing of a widget holds for: @@ -50,7 +50,7 @@ impl Holds { /// the length alone instead gives a point that need not even contain the /// box the part was drawn in, which is a range excluding the drawing it /// was made for. - pub const fn through(self, len: UiScalar) -> Self { + pub const fn through(self, len: Len) -> Self { let rel = len.rel.raw() as i64; if rel == 0 { return Self::ANY; @@ -98,7 +98,7 @@ mod tests { #[test] fn through_reverses_a_range_for_a_negative_fraction() { // `10 - box / 2` is between 20 and 40 for boxes from -60 to -20. - let part = UiScalar::from_parts(Rel::from_f32(-0.5), Px::from_int(10)); + let part = Len::from_parts(Rel::from_f32(-0.5), Px::from_int(10)); let holds = Holds::from(Px::from_int(20)..=Px::from_int(40)).through(part); assert!(holds.contains(Px::from_int(-60)) && holds.contains(Px::from_int(-20))); assert!(!holds.contains(Px::from_int(-61)) && !holds.contains(Px::from_int(-19))); @@ -109,7 +109,7 @@ mod tests { /// box is not a whole number of steps. #[test] fn a_part_maps_back_onto_the_box_it_was_measured_in() { - let part = UiScalar::from_parts(Rel::from_f32(1.0 / 3.0), Px::from_int(-146)); + let part = Len::from_parts(Rel::from_f32(1.0 / 3.0), Px::from_int(-146)); for box_len in (440..460).map(Px::from_int) { let holds = Holds::at(part.to_px(box_len)).through(part); assert!(holds.contains(box_len), "{box_len:?} left out by {holds:?}"); diff --git a/core/src/ui/painter.rs b/core/src/ui/painter.rs index 9df8484..d4d7518 100644 --- a/core/src/ui/painter.rs +++ b/core/src/ui/painter.rs @@ -1,8 +1,8 @@ #[cfg(feature = "layout-diagnostics")] use crate::layout_diagnostics::{self as diag, Counter}; use crate::{ - Axis, Holds, Len, Px, PxVec2, RegionAlign, Rel, RenderedText, Size, StrongWidget, TextAttrs, - TextBuffer, TextData, TextureHandle, UiRegion, UiRenderState, UiRsc, UiScalar, UiVec2, Weight, + Axis, Holds, LayoutLen, Len, Px, PxVec2, RegionAlign, Rel, RenderedText, Size, StrongWidget, + TextAttrs, TextBuffer, TextData, TextureHandle, UiRegion, UiRenderState, UiRsc, UiVec2, Weight, WidgetId, Widgets, render::{ GlyphPrimitive, Mask, MaskIdx, MoveIdx, Primitive, PrimitiveHandle, PrimitiveInst, @@ -109,7 +109,7 @@ impl<'a> Painter<'a> { /// it resolves into its box. Reading them depends on nothing -- the box /// that comes of them is kept on the child, and `redraw` compares it /// there. - fn declared_lens(&self, id: &StrongWidget) -> [Option; 2] { + fn declared_lens(&self, id: &StrongWidget) -> [Option; 2] { declared_lens(self.rsc.widgets(), id.id()) } @@ -218,7 +218,7 @@ impl<'a> Painter<'a> { /// What a child says its length is without being drawn, if it can say. /// Asking counts as reading its size. - pub fn size_hint(&mut self, id: &StrongWidget, axis: Axis) -> Option { + pub fn size_hint(&mut self, id: &StrongWidget, axis: Axis) -> Option { let widgets = self.rsc.widgets(); // A rule is the answer where there is one: it wins over whatever the // widget would draw, so it has to win over what the widget says too. @@ -252,7 +252,7 @@ impl<'a> Painter<'a> { child: &StrongWidget, axis: Axis, region: UiRegion, - ) -> Option { + ) -> Option { let declared = self.declared_lens(child); let align = self.rsc.widgets().alignment(child.id()); let local = declared_box(region, declared, align); @@ -472,7 +472,7 @@ impl DrawResult<'_, '_, W> { self.size } - pub fn len(self, axis: Axis) -> Len { + pub fn len(self, axis: Axis) -> LayoutLen { self.size().axis(axis) } } @@ -505,7 +505,7 @@ impl PrimitiveLike for &TextureHandle { /// What a widget declares a length of its box to be. `leftover` is not one: a /// share of what is left over is only a length to the widget dividing one, /// so it passes up in the size instead. -pub(crate) fn declared_lens(widgets: &Widgets, id: WidgetId) -> [Option; 2] { +pub(crate) fn declared_lens(widgets: &Widgets, id: WidgetId) -> [Option; 2] { let rules = widgets.size_rules(id); let widget = widgets.get_dyn(id); AXES.map(|axis| { @@ -537,7 +537,7 @@ pub(crate) fn placed_box( region: UiRegion, size: Size, align: RegionAlign, - declared: [Option; 2], + declared: [Option; 2], ) -> UiRegion { let mut placed = region; for (axis, declared) in AXES.into_iter().zip(declared) { @@ -546,7 +546,7 @@ pub(crate) fn placed_box( continue; } let span = placed.axis_mut(axis); - let len = span.len().scale(reported.rel) + UiScalar::from_parts(Rel::ZERO, reported.px); + let len = span.len().scale(reported.rel) + Len::from_parts(Rel::ZERO, reported.px); span.start += (span.len() - len).scale(align.axis(axis).rel()); span.end = span.start + len; } @@ -559,13 +559,13 @@ pub(crate) fn placed_box( /// space hands back the same length, so this is the identity for it. pub(crate) fn declared_box( mut region: UiRegion, - declared: [Option; 2], + declared: [Option; 2], align: RegionAlign, ) -> UiRegion { for (axis, len) in AXES.into_iter().zip(declared) { let Some(len) = len else { continue }; let span = region.axis_mut(axis); - let len = UiScalar::from_parts(len.rel, len.px); + let len = Len::from_parts(len.rel, len.px); span.start += (span.len() - len).scale(align.axis(axis).rel()); span.end = span.start + len; } diff --git a/core/src/ui/render_state.rs b/core/src/ui/render_state.rs index d70d994..8006e4d 100644 --- a/core/src/ui/render_state.rs +++ b/core/src/ui/render_state.rs @@ -2,9 +2,9 @@ use crate::layout_diagnostics::{self as diag, Counter, ReuseOutcome, TimerKind}; use crate::ui::painter::{declared_box, declared_lens, placed_box}; use crate::{ - ActiveData, Axis, DrawLayers, Holds, IdLike, Len, MaskIdx, MoveIdx, Moves, Painter, - PixelRegion, PxVec2, RegionAlign, Rel, Size, StrongWidget, UiRegion, UiRsc, UiScalar, UiSpan, - Weight, WidgetId, Widgets, + ActiveData, Axis, DrawLayers, Holds, IdLike, LayoutLen, Len, MaskIdx, MoveIdx, Moves, Painter, + PixelRegion, PxVec2, RegionAlign, Rel, Size, StrongWidget, UiRegion, UiRsc, UiSpan, Weight, + WidgetId, Widgets, util::{HashMap, Vec2}, }; @@ -75,14 +75,8 @@ impl UiRenderState { /// downstream has to know the output's size to resolve a position. fn write_root(&mut self) { let region = UiRegion::new( - UiSpan::new( - UiScalar::ZERO, - UiScalar::from_parts(Rel::ZERO, self.output_size.x), - ), - UiSpan::new( - UiScalar::ZERO, - UiScalar::from_parts(Rel::ZERO, self.output_size.y), - ), + UiSpan::new(Len::ZERO, Len::from_parts(Rel::ZERO, self.output_size.x)), + UiSpan::new(Len::ZERO, Len::from_parts(Rel::ZERO, self.output_size.y)), ); match self.root_move == MoveIdx::NONE { true => self.root_move = self.moves.push(MoveIdx::NONE, region), @@ -255,8 +249,8 @@ impl UiRenderState { let reported = answer.0.axis(axis); let placed_len = match reported.leftover != Weight::ZERO || declared[axis as usize].is_some() { - true => UiScalar::FULL, - false => UiScalar::from_parts(reported.rel, reported.px), + true => Len::FULL, + false => Len::from_parts(reported.rel, reported.px), }; settled.1[axis as usize] = settled.1[axis as usize].and(drawing_holds[axis as usize].through(placed_len)); @@ -765,10 +759,10 @@ impl UiRenderState { let size = Size { x: widget .and_then(|w| w.size_hint(Axis::X)) - .unwrap_or(Len::ZERO), + .unwrap_or(LayoutLen::ZERO), y: widget .and_then(|w| w.size_hint(Axis::Y)) - .unwrap_or(Len::ZERO), + .unwrap_or(LayoutLen::ZERO), }; self.active.insert( id, @@ -1079,7 +1073,7 @@ impl RegionRemap { } } - fn apply_scalar(self, scalar: UiScalar, from: UiSpan, to: UiSpan) -> UiScalar { + fn apply_scalar(self, scalar: Len, from: UiSpan, to: UiSpan) -> Len { let extent = from.end.rel - from.start.rel; // A box that only moved, or that has no relative extent to divide, // carries its parts by moving them, which is exact. Dividing to find @@ -1100,7 +1094,7 @@ impl RegionRemap { let from_px = fraction.lerp(from.start.px, from.end.px); let to_rel = fraction.lerp(to.start.rel, to.end.rel); let to_px = fraction.lerp(to.start.px, to.end.px); - UiScalar::from_parts(to_rel, scalar.px - from_px + to_px) + Len::from_parts(to_rel, scalar.px - from_px + to_px) } } diff --git a/core/src/widget/mod.rs b/core/src/widget/mod.rs index f88f411..8d4637e 100644 --- a/core/src/widget/mod.rs +++ b/core/src/widget/mod.rs @@ -1,4 +1,4 @@ -use crate::{Axis, Len, Painter, Size}; +use crate::{Axis, LayoutLen, Painter, Size}; use std::any::Any; mod data; @@ -24,7 +24,7 @@ pub trait Widget: Any { /// An exact length the widget can give without a painter or its children. /// Optional, and saves a draw rather than changing one: a hint that /// disagrees with the eventual draw fails a debug assertion. - fn size_hint(&self, _axis: Axis) -> Option { + fn size_hint(&self, _axis: Axis) -> Option { None } } @@ -35,8 +35,8 @@ impl Widget for () { Size::default() } - fn size_hint(&self, _axis: Axis) -> Option { - Some(Len::default()) + fn size_hint(&self, _axis: Axis) -> Option { + Some(LayoutLen::default()) } } diff --git a/core/src/widget/size_rule.rs b/core/src/widget/size_rule.rs index 4cae504..6001cd1 100644 --- a/core/src/widget/size_rule.rs +++ b/core/src/widget/size_rule.rs @@ -1,4 +1,4 @@ -use crate::{Axis, Len, Weight}; +use crate::{Axis, LayoutLen, Weight}; /// What a widget's length on one axis is, as a rule its parent applies where /// it draws it rather than an answer the widget gives about itself. @@ -14,7 +14,7 @@ pub enum SizeRule { #[default] Free, /// This length, whatever the widget reports. - Exact(Len), + Exact(LayoutLen), } impl SizeRule { @@ -22,7 +22,7 @@ impl SizeRule { /// give one. `leftover` is never among them: a share is a length only to /// whoever divides one, so it passes up in the reported size instead and /// is resolved there. - pub fn declared(&self) -> Option { + pub fn declared(&self) -> Option { match self { Self::Exact(len) if len.leftover == Weight::ZERO => Some(*len), _ => None, @@ -33,7 +33,7 @@ impl SizeRule { /// share is a length the widget's parent still has to divide, so it is /// known here and resolved there -- unlike `declared`, which is only the /// ones that give a box directly. - pub fn known(&self) -> Option { + pub fn known(&self) -> Option { match self { Self::Free => None, Self::Exact(len) => Some(*len), @@ -41,7 +41,7 @@ impl SizeRule { } /// The length a widget reporting `reported` ends up with. - pub fn apply(&self, reported: Len) -> Len { + pub fn apply(&self, reported: LayoutLen) -> LayoutLen { match self { Self::Free => reported, Self::Exact(len) => *len, @@ -49,14 +49,14 @@ impl SizeRule { } } -impl From for SizeRule { - fn from(len: Len) -> Self { +impl From for SizeRule { + fn from(len: LayoutLen) -> Self { Self::Exact(len) } } -impl From> for SizeRule { - fn from(len: Option) -> Self { +impl From> for SizeRule { + fn from(len: Option) -> Self { len.map_or(Self::Free, Self::Exact) } } diff --git a/src/harness.rs b/src/harness.rs index 281514d..9d5d796 100644 --- a/src/harness.rs +++ b/src/harness.rs @@ -165,7 +165,7 @@ impl Harness { } /// Changes a length rule after the fact, the way `.width()` sets one. - pub fn set_len(&mut self, id: impl IdLike, axis: Axis, len: impl Into) { + pub fn set_len(&mut self, id: impl IdLike, axis: Axis, len: impl Into) { self.rsc .widgets_mut() .set_size_rule(id, axis, SizeRule::Exact(len.into())); diff --git a/src/random.rs b/src/random.rs index 7c0d5e4..daf137f 100644 --- a/src/random.rs +++ b/src/random.rs @@ -9,7 +9,7 @@ use crate::prelude::*; use std::collections::HashMap; /// The declared lengths of one widget carrying a size rule, by axis. -pub type Lens = [Option; 2]; +pub type Lens = [Option; 2]; /// Where one widget carrying an alignment sits, by axis. `None` uses the /// centered default. @@ -181,10 +181,10 @@ impl Grow<'_, Rsc> { id } - fn len(&mut self) -> Option { + fn len(&mut self) -> Option { match self.rng.below(4) { - 0 => Some(Len::px(20.0 + self.rng.below(180) as f32)), - 1 => Some(Len::LEFTOVER), + 0 => Some(LayoutLen::px(20.0 + self.rng.below(180) as f32)), + 1 => Some(LayoutLen::LEFTOVER), _ => None, } } @@ -367,7 +367,7 @@ impl Grow<'_, Rsc> { if dir.axis == Axis::X { self.rsc .widgets_mut() - .set_size_rules(id, None, Some(Len::rel(1.0))); + .set_size_rules(id, None, Some(LayoutLen::rel(1.0))); } self.tree.ids.push(id.id()); self.tree.spans.push(Spanned { id, spares, grown }); diff --git a/src/widget/image.rs b/src/widget/image.rs index 1f71970..c6bb62e 100644 --- a/src/widget/image.rs +++ b/src/widget/image.rs @@ -11,8 +11,8 @@ impl Widget for Image { Size::px(self.handle.size()) } - fn size_hint(&self, axis: Axis) -> Option { - Some(Len::px(self.handle.size().axis(axis))) + fn size_hint(&self, axis: Axis) -> Option { + Some(LayoutLen::px(self.handle.size().axis(axis))) } } diff --git a/src/widget/position/pad.rs b/src/widget/position/pad.rs index 1a62d57..82d1ba3 100644 --- a/src/widget/position/pad.rs +++ b/src/widget/position/pad.rs @@ -11,11 +11,11 @@ impl Widget for Pad { .widget_aligned(&self.inner, self.padding.region(), RegionAlign::NEAR) .size(); Size { - x: Len { + x: LayoutLen { px: inner.x.px + self.padding.left + self.padding.right, ..inner.x }, - y: Len { + y: LayoutLen { px: inner.y.px + self.padding.top + self.padding.bottom, ..inner.y }, diff --git a/src/widget/position/scroll.rs b/src/widget/position/scroll.rs index fb2e26b..178fb2d 100644 --- a/src/widget/position/scroll.rs +++ b/src/widget/position/scroll.rs @@ -57,8 +57,8 @@ impl Widget for Scroll { if moved || self.content_len != self.container_len { let offset = UiVec2::from_axis( self.axis, - UiScalar::from_parts(Rel::ZERO, anchor - self.amt), - UiScalar::ZERO, + Len::from_parts(Rel::ZERO, anchor - self.amt), + Len::ZERO, ); region = region.offset(offset); region.axis_mut(self.axis).end = region.axis(self.axis).start.offset(self.content_len); diff --git a/src/widget/position/span.rs b/src/widget/position/span.rs index b92fa6f..659c788 100644 --- a/src/widget/position/span.rs +++ b/src/widget/position/span.rs @@ -12,10 +12,10 @@ impl Widget for Span { let axis = self.dir.axis; // A length for every child before their final boxes are chosen: from // a hint where one exists, and from drawing otherwise. - let mut cursor = UiScalar::rel_min(); + let mut cursor = Len::rel_min(); let mut lens = Vec::with_capacity(self.children.len()); for child in &self.children { - let mut span = UiSpan::new(cursor, UiScalar::rel_max()); + let mut span = UiSpan::new(cursor, Len::rel_max()); if self.dir.sign == Sign::Neg { span.flip(); } @@ -33,9 +33,9 @@ impl Widget for Span { .gap .mul_int(self.children.len().saturating_sub(1) as i32); let total = lens.iter().fold( - Len { + LayoutLen { px: gaps, - ..Len::ZERO + ..LayoutLen::ZERO }, |sum, len| sum + *len, ); @@ -89,11 +89,11 @@ impl Widget for Span { // from the last child: the share of the room is rounded, and taking // each from the one before it would carry every rounding along the // row. - let mut fixed = UiScalar::rel_min(); + let mut fixed = Len::rel_min(); let mut taken = Weight::ZERO; - let room = UiScalar::rel_max() - UiScalar::from_parts(total.rel, total.px); - let mut start = UiScalar::rel_min(); - let mut ortho = Len::ZERO; + let room = Len::rel_max() - Len::from_parts(total.rel, total.px); + let mut start = Len::rel_min(); + let mut ortho = LayoutLen::ZERO; for (child, len) in self.children.iter().zip(&lens) { // A child asking for nothing but a part of what is left over, // when nothing is, is not drawn at all. One that also asked for @@ -125,7 +125,7 @@ impl Widget for Span { // A scalable child therefore makes Children scalable too; // only fixed children are compared with one another. if used.rel != Rel::ZERO || used.leftover != Weight::ZERO { - ortho = Len::LEFTOVER; + ortho = LayoutLen::LEFTOVER; } else if ortho.leftover == Weight::ZERO { ortho.px = ortho.px.max(used.px); } @@ -144,7 +144,7 @@ impl Widget for Span { let along = total; let ortho = match shrinks { true => ortho, - false => Len::rel(1.0), + false => LayoutLen::rel(1.0), }; Size::from_axis(axis, along, ortho) } @@ -153,7 +153,7 @@ impl Widget for Span { /// Where a row has reached: everything fixed before this point, which is a /// sum and exact, plus the share of the room the weights so far are worth, /// which is one rounding wherever it is asked for. -fn shared(fixed: UiScalar, taken: Weight, weight: Weight, room: UiScalar) -> UiScalar { +fn shared(fixed: Len, taken: Weight, weight: Weight, room: Len) -> Len { if taken == Weight::ZERO { return fixed; } diff --git a/src/widget/rect.rs b/src/widget/rect.rs index add00a0..0990aec 100644 --- a/src/widget/rect.rs +++ b/src/widget/rect.rs @@ -38,8 +38,8 @@ impl Widget for Rect { Size::LEFTOVER } - fn size_hint(&self, _: Axis) -> Option { - Some(Len::LEFTOVER) + fn size_hint(&self, _: Axis) -> Option { + Some(LayoutLen::LEFTOVER) } } diff --git a/src/widget/trait_fns.rs b/src/widget/trait_fns.rs index 4ec85fb..8bd912d 100644 --- a/src/widget/trait_fns.rs +++ b/src/widget/trait_fns.rs @@ -59,7 +59,7 @@ widget_trait! { } } - fn width(self, len: impl Into) -> impl WidgetIdFn { + fn width(self, len: impl Into) -> impl WidgetIdFn { let len = len.into(); move |state| { let id = self.add(state); @@ -71,7 +71,7 @@ widget_trait! { } } - fn height(self, len: impl Into) -> impl WidgetIdFn { + fn height(self, len: impl Into) -> impl WidgetIdFn { let len = len.into(); move |state| { let id = self.add(state); diff --git a/tests/cases/layout.rs b/tests/cases/layout.rs index 497e532..51b69b4 100644 --- a/tests/cases/layout.rs +++ b/tests/cases/layout.rs @@ -27,7 +27,7 @@ fn a_span_ruled_across_itself_does_not_measure_its_children_there() { let span = (child,).span(Dir::RIGHT).height(rel(1.0)).add(&mut h.rsc); h.set_root(span); - assert_eq!(h.render.active[&span.id()].size.y, Len::rel(1.0)); + assert_eq!(h.render.active[&span.id()].size.y, LayoutLen::rel(1.0)); } #[test] @@ -38,7 +38,7 @@ fn a_span_reports_its_tallest_fixed_child() { let span = (short, tall).span(Dir::RIGHT).add(&mut h.rsc); h.set_root(span); - assert_eq!(h.render.active[&span.id()].size.y, Len::px(70.0)); + assert_eq!(h.render.active[&span.id()].size.y, LayoutLen::px(70.0)); } #[test] @@ -331,7 +331,7 @@ fn drawn_edges(h: &Harness, id: WidgetId, axis: Axis) -> (f32, f32) { let region = h.render.moves.resolve(active.parent_move, active.region); let dim = h.size().axis(axis); let snap = |v: f32| (v + Px::STEP.to_f32() * 0.5).floor(); - let edge = |s: UiScalar| snap(s.rel.to_f32() * dim) + snap(s.px.to_f32()); + let edge = |s: Len| snap(s.rel.to_f32() * dim) + snap(s.px.to_f32()); let span = region.axis(axis); (edge(span.start), edge(span.end)) } @@ -343,7 +343,7 @@ fn hairline(h: &mut Harness, marks: &mut Vec) -> StrongWidget { } fn share(h: &mut Harness, inner: StrongWidget, ratio: f32) -> StrongWidget { - h.set_len(&inner, Axis::X, Len::leftover(ratio)); + h.set_len(&inner, Axis::X, LayoutLen::leftover(ratio)); inner } @@ -454,7 +454,7 @@ fn only_a_pure_leftover_child_disappears_when_nothing_is_left() { let mut h = Harness::new((100, 20)); let fixed = rect(Color::RED).width(100).add(&mut h.rsc); let mixed = rect(Color::BLUE) - .width(Len::px(20) + Len::LEFTOVER) + .width(LayoutLen::px(20) + LayoutLen::LEFTOVER) .add(&mut h.rsc); h.set_root((fixed, mixed).span(Dir::RIGHT)); diff --git a/tests/cases/retained.rs b/tests/cases/retained.rs index 091c897..827b3b0 100644 --- a/tests/cases/retained.rs +++ b/tests/cases/retained.rs @@ -125,10 +125,7 @@ fn moving_an_ordinary_subtree_remaps_its_mask() { let active = &h.render.active[&masked.id()]; assert_eq!( h.rsc.ui().masks[active.mask.idx()].region, - UiRegion::new( - UiSpan::new(UiScalar::px(150.0), UiScalar::rel_max()), - UiSpan::FULL, - ) + UiRegion::new(UiSpan::new(Len::px(150.0), Len::rel_max()), UiSpan::FULL,) ); assert_corners!(h, inner, (150, 0), (400, 200)); } @@ -312,7 +309,7 @@ fn a_span_ruled_across_itself_moves_its_child_without_redrawing_it() { assert_eq!(draws.get(), settled); assert_corners!(h, leaf, (0, 0), (400, 100)); - assert_eq!(h.render.active[&span.id()].size.y, Len::rel(1.0)); + assert_eq!(h.render.active[&span.id()].size.y, LayoutLen::rel(1.0)); } /// The output is the root of the box chain, so a resize is a box that changed @@ -407,12 +404,12 @@ fn a_box_change_within_one_step_is_not_a_change() { let step = Px::STEP.to_f32(); for part in [0.1, 0.2, 0.3] { - h.rsc[first].size.x = Len::px(100.0 + step * part); + h.rsc[first].size.x = LayoutLen::px(100.0 + step * part); h.frame(); assert_eq!(draws.get(), settled); } - h.rsc[first].size.x = Len::px(100.0 + step); + h.rsc[first].size.x = LayoutLen::px(100.0 + step); h.frame(); assert_eq!(draws.get(), settled + 1); } diff --git a/tests/cases/unsettled.rs b/tests/cases/unsettled.rs index 8799754..926a58a 100644 --- a/tests/cases/unsettled.rs +++ b/tests/cases/unsettled.rs @@ -281,11 +281,11 @@ struct Wider { impl Widget for Wider { fn draw(&mut self, painter: &mut Painter) -> Size { Size { - x: Len { + x: LayoutLen { px: painter.px_len(Axis::X) + Px::from_f32(self.extra), - ..Len::ZERO + ..LayoutLen::ZERO }, - y: Len::LEFTOVER, + y: LayoutLen::LEFTOVER, } } } @@ -341,7 +341,7 @@ fn plant_boundary(h: &mut Harness, swapped: bool) -> (Vec, [WeakWidget let whole = rect(Color::RED).add(&mut h.rsc); h.rsc .widgets_mut() - .set_size_rules(whole, None, Some(Len::rel(1.0))); + .set_size_rules(whole, None, Some(LayoutLen::rel(1.0))); let mut inner_children: Vec = vec![ measured.add_strong(&mut h.rsc), whole.add_strong(&mut h.rsc), @@ -357,7 +357,7 @@ fn plant_boundary(h: &mut Harness, swapped: bool) -> (Vec, [WeakWidget .add(&mut h.rsc); h.rsc .widgets_mut() - .set_size_rules(inner, None, Some(Len::px(198.0))); + .set_size_rules(inner, None, Some(LayoutLen::px(198.0))); // One more span above it: without a box composed through it, both trees // round the same way and the boundary is never crossed. let outer = (inner,).span(Dir::DOWN).add(&mut h.rsc); diff --git a/tests/chain_cost.rs b/tests/chain_cost.rs index 038ff7d..4dc27bd 100644 --- a/tests/chain_cost.rs +++ b/tests/chain_cost.rs @@ -16,8 +16,8 @@ use iris::prelude::*; use iris_core::{ - MaskIdx, MoveIdx, PrimitiveInst, RectPrimitive, UiData, UiRegion, UiRenderNode, UiRenderState, - UiScalar, UiSpan, + Len, MaskIdx, MoveIdx, PrimitiveInst, RectPrimitive, UiData, UiRegion, UiRenderNode, + UiRenderState, UiSpan, }; use wgpu::{Color as GpuColor, *}; @@ -79,7 +79,7 @@ fn fill(ui: &mut UiData, render: &mut UiRenderState, depth: usize) { slot = render.moves.push(slot, UiRegion::FULL); } - let px = |v: f32| UiScalar::px(v); + let px = |v: f32| Len::px(v); for i in 0..INSTANCES { let x = (i % (SIZE as usize / 2)) as f32 * 2.0; let y = (i / (SIZE as usize / 2)) as f32; diff --git a/tests/generated.rs b/tests/generated.rs index b1ded0d..02372e5 100644 --- a/tests/generated.rs +++ b/tests/generated.rs @@ -61,8 +61,8 @@ fn plant(h: &mut Harness, seed: u64, edits: &Edits) -> Tree { fn resize_one(h: &mut Harness, tree: &Tree, idx: usize, rng: &mut Rng) -> Lens { let lens = [ - Some(Len::px(20.0 + rng.below(180) as f32)), - Some(Len::px(20.0 + rng.below(180) as f32)), + Some(LayoutLen::px(20.0 + rng.below(180) as f32)), + Some(LayoutLen::px(20.0 + rng.below(180) as f32)), ]; h.rsc .widgets_mut() diff --git a/tests/layout_diagnostics.rs b/tests/layout_diagnostics.rs index 5dae327..e7a9548 100644 --- a/tests/layout_diagnostics.rs +++ b/tests/layout_diagnostics.rs @@ -216,7 +216,7 @@ fn layout_cost() { trace_selected(&tree); let sized = tree.sized[0]; run("size", frames, &mut harness, move |harness, frame| { - let len = Len::px(100.0 + (frame % 2) as f32 * 40.0); + let len = LayoutLen::px(100.0 + (frame % 2) as f32 * 40.0); harness .rsc .widgets_mut() diff --git a/tests/revision_cost.rs b/tests/revision_cost.rs index a6d5a16..8f4a385 100644 --- a/tests/revision_cost.rs +++ b/tests/revision_cost.rs @@ -94,7 +94,11 @@ fn build(h: &mut Harness, rows: usize) -> Vec { let mut col = Span::empty(Dir::DOWN); for _ in 0..rows { let mut row = Span::empty(Dir::RIGHT); - row.push(rect(Color::RED).width(Len::px(40.0)).add_strong(&mut h.rsc)); + row.push( + rect(Color::RED) + .width(LayoutLen::px(40.0)) + .add_strong(&mut h.rsc), + ); let mut body = Span::empty(Dir::DOWN); let para = wtext(words(&mut rng, 12, 52)) .size(16) diff --git a/tests/shrink.rs b/tests/shrink.rs index 724b774..f971874 100644 --- a/tests/shrink.rs +++ b/tests/shrink.rs @@ -72,7 +72,7 @@ enum Node { Stack(Vec), Pad(f32, Box), Aligned(u8, u8, Box), - Sized(Option, Option, Box), + Sized(Option, Option, Box), Scroll(bool, Box), Branch(Box, Box, Box, f32), } @@ -131,7 +131,7 @@ impl Node { if !*down { h.rsc .widgets_mut() - .set_size_rules(handle, None, Some(Len::rel(1.0))); + .set_size_rules(handle, None, Some(LayoutLen::rel(1.0))); } spans.push(handle); handle.add_strong(&mut h.rsc) @@ -191,7 +191,7 @@ impl Node { /// The lengths every `Sized` node would carry after `resized`, in the /// order `build` pushes them. - fn sized_lens(&self, out: &mut Vec<(Option, Option)>) { + fn sized_lens(&self, out: &mut Vec<(Option, Option)>) { match self { Node::Text(..) | Node::OneLine | Node::Rect => {} Node::Span(_, _, kids, _) | Node::Stack(kids) => { @@ -352,8 +352,8 @@ fn sized(rng: &mut Rng, inner: Node) -> Node { return inner; } let len = |rng: &mut Rng| match rng.below(4) { - 0 => Some(Len::px(20.0 + rng.below(180) as f32)), - 1 => Some(Len::LEFTOVER), + 0 => Some(LayoutLen::px(20.0 + rng.below(180) as f32)), + 1 => Some(LayoutLen::LEFTOVER), _ => None, }; Node::Sized(len(rng), len(rng), Box::new(inner)) @@ -368,9 +368,9 @@ fn grow(rng: &mut Rng, depth: usize) -> Node { }; } let len = |rng: &mut Rng| match rng.below(4) { - 0 => Some(Len::px(20.0 + rng.below(180) as f32)), - 1 => Some(Len::LEFTOVER), - 2 => Some(Len::rel(0.25 + rng.below(3) as f32 * 0.25)), + 0 => Some(LayoutLen::px(20.0 + rng.below(180) as f32)), + 1 => Some(LayoutLen::LEFTOVER), + 2 => Some(LayoutLen::rel(0.25 + rng.below(3) as f32 * 0.25)), _ => None, }; let kid = |rng: &mut Rng| { @@ -408,9 +408,9 @@ enum Case { /// A different declared length, kept the same kind so the change is to the /// value alone. -fn resized_len(len: Option) -> Option { +fn resized_len(len: Option) -> Option { let half = Rel::from_f32(0.5); - len.map(|len| Len { + len.map(|len| LayoutLen { px: len.px.mul(half) + Px::from_int(13), rel: len.rel.mul(half), leftover: len.leftover,