Ask each child once and place its answer by re-expression
A widget draws in the box it is asked in and its answer is placed inside that box by re-expressing the drawing; nothing is drawn again in a box an answer chose. The offer machinery, whose job was to tell a measuring draw from a placing one, goes with the placing draw. A span measures each child from its cursor and moves fixed children to their slots with place_at; a share child is asked once more in its decided slot with its frame narrowed to it. A stack asks non-sizing children in the box its sizing child decided. A scroll asks its content once and moves it to the scrolled offset. A local redraw asks the retained question again and puts the answer back where the parent placed it. A symbolic length a child pinned composes through Part::Of exactly where the part is the whole box less pixels, and pins the parent's own length otherwise; dropping it let a pad reuse a drawing across a narrowed frame of the same pixel length (shrinker seeds 60, 248 and 384 at depth 5). Suite 114/114 including the two decided-box pins, fast oracle 11/11, shrinker 400 seeds at depth 5 over all fifteen cases. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
4328eac756
commit
3091fb86df
12 files changed
+353
-354
No files matched your search
@@ -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, UiRegion::FULL, [Place::Within(Part::All), top])
|
||||
.widget_at(&self.probe, [None; 2], [Place::Within(Part::All), top])
|
||||
.len(Axis::X);
|
||||
let px = measured.apply_leftover().to_px(painter.px_len(Axis::X));
|
||||
|
||||
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),
|
||||
true => painter.widget_at(&self.wide, [None; 2], place),
|
||||
false => painter.widget_at(&self.narrow, [None; 2], place),
|
||||
};
|
||||
Size::LEFTOVER
|
||||
}
|
||||
|
||||
+16
-17
@@ -156,9 +156,9 @@ fn a_span_child_that_declares_its_length_is_drawn_once() {
|
||||
h.set_root((hinted, asked).span(Dir::RIGHT));
|
||||
|
||||
assert_eq!(told_draws.get(), 1);
|
||||
// Only the available length changes: positioning the final slot does
|
||||
// not invalidate a numeric size read.
|
||||
assert_eq!(asked_draws.get(), 2);
|
||||
// Asked once, from the cursor; its slot is its answer and the drawing is
|
||||
// moved there.
|
||||
assert_eq!(asked_draws.get(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -216,7 +216,7 @@ impl Widget for FromHint {
|
||||
let top = UiSpan::new(Len::ZERO, Len::from_parts(Rel::ZERO, len.px));
|
||||
painter.widget_at(
|
||||
&self.inner,
|
||||
UiRegion::FULL,
|
||||
[None; 2],
|
||||
[Place::Within(Part::All), Place::Within(Part::From(top))],
|
||||
);
|
||||
Size::LEFTOVER
|
||||
@@ -255,10 +255,9 @@ impl Widget for ReadsBox {
|
||||
/// Reads its box across one axis only, so its drawing holds for a taller
|
||||
/// box on its own and only a wider one is worth a draw.
|
||||
///
|
||||
/// Both of these report a quarter of what they read, without saying that the
|
||||
/// drawing holds there too, so each length they are asked at costs two draws:
|
||||
/// one to answer, and one in the quarter-sized box that answer places them
|
||||
/// in. The counts below are in those pairs.
|
||||
/// Both of these report a quarter of what they read. The quarter-sized box
|
||||
/// the answer places them in is not a question: the drawing is moved there,
|
||||
/// so each length they are asked at costs one draw.
|
||||
struct ReadsWidth {
|
||||
draws: Rc<Cell<usize>>,
|
||||
}
|
||||
@@ -384,7 +383,7 @@ fn a_resize_redraws_what_read_its_box() {
|
||||
h.resize((800, 100));
|
||||
h.frame();
|
||||
|
||||
assert_eq!(draws.get(), settled + 2);
|
||||
assert_eq!(draws.get(), settled + 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -404,7 +403,7 @@ fn a_resize_only_redraws_read_axes() {
|
||||
|
||||
h.resize((800, 300));
|
||||
h.frame();
|
||||
assert_eq!(draws.get(), settled + 2, "width changes its answer");
|
||||
assert_eq!(draws.get(), settled + 1, "width changes its answer");
|
||||
}
|
||||
|
||||
/// A window is measured onto the grid like everything else, so a resize too
|
||||
@@ -431,7 +430,7 @@ fn a_resize_within_one_step_is_not_a_resize() {
|
||||
|
||||
h.resize((400.0 + step, 200.0));
|
||||
h.frame();
|
||||
assert_eq!(draws.get(), settled + 2);
|
||||
assert_eq!(draws.get(), settled + 1);
|
||||
}
|
||||
|
||||
/// The same for a box that changes because a sibling did: what is compared
|
||||
@@ -878,7 +877,7 @@ fn resizing_a_fixed_frame_recomposes_its_contents_without_drawing_them() {
|
||||
fn draw(&mut self, painter: &mut Painter) -> Size {
|
||||
painter.widget_at(
|
||||
&self.child,
|
||||
UiRegion::FULL,
|
||||
[None; 2],
|
||||
[
|
||||
Place::Within(Part::From(self.region.x)),
|
||||
Place::Within(Part::From(self.region.y)),
|
||||
@@ -967,7 +966,7 @@ fn glyph_origins_compose_identically_when_drawn_and_when_retained() {
|
||||
fn draw(&mut self, painter: &mut Painter) -> Size {
|
||||
painter.widget_at(
|
||||
&self.child,
|
||||
self.region,
|
||||
[Some(self.region.x.len()), None],
|
||||
[
|
||||
Place::Fill(Part::From(self.extent.x)),
|
||||
Place::Fill(Part::From(self.extent.y)),
|
||||
@@ -1137,7 +1136,7 @@ fn padding_and_stack_boxes_follow_the_extent_without_drawing_again() {
|
||||
fn draw(&mut self, painter: &mut Painter) -> Size {
|
||||
painter.widget_at(
|
||||
&self.child,
|
||||
UiRegion::FULL,
|
||||
[None; 2],
|
||||
[
|
||||
Place::Fill(Part::From(self.extent.x)),
|
||||
Place::Fill(Part::From(self.extent.y)),
|
||||
@@ -1225,7 +1224,7 @@ fn moving_an_extent_child_preserves_the_slot_chosen_from_its_measurement() {
|
||||
fn draw(&mut self, painter: &mut Painter) -> Size {
|
||||
painter.widget_at(
|
||||
&self.child,
|
||||
UiRegion::FULL,
|
||||
[None; 2],
|
||||
[
|
||||
Place::Fill(Part::From(UiSpan::new(
|
||||
Len::px(self.start),
|
||||
@@ -1267,7 +1266,7 @@ fn extent_frames_keep_fractional_reports_and_numeric_dependencies_valid() {
|
||||
painter
|
||||
.widget_at(
|
||||
&self.child,
|
||||
UiRegion::FULL,
|
||||
[None; 2],
|
||||
[
|
||||
Place::Within(Part::From(self.region.x)),
|
||||
Place::Within(Part::From(self.region.y)),
|
||||
@@ -1287,7 +1286,7 @@ fn extent_frames_keep_fractional_reports_and_numeric_dependencies_valid() {
|
||||
painter
|
||||
.widget_at(
|
||||
&self.child,
|
||||
UiRegion::FULL,
|
||||
[None; 2],
|
||||
[
|
||||
Place::Fill(Part::From(self.extent.x)),
|
||||
Place::Fill(Part::From(self.extent.y)),
|
||||
|
||||
Reference in new issue
Block a user