Application Control
Lifecycle, the app's model, window mode and the clock
Lifecycle
- Launch: the model is allocated and zeroed, then
init()runs, then the app'smemory_if.load(). Ifinit()returns false the launch stops anddeinit()is not called. - Running:
tick()runs every frame.redraw()runs on frames wheretick()returned true, and on input, focus changes and menu animations.on_pause()/on_resume()bracket the main menu opening over the app. - Close: the app's engine is stopped,
deinit()runs, the model is freed.
A source app loads in the background and comes on screen when its main menu cell is pressed.
Screen defaults per app type
| type | statusbar | hints | BTN4 / BTN5 hold |
|---|---|---|---|
| utility | shown | hidden | sent to the app |
| utility (window) | the menu's | the menu's | close the window |
| standalone | shown | shown on a hold | quick hints / main menu |
| source | hidden | shown | main menu / tape screen |
Full-screen apps start with the tape timeline off.
To change a default, call ui_statusbar_show(), ui_hints_show() or tape_timeline_show() once, in init(). The firmware remembers the call for the rest of the session. A source app's init() runs off-screen, so make these calls from its first tick() instead.
- Draw from TAPP_CONTENT_Y down. The hint band sits above that line whenever it is up.
- Call ui_hints_set() whenever the app's state changes. It sets the whole band and is cheap.
- Don't draw your own hint bar. The real band slides over it as soon as a hold reveals it.
Window mode
A utility app can draw in a rectangle over the main menu instead of taking the whole screen: call os_app_set_window() first thing in init(). The menu underneath keeps its statusbar and hint band. The app may label single hint cells with ui_hints_set(); cells it leaves empty keep the menu's label, dimmed. A window must not call ui_statusbar_show().
Examples: examples/leds/ (a window with its own menu) and examples/tuner.c (one hint cell, BTN1).
Exit the current app programmatically
Closes the app. deinit() runs before it is unloaded.
Draw in a rectangle over the main menu instead of the whole screen. Utility apps only.
| uint16_t | x | Left edge, in pixels. |
| uint16_t | y | Top edge, in pixels. 48 or more, below the hint band. |
| uint16_t | w | Width, at least 40 pixels. |
| uint16_t | h | Height, at least 24 pixels. |
Call it first in init(), before any ui_hints_* call. The rectangle must fit on screen. A refused call is logged and the app runs full screen.
redraw() is clipped to the rectangle. Holding BTN4 or BTN5 closes the window; presses still reach the app.
static bool my_init(os_app_t* app) {
os_app_set_window(100, 60, 200, 170);
return true;
}Get app's model data
| const os_app_t* | app | App context |
Returns — Pointer to model, or NULL if not allocated
my_model_t* m = (my_model_t*)os_app_get_model(app); m->counter++;
Milliseconds since boot
The only clock available to a TAPP. Use it for animation and timeouts:
uint32_t now = os_tick_get();
if (now - m->last_step >= 120) { m->last_step = now; step(m); }