std1.0.0-beta-7 SafeC docs

Module gui::gui

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

GUI: cross-platform windows + software framebuffer.

The std/gui stack, bottom to top (include only what you use):

gui.h          windows, events, clipboard, cursors, the pixel buffer
gui_draw.h     the original integer primitives + 8x8 bitmap font
gui_canvas.h   anti-aliased 2D vector canvas (paths, gradients, images,
               transforms, clipping, blend modes, TrueType text)
gui_text.h     TrueType/OpenType fonts and text layout
gui_widget.h   retained widget toolkit (layout, theming, ~35 widgets)
gui_app.h      application object: many windows, one event loop,
               timers, animation frames
gui_backend.h  the interface a windowing backend implements
gui_headless.h an in-memory backend (tests, CI, offscreen rendering)
gui_gpu.h      GPU presentation (OpenGL ES/EGL, Metal, Direct3D 11, WebGL)
gui_wayland.h  the Wayland backend (Linux)
gui_web.h      the WebAssembly <canvas> backend

Exactly one platform backend is linked — safeguard picks it by the file's suffix for the target (see gui_backend.h for the contract):

std/gui/gui_cocoa.sc   macOS, via the Objective-C runtime + Core Graphics
std/gui/gui_win32.sc   Windows, via the Win32 API
std/gui/gui_x11.sc     Linux/BSD/Unix, via Xlib — and on Linux the
                       Wayland backend next to it, chosen at run time
                       when there is a compositor (gui_wayland.h)
std/gui/gui_web_wasm.sc  WebAssembly: <canvas> elements of a web page
                       (gui_web.h, with std/gui/gui_web.js)
std/gui/gui_fb.sc      bare metal, via a linear framebuffer (see gui_fb.h)

A program can also install another backend at run time before its first window (gui_set_backend(), gui_backend.h) — gui_headless.h's in-memory one (or any program: SAFEC_GUI_BACKEND=headless). Presenting can go through the GPU instead of a software blit: gui_gpu.h.

