`declared_lens` filtered `leftover` out of both its sources and every consumer then re-dropped it, so the rule lived in two filters and a comment. A declaration is a `Len`: `LayoutLen::declared` states the rule once and both sources go through it, and `Declared` replaces the bare two-element array on `ActiveData` and in four signatures. The two sources stay one value deliberately. A rule decides the child's box; a hint only promises what it will report -- but `size_hint` is by contract an exact answer with no painter context, and `hints_agree` fails a widget that draws something else, so narrowing the box to a hint cannot change what is drawn. Every consumer asks about the length, never which said it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
88 lines
4.2 KiB
Rust
88 lines
4.2 KiB
Rust
use crate::{
|
|
Declared, LayerId, LayoutHolds, MaskIdx, MoveIdx, PlaceDesc, RegionAlign, RetainedPrimitive,
|
|
Size, TextureHandle, UiRegion, UiVec2, WidgetId,
|
|
};
|
|
|
|
/// What is kept of a widget its parent has asked about. `drawn` says whether
|
|
/// it currently draws; one that does not is kept so that a change to it, or
|
|
/// under it, still reaches whoever asked.
|
|
#[derive(Debug)]
|
|
pub struct ActiveData {
|
|
pub id: WidgetId,
|
|
/// Where its drawing goes, in its region node's coordinates.
|
|
pub placement: UiRegion,
|
|
/// What a fraction declared or reported under this widget is a fraction
|
|
/// of, as a length of the window.
|
|
pub rel_base: UiVec2,
|
|
/// Where its drawing was put, and where it was asked. The two differ
|
|
/// where a container asks in one place and puts the answer in another --
|
|
/// a row measures from its cursor and puts the child in its slot. Each
|
|
/// carries the rel base that ask stated, so asking again from either is
|
|
/// the same question it was.
|
|
pub placed: PlaceDesc,
|
|
pub asked: PlaceDesc,
|
|
/// The box it was asked in, in the parent's region-node coordinates: the
|
|
/// box its drawing was made in and the one its contract is about. Its
|
|
/// drawing is placed elsewhere by re-expression, never by asking again.
|
|
pub region: UiRegion,
|
|
/// The measured answer and its dependencies. A hint-only dependency or
|
|
/// a widget first encountered during placement has no measurement yet.
|
|
pub answer: Option<(Size, LayoutHolds)>,
|
|
/// Asked more than once in its parent's last draw -- measured in one box
|
|
/// and then asked in the one the parent decided. The parent's layout
|
|
/// rests on the first answer and its drawing on the last, so only the
|
|
/// parent can ask either again.
|
|
pub re_asked: bool,
|
|
/// What the widget reported, in window-unit lengths.
|
|
pub size: Size,
|
|
/// The window and region reads that this drawing holds for, and the
|
|
/// rel base and region it pinned.
|
|
pub holds: LayoutHolds,
|
|
pub drawn: bool,
|
|
pub parent: Option<WidgetId>,
|
|
/// How far down the tree it was drawn, the root being 1. Carried down a
|
|
/// draw rather than worked out by walking up, so it is right for every
|
|
/// widget a frame visits and cannot drift while one is being drawn.
|
|
pub depth: usize,
|
|
pub textures: Vec<TextureHandle>,
|
|
/// Its primitives, each keeping the box it was written in -- in this
|
|
/// widget's placement coordinates, which is what a move recomposes from.
|
|
pub primitives: Vec<RetainedPrimitive>,
|
|
/// An owned mask holds one reference independently of its primitives.
|
|
pub mask_region: Option<UiRegion>,
|
|
pub children: Vec<WidgetId>,
|
|
/// The children whose size this widget read while drawing.
|
|
pub size_deps: Vec<WidgetId>,
|
|
/// The movable region its primitives are positioned through: its own when
|
|
/// opted in, otherwise the nearest ancestor's.
|
|
pub move_idx: MoveIdx,
|
|
/// The declared lengths whoever drew this widget resolved into its rel base.
|
|
/// A change to one moves a box this widget cannot fix by drawing again,
|
|
/// and comparing them is what says so.
|
|
pub declared: Declared,
|
|
/// Its alignment when it was last drawn, which a change to the property
|
|
/// is found against.
|
|
pub own_align: RegionAlign,
|
|
/// The movable region whose coordinates its placement is in when this
|
|
/// widget does not own a region node.
|
|
pub parent_move: MoveIdx,
|
|
/// The mask its drawing is clipped to: one it set itself, or the one it
|
|
/// inherited from whoever drew it.
|
|
pub mask: MaskIdx,
|
|
/// That inherited one. The two differ exactly where the widget set a
|
|
/// mask of its own, which is the one it owns and the one a move rewrites
|
|
/// -- and the one a redraw of it must not be handed back, since setting
|
|
/// a mask asserts there is none.
|
|
pub parent_mask: MaskIdx,
|
|
pub layer: LayerId,
|
|
}
|
|
|
|
impl ActiveData {
|
|
/// What it answered when its parent asked, where it has been asked at
|
|
/// all. Not `size`, which is what its last drawing reported: a drawing
|
|
/// re-expressed in the box that answer chose is not a second answer.
|
|
pub fn measured(&self) -> Option<Size> {
|
|
self.answer.map(|(size, _)| size)
|
|
}
|
|
}
|