UI menu
This commit is contained in:
@@ -30,7 +30,8 @@ uifocusitem_t * uiFocusPush(
|
|||||||
const uint8_t rows,
|
const uint8_t rows,
|
||||||
uifocusitemcallback_t selected,
|
uifocusitemcallback_t selected,
|
||||||
uifocusitemcallback_t changed,
|
uifocusitemcallback_t changed,
|
||||||
uifocusitemcallback_t closed
|
uifocusitemcallback_t closed,
|
||||||
|
void *user
|
||||||
) {
|
) {
|
||||||
assertTrue(
|
assertTrue(
|
||||||
UI_FOCUS.count < UI_FOCUS_STACK_MAX,
|
UI_FOCUS.count < UI_FOCUS_STACK_MAX,
|
||||||
@@ -46,6 +47,7 @@ uifocusitem_t * uiFocusPush(
|
|||||||
item->selected = selected;
|
item->selected = selected;
|
||||||
item->changed = changed;
|
item->changed = changed;
|
||||||
item->closed = closed;
|
item->closed = closed;
|
||||||
|
item->user = user;
|
||||||
UI_FOCUS.count++;
|
UI_FOCUS.count++;
|
||||||
if(item->changed != NULL) item->changed(item);
|
if(item->changed != NULL) item->changed(item);
|
||||||
return item;
|
return item;
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ void uiFocusInit(void);
|
|||||||
* @param selected Called when the user selects the focused cell.
|
* @param selected Called when the user selects the focused cell.
|
||||||
* @param changed Called when the focused cell position changes.
|
* @param changed Called when the focused cell position changes.
|
||||||
* @param closed Called when this focus item is popped.
|
* @param closed Called when this focus item is popped.
|
||||||
|
* @param user Arbitrary pointer stored on the item before changed fires.
|
||||||
* @returns Pointer to the newly pushed focus item.
|
* @returns Pointer to the newly pushed focus item.
|
||||||
*/
|
*/
|
||||||
uifocusitem_t * uiFocusPush(
|
uifocusitem_t * uiFocusPush(
|
||||||
@@ -78,7 +79,8 @@ uifocusitem_t * uiFocusPush(
|
|||||||
const uint8_t rows,
|
const uint8_t rows,
|
||||||
uifocusitemcallback_t selected,
|
uifocusitemcallback_t selected,
|
||||||
uifocusitemcallback_t changed,
|
uifocusitemcallback_t changed,
|
||||||
uifocusitemcallback_t closed
|
uifocusitemcallback_t closed,
|
||||||
|
void *user
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -29,4 +29,5 @@ struct uifocusitem_s {
|
|||||||
uifocusitemcallback_t selected;
|
uifocusitemcallback_t selected;
|
||||||
uifocusitemcallback_t changed;
|
uifocusitemcallback_t changed;
|
||||||
uifocusitemcallback_t closed;
|
uifocusitemcallback_t closed;
|
||||||
|
void *user;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,63 +7,67 @@
|
|||||||
|
|
||||||
#include "uisettings.h"
|
#include "uisettings.h"
|
||||||
#include "ui/frame/uiframe.h"
|
#include "ui/frame/uiframe.h"
|
||||||
#include "ui/widget/uicheckbox.h"
|
|
||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
#include "display/spritebatch/spritebatch.h"
|
#include "display/spritebatch/spritebatch.h"
|
||||||
#include "display/text/text.h"
|
#include "display/text/text.h"
|
||||||
|
|
||||||
uisettings_t UI_SETTINGS;
|
uisettings_t UI_SETTINGS;
|
||||||
|
|
||||||
bool_t uiSettingsSelected(const uifocusitem_t *item) {
|
void uiSettingsSelected(
|
||||||
if(item->y == 3) uiCheckboxToggle(&UI_SETTINGS.checkboxTest);
|
const uimenu_t *menu,
|
||||||
return true;
|
const uint8_t index,
|
||||||
|
const uimenuitem_t *item
|
||||||
|
) {
|
||||||
|
if(item->type == UIMENU_WIDGET_TYPE_CHECKBOX) {
|
||||||
|
uiCheckboxToggle(&UI_SETTINGS.items[index].checkbox);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool_t uiSettingsChanged(const uifocusitem_t *item) {
|
void uiSettingsClosed(const uimenu_t *menu) {
|
||||||
uiCheckboxSetHighlighted(&UI_SETTINGS.checkboxTest, item->y == 3);
|
// nothing extra needed; menu clears focusItem itself
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool_t uiSettingsClosed(const uifocusitem_t *item) {
|
|
||||||
UI_SETTINGS.item = NULL;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
errorret_t uiSettingsInit(void) {
|
errorret_t uiSettingsInit(void) {
|
||||||
memoryZero(&UI_SETTINGS, sizeof(uisettings_t));
|
memoryZero(&UI_SETTINGS, sizeof(uisettings_t));
|
||||||
uiCheckboxInit(&UI_SETTINGS.checkboxTest, "Enable thing?");
|
|
||||||
|
UI_SETTINGS.items[0] = (uimenuitem_t){
|
||||||
|
.type = UIMENU_WIDGET_TYPE_LABEL,
|
||||||
|
.label = "Settings"
|
||||||
|
};
|
||||||
|
UI_SETTINGS.items[1] = (uimenuitem_t){
|
||||||
|
.type = UIMENU_WIDGET_TYPE_LABEL,
|
||||||
|
.label = "Settings two"
|
||||||
|
};
|
||||||
|
UI_SETTINGS.items[2] = (uimenuitem_t){
|
||||||
|
.type = UIMENU_WIDGET_TYPE_LABEL,
|
||||||
|
.label = "Settings three"
|
||||||
|
};
|
||||||
|
UI_SETTINGS.items[3].type = UIMENU_WIDGET_TYPE_CHECKBOX;
|
||||||
|
uiCheckboxInit(&UI_SETTINGS.items[3].checkbox, "Enable thing?");
|
||||||
|
|
||||||
|
uiMenuInit(&UI_SETTINGS.menu, uiSettingsSelected, uiSettingsClosed, NULL);
|
||||||
|
uiMenuSetItems(
|
||||||
|
&UI_SETTINGS.menu,
|
||||||
|
UI_SETTINGS.items,
|
||||||
|
UI_SETTINGS_ITEM_COUNT,
|
||||||
|
2
|
||||||
|
);
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
errorret_t uiSettingsDraw(void) {
|
errorret_t uiSettingsDraw(void) {
|
||||||
if(UI_SETTINGS.item == NULL) errorOk();
|
if(!uiMenuIsActive(&UI_SETTINGS.menu)) errorOk();
|
||||||
|
|
||||||
const char_t *texts[] = {
|
uint8_t rows = UI_SETTINGS_ITEM_COUNT;
|
||||||
"Settings",
|
|
||||||
"Settings two",
|
|
||||||
"Settings three"
|
|
||||||
};
|
|
||||||
const uint8_t textCount = sizeof(texts) / sizeof(texts[0]);
|
|
||||||
const uint8_t totalRows = textCount + 1;
|
|
||||||
|
|
||||||
errorChain(uiFrameDraw(
|
errorChain(uiFrameDraw(0.0f, 0.0f, 300.0f, 300));
|
||||||
0.0f, 0.0f, 100.0f,
|
errorChain(uiMenuDraw(
|
||||||
FONT_DEFAULT.tileset->tileHeight * totalRows + (UIFRAME_BORDER_HEIGHT * 2)
|
&UI_SETTINGS.menu,
|
||||||
));
|
|
||||||
|
|
||||||
for(uint8_t i = 0; i < textCount; i++) {
|
|
||||||
errorChain(textDraw(
|
|
||||||
UIFRAME_BORDER_WIDTH,
|
|
||||||
UIFRAME_BORDER_HEIGHT + (i * FONT_DEFAULT.tileset->tileHeight),
|
|
||||||
texts[i],
|
|
||||||
UI_SETTINGS.item->y == i ? COLOR_RED : COLOR_WHITE, NULL
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
errorChain(uiCheckboxDraw(
|
|
||||||
&UI_SETTINGS.checkboxTest,
|
|
||||||
UIFRAME_BORDER_WIDTH,
|
UIFRAME_BORDER_WIDTH,
|
||||||
UIFRAME_BORDER_HEIGHT + (textCount * FONT_DEFAULT.tileset->tileHeight)
|
UIFRAME_BORDER_HEIGHT,
|
||||||
|
300.0f - (UIFRAME_BORDER_WIDTH * 2),
|
||||||
|
300.0f - (UIFRAME_BORDER_HEIGHT * 2)
|
||||||
));
|
));
|
||||||
|
|
||||||
errorChain(spriteBatchFlush());
|
errorChain(spriteBatchFlush());
|
||||||
@@ -71,22 +75,15 @@ errorret_t uiSettingsDraw(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool_t uiSettingsIsOpen(void) {
|
bool_t uiSettingsIsOpen(void) {
|
||||||
return UI_SETTINGS.item != NULL;
|
return uiMenuIsActive(&UI_SETTINGS.menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
void uiSettingsOpen() {
|
void uiSettingsOpen() {
|
||||||
if(UI_SETTINGS.item != NULL) return;
|
uiMenuOpen(&UI_SETTINGS.menu);
|
||||||
|
|
||||||
UI_SETTINGS.item = uiFocusPush(
|
|
||||||
1, 4, uiSettingsSelected, uiSettingsChanged, uiSettingsClosed
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void uiSettingsClose() {
|
void uiSettingsClose() {
|
||||||
if(UI_SETTINGS.item == NULL) return;
|
uiMenuClose(&UI_SETTINGS.menu);
|
||||||
|
|
||||||
uiFocusPopItem(UI_SETTINGS.item);
|
|
||||||
UI_SETTINGS.item = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
errorret_t uiSettingsDispose(void) {
|
errorret_t uiSettingsDispose(void) {
|
||||||
|
|||||||
@@ -7,12 +7,13 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "error/error.h"
|
#include "error/error.h"
|
||||||
#include "ui/focus/uifocus.h"
|
#include "ui/widget/uimenu.h"
|
||||||
#include "ui/widget/uicheckbox.h"
|
|
||||||
|
#define UI_SETTINGS_ITEM_COUNT 4
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uifocusitem_t *item;
|
uimenu_t menu;
|
||||||
uicheckbox_t checkboxTest;
|
uimenuitem_t items[UI_SETTINGS_ITEM_COUNT];
|
||||||
} uisettings_t;
|
} uisettings_t;
|
||||||
|
|
||||||
extern uisettings_t UI_SETTINGS;
|
extern uisettings_t UI_SETTINGS;
|
||||||
|
|||||||
@@ -6,4 +6,5 @@
|
|||||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||||
PUBLIC
|
PUBLIC
|
||||||
uicheckbox.c
|
uicheckbox.c
|
||||||
|
uimenu.c
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,163 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uimenu.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
#include "display/text/text.h"
|
||||||
|
#include "display/color.h"
|
||||||
|
|
||||||
|
void uiMenuInit(
|
||||||
|
uimenu_t *menu,
|
||||||
|
uimenuselectedcallback_t selected,
|
||||||
|
uimenuclosedcallback_t closed,
|
||||||
|
uimenuchangedcallback_t changed
|
||||||
|
) {
|
||||||
|
assertNotNull(menu, "Menu cannot be NULL");
|
||||||
|
memoryZero(menu, sizeof(uimenu_t));
|
||||||
|
menu->selected = selected;
|
||||||
|
menu->closed = closed;
|
||||||
|
menu->changed = changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uiMenuSetItems(
|
||||||
|
uimenu_t *menu,
|
||||||
|
const uimenuitem_t *items,
|
||||||
|
const uint8_t itemCount,
|
||||||
|
const uint8_t columns
|
||||||
|
) {
|
||||||
|
assertNotNull(menu, "Menu cannot be NULL");
|
||||||
|
assertNotNull(items, "Items cannot be NULL");
|
||||||
|
assertTrue(itemCount > 0, "Item count must be > 0");
|
||||||
|
assertTrue(columns > 0, "Columns must be > 0");
|
||||||
|
menu->items = (uimenuitem_t *)items;
|
||||||
|
menu->itemCount = itemCount;
|
||||||
|
menu->columns = columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uiMenuSetPosition(uimenu_t *menu, const uint8_t x, const uint8_t y) {
|
||||||
|
assertNotNull(menu, "Menu cannot be NULL");
|
||||||
|
if(menu->focusItem == NULL) return;
|
||||||
|
uiFocusSetPosition(menu->focusItem, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uiMenuOpen(uimenu_t *menu) {
|
||||||
|
assertNotNull(menu, "Menu cannot be NULL");
|
||||||
|
assertNotNull(menu->items, "Menu items cannot be NULL");
|
||||||
|
assertTrue(menu->itemCount > 0, "Menu item count must be > 0");
|
||||||
|
assertTrue(menu->columns > 0, "Menu columns must be > 0");
|
||||||
|
if(menu->focusItem != NULL) return;
|
||||||
|
|
||||||
|
uint8_t rows = (menu->itemCount + menu->columns - 1) / menu->columns;
|
||||||
|
menu->focusItem = uiFocusPush(
|
||||||
|
menu->columns, rows,
|
||||||
|
uiMenuFocusSelected,
|
||||||
|
uiMenuFocusChanged,
|
||||||
|
uiMenuFocusClosed,
|
||||||
|
menu
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uiMenuClose(uimenu_t *menu) {
|
||||||
|
assertNotNull(menu, "Menu cannot be NULL");
|
||||||
|
if(menu->focusItem == NULL) return;
|
||||||
|
uiFocusPopItem(menu->focusItem);
|
||||||
|
menu->focusItem = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t uiMenuIsActive(const uimenu_t *menu) {
|
||||||
|
assertNotNull(menu, "Menu cannot be NULL");
|
||||||
|
return menu->focusItem != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
errorret_t uiMenuDraw(
|
||||||
|
const uimenu_t *menu,
|
||||||
|
const float_t x,
|
||||||
|
const float_t y,
|
||||||
|
const float_t width,
|
||||||
|
const float_t height
|
||||||
|
) {
|
||||||
|
assertNotNull(menu, "Menu cannot be NULL");
|
||||||
|
if(menu->itemCount == 0) errorOk();
|
||||||
|
|
||||||
|
float_t colStep = width / (float_t)menu->columns;
|
||||||
|
float_t rowHeight = (float_t)FONT_DEFAULT.tileset->tileHeight;
|
||||||
|
|
||||||
|
uint8_t focusIndex = menu->focusItem != NULL ?
|
||||||
|
menu->focusItem->y * menu->columns + menu->focusItem->x :
|
||||||
|
0xFF;
|
||||||
|
|
||||||
|
for(uint8_t i = 0; i < menu->itemCount; i++) {
|
||||||
|
const uimenuitem_t *item = &menu->items[i];
|
||||||
|
uint8_t col = i % menu->columns;
|
||||||
|
uint8_t row = i / menu->columns;
|
||||||
|
float_t ix = x + (float_t)col * colStep;
|
||||||
|
float_t iy = y + (float_t)row * rowHeight;
|
||||||
|
bool_t highlighted = i == focusIndex;
|
||||||
|
|
||||||
|
switch(item->type) {
|
||||||
|
case UIMENU_WIDGET_TYPE_LABEL:
|
||||||
|
errorChain(textDraw(
|
||||||
|
ix, iy, item->label,
|
||||||
|
highlighted ? COLOR_RED : COLOR_WHITE,
|
||||||
|
&FONT_DEFAULT
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UIMENU_WIDGET_TYPE_CHECKBOX:
|
||||||
|
errorChain(uiCheckboxDraw(&item->checkbox, ix, iy));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t uiMenuFocusSelected(const uifocusitem_t *focusItem) {
|
||||||
|
assertNotNull(focusItem, "Focus item cannot be NULL");
|
||||||
|
assertNotNull(focusItem->user, "Focus item user cannot be NULL");
|
||||||
|
uimenu_t *menu = (uimenu_t *)focusItem->user;
|
||||||
|
if(menu->selected == NULL) return true;
|
||||||
|
|
||||||
|
uint8_t index = focusItem->y * menu->columns + focusItem->x;
|
||||||
|
if(index >= menu->itemCount) return true;
|
||||||
|
|
||||||
|
menu->selected(menu, index, &menu->items[index]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t uiMenuFocusChanged(const uifocusitem_t *focusItem) {
|
||||||
|
assertNotNull(focusItem, "Focus item cannot be NULL");
|
||||||
|
assertNotNull(focusItem->user, "Focus item user cannot be NULL");
|
||||||
|
uimenu_t *menu = (uimenu_t *)focusItem->user;
|
||||||
|
|
||||||
|
uint8_t index = focusItem->y * menu->columns + focusItem->x;
|
||||||
|
|
||||||
|
for(uint8_t i = 0; i < menu->itemCount; i++) {
|
||||||
|
uimenuitem_t *item = &menu->items[i];
|
||||||
|
if(item->type != UIMENU_WIDGET_TYPE_CHECKBOX) continue;
|
||||||
|
uiCheckboxSetHighlighted(&item->checkbox, i == index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(menu->changed == NULL) return true;
|
||||||
|
if(index >= menu->itemCount) return true;
|
||||||
|
|
||||||
|
menu->changed(menu, index, &menu->items[index]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t uiMenuFocusClosed(const uifocusitem_t *focusItem) {
|
||||||
|
assertNotNull(focusItem, "Focus item cannot be NULL");
|
||||||
|
assertNotNull(focusItem->user, "Focus item user cannot be NULL");
|
||||||
|
uimenu_t *menu = (uimenu_t *)focusItem->user;
|
||||||
|
menu->focusItem = NULL;
|
||||||
|
if(menu->closed != NULL) menu->closed(menu);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "error/error.h"
|
||||||
|
#include "ui/focus/uifocus.h"
|
||||||
|
#include "ui/widget/uicheckbox.h"
|
||||||
|
|
||||||
|
#define UI_MENU_LABEL_MAX UI_CHECKBOX_LABEL_MAX
|
||||||
|
|
||||||
|
typedef struct uimenu_s uimenu_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
UIMENU_WIDGET_TYPE_NONE,
|
||||||
|
UIMENU_WIDGET_TYPE_LABEL,
|
||||||
|
UIMENU_WIDGET_TYPE_CHECKBOX,
|
||||||
|
} uimenuwidgettype_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uimenuwidgettype_t type;
|
||||||
|
union {
|
||||||
|
char_t label[UI_MENU_LABEL_MAX];
|
||||||
|
uicheckbox_t checkbox;
|
||||||
|
};
|
||||||
|
} uimenuitem_t;
|
||||||
|
|
||||||
|
typedef void (*uimenuselectedcallback_t)(
|
||||||
|
const uimenu_t *menu,
|
||||||
|
const uint8_t index,
|
||||||
|
const uimenuitem_t *item
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef void (*uimenuchangedcallback_t)(
|
||||||
|
const uimenu_t *menu,
|
||||||
|
const uint8_t index,
|
||||||
|
const uimenuitem_t *item
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef void (*uimenuclosedcallback_t)(const uimenu_t *menu);
|
||||||
|
|
||||||
|
typedef struct uimenu_s {
|
||||||
|
uimenuitem_t *items;
|
||||||
|
uint8_t itemCount;
|
||||||
|
uint8_t columns;
|
||||||
|
uifocusitem_t *focusItem;
|
||||||
|
|
||||||
|
uimenuselectedcallback_t selected;
|
||||||
|
uimenuclosedcallback_t closed;
|
||||||
|
uimenuchangedcallback_t changed;
|
||||||
|
} uimenu_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes a menu, clearing all items and focus state.
|
||||||
|
*
|
||||||
|
* @param menu The menu to initialize.
|
||||||
|
* @param items The list of items to display in the menu.
|
||||||
|
* @param itemCount The number of items in the list.
|
||||||
|
* @param columns The number of columns to display the items in.
|
||||||
|
* @param selected The callback to invoke when an item is selected.
|
||||||
|
* @param closed The callback to invoke when the menu is closed.
|
||||||
|
* @param changed The callback to invoke when the menu changes.
|
||||||
|
*/
|
||||||
|
void uiMenuInit(
|
||||||
|
uimenu_t *menu,
|
||||||
|
uimenuselectedcallback_t selected,
|
||||||
|
uimenuclosedcallback_t closed,
|
||||||
|
uimenuchangedcallback_t changed
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the items to display in the menu.
|
||||||
|
*
|
||||||
|
* @param menu The menu to update.
|
||||||
|
* @param items The list of items to display in the menu.
|
||||||
|
* @param itemCount The number of items in the list.
|
||||||
|
* @param columns The number of columns to display the items in.
|
||||||
|
*/
|
||||||
|
void uiMenuSetItems(
|
||||||
|
uimenu_t *menu,
|
||||||
|
const uimenuitem_t *items,
|
||||||
|
const uint8_t itemCount,
|
||||||
|
const uint8_t columns
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the position of the menu on the screen.
|
||||||
|
*
|
||||||
|
* @param menu The menu to position.
|
||||||
|
* @param x The x-coordinate to position the menu at.
|
||||||
|
* @param y The y-coordinate to position the menu at.
|
||||||
|
*/
|
||||||
|
void uiMenuSetPosition(uimenu_t *menu, const uint8_t x, const uint8_t y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pushes a menu onto the UI focus stack, making it the active menu.
|
||||||
|
*
|
||||||
|
* @param menu The menu to push.
|
||||||
|
*/
|
||||||
|
void uiMenuOpen(uimenu_t *menu);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pops a menu from the UI focus stack, removing it from the active menu.
|
||||||
|
*
|
||||||
|
* @param menu The menu to pop.
|
||||||
|
*/
|
||||||
|
void uiMenuClose(uimenu_t *menu);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the menu is currently active (on the UI focus stack).
|
||||||
|
*
|
||||||
|
* @param menu The menu to query.
|
||||||
|
* @returns True if the menu is active.
|
||||||
|
*/
|
||||||
|
bool_t uiMenuIsActive(const uimenu_t *menu);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws the menu at the specified position and size.
|
||||||
|
*
|
||||||
|
* @param menu The menu to draw.
|
||||||
|
* @param x The x-coordinate to draw the menu at.
|
||||||
|
* @param y The y-coordinate to draw the menu at.
|
||||||
|
* @param width The width of the menu.
|
||||||
|
* @param height The height of the menu.
|
||||||
|
* @returns An error code indicating success or failure.
|
||||||
|
*/
|
||||||
|
errorret_t uiMenuDraw(
|
||||||
|
const uimenu_t *menu,
|
||||||
|
const float_t x,
|
||||||
|
const float_t y,
|
||||||
|
const float_t width,
|
||||||
|
const float_t height
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal focus callback — forwards selection to the menu's selected handler.
|
||||||
|
*
|
||||||
|
* @param focusItem The active focus item; user field must point to uimenu_t.
|
||||||
|
* @returns True.
|
||||||
|
*/
|
||||||
|
bool_t uiMenuFocusSelected(const uifocusitem_t *focusItem);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal focus callback — updates checkbox highlights and fires changed.
|
||||||
|
*
|
||||||
|
* @param focusItem The active focus item; user field must point to uimenu_t.
|
||||||
|
* @returns True.
|
||||||
|
*/
|
||||||
|
bool_t uiMenuFocusChanged(const uifocusitem_t *focusItem);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal focus callback — clears focusItem and fires the closed handler.
|
||||||
|
*
|
||||||
|
* @param focusItem The active focus item; user field must point to uimenu_t.
|
||||||
|
* @returns True.
|
||||||
|
*/
|
||||||
|
bool_t uiMenuFocusClosed(const uifocusitem_t *focusItem);
|
||||||
Reference in New Issue
Block a user