5.2 KiB
UI System
Source: src/dusk/ui/
See also: .claude/display-spritebatch.md, .claude/display-text.md,
.claude/display-color.md
Overview
The UI system renders overlaid interface elements on top of the scene each frame. It is called by the engine after the scene render pipeline and before the screen unbind -- game code does not drive it directly.
All UI elements render through the global SpriteBatch.
Lifecycle
extern ui_t UI;
errorret_t uiInit(void);
void uiUpdate(void);
errorret_t uiRender(void);
void uiDispose(void);
uiUpdate is called each game tick; uiRender is called each render
tick. The engine calls both automatically -- do not call them from
game scripts.
Element registration (uielement.h)
typedef struct {
uielementtype_t type; // UI_ELEMENT_TYPE_NULL or UI_ELEMENT_TYPE_NATIVE
errorret_t (*draw)(); // draw callback
} uielement_t;
extern uielement_t UI_ELEMENTS[]; // registered element array
uiRender iterates UI_ELEMENTS and calls each element's draw
callback. Elements register themselves during uiInit.
Elements
uiframe_t -- 9-slice border (uiframe.h)
A resizable bordered panel rendered using 9-slice (9-patch) technique from a 3x3 tileset.
typedef struct {
tileset_t tileset;
texture_t *texture;
} uiframe_t;
errorret_t uiFrameInit(uiframe_t *frame);
errorret_t uiFrameDraw(
const uiframe_t *frame,
const float_t x,
const float_t y,
const float_t width,
const float_t height
);
void uiFrameDispose(uiframe_t *frame); // does not dispose texture
uiFrameDraw pushes 9 quads (corners + edges + centre) to the
SpriteBatch without flushing. The caller must call spriteBatchFlush()
after all sprites for a draw pass are buffered.
uitextbox_t -- typewriter dialogue box (uitextbox.h)
A global single-instance dialogue box that displays text one character at a time with word-wrap and multi-page support.
extern uitextbox_t UI_TEXTBOX;
errorret_t uiTextboxInit(void);
void uiTextboxDispose(void);
Setting text:
uiTextboxSetText("Hello, world!");
// Automatically word-wraps and paginates.
// Resets currentPage and scroll to 0.
Tick update (called from script update or uiUpdate):
uiTextboxUpdate();
// Advances typewriter by UI_TEXTBOX_SCROLL_CHARS_PER_TICK (1) each
// fixed tick. Skipped on dynamic sub-ticks.
Page control:
bool_t uiTextboxPageIsComplete(void); // scroll revealed full page
bool_t uiTextboxHasNextPage(void); // more pages remain
void uiTextboxNextPage(void); // advance; no-op on last page
int32_t uiTextboxGetPageCharCount(void);
Events:
// Fires when the current page is fully scrolled into view:
UI_TEXTBOX.onPageComplete
// Fires when the last page has been fully scrolled:
UI_TEXTBOX.onLastPage
Subscribe via the event system (see .claude/events.md).
Limits:
| Constant | Value |
|---|---|
UI_TEXTBOX_TEXT_MAX |
1024 chars |
UI_TEXTBOX_LINES_MAX |
64 lines |
UI_TEXTBOX_LINES_PER_PAGE_MAX |
3 lines per page |
UI_TEXTBOX_SCROLL_CHARS_PER_TICK |
1 char per tick |
uifullbox_t -- full-screen colour overlay (uifullbox.h)
An animated solid-colour overlay that covers the entire screen. Used for fade-to-black, scene transitions, and flash effects.
Two global instances are provided:
extern uifullbox_t UI_FULLBOX_UNDER; // draws below scene content
extern uifullbox_t UI_FULLBOX_OVER; // draws above all content
void uiFullboxInit(uifullbox_t *fullbox);
// Start a colour-to-colour transition:
void uiFullboxTransition(
uifullbox_t *fullbox,
color_t from,
color_t to,
float_t duration,
easingtype_t easing
);
void uiFullboxUpdate(uifullbox_t *fullbox, float_t delta);
errorret_t uiFullboxDraw(uifullbox_t *fullbox);
// Draw is skipped entirely when alpha == 0.
fullbox.onTransitionEnd event fires once when the transition
completes. Subscribe to it to chain scene transitions:
// Typical fade-out before a scene change:
uiFullboxTransition(
&UI_FULLBOX_OVER,
COLOR_TRANSPARENT, COLOR_BLACK,
0.5f, EASING_OUT_QUAD
);
eventSubscribe(&UI_FULLBOX_OVER.onTransitionEnd, onFadeComplete, NULL);
uiloading_t -- loading indicator (uiloading.h)
An animated loading indicator with fade-in / fade-out transitions. Shown while asset batches are loading.
extern uiloading_t UI_LOADING;
void uiLoadingInit(void);
void uiLoadingUpdate(float_t delta);
errorret_t uiLoadingDraw(void);
// Fade in; callback fires when fully visible:
void uiLoadingShow(eventcallback_t callback, void *user);
// Fade out; callback fires when fully hidden:
void uiLoadingHide(eventcallback_t callback, void *user);
UI_LOADING_FADE_DURATION is 0.5 seconds. UI_LOADING_MARGIN is 8px.
uiLoadingDraw is a no-op when the indicator is fully transparent.
uifps_t -- FPS counter (uifps.h)
Debug FPS display. Measures real elapsed time between ticks and draws the average frame rate as text in the corner of the screen.
extern uifps_t UIFPS;
errorret_t uiFPSDraw(); // also performs the measurement update
Intended for debug builds only. Draw it explicitly from a JS render
hook or from a UI element -- it is not registered in UI_ELEMENTS by
default.