Every backend presents the same model: a window owns a CPU-side pixel buffer, 'pixels' — RGBA8888, premultiplied alpha, top-left origin, row-major, 4 bytes per pixel, R first in memory on every platform — that the application draws into (directly, through gui_draw.h, through gui_canvas.h, or through the widget toolkit), and win.present() puts it on the screen (the backend converts to its native pixel order on the way, or hands it to a GPU presenter: see gui_backend.h's GuiPresenter). Rasterization is always on the CPU, deterministic and identical on every backend: the same frame is the same bytes on Cocoa, Win32, X11, bare metal and the headless backend.

Sizes: a window's size is given in logical units (points on macOS, device-independent pixels on Windows, pixels on X11). With GuiWindowOptions.hiDpi set, the pixel buffer is the window's size times the display's scale factor (win.scale, e.g. 2.0 on a Retina display), so drawing is sharp; otherwise scale is 1 and the OS scales the window up. Event coordinates and win.width/height are always in buffer pixels.

Structs

GuiColorAn RGBA color, straight (not premultiplied) alpha — the canvas premultiplies when it blends. Lives here (rather than in gui_draw.h) so GuiWindow can declare its drawing methods without the core header depending on any add-on header.
GuiEvent
GuiWindowOptionsEverything GuiWindow::create_with() can be told. Start from GuiWindowOptions::new(title, w, h) and change fields.
GuiWindow

Functions

gui_time_msMilliseconds on a monotonic clock (the headless backend's is virtual and only moves with gui_headless_advance()).
gui_clipboard_set_textThe system clipboard, as UTF-8 text. set returns 1 on success; get replaces 'out' with the clipboard's text and returns 1, or returns 0 (leaving 'out' empty) when there is no text on it. Needs a window to exist on X11 (the clipboard is owned by a window there).
gui_clipboard_get_text
gui_primary_modGUI_MOD_META on macOS, GUI_MOD_CTRL elsewhere (for the backend in use).
gui_display_scaleThe display scale factor new hiDpi windows will get (1.0, 1.25, 2.0, ...).

Macros

GUI_EVENT_NONEEvent/key constants are plain #defines (not enums) to match the rest of the standard library's convention for cross-namespace constant access (see e.g. std/serial/protobuf.h's PB_WIRE_* ) — a real 'enum' declared inside 'namespace std' can't be referenced from user code as 'std::SOME_CONSTANT' the way a free function or #define can.
GUI_EVENT_CLOSEthe user asked to close the window (title-bar close, Alt+F4, ...)
GUI_EVENT_RESIZEwidth/height: the new buffer size (already applied to win.pixels)
GUI_EVENT_MOUSE_DOWN
GUI_EVENT_MOUSE_UP
GUI_EVENT_MOUSE_MOVE
GUI_EVENT_KEY_DOWNkeycode + modifiers; codepoint = the typed character, if any
GUI_EVENT_KEY_UP
GUI_EVENT_CHARa typed character with no KEY_DOWN to carry it (IME, compose)
GUI_EVENT_SCROLLscrollDx/scrollDy in "lines" (+y = away from the user / up)
GUI_EVENT_FOCUS_INthe window became the keyboard-focus window
GUI_EVENT_FOCUS_OUT
GUI_EVENT_MOVEx/y: the window's new position on screen (logical units)
GUI_EVENT_MOUSE_ENTER
GUI_EVENT_MOUSE_LEAVE
GUI_EVENT_SCALEthe scale factor changed (moved to another display); width/height = new buffer size
GUI_EVENT_EXPOSEthe OS lost the window's contents: present again
GUI_KEY_UNKNOWNPortable key codes for GUI_EVENT_KEY_DOWN/UP's 'keycode' field — each backend translates its own native key codes into these, so application code never sees a platform-specific key code. Letter keys are their upper-case ASCII value ('A'..'Z' = 65..90) and digit keys theirs ('0'..'9' = 48..57), whatever the keyboard layout's shift state.
GUI_KEY_LEFT
GUI_KEY_RIGHT
GUI_KEY_UP
GUI_KEY_DOWN
GUI_KEY_ENTER
GUI_KEY_ESCAPE
GUI_KEY_TAB
GUI_KEY_BACKSPACE
GUI_KEY_SPACE
GUI_KEY_DELETE
GUI_KEY_HOME
GUI_KEY_END
GUI_KEY_PAGE_UP
GUI_KEY_PAGE_DOWN
GUI_KEY_INSERT
GUI_KEY_F1F1..F12 = 16..27
GUI_KEY_F12
GUI_KEY_SHIFT
GUI_KEY_CONTROL
GUI_KEY_ALT
GUI_KEY_METACommand (macOS), Windows/Super key
GUI_KEY_MENU
GUI_MOD_SHIFTGuiEvent.modifiers bits (held while the event happened).
GUI_MOD_CTRL
GUI_MOD_ALTOption on macOS
GUI_MOD_METACommand on macOS, Windows/Super key elsewhere
GUI_BUTTON_LEFTGuiEvent.button.
GUI_BUTTON_RIGHT
GUI_BUTTON_MIDDLE
GUI_CURSOR_ARROWMouse cursor shapes (GuiWindow::set_cursor).
GUI_CURSOR_IBEAM
GUI_CURSOR_HAND
GUI_CURSOR_CROSSHAIR
GUI_CURSOR_RESIZE_EW↔
GUI_CURSOR_RESIZE_NS↕
GUI_CURSOR_RESIZE_NWSE
GUI_CURSOR_RESIZE_NESW
GUI_CURSOR_MOVE
GUI_CURSOR_WAIT
GUI_CURSOR_NOT_ALLOWED
GUI_CURSOR_HIDDEN
GUI_CURSOR_COUNT
GUI_POS_DEFAULTGuiWindowOptions.x/y: let the window system place the window.
GUI_PRESENT_DEFAULTGuiWindowOptions.present: how win.present() gets the buffer on screen (see gui_gpu.h). Either way rendering stays on the CPU.
GUI_PRESENT_GPUthrough the GPU (OpenGL ES/EGL, Metal, Direct3D 11); CPU if that fails
GUI_PRESENT_CPUthe backend's software blit, whatever the environment says