Hold the output as the box every chain bottoms out in
A position was composed up the slot chain to a normalized region and then multiplied by the output's size, so the window was the one box in the system that was not a box. Seeding the chain with a root slot holding it in pixels makes composing through it leave everything below in pixels, which is what the multiplication was doing. `within` already does the arithmetic: a child at `rel` 1 inside a span of `px` 0 to `px` 1920 composes to `px` 1920 and `rel` 0, so the trailing `to_px` becomes the identity rather than a step. The shader walks the same chain and needs no change for the same reason. This is the shape the resize machinery wants before it can be deleted: a resize becomes one slot written, which `try_reuse` and `redraws_under` already carry. Nothing is removed yet. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
7c50a3e51b
commit
9f4311774b
2 files changed
+28
-3
No files matched your search
@@ -2,7 +2,7 @@
|
|||||||
use crate::layout_diagnostics::{self as diag, Counter, ReuseOutcome, TimerKind};
|
use crate::layout_diagnostics::{self as diag, Counter, ReuseOutcome, TimerKind};
|
||||||
use crate::{
|
use crate::{
|
||||||
ActiveData, Axis, DrawLayers, IdLike, MaskIdx, MoveIdx, Moves, OnResize, Painter, PixelRegion,
|
ActiveData, Axis, DrawLayers, IdLike, MaskIdx, MoveIdx, Moves, OnResize, Painter, PixelRegion,
|
||||||
Size, StrongWidget, UiRegion, UiRsc, WidgetId, Widgets,
|
Size, StrongWidget, UiRegion, UiRsc, UiScalar, UiSpan, WidgetId, Widgets,
|
||||||
util::{HashMap, HashSet, Vec2},
|
util::{HashMap, HashSet, Vec2},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -19,6 +19,8 @@ pub struct UiRenderState {
|
|||||||
pub(super) output_size: Vec2,
|
pub(super) output_size: Vec2,
|
||||||
|
|
||||||
old_root: Option<WidgetId>,
|
old_root: Option<WidgetId>,
|
||||||
|
/// The slot every chain bottoms out in, holding the output as a box.
|
||||||
|
root_move: MoveIdx,
|
||||||
resized: [bool; 2],
|
resized: [bool; 2],
|
||||||
/// Content/state dirtiness whose retained size cannot answer a layout
|
/// Content/state dirtiness whose retained size cannot answer a layout
|
||||||
/// question until that widget has drawn again.
|
/// question until that widget has drawn again.
|
||||||
@@ -50,6 +52,22 @@ impl UiRenderState {
|
|||||||
draw_started: Default::default(),
|
draw_started: Default::default(),
|
||||||
slots: Default::default(),
|
slots: Default::default(),
|
||||||
moves: Default::default(),
|
moves: Default::default(),
|
||||||
|
root_move: MoveIdx::NONE,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The window as a box, so a chain bottoms out in one rather than in a
|
||||||
|
/// multiplication applied after it. Composing through a box held in
|
||||||
|
/// pixels leaves everything below it in pixels, which is why nothing
|
||||||
|
/// 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::px(self.output_size.x)),
|
||||||
|
UiSpan::new(UiScalar::ZERO, UiScalar::px(self.output_size.y)),
|
||||||
|
);
|
||||||
|
match self.root_move == MoveIdx::NONE {
|
||||||
|
true => self.root_move = self.moves.push(MoveIdx::NONE, region),
|
||||||
|
false => self.moves.set(self.root_move, region),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,6 +77,7 @@ impl UiRenderState {
|
|||||||
*resized |= size.axis(axis) != self.output_size.axis(axis);
|
*resized |= size.axis(axis) != self.output_size.axis(axis);
|
||||||
}
|
}
|
||||||
self.output_size = size;
|
self.output_size = size;
|
||||||
|
self.write_root();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn output_size(&self) -> Vec2 {
|
pub fn output_size(&self) -> Vec2 {
|
||||||
@@ -149,6 +168,7 @@ impl UiRenderState {
|
|||||||
let _layout = diag::timer(TimerKind::FullLayout);
|
let _layout = diag::timer(TimerKind::FullLayout);
|
||||||
self.clear(rsc);
|
self.clear(rsc);
|
||||||
// free all resources & cache
|
// free all resources & cache
|
||||||
|
self.write_root();
|
||||||
if let Some(id) = root {
|
if let Some(id) = root {
|
||||||
self.draw_inner(
|
self.draw_inner(
|
||||||
0,
|
0,
|
||||||
@@ -156,7 +176,7 @@ impl UiRenderState {
|
|||||||
UiRegion::FULL,
|
UiRegion::FULL,
|
||||||
None,
|
None,
|
||||||
1,
|
1,
|
||||||
MoveIdx::NONE,
|
self.root_move,
|
||||||
false,
|
false,
|
||||||
MaskIdx::NONE,
|
MaskIdx::NONE,
|
||||||
None,
|
None,
|
||||||
@@ -589,6 +609,7 @@ impl UiRenderState {
|
|||||||
}
|
}
|
||||||
self.slots.clear();
|
self.slots.clear();
|
||||||
self.moves.clear();
|
self.moves.clear();
|
||||||
|
self.root_move = MoveIdx::NONE;
|
||||||
self.layers.clear();
|
self.layers.clear();
|
||||||
self.invalid_sizes.clear();
|
self.invalid_sizes.clear();
|
||||||
self.resize_marks.clear();
|
self.resize_marks.clear();
|
||||||
|
|||||||
+5
-1
@@ -180,5 +180,9 @@ fn only_a_container_that_places_its_children_lengthens_the_chain() {
|
|||||||
h.set_root((bar, buried).span(Dir::RIGHT));
|
h.set_root((bar, buried).span(Dir::RIGHT));
|
||||||
|
|
||||||
let slot = h.render.active[&leaf.id()].parent_move;
|
let slot = h.render.active[&leaf.id()].parent_move;
|
||||||
assert_eq!(h.render.moves.depth(slot), 1, "one span above the leaf");
|
assert_eq!(
|
||||||
|
h.render.moves.depth(slot),
|
||||||
|
2,
|
||||||
|
"the span above the leaf, and the root the window is held in"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user