Skip to content

Native UI

Responsibility

The native UI layer coordinates a stack of screen regions, resize and redraw invalidation, curses-compatible windows, SDL/tile rendering, lists, popups, and newer ImGui surfaces. ui_adaptor is the central lifetime and redraw boundary.

Entry points

Start with src/ui_manager.h / .cpp, then ui_helpers, uilist, and the focused screen. Register on_screen_resize and on_redraw, set the adaptor's region, and drive it through an input_context.

Data ownership

A stack-local ui_adaptor owns callbacks and membership in the UI stack by RAII. The screen function owns its windows and view model; render backends own textures/buffers; global uistate stores only intentionally persistent presentation choices.

Dependencies

UI depends on input contexts, translation, color/font and terminal metrics, render backends, game view models, Android UI mode, and optional Lua UI/ImGui integration.

Lifecycle

Constructing an adaptor pushes it, resize establishes geometry, redraw paints only that region, input may trigger more resize/redraw events, and destruction pops it. Callbacks must not mutate the adaptor stack during a redraw.

Invariants

Declared geometry contains all drawing; callbacks obey manager reentrancy rules; the top UI owns input focus; window sizes use cells unless an absolute pixel API is explicit; and resize invalidates layout before drawing.

Extension points

Use a local adaptor and input context for a native screen. Put reusable layout in helpers; expose data to Lua only through the bounded public API, never by leaking a native UI pointer.

Serialization

Adaptors, windows, callbacks, and renderer resources are ephemeral. Persist only explicit user configuration or uistate fields, with defaults and tests; reconstruct layout after load.

Tests

Use UI profile and screen-specific tests, plus resize, narrow-terminal, keyboard, tiles/curses, Android touch, and Lua-disabled paths where applicable.

Performance

Redraw runs frequently. Limit invalidated regions, avoid rebuilding expensive view models in the paint callback, and prevent transparent ImGui layers from leaving stale SDL pixels.

CCB divergence

CCB combines legacy native screens with project-specific Lua UI, ImGui, and Android HUD paths. Upstream UI ports must preserve all enabled backend and input-mode boundaries.

Technical debt

Cell, pixel, curses, SDL, ImGui, and Android abstractions coexist. New screens should keep geometry explicit and avoid another global redraw or input shortcut.