diff --git a/core/src/ui/painter.rs b/core/src/ui/painter.rs index 60079fa..ef0d03e 100644 --- a/core/src/ui/painter.rs +++ b/core/src/ui/painter.rs @@ -1,7 +1,7 @@ #[cfg(feature = "layout-diagnostics")] use crate::layout_diagnostics::{self as diag, Counter}; use crate::{ - Axis, Holds, LayoutHolds, LayoutLen, Len, Place, Px, PxVec2, RegionAlign, RenderedText, + Axis, Holds, LayoutHolds, LayoutLen, Len, Part, Place, Px, PxVec2, RegionAlign, RenderedText, RetainedPrimitive, Size, StrongWidget, TextAttrs, TextBuffer, TextData, TextureHandle, UiRegion, UiRenderState, UiRsc, UiSpan, UiVec2, Weight, WidgetId, Widgets, render::{ @@ -151,7 +151,7 @@ impl<'a> Painter<'a> { /// one child wants, and what every transparent container passes for the /// frame. pub fn widget<'s, W: ?Sized>(&'s mut self, id: &'s StrongWidget) -> DrawResult<'s, 'a, W> { - self.widget_at(id, UiRegion::FULL, [Place::Within(None); 2]) + self.widget_at(id, UiRegion::FULL, [Place::Within(Part::All); 2]) } /// Draws a child, saying what its fractions are of and where its drawing @@ -225,12 +225,12 @@ impl<'a> Painter<'a> { place, offer_place, // The question its parent measured it by, asked again: the - // same box of the same widget, however this draw came about. + // same widget in the same place, however this draw came + // about. offer: place == offer_place, px, }, None, - false, self.rsc, ); let compose = |holds| in_parent(holds, local, extent, place, declared); @@ -353,13 +353,15 @@ impl<'a> Painter<'a> { } } - /// The symbolic length of this widget's own box, in the lengths of its - /// frame that it places its children in. Reading it pins the drawing to - /// that length -- and to nothing about where the box starts, which is - /// what lets a container move without being drawn again. - pub fn extent_len(&mut self) -> UiVec2 { - let len = self.extent.size(); - self.extent_len = [Some(len.x), Some(len.y)]; + /// The symbolic length of this widget's own box along one axis, in the + /// lengths of its frame that it places its children in. Reading it pins + /// the drawing to that length -- and to nothing about where the box + /// starts, which is what lets a container move without being drawn + /// again. One axis at a time, because a container that divides one axis + /// holds for any length of the other. + pub fn extent_len(&mut self, axis: Axis) -> Len { + let len = self.extent.axis(axis).len(); + self.extent_len[axis as usize] = Some(len); len } @@ -553,17 +555,22 @@ pub(crate) fn in_parent( let n = axis as usize; let frame_len = frame.axis(axis).len(); result.frame[n] = holds.frame[n].through(frame_len); - match (place[n].span(), declared[n]) { - // Its box is this widget's own, so what it holds for is a range - // on this widget's own box -- which is what lets that box move - // without a redraw. A length it pinned is this widget's length, - // and pins the same way: where the part is a span instead, that - // span is this widget's own to decide and nothing has to be - // said. - (None, None) => { + match (place[n].part(), declared[n]) { + // Its box is this widget's own, or a part of it in that box's + // own lengths: so what it holds for is a range on this widget's + // own box, which is what lets that box move without a redraw. A + // length it pinned is this widget's length wherever the part is + // the whole of it, and pins the same way. + (Part::All, None) => { result.extent[n] = holds.extent[n]; result.extent_len[n] = holds.extent_len[n]; } + // Its box is a part of this widget's own box, in that box's own + // lengths, so what it holds for maps back through that part into + // a range on this widget's box. + (Part::Of(span), None) => { + result.extent[n] = holds.extent[n].through(span.len()); + } // Its box is a part of this widget's frame: a length of the // frame is all that reaches it, so what it holds for is a range // on the frame and none of it on this widget's own box. @@ -663,10 +670,7 @@ pub(crate) fn placed_extent( pub(crate) fn part_of(extent: UiRegion, place: [Place; 2]) -> UiRegion { let mut part = extent; for axis in AXES { - if let Some(span) = place[axis as usize].span() { - let start = extent.axis(axis).start; - *part.axis_mut(axis) = UiSpan::new(start + span.start, start + span.end); - } + *part.axis_mut(axis) = place[axis as usize].part().of(*extent.axis(axis)); } part } diff --git a/core/src/ui/place.rs b/core/src/ui/place.rs index 561726a..c292716 100644 --- a/core/src/ui/place.rs +++ b/core/src/ui/place.rs @@ -1,23 +1,47 @@ use crate::{PrimitiveHandle, UiRegion, UiSpan}; -/// Where a child goes along one axis, as a part of this widget's extent. -/// Spans are frame lengths from the extent's start, so a span's slot is -/// `from..start` and a moved extent re-places every child by re-adding its -/// start, exactly. `None` is the whole extent. +/// 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, + /// Frame lengths from where the box starts, which is what a container + /// dividing room among its children speaks: a child's report is a length + /// of the frame, so the cursor that sums those reports is one too. A + /// moved box re-places every child by re-adding its start, exactly. + 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 + /// length, where saying the same thing in frame lengths would make the + /// container read its own box -- and a box chosen from its own answer + /// then feeds back into the answer. + Of(UiSpan), +} + +impl Part { + /// Where it lands in the coordinates `extent` is in. + pub(crate) fn of(self, extent: UiSpan) -> UiSpan { + match self { + Self::All => extent, + Self::From(span) => UiSpan::new(extent.start + span.start, extent.start + span.end), + Self::Of(span) => span.within(&extent), + } + } +} + +/// Where a child goes along one axis, as a part of this widget's box. #[derive(Clone, Copy, Debug, PartialEq)] pub enum Place { /// The child's answer, aligned inside the part by the child's alignment. - Within(Option), + Within(Part), /// Exactly the part; the answer is not placed inside it again. - Fill(Option), + Fill(Part), } impl Place { - /// The part, where the caller named one rather than giving the whole - /// extent. - pub(crate) fn span(self) -> Option { + pub(crate) fn part(self) -> Part { match self { - Self::Within(span) | Self::Fill(span) => span, + Self::Within(part) | Self::Fill(part) => part, } } @@ -28,8 +52,8 @@ impl Place { } } -/// A primitive as it was written: its box in the widget's extent -/// coordinates, which is what a move of that extent re-composes from. +/// A primitive as it was written: its box in the widget's own box's +/// coordinates, which is what a move of that box re-composes from. #[derive(Debug)] pub struct RetainedPrimitive { pub handle: PrimitiveHandle, diff --git a/core/src/ui/render_state.rs b/core/src/ui/render_state.rs index 6b6e6cb..ab5b371 100644 --- a/core/src/ui/render_state.rs +++ b/core/src/ui/render_state.rs @@ -3,7 +3,7 @@ use crate::layout_diagnostics::{self as diag, Counter, ReuseOutcome, TimerKind}; use crate::ui::painter::{declared_lens, frame_and_extent, part_of, placed_extent}; use crate::{ ActiveData, Axis, DrawLayers, Holds, IdLike, LayoutHolds, LayoutLen, Len, MaskIdx, MoveIdx, - Moves, Painter, PixelRegion, Place, PxVec2, Size, StrongWidget, UiRegion, UiRsc, Weight, + Moves, Painter, Part, PixelRegion, Place, PxVec2, Size, StrongWidget, UiRegion, UiRsc, Weight, WidgetId, Widgets, util::{HashMap, Vec2}, }; @@ -151,8 +151,8 @@ impl UiRenderState { frame: region, frame_abs: region, part: UiRegion::FULL, - place: [Place::Within(None); 2], - offer_place: [Place::Within(None); 2], + place: [Place::Within(Part::All); 2], + offer_place: [Place::Within(Part::All); 2], offer: true, px, } @@ -202,7 +202,7 @@ impl UiRenderState { if let Some(id) = root { let region = Self::root_region(id.id(), rsc.widgets()); let info = self.root_info(region); - self.draw_inner(id.id(), info, None, true, rsc); + self.draw_inner(id.id(), info, None, rsc); } } @@ -226,7 +226,6 @@ impl UiRenderState { id: WidgetId, info: DrawInfo, mut old: Option, - place_answer: bool, rsc: &mut dyn UiRsc, ) -> (Size, LayoutHolds, LayoutHolds) { let (frame, part) = (info.frame_abs, info.part); @@ -258,31 +257,21 @@ impl UiRenderState { // axis the parent left open. The frame itself does not change, so // nothing under it resolves a fraction a second time. // - // Placing the answer waits for the end of the parent's draw, or for - // the next ask of this child in it: a child measured in the room its - // parent had left over and then given a slot would otherwise be put - // in a box neither of them chose, between the two. Whoever asks with - // nobody to finish it -- the root, a local redraw -- places here. - let extent = match place_answer { - // From the answer it gave when its parent first asked, and not - // from what a placing evaluation reported: a drawing made in the - // box that answer chose is answering a different question, and - // placing it by that would move the box out from under itself. - true => { - let measured = match info.offer { - true => answer.0, - false => self.active[&id].answer.map_or(answer.0, |(size, _)| size), - }; - placed_extent( - part, - measured, - declared_lens(rsc.widgets(), id), - info.fill(), - align, - ) - } - false => part, + // From the answer it gave when its parent first asked, and not from + // what a placing evaluation reported: a drawing made in the box that + // answer chose is answering a different question, and placing it by + // that would move the box out from under itself. + let measured = match info.offer { + true => answer.0, + false => self.active[&id].answer.map_or(answer.0, |(size, _)| size), }; + let extent = placed_extent( + part, + measured, + declared_lens(rsc.widgets(), id), + info.fill(), + align, + ); self.place(id, extent, info, rsc); // On axes the parent filled, measurement and drawing share an extent. @@ -468,28 +457,13 @@ impl UiRenderState { if let Some(idx) = retired_move { self.moves.remove(idx); } - // The draw is over, so a child whose box was left to its own answer - // gets that box now. Nothing it did is undone by this: a child it - // asked twice was placed by the second ask, and one that fills what - // it was given is already there. What those drawings need is part of - // what this one does, so it comes before the contract is settled. - let at = Placing { - id, - extent, - local, - px, - depth: info.depth, - move_idx, - mask, - }; - let placed = self.place_answers(&at, &children, rsc); let own_holds = LayoutHolds { frame: own, extent: extent_own, extent_len, }; let answer_holds = own_holds.and(answer_under); - let holds = answer_holds.and(under).and(placed); + let holds = answer_holds.and(under); debug_assert!( holds.contains(px, extent), "'{}' ({id:?}) drew in {px:?}, outside the ranges it reported: {holds:?}", @@ -512,8 +486,8 @@ impl UiRenderState { frame: UiRegion::FULL, frame_abs: UiRegion::FULL, part: UiRegion::FULL, - place: [Place::Within(None); 2], - offer_place: [Place::Within(None); 2], + place: [Place::Within(Part::All); 2], + offer_place: [Place::Within(Part::All); 2], offer: false, px, }, @@ -741,61 +715,6 @@ impl UiRenderState { Some(answer) } - /// Puts each child of a widget that has just drawn where its answer - /// says, for the axes the ask left open. Doing it here rather than as - /// each child answers is what keeps a child that is asked twice -- a - /// span measuring it and then giving it a slot -- to one drawing and one - /// move, instead of a move to its answer in between that nobody asked - /// for. - /// Answers with what those drawings then depend on, as dependencies of - /// this widget: a child placed here may have been drawn again in the box - /// its answer chose, and what that drawing needs was not known when the - /// child was asked. - fn place_answers( - &mut self, - at: &Placing, - children: &[WidgetId], - rsc: &mut dyn UiRsc, - ) -> LayoutHolds { - let mut under = LayoutHolds::ANY; - for &child in children { - let Some(active) = self.active.get(&child) else { - continue; - }; - if active.place.iter().all(|place| place.fills()) { - continue; - } - self.place_child(child, at, rsc); - under = under.and(self.placed_holds(child)); - } - under - } - - /// What a child's finished drawing needs, as a range on the frame of the - /// widget that drew it. - /// - /// Only the frame: where the box the child ended up in is the answer it - /// gave, that box is a length of this frame and maps back through it - /// exactly, and where the parent chose the box instead, the ask already - /// said what that costs on the parent's own box. - fn placed_holds(&self, child: WidgetId) -> LayoutHolds { - let active = &self.active[&child]; - let mut result = LayoutHolds::ANY; - for axis in AXES { - let n = axis as usize; - let frame_len = active.frame.axis(axis).len(); - result.frame[n] = active.holds.frame[n].through(frame_len); - if !active.place[n].fills() { - result.frame[n] = result.frame[n].and( - active.holds.extent[n] - .through(active.extent.axis(axis).len()) - .through(frame_len), - ); - } - } - result - } - /// Places one child of `at.id` in the box that widget's own box gives /// it: its part of the extent, with its answer placed inside that part /// where the ask left the axis open. @@ -1025,8 +944,8 @@ impl UiRenderState { frame_abs: UiRegion::FULL, extent: UiRegion::FULL, frame: UiRegion::FULL, - place: [Place::Within(None); 2], - offer_place: [Place::Within(None); 2], + place: [Place::Within(Part::All); 2], + offer_place: [Place::Within(Part::All); 2], offer_part: UiRegion::FULL, answer: None, size, @@ -1256,7 +1175,7 @@ impl UiRenderState { #[cfg(feature = "layout-diagnostics")] diag::bump(Counter::LocalRedraws); let old = self.remove(id, false, rsc); - self.draw_inner(id, info, old, true, rsc); + self.draw_inner(id, info, old, rsc); return true; }; let px = self.asked_px(id); @@ -1315,12 +1234,10 @@ impl UiRenderState { let old = self.remove(id, false, rsc); // The original measurement is refreshed before the assigned slot is // restored: its lengths may differ even though the frame is - // unchanged. Nobody above is drawing, so this places its own answer, - // at the slot it has. - let places = info.place == info.offer_place && info.part == offered.part; - let answer = self.draw_inner(id, offered, old, places, rsc); - if !places { - self.draw_inner(id, info, None, true, rsc); + // unchanged. + let answer = self.draw_inner(id, offered, old, rsc); + if info.place != info.offer_place || info.part != offered.part { + self.draw_inner(id, info, None, rsc); } let active = self.active.get_mut(&id).unwrap(); // A wider contract does not invalidate the guarantee the parent kept. diff --git a/src/random.rs b/src/random.rs index 2e38353..b3dc2c7 100644 --- a/src/random.rs +++ b/src/random.rs @@ -117,16 +117,15 @@ pub struct Branch { impl Widget for Branch { fn draw(&mut self, painter: &mut Painter) -> Size { - let len = painter.extent_len(); let cut = Len::from_parts(Rel::ZERO, Px::from_int(40)); - let top = Place::Within(Some(UiSpan::new(Len::ZERO, cut))); + let top = Place::Within(Part::From(UiSpan::new(Len::ZERO, cut))); let measured = painter - .widget_at(&self.probe, UiRegion::FULL, [Place::Within(None), top]) + .widget_at(&self.probe, UiRegion::FULL, [Place::Within(Part::All), top]) .len(Axis::X); let px = measured.apply_leftover().to_px(painter.px_len(Axis::X)); - let below = Place::Within(Some(UiSpan::new(cut, len.y))); - let place = [Place::Within(None), below]; + let below = Place::Within(Part::From(UiSpan::new(cut, painter.extent_len(Axis::Y)))); + let place = [Place::Within(Part::All), below]; match px > Px::from_f32(self.threshold) { true => painter.widget_at(&self.wide, UiRegion::FULL, place), false => painter.widget_at(&self.narrow, UiRegion::FULL, place), diff --git a/src/widget/position/offset.rs b/src/widget/position/offset.rs index 6870789..b976826 100644 --- a/src/widget/position/offset.rs +++ b/src/widget/position/offset.rs @@ -10,9 +10,11 @@ impl Widget for Offset { // The whole of this widget's box, moved: the frame passes through, so // what the child declares or reports means the same as it would // without the offset. - let len = painter.extent_len(); - let moved = |len: Len, amt: Len| Place::Within(Some(UiSpan::new(amt, len + amt))); - let place = [moved(len.x, self.amt.x), moved(len.y, self.amt.y)]; + let moved = |len: Len, amt: Len| Place::Within(Part::From(UiSpan::new(amt, len + amt))); + let place = [ + moved(painter.extent_len(Axis::X), self.amt.x), + moved(painter.extent_len(Axis::Y), self.amt.y), + ]; painter.widget_at(&self.inner, UiRegion::FULL, place).size() } } diff --git a/src/widget/position/pad.rs b/src/widget/position/pad.rs index 7bce0a8..c7d88f6 100644 --- a/src/widget/position/pad.rs +++ b/src/widget/position/pad.rs @@ -17,16 +17,20 @@ impl Widget for Pad { // The padding goes around what it pads: the frame passes through, so // the inner's fractions mean what they would without it, and only // the box it draws in is moved in by the pixels. - let len = painter.extent_len(); - let inset = |len: Len, lead: Px, trail: Px| { - Place::Within(Some(UiSpan::new( + // A part of this widget's own box, in that box's own lengths: the + // padding is pixels, which are the same pixels wherever the box + // lands, so nothing here reads how long the box is -- and a box + // chosen from this widget's own answer therefore does not feed back + // into that answer. + let inset = |lead: Px, trail: Px| { + Place::Within(Part::Of(UiSpan::new( Len::from_parts(Rel::ZERO, lead), - len - Len::from_parts(Rel::ZERO, trail), + Len::from_parts(Rel::ONE, -trail), ))) }; let place = [ - inset(len.x, self.padding.left, self.padding.right), - inset(len.y, self.padding.top, self.padding.bottom), + inset(self.padding.left, self.padding.right), + inset(self.padding.top, self.padding.bottom), ]; let inner = painter.widget_at(&self.inner, UiRegion::FULL, place).size(); Size { diff --git a/src/widget/position/scroll.rs b/src/widget/position/scroll.rs index edcd7c8..6dba289 100644 --- a/src/widget/position/scroll.rs +++ b/src/widget/position/scroll.rs @@ -15,7 +15,7 @@ impl Widget for Scroll { // Measured in the whole viewport, then drawn at the scrolled offset. let whole = UiRegion::FULL; let answer_len = painter - .widget_at(&self.inner, whole, [Place::Fill(None); 2]) + .widget_at(&self.inner, whole, [Place::Fill(Part::All); 2]) .len(self.axis); let content = answer_len.apply_leftover(); self.container_len = container_len; @@ -65,7 +65,7 @@ impl Widget for Scroll { &self.inner, whole, self.axis - .pair(Place::Fill(Some(content)), Place::Fill(None)), + .pair(Place::Fill(Part::From(content)), Place::Fill(Part::All)), ); // What it occupies is its box, on both axes: it clips its content to // that box, so it can neither take less of one nor honestly ask for diff --git a/src/widget/position/span.rs b/src/widget/position/span.rs index 94e75fe..320fda0 100644 --- a/src/widget/position/span.rs +++ b/src/widget/position/span.rs @@ -13,7 +13,7 @@ impl Widget for Span { // The row: this span's own box, as a length of the frame its children // are laid out against. Its start is nothing's business -- a slot is // a length from it -- so what this reads is the length alone. - let far = painter.extent_len().axis(axis); + let far = painter.extent_len(axis); let along = |from: Len, to: Len| match self.dir.sign { Sign::Pos => UiSpan::new(from, to), Sign::Neg => UiSpan::new(far - to, far - from), @@ -21,7 +21,7 @@ impl Widget for Span { // Across itself the child sits where its own alignment says, in the // whole of the row: a span is what contains its children there, and // nothing divides that axis. - let across = Place::Within(None); + let across = Place::Within(Part::All); // A length for every child before their final slots are chosen. The // frame passes through unchanged, so `rel(0.5)` is half the area this // span was given whatever else is in it and wherever this child sits @@ -30,7 +30,7 @@ impl Widget for Span { let mut cursor = Len::rel_min(); let mut lens = Vec::with_capacity(self.children.len()); for child in &self.children { - let room = Place::Within(Some(along(cursor, far))); + let room = Place::Within(Part::From(along(cursor, far))); let len = painter .widget_at(child, UiRegion::FULL, axis.pair(room, across)) .len(axis); @@ -108,7 +108,7 @@ impl Widget for Span { // Along the row the span says where the child goes, and that slot // is the drawing's box outright rather than something to place an // answer inside again. - let slot = Place::Fill(Some(along(from, start))); + let slot = Place::Fill(Part::From(along(from, start))); let placed = painter.widget_at(child, UiRegion::FULL, axis.pair(slot, across)); if shrinks { let used = placed.len(!axis); diff --git a/src/widget/position/stack.rs b/src/widget/position/stack.rs index 52bb35c..f83ba09 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, UiRegion::FULL, [Place::Fill(None); 2]) + .widget_at(child, UiRegion::FULL, [Place::Fill(Part::All); 2]) .size() } None => Size::LEFTOVER, diff --git a/tests/cases/determinism.rs b/tests/cases/determinism.rs index 0b080f6..e5240e3 100644 --- a/tests/cases/determinism.rs +++ b/tests/cases/determinism.rs @@ -21,16 +21,15 @@ struct BranchesOnMeasurement { impl Widget for BranchesOnMeasurement { fn draw(&mut self, painter: &mut Painter) -> Size { - let len = painter.extent_len(); let cut = Len::from_parts(Rel::ZERO, Px::from_int(40)); - let top = Place::Within(Some(UiSpan::new(Len::ZERO, cut))); + let top = Place::Within(Part::From(UiSpan::new(Len::ZERO, cut))); let measured = painter - .widget_at(&self.probe, UiRegion::FULL, [Place::Within(None), top]) + .widget_at(&self.probe, UiRegion::FULL, [Place::Within(Part::All), top]) .len(Axis::X); let px = measured.apply_leftover().to_px(painter.px_len(Axis::X)); - let below = Place::Within(Some(UiSpan::new(cut, len.y))); - let place = [Place::Within(None), below]; + let below = Place::Within(Part::From(UiSpan::new(cut, painter.extent_len(Axis::Y)))); + let place = [Place::Within(Part::All), below]; match px > Px::from_f32(self.threshold) { true => painter.widget_at(&self.wide, UiRegion::FULL, place), false => painter.widget_at(&self.narrow, UiRegion::FULL, place), diff --git a/tests/cases/retained.rs b/tests/cases/retained.rs index 099257e..5d97630 100644 --- a/tests/cases/retained.rs +++ b/tests/cases/retained.rs @@ -217,7 +217,7 @@ impl Widget for FromHint { painter.widget_at( &self.inner, UiRegion::FULL, - [Place::Within(None), Place::Within(Some(top))], + [Place::Within(Part::All), Place::Within(Part::From(top))], ); Size::LEFTOVER } @@ -880,8 +880,8 @@ fn resizing_a_fixed_frame_recomposes_its_contents_without_drawing_them() { &self.child, UiRegion::FULL, [ - Place::Within(Some(self.region.x)), - Place::Within(Some(self.region.y)), + Place::Within(Part::From(self.region.x)), + Place::Within(Part::From(self.region.y)), ], ); Size::LEFTOVER @@ -940,43 +940,6 @@ fn resizing_a_fixed_frame_recomposes_its_contents_without_drawing_them() { } } -#[test] -fn a_span_does_not_place_its_measurement_before_assigning_the_childs_slot() { - struct MeasuredBox(Rc>); - - impl Widget for MeasuredBox { - fn draw(&mut self, painter: &mut Painter) -> Size { - self.0.set(self.0.get() + 1); - painter.px_size(); - painter.primitive(RectPrimitive::color(Color::BLUE)); - Size::from((100, 50)) - } - } - - let mut h = Harness::new((400, 200)); - let draws = Rc::new(Cell::new(0)); - let leaf = MeasuredBox(draws.clone()).add(&mut h.rsc); - h.set_root((leaf,).span(Dir::RIGHT).width(rel(1.0)).height(rel(1.0))); - - assert_eq!(draws.get(), 3); - assert_corners!(h, leaf, (0, 75), (100, 125)); - assert_eq!( - primitive_bounds(&h, leaf.id()), - vec![h.region(&leaf.id()).unwrap()] - ); - h.frame(); - assert_eq!(draws.get(), 3); - - h.resize((600, 300)); - h.frame(); - assert_eq!(draws.get(), 6); - assert_corners!(h, leaf, (0, 125), (100, 175)); - assert_eq!( - primitive_bounds(&h, leaf.id()), - vec![h.region(&leaf.id()).unwrap()] - ); -} - #[test] fn glyph_origins_compose_identically_when_drawn_and_when_retained() { struct Glyphs { @@ -1006,8 +969,8 @@ fn glyph_origins_compose_identically_when_drawn_and_when_retained() { &self.child, self.region, [ - Place::Fill(Some(self.extent.x)), - Place::Fill(Some(self.extent.y)), + Place::Fill(Part::From(self.extent.x)), + Place::Fill(Part::From(self.extent.y)), ], ); Size::LEFTOVER @@ -1176,8 +1139,8 @@ fn padding_and_stack_boxes_follow_the_extent_without_drawing_again() { &self.child, UiRegion::FULL, [ - Place::Fill(Some(self.extent.x)), - Place::Fill(Some(self.extent.y)), + Place::Fill(Part::From(self.extent.x)), + Place::Fill(Part::From(self.extent.y)), ], ); Size::LEFTOVER @@ -1264,11 +1227,11 @@ fn moving_an_extent_child_preserves_the_slot_chosen_from_its_measurement() { &self.child, UiRegion::FULL, [ - Place::Fill(Some(UiSpan::new( + Place::Fill(Part::From(UiSpan::new( Len::px(self.start), Len::px(self.start + 200.0), ))), - Place::Fill(Some(UiSpan::FULL)), + Place::Fill(Part::From(UiSpan::FULL)), ], ); Size::LEFTOVER @@ -1306,8 +1269,8 @@ fn extent_frames_keep_fractional_reports_and_numeric_dependencies_valid() { &self.child, UiRegion::FULL, [ - Place::Within(Some(self.region.x)), - Place::Within(Some(self.region.y)), + Place::Within(Part::From(self.region.x)), + Place::Within(Part::From(self.region.y)), ], ) .size() @@ -1326,8 +1289,8 @@ fn extent_frames_keep_fractional_reports_and_numeric_dependencies_valid() { &self.child, UiRegion::FULL, [ - Place::Fill(Some(self.extent.x)), - Place::Fill(Some(self.extent.y)), + Place::Fill(Part::From(self.extent.x)), + Place::Fill(Part::From(self.extent.y)), ], ) .size(),