diff --git a/docs/22-ui.md b/docs/22-ui.md index 88ef180..d79ef20 100644 --- a/docs/22-ui.md +++ b/docs/22-ui.md @@ -28,6 +28,15 @@ declarative blocks yourself between the same two frame calls, with the whole DSL available. The demo this chapter quotes, [`examples/uidemo`](../examples/uidemo), does both: its title menu and HUD are widgets, its options screen is raw `CLAY()`. +**What this chapter assumes.** A program that already brings libakgl up — the +`akgl_game_init` startup order from [Chapter 7](07-the-game-and-the-frame.md) (or +[Chapter 3](03-getting-started.md)'s smallest window), plus one loaded font from +[Chapter 17](17-text-and-fonts.md). None of that is restated here, and the UI adds only +three calls to it, shown below. When something in *your* bring-up fights you, the demo's +`startup()` in [`examples/uidemo/uidemo.c`](../examples/uidemo/uidemo.c) is the complete +working sequence to diff against — including the `main()` shape, which the runnable +snippets in this manual deliberately hide. + Like collision, the subsystem is optional at runtime rather than at build time: it is always compiled in, costs static storage until `akgl_ui_init` runs, and a game that never calls that pays nothing else. @@ -242,8 +251,13 @@ static akgl_UiMenu title_menu = { Declaring it each frame is `akgl_ui_menu(&title_menu)`. Input reaches it two ways, and they meet in the same struct: `akgl_ui_menu_handle_event` moves `selected` from the arrow keys and D-pad (wrapping at both ends) and sets `activated` on Return or gamepad -South; the mouse selects by *moving onto* a row and activates by clicking one, during -the declaration itself. A stationary pointer claims nothing — parking the mouse over the +South — exactly `SDLK_UP`, `SDLK_DOWN` and `SDLK_RETURN` against `SDL_Event.key.key`, +and `SDL_GAMEPAD_BUTTON_DPAD_UP`, `_DPAD_DOWN` and `_SOUTH` against +`SDL_Event.gbutton.button`. Keycodes, not scancodes — which only matters when you +*synthesize* events, as the demo's `--demo` script does: a hand-built key event must +fill in `key.key`, or it matches nothing and the menu silently ignores it. The mouse +selects by *moving onto* a row and activates by clicking one, during the declaration +itself. A stationary pointer claims nothing — parking the mouse over the menu must not pin the selection against the keyboard, which would otherwise fight it sixty times a second and lose. diff --git a/include/akgl/ui.h b/include/akgl/ui.h index 01f43da..58ebcf2 100644 --- a/include/akgl/ui.h +++ b/include/akgl/ui.h @@ -391,6 +391,13 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_ui_frame_end(akgl_RenderBackend *self); * -- clay keeps the pointer, not a copy. May be empty, which * draws an empty panel. * @param style Look to draw with, or `NULL` for the textbox palette. + * + * @note The panel's height is fixed at #AKGL_UI_DIALOG_HEIGHT and the text is + * not clipped to it: a message that wraps to more lines than fit runs + * past the bottom border, visibly. That is the same behaviour as the + * hand-rolled panel this widget mirrors, and it is deliberate -- + * overflow you can see beats truncation you cannot. Size the height for + * your longest message, or raise the override. * @return `NULL` on success, otherwise an error context owned by the caller. * @throws AKERR_NULLPOINTER If @p id or @p text is `NULL`. * @throws AKGL_ERR_UI If the subsystem is not initialized or no frame is