The widget set

The retained widget tree

A widget is a node in a retained tree with two-phase layout: measure (how big do I want to be, given an available width) then arrange (here is your final rect). A WidgetView hosts the tree inside a region, lays it out, draws it, and routes events with a capture slot for modal drags and a focus slot for typing.

struct Widget {
    virtual Size measure(const Theme&, float availW) = 0;
    virtual void arrange(const Theme&, Rect);
    virtual void draw(gpu::Canvas&, const Theme&) = 0;
    virtual bool handle(const Event&) { return false; }
};

The control set

The toolkit ships the controls a real application needs, each drawn through the theme (no hardcoded colours) and acting on synthesized intent:

Construction without ceremony

Widgets are built through the Build.h factories so a tree is one readable expression — containers take their children directly, leaves configure up front, and there is no make_unique, static_cast, or move at the call site:

auto panel = column(
    title("Transform"),
    field("Position", numberField(0.0f)),
    field("Visible",  checkbox(true)),
    row(flex(button("Cancel"), 1), flex(button("Apply"), 2)));

flex(child, weight) weights a row child; cfg(widget, fn) tweaks any extra knob in place. This parsimony is the toolkit's house style: the common thing is short, and the easy way is the safe way.

Acting on intent

Momentary controls fire on a clean Click (press + release with no drag), so pressing a button and dragging away cancels it — the desktop-correct behaviour. Drags begin on the first Drag event past the threshold (a NumberField scrub, a list reorder). Because the event-value model synthesizes this uniformly, every widget agrees on what a click is. Hover, active and focused states are tracked per widget and drawn through the theme, so the whole set restyles at once when the theme changes.