ui::VisualTree¶
Header: winui/ui/VisualTree.hpp.
A flat, data-oriented snapshot of the laid-out tree's shape: one slot per Element, with parent / first-child / next-sibling links by stable VisualId, bounds and dirty flags held in parallel arrays.
Window::layout() clears and rebuilds it on every pass that re-lays out, through Element::build_visual_tree(), and hands it out read-only via Window::visual_tree(). It is an inspection surface (tests, tooling), not a way to drive controls: changes go through the Element tree. Slots are indices in pre-order and are only valid until the next rebuild; a VisualId stays the same across rebuilds.
Example:
// Every element of a laid-out window, flat, for a tool that inspects the tree:
const ui::VisualTree& tree = window.visual_tree();
for (std::size_t slot = 0; slot < tree.size(); ++slot)
{
const ui::Rect& bounds = tree.bounds_at(slot);
std::println("{} under {}: {}x{}", tree.id_at(slot), tree.parent_at(slot), bounds.width, bounds.height);
}
// And one element by its id, here a button built with `.control = save_button`:
ui::Control<ui::Button> save_button;
std::size_t slot = 0;
if (save_button && tree.find(save_button->visual_id(), slot))
{
std::println("Save is at {}, {}", tree.bounds_at(slot).x, tree.bounds_at(slot).y);
}
clear¶
Drops every node; the tree is empty (size() == 0) afterwards.
add_node¶
std::size_t add_node(VisualId id, VisualId parent, const Rect& bounds, DirtyFlags flags_at_build = DirtyFlags::None)
Append a node under parent (InvalidVisualId for the root) and return its slot. id must be unique within the tree and, if parent is not InvalidVisualId, parent must already be in the tree (asserted). Nodes are expected in pre-order (parent before children), which is how Element::build_visual_tree walks the logical tree; a new child becomes the last in its parent's sibling chain. bounds is in window DIPs and flags_at_build records what was still dirty when the snapshot was taken.
size¶
The number of nodes; valid slots are 0 .. size() - 1, in insertion (pre-)order.
id_at¶
The stable VisualId of the node in slot. The *_at() accessors do not bounds-check.
parent_at¶
The parent's id, or InvalidVisualId for the root.
first_child_at¶
The first child's id, or InvalidVisualId for a leaf.
next_sibling_at¶
The next child of the same parent, in add order, or InvalidVisualId for the last one.
bounds_at¶
The node's arranged bounds at snapshot time, in window DIPs.
flags_at¶
The node's dirty flags at snapshot time (Window::layout() builds before clearing them).
find¶
Look up a node's slot by its stable id in O(1). Returns false, leaving out_slot untouched, when no node has that id.