Module gui::gui_widget
GUI: the retained-mode widget toolkit.
A tree of Widgets — containers (vertical/horizontal boxes, grids, overlapping stacks, scroll views, splitters, tabs, group boxes, panels) and controls (labels, buttons, toggles, check boxes, radio groups, sliders, progress bars, number spinners, text inputs, multi-line text areas, combo boxes, list / tree / table views, menu bars and context menus, tooltips, modal dialogs and message boxes, images, a vector canvas, a color picker, separators, status bars) — laid out, painted with the anti-aliased canvas (gui_canvas.h) in a light or dark theme, and driven by GuiEvents with keyboard focus, Tab navigation, hover / pressed / disabled states and the clipboard.
&Widget root = Widget::vstack();
&Widget name = Widget::textinput("Your name");
root.add_child(Widget::label("Hello!"));
root.add_child(name);
root.add_child(Widget::button("OK").on_click(ok_clicked, (?&State)&state));
Driving it: with gui_app.h's GuiApp (app.set_root(win, root) — events, layout, painting, timers and tooltips are then automatic, for any number of windows), or by hand, once per frame:
while (win.poll_event(&ev)) { root.dispatch_event(&ev); }
root.render(&win); // layout + paint into win.pixels
win.present();
The by-hand calls work on the root widget (as before this toolkit existed: root.layout(x, y, w, h), root.render(&win), root.dispatch_event(&ev)) and use a GuiUi created for it on first use; GuiUi::new(root) gives you that object to hold (themes, focus, popups, dialogs, tooltips, scale).
Units: sizes given to widgets (set_pref_size, set_min_size, margins, padding, fonts) are logical; the GuiUi multiplies them by the window's scale factor, so a hiDpi window gets the same layout at twice the pixels. Widget rects (x, y, w, h) are in window pixels.
Layout model: each widget has a natural size (its content, plus padding; set_pref_size() overrides either dimension; min/max sizes clamp it) and margins. Boxes place children in a row or column with 'spacing' between them, give extra space to children with a stretch weight (set_stretch, in proportion), and shrink stretching children (down to their minimum) when space is short; on the cross axis each child is aligned by set_alignment() (START/CENTER/END/STRETCH). Grids size columns and rows to their widest/tallest cell, with stretch weights per column/row (set_column_stretch / set_row_stretch) and cells spanning several. Stacks overlap children, each aligned on both axes. Scroll views give their child its natural size and scroll the rest into view.
Callbacks receive the widget and a typed user-data reference (stored erased, see the note on Widget's callback fields):
on_click(cb, data) buttons, menu items, toggles/check boxes (after the change), links
on_change(cb, data) any value change: text, check state, slider/spinner value,
selection, color, splitter position, tab
on_activate(cb, data) double click / Enter on a list, tree or table row
on_draw(cb, data) Widget::canvas: draw with the vector canvas
Keyboard: Tab / Shift+Tab move focus through the focusable widgets in tree order (skipping hidden and disabled ones, staying inside an open modal dialog); Space/Enter activate buttons, toggles and check boxes; arrows move sliders, spinners, radio groups, list/tree/table selections and tabs; Escape closes a popup, a dialog, or clears focus; menu item shortcuts (set_shortcut("Ctrl+S"), or the primary modifier on macOS) fire from anywhere in the window. Text fields support selection with Shift+arrows/Home/End and the mouse (double click selects a word, triple click everything), word-wise moves with Ctrl (Alt on macOS), and Cut/Copy/Paste/Select-all through the system clipboard.
Structs
| GuiTheme | Colors, fonts and metrics every built-in widget paints with. Metrics are logical units (scaled by the window's scale factor). Start from light() or dark() and change fields; GuiUi::set_theme() applies one. |
| WidgetStyle | The original per-widget style. Each field, once set through a setter (set_bg, set_fg, set_border, set_padding, set_spacing, set_font_scale, set_font), overrides the theme for that widget; until then the theme decides. 'font' (a bitmap GuiFont) replaces the TrueType theme font when set; fontScale then multiplies its cells, and otherwise multiplies the theme's font size. |
| WidgetTreeNode | One node of a tree view. |
| WidgetColumn | One column of a table view. |
| Widget | |
| GuiUi | Everything a widget tree needs that isn't a widget: the window it's shown in, the theme and scale, keyboard focus, the pointer, open popups (menus, drop-down lists, tooltips) and modal dialogs, and the canvas it paints with. One per window. GuiApp makes them (GuiApp::set_root); Widget::render/dispatch_event make one on first use for a root that has none; or make one yourself. |
Type aliases
| WidgetCallback | onClick/onChange/onActivate(widget, userData). |
| WidgetCanvasFn | A canvas widget's draw(widget, canvas, userData). |
| WidgetDrawFn | Custom draw(window, widget) — called instead of the built-in renderer for a WIDGET_CUSTOM node; must draw within [widget->x, widget->x+widget->w) x [widget->y, widget->y+widget->h) using GuiWindow's drawing methods (win.fill_rect(), win.draw_text(), ...). |
| WidgetLayoutFn | Custom layout(widget, x, y, w, h) — called instead of the built-in layout for a WIDGET_CUSTOM node; must set widget->x/y/w/h (typically to the given box) and lay out+recurse into any children itself. |
| WidgetCustomEventFn | Custom event(widget, event) -> 1 if handled (stops the event from reaching this widget's parent/siblings), 0 to let normal dispatch (hover/press/click detection) continue. |
Functions
| gui_message_box | A standard message box: 'text' and a row of buttons (GUI_MB_* bits), shown modally. onClose(dialog, result) runs once a button (result GUI_RESULT_*) or Escape (GUI_RESULT_CANCEL) closed it; the box frees itself afterwards. The buttons are named "yes", "no", "ok" and "cancel" (Widget::find). |