use crate::{ LayerId, LayoutHolds, LayoutLen, Len, MaskIdx, MoveIdx, Place, 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 extent: UiRegion, /// What a fraction declared or reported under this widget is a fraction /// of, as a length of the window. pub frame: UiVec2, /// A frame its parent decided for it on each axis -- a row's slot, or /// padding's frame less its pixels -- as a length of the window. `None` /// forwards the parent's frame. What it declared is kept separately in /// `declared` and is a fraction of whichever of the two reached it. pub narrow: [Option; 2], /// Where its drawing was put, as a part of its parent's box, and where /// it was asked. The two differ where a container asks in one place and /// places the answer in another -- a row measures from its cursor and /// puts the child in its slot. A part is a length from the box's start, /// so a box that moved re-places every child by re-adding that start. pub place: [Place; 2], pub offer_place: [Place; 2], /// 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 offer_part: 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 extent reads that this drawing holds for, and the /// frame and box it pinned. pub holds: LayoutHolds, pub drawn: bool, pub parent: Option, /// 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, /// Its primitives, each keeping the box it was written in -- in this /// widget's extent coordinates, which is what a move recomposes from. pub primitives: Vec, pub mask_region: Option, pub children: Vec, /// The children whose size this widget read while drawing. pub size_deps: Vec, /// 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 frame. /// A change to one moves a box this widget cannot fix by drawing again, /// and comparing them is what says so. pub declared: [Option; 2], /// 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 `extent` uses 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 measured it, where it has been /// measured at all. Not `size`, which is what its last drawing reported: /// a drawing made in the box that answer chose is answering a different /// question. pub fn measured(&self) -> Option { self.answer.map(|(size, _)| size) } /// Whether what it answered still stands in this window, for the frame /// and the box it was asked in. The answer was given in the box its /// parent first asked about, which is what it is checked against -- /// `holds` on the record is about the box the answer then chose. pub fn answers_at(&self, window: crate::PxVec2, part: UiRegion) -> bool { self.answer .is_some_and(|(_, holds)| holds.contains(window, self.frame, part)) } }