UIWidget.h file
Widgets: node kinds with their own state and behaviour.
A widget is a struct. Its members are the per-node state; its methods are the hooks it wants. Hooks are detected at compile time: a missing one costs nothing, and one with the right name but the wrong signature fails to compile.
struct LogView { static constexpr std::string_view Name = "LogView"; uint64_t Top = 0; // state void Woken(WidgetHost<LogView>& host); // a watched revision changed void Sized(WidgetHost<LogView>& host); // layout gave it a new size void Valued(WidgetHost<LogView>& host); // its value changed (value widgets) void Language(WidgetHost<LogView>& host); // the language or the text measurer changed void Laid(WidgetHost<LogView>& host); // layout finished (after AfterLayout) void Focus(WidgetHost<LogView>& host, bool bFocused, bool bFromKeys); bool Text(WidgetHost<LogView>& host, const TextInputEvent& text); // typed, composed, or pasted bool Key(WidgetHost<LogView>& host, const InputEvent& input); // true = handled bool Wheel(WidgetHost<LogView>& host, float notches); // true = scrolled void Publish(const WidgetHost<LogView>& host, GGSnapshot& out) const; bool ScrollBar(const WidgetHost<LogView>& host, float& scrollY, float& contentHeight) const; void ScrollBarTo(WidgetHost<LogView>& host, float scrollY); // its scroll bar was dragged };
A widget also opts into services with constants: static constexpr bool EditsValue = true; (the value service, UIValues.h), TakesText (text input), ShowsFocus (shows focus however it was gained), and KeysFirst (its Key hook runs before commands and navigation).
Hooks get a WidgetHost<T>: the widget's node plus the part of the document a widget may use. It is deliberately not the UIContext. A widget only runs when an event reaches it, a revision it watches moves, or it asked to be woken, so an idle document stays idle.
A node becomes a widget where it is built (UI::Widget<T>):
if (auto box = ui.Widget<LogView>(where)) { box.Layout({ ... }); box.OnPress([](LogView& view, WidgetHost<LogView>& host, const PointerEvent& event) { ... }); box->Configure(box.Host(), lines, props); }
The core knows no widget by name. It holds one WidgetDef per kind, generated from the struct, and calls through it.
Namespaces
- namespace GGUI
Classes
- struct GGUI::WidgetDef
- The core's view of a widget kind: state size, construct/destruct, and one function pointer per hook the struct has. Generated by WidgetDefOf<T>; never written by hand.
- class GGUI::WidgetHostBase
- The document API available to every widget. WidgetHost<T> adds the typed state.
-
template<typename T>class GGUI::WidgetHost
- What a widget's hooks are given: its node, its typed state, and the document services it may use.