diff --git a/core/src/ui/active.rs b/core/src/ui/active.rs index 1ea06a7..63318d7 100644 --- a/core/src/ui/active.rs +++ b/core/src/ui/active.rs @@ -18,7 +18,7 @@ pub struct ActiveData { /// padding's rel base less its pixels -- as a length of the window. `None` /// forwards the parent's rel base. What it declared is kept separately in /// `declared` and is a fraction of whichever of the two reached it. - pub narrow: [Option; 2], + pub narrow_rel_base: [Option; 2], /// Where its drawing was put, and where it was asked, each as a part of /// its parent's box. The two differ where a container asks in one place /// and puts the answer in another -- a row measures from its cursor and diff --git a/core/src/ui/painter.rs b/core/src/ui/painter.rs index 009b3bc..bca366d 100644 --- a/core/src/ui/painter.rs +++ b/core/src/ui/painter.rs @@ -174,14 +174,14 @@ impl<'a> Painter<'a> { /// Asks a child, saying what its fractions are of and where it is asked. /// - /// `narrow` is the child's rel base, per axis, as a length of the - /// window: a resolved share, or a box a sibling's answer decided. `None` - /// forwards this widget's own, which is what a container that only - /// divides room passes, so a fraction under it means the same wherever - /// it sits and however deeply it is nested. It only ever narrows -- a - /// length the child declares narrows it again here whatever the caller - /// says -- and what comes of it is also the box the child is asked in, - /// placed in the part by the child's alignment. + /// `narrow_rel_base` is the child's rel base, per axis, as a length of + /// the window: a resolved share, or a box a sibling's answer decided. + /// `None`, whole or per axis, forwards this widget's own -- which is + /// what a container that only divides room passes, so a fraction under + /// it means the same wherever it sits and however deeply it is nested. + /// It only ever narrows: a length the child declares narrows it again + /// here whatever the caller says, and what comes of it is also the box + /// the child is asked in, placed in the part by the child's alignment. /// /// `place` is where the child is asked, per axis, as a part of this /// widget's box: see [`Place`]. The child draws once, in that box, and @@ -191,14 +191,21 @@ impl<'a> Painter<'a> { pub fn widget_at<'s, W: ?Sized>( &'s mut self, id: &'s StrongWidget, - narrow: [Option; 2], + narrow_rel_base: impl Into; 2]>>, place: [Place; 2], ) -> DrawResult<'s, 'a, W> { + let narrow_rel_base = narrow_rel_base.into().unwrap_or([None; 2]); let region_node = self.rsc.widgets().is_region_node(id.id()); let declared = self.declared_lens(id); let align = self.rsc.widgets().alignment(id.id()); - let (rel_base, region) = - rel_base_and_region(self.region, self.rel_base, place, narrow, declared, align); + let (rel_base, region) = rel_base_and_region( + self.region, + self.rel_base, + place, + narrow_rel_base, + declared, + align, + ); #[cfg(feature = "layout-diagnostics")] if region_node { diag::bump(Counter::RegionNodeDraws); @@ -223,15 +230,15 @@ impl<'a> Painter<'a> { region, placed: place, asked: place, - narrow, + narrow_rel_base, re_asked, px, }, None, self.rsc, ); - let holds = self.in_parent(holds, region, place, narrow, declared); - let answer_holds = self.in_parent(answer_holds, region, place, narrow, declared); + let holds = self.in_parent(holds, region, place, narrow_rel_base, declared); + let answer_holds = self.in_parent(answer_holds, region, place, narrow_rel_base, declared); match self.under.iter_mut().find(|(child, _)| *child == id.id()) { Some((_, kept)) => *kept = holds, None => self.under.push((id.id(), holds)), @@ -266,11 +273,12 @@ impl<'a> Painter<'a> { pub fn place_at<'s, W: ?Sized>( &'s mut self, id: &'s StrongWidget, - narrow: [Option; 2], + narrow_rel_base: impl Into; 2]>>, place: [Place; 2], ) -> DrawResult<'s, 'a, W> { - if narrow.iter().any(Option::is_some) || !self.children.contains(&id.id()) { - return self.widget_at(id, narrow, place); + let narrow_rel_base = narrow_rel_base.into().unwrap_or([None; 2]); + if narrow_rel_base.iter().any(Option::is_some) || !self.children.contains(&id.id()) { + return self.widget_at(id, narrow_rel_base, place); } let at = self.placing(); self.state.place_in(id.id(), &at, place, self.rsc); @@ -612,7 +620,7 @@ impl Painter<'_> { holds: LayoutHolds, region: UiRegion, place: [Place; 2], - narrow: [Option; 2], + narrow_rel_base: [Option; 2], declared: [Option; 2], ) -> LayoutHolds { let mut result = LayoutHolds::ANY; @@ -621,7 +629,7 @@ impl Painter<'_> { // Every read became pixels against the window, so a range on // it is already in this widget's terms. result.window[n] = holds.window[n]; - let reaches = narrow[n].is_none() + let reaches = narrow_rel_base[n].is_none() && !matches!(place[n].part(), Part::Sized(_)) && declared[n].is_none_or(|len| len.rel != Rel::ZERO); result.rel_base[n] = holds.rel_base[n].and(reaches.then(|| self.rel_base.axis(axis))); @@ -729,7 +737,7 @@ pub(crate) fn placement( /// widget asking draws in. /// /// `own` is that widget's own box, and `place` what of it the child is -/// given. `narrow` is a rel base the container decided for the child -- a row's +/// given. `narrow_rel_base` is a rel base the container decided for the child -- a row's /// slot, or padding's rel base less its pixels -- and [`Part::Sized`] one a /// sibling's answer decided; both are window lengths, like every other /// length here, since a slot of a row is not a fraction of anything the row @@ -740,7 +748,7 @@ pub(crate) fn rel_base_and_region( own: UiRegion, parent_rel_base: UiVec2, place: [Place; 2], - narrow: [Option; 2], + narrow_rel_base: [Option; 2], declared: [Option; 2], align: RegionAlign, ) -> (UiVec2, UiRegion) { @@ -754,7 +762,7 @@ pub(crate) fn rel_base_and_region( _ => None, }; let base = sized - .or(narrow[n]) + .or(narrow_rel_base[n]) .unwrap_or_else(|| parent_rel_base.axis(axis)); let len = declared[n] .map(|len| Len::from_parts(len.rel, len.px).within_len(base)) diff --git a/core/src/ui/render_state.rs b/core/src/ui/render_state.rs index 5cc5a43..b847c33 100644 --- a/core/src/ui/render_state.rs +++ b/core/src/ui/render_state.rs @@ -33,7 +33,7 @@ pub(super) struct DrawInfo { pub asked: [Place; 2], /// A rel base the parent decided for it on each axis, as a length of the /// window, which the widget's own declaration is a fraction of. - pub narrow: [Option; 2], + pub narrow_rel_base: [Option; 2], /// Whether the parent already asked about this widget in this draw. pub re_asked: bool, /// The rel base in pixels, resolved once against the window. @@ -133,7 +133,7 @@ impl UiRenderState { } } - /// The root is asked about in the output. Its own rules narrow both its + /// The root is asked about in the output. Its own rules narrow_rel_base both its /// rel base and box; nothing above it chose a different one. fn root_info(&self, rel_base: UiVec2, region: UiRegion) -> DrawInfo { let px = rel_base.to_px(self.output_size); @@ -148,7 +148,7 @@ impl UiRenderState { region, placed: [Place::Within(Part::WHOLE); 2], asked: [Place::Within(Part::WHOLE); 2], - narrow: [None; 2], + narrow_rel_base: [None; 2], re_asked: false, px, } @@ -273,7 +273,7 @@ impl UiRenderState { // and what of its own box it asked in. A local redraw asks the same // question again from these. active.rel_base = info.rel_base; - active.narrow = info.narrow; + active.narrow_rel_base = info.narrow_rel_base; active.re_asked = info.re_asked; active.answer = Some(answer); active.asked = info.asked; @@ -470,7 +470,7 @@ impl UiRenderState { region: UiRegion::FULL, placed: [Place::Within(Part::WHOLE); 2], asked: [Place::Within(Part::WHOLE); 2], - narrow: [None; 2], + narrow_rel_base: [None; 2], re_asked: false, px, }, @@ -484,7 +484,7 @@ impl UiRenderState { id, placement: region, rel_base: info.rel_base, - narrow: info.narrow, + narrow_rel_base: info.narrow_rel_base, placed: info.placed, asked: info.asked, region, @@ -741,7 +741,7 @@ impl UiRenderState { region, placed: place, asked: active.asked, - narrow: active.narrow, + narrow_rel_base: active.narrow_rel_base, re_asked: active.re_asked, px: rel_base.to_px(at.window), }; @@ -757,7 +757,7 @@ impl UiRenderState { at.region, at.rel_base, place, - active.narrow, + active.narrow_rel_base, active.declared, active.own_align, ) @@ -886,7 +886,7 @@ impl UiRenderState { id, placement: UiRegion::FULL, rel_base: UiVec2::FULL_SIZE, - narrow: [None; 2], + narrow_rel_base: [None; 2], placed: [Place::Within(Part::WHOLE); 2], asked: [Place::Within(Part::WHOLE); 2], region: UiRegion::FULL, @@ -1146,7 +1146,7 @@ impl UiRenderState { region, placed: active.asked, asked: active.asked, - narrow: active.narrow, + narrow_rel_base: active.narrow_rel_base, re_asked: false, px: rel_base.to_px(self.output_size), }; @@ -1171,7 +1171,7 @@ impl UiRenderState { } if active.answer != was_answer || active.holds != was_holds { // The parent retains both the answer and the drawing's validity; - // even an unchanged size can narrow the range safe for a resize. + // even an unchanged size can narrow_rel_base the range safe for a resize. #[cfg(feature = "layout-diagnostics")] { diag::bump(Counter::SizeChanges); diff --git a/src/random.rs b/src/random.rs index 5c0299b..cfc5ec9 100644 --- a/src/random.rs +++ b/src/random.rs @@ -120,7 +120,7 @@ impl Widget for Branch { let cut = Len::from_parts(Rel::ZERO, Px::from_int(40)); let top = Place::Within(Part::From(UiSpan::new(Len::ZERO, cut))); let measured = painter - .widget_at(&self.probe, [None; 2], [Place::Within(Part::WHOLE), top]) + .widget_at(&self.probe, None, [Place::Within(Part::WHOLE), top]) .len(Axis::X); let len = measured.apply_leftover(); let px = painter.to_px(len, Axis::X); @@ -137,8 +137,8 @@ impl Widget for Branch { let below = Place::Within(Part::From(UiSpan::new(cut, painter.region_len(Axis::Y)))); let place = [Place::Within(Part::WHOLE), below]; match px > threshold { - true => painter.widget_at(&self.wide, [None; 2], place), - false => painter.widget_at(&self.narrow, [None; 2], place), + true => painter.widget_at(&self.wide, None, place), + false => painter.widget_at(&self.narrow, None, place), }; Size::LEFTOVER } diff --git a/src/widget/position/scroll.rs b/src/widget/position/scroll.rs index 1369a95..589f766 100644 --- a/src/widget/position/scroll.rs +++ b/src/widget/position/scroll.rs @@ -14,7 +14,7 @@ impl Widget for Scroll { let container_len = painter.px_len(self.axis); // Asked in the whole viewport, then put at the scrolled offset. let answer_len = painter - .widget_at(&self.inner, [None; 2], [Place::Fill(Part::WHOLE); 2]) + .widget_at(&self.inner, None, [Place::Fill(Part::WHOLE); 2]) .len(self.axis); let fixed = painter.to_px(Len::from_parts(answer_len.rel, answer_len.px), self.axis); self.container_len = container_len; @@ -64,7 +64,7 @@ impl Widget for Scroll { // box, scrolled: its drawing moved there, not made again there. painter.place_at( &self.inner, - [None; 2], + None, self.axis .pair(Place::Fill(content), Place::Fill(Part::WHOLE)), ); diff --git a/src/widget/position/span.rs b/src/widget/position/span.rs index f6c3c97..26fefeb 100644 --- a/src/widget/position/span.rs +++ b/src/widget/position/span.rs @@ -36,7 +36,7 @@ impl Widget for Span { None => { let room = Place::Within(Part::From(along(cursor, far))); painter - .widget_at(child, [None; 2], axis.pair(room, across)) + .widget_at(child, None, axis.pair(room, across)) .len(axis) } }; @@ -121,10 +121,8 @@ impl Widget for Span { // room is put there as it is, and one not made yet is made here. let slot = along(from, start); let place = axis.pair(Place::Fill(Part::From(slot)), across); - let mut narrow = [None; 2]; - if len.leftover > Weight::ZERO && shares { - narrow[axis as usize] = Some(slot.len()); - } + let narrow = + (len.leftover > Weight::ZERO && shares).then(|| axis.pair(Some(slot.len()), None)); let used = painter.place_at(child, narrow, place).len(!axis); if shrinks { // Choosing between a fixed and a relative length from the diff --git a/src/widget/position/stack.rs b/src/widget/position/stack.rs index 7157618..e1c2f5e 100644 --- a/src/widget/position/stack.rs +++ b/src/widget/position/stack.rs @@ -23,7 +23,7 @@ impl Widget for Stack { Some((i, child)) => { painter.child_layer_at(i); painter - .widget_at(child, [None; 2], [Place::Fill(Part::WHOLE); 2]) + .widget_at(child, None, [Place::Fill(Part::WHOLE); 2]) .size() } None => Size::LEFTOVER, @@ -45,7 +45,7 @@ impl Widget for Stack { continue; } painter.child_layer_at(i); - painter.widget_at(child, [None; 2], place); + painter.widget_at(child, None, place); } size } diff --git a/tests/cases/determinism.rs b/tests/cases/determinism.rs index 76dd590..7e1604a 100644 --- a/tests/cases/determinism.rs +++ b/tests/cases/determinism.rs @@ -24,15 +24,15 @@ impl Widget for BranchesOnMeasurement { let cut = Len::from_parts(Rel::ZERO, Px::from_int(40)); let top = Place::Within(Part::From(UiSpan::new(Len::ZERO, cut))); let measured = painter - .widget_at(&self.probe, [None; 2], [Place::Within(Part::WHOLE), top]) + .widget_at(&self.probe, None, [Place::Within(Part::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]; match px > Px::from_f32(self.threshold) { - true => painter.widget_at(&self.wide, [None; 2], place), - false => painter.widget_at(&self.narrow, [None; 2], place), + true => painter.widget_at(&self.wide, None, place), + false => painter.widget_at(&self.narrow, None, place), }; Size::LEFTOVER }