std1.0.0-beta-7 SafeC docs

Module gui::gui_widget

#include <std/gui/gui_widget.h> source

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

GuiThemeColors, 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.
WidgetStyleThe 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.
WidgetTreeNodeOne node of a tree view.
WidgetColumnOne column of a table view.
Widget
GuiUiEverything 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

WidgetCallbackonClick/onChange/onActivate(widget, userData).
WidgetCanvasFnA canvas widget's draw(widget, canvas, userData).
WidgetDrawFnCustom 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(), ...).
WidgetLayoutFnCustom 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.
WidgetCustomEventFnCustom 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_boxA 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).

Macros

WIDGET_VSTACK
WIDGET_HSTACK
WIDGET_BUTTON
WIDGET_LABEL
WIDGET_CHECKBOX
WIDGET_TEXTINPUT
WIDGET_SPACER
WIDGET_SLIDER
WIDGET_CUSTOM
WIDGET_TOGGLE
WIDGET_RADIOa radio group: one choice of several items
WIDGET_PROGRESS
WIDGET_SPINNERnumber input with up/down buttons
WIDGET_TEXTAREA
WIDGET_COMBO
WIDGET_LIST
WIDGET_TREE
WIDGET_TABLE
WIDGET_TABS
WIDGET_SCROLL
WIDGET_SPLITTER
WIDGET_MENUBAR
WIDGET_MENUa menu: a menubar entry, a submenu, or a popup/context menu
WIDGET_MENUITEM
WIDGET_DIALOG
WIDGET_IMAGE
WIDGET_CANVAS
WIDGET_COLORcolor picker
WIDGET_GROUPtitled group box
WIDGET_SEPARATOR
WIDGET_STATUSBAR
WIDGET_GRID
WIDGET_STACKchildren overlap
WIDGET_PANELa box with background and border (a frame)
WIDGET_TOOLTIPshown by GuiUi
WIDGET_POPUPLISTa combo box's drop-down list
WIDGET_KIND_COUNT
WIDGET_ALIGN_STARTAlignment within the space a container gives a child.
WIDGET_ALIGN_CENTER
WIDGET_ALIGN_END
WIDGET_ALIGN_STRETCH
WIDGET_HORIZONTAL
WIDGET_VERTICAL
WIDGET_FIT_CONTAINImage view fit modes (Widget::set_fit).
WIDGET_FIT_COVERfill, aspect kept, cropped
WIDGET_FIT_STRETCH
WIDGET_FIT_NONEnatural size, centered
GUI_MB_OKMessage box buttons (gui_message_box) and dialog results.
GUI_MB_CANCEL
GUI_MB_YES
GUI_MB_NO
GUI_RESULT_NONE
GUI_RESULT_OK
GUI_RESULT_CANCEL
GUI_RESULT_YES
GUI_RESULT_NO
WIDGET_STYLE_BG
WIDGET_STYLE_FG
WIDGET_STYLE_BORDER
WIDGET_STYLE_PADDING
WIDGET_STYLE_SPACING
WIDGET_STYLE_FONT