Bedtime. /Menu System

Menu System

Pre-built menu UI components

The menu system provides a complete solution for building settings screens and navigation hierarchies.

static void settings_menu(ui_menu_t* menu) {
    ui_menu_add_custom(menu, "Reset", NULL, reset_action, NULL);
}

static void root_menu(ui_menu_t* menu) {
    ui_menu_add_custom(menu, "Play", NULL, play_action, NULL);
    ui_menu_add_submenu(menu, "Settings", NULL, settings_menu, NULL);
}

// In init
ui_menu_t* menu = ui_menu_init(app, root_menu);
ui_menu_t* ui_menu_create(void* app_ctx, ui_menu_sub_cb root_builder)

Create a menu instance

void*app_ctxApp context (typically os_app_t*)
ui_menu_sub_cbroot_builderRoot menu builder callback

Returns — Pointer to menu instance, or NULL on error

void ui_menu_destroy(ui_menu_t* menu)

Destroy a menu instance

ui_menu_t*menuMenu instance
void ui_menu_add(ui_menu_t* menu, ui_menu_node_t entry)

Add an entry to the menu

ui_menu_t*menuMenu instance
ui_menu_node_tentryMenu node entry
void* ui_menu_ctx(ui_menu_t* menu)

Get menu context

ui_menu_t*menuMenu instance

Returns — Context pointer passed to ui_menu_create

void ui_menu_rebuild(ui_menu_t* menu)

Rebuild current menu view

ui_menu_t*menuMenu instance
void ui_menu_input(ui_menu_t* menu, uint8_t button_id, KeyStateEnum state)

Unified input handler for menus

ui_menu_t*menuMenu instance
uint8_tbutton_idButton ID (0-5)
KeyStateEnumstateButton state
void ui_menu_show(ui_menu_t* menu)

Show menu (attach to widget layer)

ui_menu_t*menuMenu instance
void ui_menu_hide(ui_menu_t* menu)

Hide menu (detach from widget layer)

ui_menu_t*menuMenu instance
bool ui_menu_is_visible(ui_menu_t* menu)

Check if menu is visible

ui_menu_t*menuMenu instance

Returns — true if visible

struct tapp_hint_pair_t

One button's hint labels. NULL or "" leaves that action blank.

const char*press
const char*hold
void ui_hints_set_labels(const tapp_hint_pair_t* labels)

Install this app's button hints into the system hint band.

const tapp_hint_pair_t*labelsarray of 5, in physical button order BTN1..BTN5
enum HintActionType
HintsActionsTotal0
void ui_hints_set_active(HintActionType action, bool active)

Highlith a hint cell (solid plate, inverted text) Use it for any on/off mode your button toggles.

HintActionTypeaction
boolactive
void ui_statusbar_hint_event(HintActionType action)

Flash a hint cell the way the device flashes its own — solid plate the instant you call it, 2px depress, fading out on its own after ~240ms. Use it for MOMENTARY actions (a shuffle, a retrigger) that have no on/off state.

HintActionTypeaction
void ui_hints_set_locked(HintActionType action, bool locked)

Dim a hint cell as UNAVAILABLE (dithered knockout, outline intact) — how the device greys out actions that don't apply, e.g. cut/copy while the deck is playing. Purely visual for a tapp: your on_input still decides.

HintActionTypeaction
boollocked
void ui_statusbar_set_text(const char* text)

Put your app's text in the system statusbar (left side)

const char*textstring to show; NULL or "" removes the item
void ui_statusbar_set_gfx_cb(tapp_statusbar_gfx_cb cb, uint16_t width, void* user)

Put your app's own GRAPHICS in the system statusbar (left side)

tapp_statusbar_gfx_cbcbDraw callback, or NULL to remove the item
uint16_twidthCell width in pixels
void*userContext handed back to cb
void ui_hints_set_icon(HintActionType action, const gfx_img_t* icon)

Put an icon INSIDE a hint cell (left of the re-centred label)

HintActionTypeactionWhich cell (HintPress1..HintHold5)
const gfx_img_t*iconYour compiled asset, or NULL to clear
void ui_hints_set_gfx_cb(HintActionType action, tapp_statusbar_gfx_cb cb, void* user)

Draw a hint cell's content YOURSELF (procedural graphics in the cell)

HintActionTypeactionWhich cell (HintPress1..HintHold5)
tapp_statusbar_gfx_cbcbDraw callback (same shape as the statusbar one), or NULL to restore the label
void*userContext handed back to cb
struct ui_roll_text_t

Mechanical rolling-TEXT state — split-flap style label animation.

char[UI_ROLL_TEXT_MAX]from
char[UI_ROLL_TEXT_MAX]tgt
float[UI_ROLL_TEXT_MAX]phase
uint8_tlen
uint8_tinited
bool ui_roll_text_draw(gfx_t* gfx, uint16_t x_right, uint16_t y, ui_roll_text_t* c, const char* value)

Draw a rolling label, right edge at x_right, baseline at y

gfx_t*gfx
uint16_tx_right
uint16_ty
ui_roll_text_t*c
const char*value

Returns — true while any character is still rolling

void ui_roll_text_snap(ui_roll_text_t* c, const char* value)
ui_roll_text_t*c
const char*value
void ui_hints_show(bool stat)

Raise or drop the hint band installed by ui_hints_set_labels()

boolstattrue to show hints, false to hide
void ui_hints_set_volume(uint8_t slot, uint8_t row, const char* name, params_t* param, uint8_t icon_id)

Install one VOLUME cell in the hint band — the same cells the device's own hold-PLAY volume band is made of (icon + name + live VU + cursor, active cell enlarged with the same animation).

uint8_tslotPhysical button, 1..5
uint8_trow0 = press row, 1 = hold row
const char*nameCell label — REFERENCED, must outlive the app state showing it
params_t*paramThe params_t this cell displays and whose ->val you adjust (typically from the encoder in on_input). NULL clears the cell — unless `name` is non-empty, which installs a plain LABEL cell instead (e.g. "<" / ">" nav arrows on the buttons that switch your selection, the same affordance the device's band has). Use ParamValDBType for gain-style 0..2.0 params — the linear draw branch assumes 0..1.
uint8_ticon_idIcon AND VU source: 0 = output (volume icon, output bus), 1 = input (jack/mic icon following the live source, input bus), 2 = fx
void ui_hints_volume_select(uint8_t slot, uint8_t row)

Enlarge/activate one volume cell (slot 0 = none). The cells animate exactly like the device's own band; call this when your selection moves.

uint8_tslot
uint8_trow
void ui_statusbar_show(bool state)

Show or hide the whole system statusbar (battery, status items, hints)

boolstatetrue to show, false to hide