Swadge 2024 2.0.0
APIs to develop games for the Magfest Swadge
Loading...
Searching...
No Matches
menu.h File Reference

Detailed Description

Design Philosophy

Menus are versatile ways to construct a UI where the user can select text labels.

Menus are vertically scrollable and may have any number of rows. Each row in the menu can be a single item selection, a horizontally scrolling multi-item selection, or a submenu. Menus can have any number of submenus.

When a menu is initialized a callback function must be provided. When menu options are selected, submenus are entered, or multi-item selections are scrolled, the callback is called.

The menu data structure is created and managed in menu.h, but graphical rendering is handled in menuManiaRenderer.h. The separation of data structure and renderer is intentional and makes it easier to render the data structure in a number of styles. As of now, only menuManiaRenderer.h is supplied.

Usage

Menus can be initialized with initMenu() and deinitialized with deinitMenu(). If menus are not deinitialized, they will leak memory. When initializing a menu, a function pointer must be provided which will be called when menu items are selected.

Submenu construction may be started and ended with startSubMenu() and endSubMenu() respectively. startSubMenu() will return a pointer to the submenu, and items can be added to it. endSubMenu() will automatically add a "Back" item to the submenu and return a pointer to the parent menu.

Items may be added to the menu with addSingleItemToMenu() or addMultiItemToMenu().

Items may be removed from the menu with removeSingleItemFromMenu() or removeMultiItemFromMenu().

Button events must be passed to the menu with menuButton(). These button presses should not be handled elsewhere simultaneously.

Menus are drawn with a renderer, such as menuManiaRenderer.h.

Example

Const strings for the example menu:

static const char demoName[] = "Demo";
static const char demoMenu1[] = "Menu 1";
static const char demoMenu2[] = "Menu 2";
static const char demoMenu3[] = "Menu 3";
static const char demoMenu4[] = "Menu 4";
static const char demoMenu5[] = "Menu 5";
static const char demoMenu6[] = "Menu 6";
static const char demoMenu7[] = "Menu 7";
static const char demoMenu8[] = "Menu 8";
static const char opt1[] = "opt1";
static const char opt2[] = "opt2";
static const char opt3[] = "opt3";
static const char opt4[] = "opt4";
static const char* const demoOpts[] = {opt1, opt2, opt3, opt4};
static const char optionSettingLabel[] = "OptSetting: "
static const char* const optionSettingLabels = {"Off", "30 Seconds", "5 Minutes"};
static const uint32_t optionSettingValues = {0, 30, 300};
static const char demoSettingLabel[] = "Setting";

Initialize a menu and renderer:

// Allocate the menu
menu_t * menu;
menu = initMenu(demoName, demoMenuCb);
// Add single items
addSingleItemToMenu(menu, demoMenu1);
addSingleItemToMenu(menu, demoMenu2);
// Start a submenu, add an item to it
menu = startSubMenu(menu, demoSubMenu1);
addSingleItemToMenu(menu, demoMenu7);
// Add a submenu with an item to the submenu
menu = startSubMenu(menu, demoSubMenu2);
addSingleItemToMenu(menu, demoMenu8);
// Finish the second submenu
menu = endSubMenu(menu);
// Finish the first submenu
menu = endSubMenu(menu);
// Add more items to the main menu, including a multi-item and settings item
addSingleItemToMenu(menu, demoMenu3);
addSingleItemToMenu(menu, demoMenu4);
addMultiItemToMenu(menu, demoOpts, ARRAY_SIZE(demoOpts), 0);
addSingleItemToMenu(menu, demoMenu5);
addSingleItemToMenu(menu, demoMenu6);
addSettingsOptionsItemToMenu(menu, optionSettingLabel, optionSettingLabels, optionSettingValues,
ARRAY_SIZE(optionSettingValues), getScreensaverTimeSettingBounds(), 0);
// Initialize a renderer
menuManiaRenderer_t* renderer = initMenuManiaRenderer(NULL, NULL, NULL);
#define ARRAY_SIZE(arr)
Definition macros.h:66
menuManiaRenderer_t * initMenuManiaRenderer(font_t *titleFont, font_t *titleFontOutline, font_t *menuFont)
Initialize a and return a menu renderer.
Definition menuManiaRenderer.c:80
A struct containing all the state data to render a mania-style menu and LEDs.
Definition menuManiaRenderer.h:59
void addSettingsItemToMenu(menu_t *menu, const char *label, const settingParam_t *bounds, int32_t val)
Add a settings entry to the menu. A settings entry is left-right scrollable where an integer setting ...
Definition menu.c:329
menu_t * initMenu(const char *title, menuCb cbFunc)
Initialize and return an empty menu. A menu is a collection of vertically scrollable rows....
Definition menu.c:49
menu_t * startSubMenu(menu_t *menu, const char *label)
Add a submenu item to the menu. When this item is select, the submenu is rendered....
Definition menu.c:131
menu_t * endSubMenu(menu_t *menu)
Finish adding items to a submenu and resume adding items to the parent menu. This will automatically ...
Definition menu.c:171
menuItem_t * addSingleItemToMenu(menu_t *menu, const char *label)
Add a single item entry to the menu. When this item is selected, the menuCb callback is called with t...
Definition menu.c:193
void addMultiItemToMenu(menu_t *menu, const char *const *labels, uint8_t numLabels, uint8_t currentLabel)
Add a multiple item entry to the menu. The multiple items exist in a single entry and are left-right ...
Definition menu.c:262
void addSettingsOptionsItemToMenu(menu_t *menu, const char *settingLabel, const char *const *optionLabels, const int32_t *optionValues, uint8_t numOptions, const settingParam_t *bounds, int32_t currentValue)
Adds a settings item entry to the menu with a specific list of options. The entry will be left-right ...
Definition menu.c:404
The underlying data for a menu. This fundamentally is a list of menuItem_t.
Definition menu.h:173
uint8_t getTftBrightnessSetting(void)
Get the current TFT brightness setting.
Definition settingsManager.c:262
const settingParam_t * getScreensaverTimeSettingBounds(void)
Get the bounds for the screensaver timeout setting. Useful for initializing settings items in menus.
Definition settingsManager.c:431
const settingParam_t * getTftBrightnessSettingBounds(void)
Get the bounds for the TFT brightness setting. Useful for initializing settings items in menus.
Definition settingsManager.c:272

Process button events:

buttonEvt_t evt = {0};
{
menu = menuButton(menu, evt);
}
A button event containing the button that triggered the event, whether it was pressed or released,...
Definition hdw-btn.h:117
menu_t * menuButton(menu_t *menu, buttonEvt_t evt)
This must be called to pass button event from the Swadge mode to the menu. If a button is passed here...
Definition menu.c:791
bool checkButtonQueueWrapper(buttonEvt_t *evt)
Service the queue of button events that caused interrupts This only returns a single event,...
Definition swadge2024.c:740

Draw the menu from swadgeMode_t.fnMainLoop:

drawMenuMania(mainMenu->menu, mainMenu->renderer, elapsedUs);
void drawMenuMania(menu_t *menu, menuManiaRenderer_t *renderer, int64_t elapsedUs)
Draw a themed menu to the display and control the LEDs.
Definition menuManiaRenderer.c:370

Receive menu callbacks:

static void demoMenuCb(const char* label, bool selected, uint32_t settingVal)
{
printf("%s %s, setting=%d\n", label, selected ? "selected" : "scrolled to", settingVal);
}

Deinitialize menu and renderer:

// Free the menu
deinitMenu(menu);
// Free the renderer
void deinitMenuManiaRenderer(menuManiaRenderer_t *renderer)
Deinitialize a menu renderer and free associated memory. This will not free the font passed into init...
Definition menuManiaRenderer.c:183
void deinitMenu(menu_t *menu)
Deinitialize a menu and all connected menus, including submenus and parent menus. This frees memory a...
Definition menu.c:68

Go to the source code of this file.

Data Structures

struct  menuItem_t
 The underlying data for an item in a menu. The item may be a single-select, multi-select, or submenu item. More...
 
struct  _menu_t
 The underlying data for a menu. This fundamentally is a list of menuItem_t. More...
 

Typedefs

typedef void(* menuCb) (const char *label, bool selected, uint32_t value)
 A callback which is called when a menu changes or items are selected.
 
typedef struct _menu_t menu_t
 The underlying data for a menu. This fundamentally is a list of menuItem_t.
 

Functions

menu_tinitMenu (const char *title, menuCb cbFunc)
 Initialize and return an empty menu. A menu is a collection of vertically scrollable rows. The rows are separated into pages, and when a page boundary is crossed the whole page scrolls.
 
void deinitMenu (menu_t *menu)
 Deinitialize a menu and all connected menus, including submenus and parent menus. This frees memory allocated for this menu, but not memory allocated elsewhere, like the font or item labels.
 
menu_tstartSubMenu (menu_t *menu, const char *label)
 Add a submenu item to the menu. When this item is select, the submenu is rendered. The menuCb is not called.
 
menu_tendSubMenu (menu_t *menu)
 Finish adding items to a submenu and resume adding items to the parent menu. This will automatically add a "Back" item to the submenu, which returns to the parent menu. menuCb will not be called when "Back" is selected.
 
menuItem_taddSingleItemToMenu (menu_t *menu, const char *label)
 Add a single item entry to the menu. When this item is selected, the menuCb callback is called with the given label as the argument.
 
void removeSingleItemFromMenu (menu_t *menu, const char *label)
 Remove a single item entry from the menu. This item is removed by pointer, not by doing a string comparison.
 
void addMultiItemToMenu (menu_t *menu, const char *const *labels, uint8_t numLabels, uint8_t currentLabel)
 Add a multiple item entry to the menu. The multiple items exist in a single entry and are left-right scrollable. The menuCb callback will be called each time the multi-item scrolls with the newly selected label as the argument. The menuCb callback will also be called if the currently displayed label is selected with that label as the argument.
 
void removeMultiItemFromMenu (menu_t *menu, const char *const *labels)
 Remove a multi item entry from the menu. This item is removed by pointer, not by doing any string comparisons.
 
void addSettingsItemToMenu (menu_t *menu, const char *label, const settingParam_t *bounds, int32_t val)
 Add a settings entry to the menu. A settings entry is left-right scrollable where an integer setting is incremented or decremented. The menuCb callback will be called each time the settings change with the newly selected value as the argument. The menuCb callback will also be called if the currently displayed setting is selected with that value as the argument.
 
void removeSettingsItemFromMenu (menu_t *menu, const char *label)
 Remove a settings item entry from the menu. This item is removed by pointer, not by doing any string comparisons.
 
void addSettingsOptionsItemToMenu (menu_t *menu, const char *settingLabel, const char *const *optionLabels, const int32_t *optionValues, uint8_t numOptions, const settingParam_t *bounds, int32_t currentValue)
 Adds a settings item entry to the menu with a specific list of options. The entry will be left-right scrollable. The menuCb callback will be called each time the setting-options item scrolls or is selected with the newly selected label and setting value as the arguments.
 
void removeSettingsOptionsItemFromMenu (menu_t *menu, const char *const *optionLabels)
 Remove a settings options item entry from the menu. This item is removed by pointer, not by doing any string comparisons.
 
menu_tmenuNavigateToItem (menu_t *menu, const char *label)
 Changes the selected item to the one with the given label, just as though it were scrolled to.
 
menu_tmenuNavigateToPrevItem (menu_t *menu)
 Navigate to the previous item in the menu. This is equivalent to pressing the UP button.
 
menu_tmenuNavigateToNextItem (menu_t *menu)
 Navigate to the next item in the menu. This is equivalent to pressing the DOWN button.
 
menu_tmenuNavigateToPrevOption (menu_t *menu)
 Navigate to the previous option in a menu item. This is equivalent to pressing the LEFT button.
 
menu_tmenuNavigateToNextOption (menu_t *menu)
 Navigate to the next option in a menu item. This is equivalent to pressing the RIGHT button.
 
menu_tmenuSelectCurrentItem (menu_t *menu)
 Select the current item in a menu item. This is equivalent to pressing the A button.
 
menu_tmenuSetCurrentOption (menu_t *menu, int32_t value)
 Performs the equivalent of scrolling to the given setting value or option index for the currently selected menu item.
 
menu_tmenuButton (menu_t *menu, buttonEvt_t evt)
 This must be called to pass button event from the Swadge mode to the menu. If a button is passed here, it should not be handled anywhere else.
 
void setShowBattery (menu_t *menu, bool showBattery)
 Show or hide the battery on the menu. This should be called from the root menu after the menu is constructed.
 

Variables

const char * mnuBackStr
 A string used to return to super-menus that says "Back".
 

Data Structure Documentation

◆ menuItem_t

struct menuItem_t
Data Fields
const char * label The label displayed if single-select or submenu.
const char *const * options The labels displayed if multi-select.
menu_t * subMenu A pointer to a submenu, maybe NULL for single-select and multi-select.
uint8_t numOptions The number of options for multi-select.
int32_t currentOpt The current selected option for multi-select.
int32_t minSetting The minimum value for settings items.
int32_t maxSetting The maximum value for settings items.
const int32_t * settingVals The setting value options for settings-options items.
int32_t currentSetting The current value for settings items.

◆ _menu_t

struct _menu_t
Data Fields
const char * title The title for this menu.
menuCb cbFunc The callback function to call when menu items are selected.
list_t * items A list_t of menu items to display.
node_t * currentItem The currently selected menu item.
menu_t * parentMenu The parent menu, may be NULL if this is not a submenu.
bool showBattery true if the battery measurement should be shown. false by default
int32_t batteryReadTimer A timer to read the battery every 10s.
int batteryLevel The current battery measurement.

Typedef Documentation

◆ menuCb

typedef void(* menuCb) (const char *label, bool selected, uint32_t value)

A callback which is called when a menu changes or items are selected.

Parameters
labelA pointer to the label which was selected or scrolled to
selectedtrue if the item was selected with the A button, false if it was scrolled to
valueIf a settings item was selected or scrolled, this is the new value for the setting

◆ menu_t

typedef struct _menu_t menu_t

The underlying data for a menu. This fundamentally is a list of menuItem_t.

Function Documentation

◆ initMenu()

menu_t * initMenu ( const char * title,
menuCb cbFunc )

Initialize and return an empty menu. A menu is a collection of vertically scrollable rows. The rows are separated into pages, and when a page boundary is crossed the whole page scrolls.

Rows may be single items, or multi items, which are collections of horizontally scrollable items. The callback is called whenever a row is moved to or selected, and when a multi item is scrolled to or selected.

Rows may also be submenus. When a submenu is selected, the callback is not called, and instead a the submenu is rendered. Each submenu automatically has a "Back" item added to it, which returns to the parent menu

Parameters
titleThe title to be displayed for this menu. The underlying memory isn't copied, so this string must persist for the lifetime of the menu.
cbFuncThe function to call when a menu option is selected. The argument to the callback will be the same pointer
Returns
A pointer to the newly allocated menu_t. This must be de-initialized when the menu is not used anymore.

◆ deinitMenu()

void deinitMenu ( menu_t * menu)

Deinitialize a menu and all connected menus, including submenus and parent menus. This frees memory allocated for this menu, but not memory allocated elsewhere, like the font or item labels.

Parameters
menuThe menu to deinitialize

◆ startSubMenu()

menu_t * startSubMenu ( menu_t * menu,
const char * label )

Add a submenu item to the menu. When this item is select, the submenu is rendered. The menuCb is not called.

All items added to this menu_t after calling startSubMenu() will be added in this submenu until endSubMenu() is called. Submenus have no limitations on how many submenus may be nested.

Submenu items are rendered with an icon indicating that it is a submenu.

Parameters
menuThe menu to create a submenu in
labelThe label for this submenu. The underlying memory isn't copied, so this string must persist for the lifetime of the menu
Returns
A pointer to the submenu

◆ endSubMenu()

menu_t * endSubMenu ( menu_t * menu)

Finish adding items to a submenu and resume adding items to the parent menu. This will automatically add a "Back" item to the submenu, which returns to the parent menu. menuCb will not be called when "Back" is selected.

During menu construction, each call to startSubMenu() must have a corresponding call to endSubMenu()

Parameters
menuThe menu to end a submenu in
Returns
A pointer to the parent menu to use for future function calls

◆ addSingleItemToMenu()

menuItem_t * addSingleItemToMenu ( menu_t * menu,
const char * label )

Add a single item entry to the menu. When this item is selected, the menuCb callback is called with the given label as the argument.

Parameters
menuThe menu to add a single item to
labelThe label for this item. The underlying memory isn't copied, so this string must persist for the lifetime of the menu
Returns
The new menuItem_t that was added to the menu

◆ removeSingleItemFromMenu()

void removeSingleItemFromMenu ( menu_t * menu,
const char * label )

Remove a single item entry from the menu. This item is removed by pointer, not by doing a string comparison.

Parameters
menuThe menu to remove a single item from
labelThe label for the item to remove

◆ addMultiItemToMenu()

void addMultiItemToMenu ( menu_t * menu,
const char *const * labels,
uint8_t numLabels,
uint8_t currentLabel )

Add a multiple item entry to the menu. The multiple items exist in a single entry and are left-right scrollable. The menuCb callback will be called each time the multi-item scrolls with the newly selected label as the argument. The menuCb callback will also be called if the currently displayed label is selected with that label as the argument.

Multi items are rendered with an icon indicating that it is horizontally scrollable.

Parameters
menuThe menu to add a multi-item to
labelsAll of the labels for this multi-item. The underlying memory isn't copied, so this string must persist for the lifetime of the menu
numLabelsThe number of labels for this multi-item
currentLabelThe current label index to display

◆ removeMultiItemFromMenu()

void removeMultiItemFromMenu ( menu_t * menu,
const char *const * labels )

Remove a multi item entry from the menu. This item is removed by pointer, not by doing any string comparisons.

Parameters
menuThe menu to remove a multi item from
labelsThe labels to remove

◆ addSettingsItemToMenu()

void addSettingsItemToMenu ( menu_t * menu,
const char * label,
const settingParam_t * bounds,
int32_t val )

Add a settings entry to the menu. A settings entry is left-right scrollable where an integer setting is incremented or decremented. The menuCb callback will be called each time the settings change with the newly selected value as the argument. The menuCb callback will also be called if the currently displayed setting is selected with that value as the argument.

Settings items are rendered with an icon indicating that it is horizontally scrollable.

Parameters
menuThe menu to add a settings item to
labelThe label for this setting. The integer setting will be drawn after it
boundsThe bounds for this setting
valThe starting value for the setting

◆ removeSettingsItemFromMenu()

void removeSettingsItemFromMenu ( menu_t * menu,
const char * label )

Remove a settings item entry from the menu. This item is removed by pointer, not by doing any string comparisons.

Parameters
menuThe menu to remove a multi item from
labelThe label to remove

◆ addSettingsOptionsItemToMenu()

void addSettingsOptionsItemToMenu ( menu_t * menu,
const char * settingLabel,
const char *const * optionLabels,
const int32_t * optionValues,
uint8_t numOptions,
const settingParam_t * bounds,
int32_t currentValue )

Adds a settings item entry to the menu with a specific list of options. The entry will be left-right scrollable. The menuCb callback will be called each time the setting-options item scrolls or is selected with the newly selected label and setting value as the arguments.

Parameters
menuThe menu to add a settings options item to
settingLabelThe overall label for this setting. This is what will be passed to the callback when the selected option changes, and this value will be rendered preceding the selected option's label.
optionLabelsAll of the labels for each option. The underlying memory isn't copied, so these strings must persist for the lifetime of the menu. The label value for the selected option will be rendered following the settingLabel.
optionValuesThe corresponding settings values for each option. The underlying memory isn't copied, so this array must persist for the lifetime of the menu. These values will not be rendered, but will be passed to the callback as the value when the selected option is changed.
numOptionsThe number of options and labels for this settings item.
boundsThe bounds for this setting
currentValueThe current value of the setting. Must be one of the values in optionValues.

◆ removeSettingsOptionsItemFromMenu()

void removeSettingsOptionsItemFromMenu ( menu_t * menu,
const char *const * optionLabels )

Remove a settings options item entry from the menu. This item is removed by pointer, not by doing any string comparisons.

Parameters
menuThe menu to remove a multi item from
optionLabelsThe list of option labels to remove

◆ menuNavigateToItem()

menu_t * menuNavigateToItem ( menu_t * menu,
const char * label )

Changes the selected item to the one with the given label, just as though it were scrolled to.

Parameters
menuThe menu to change the selected item of
labelThe label of the menu item or an option to select
Returns
A pointer to the menu to use for future function calls. It may be a sub or parent menu.

◆ menuNavigateToPrevItem()

menu_t * menuNavigateToPrevItem ( menu_t * menu)

Navigate to the previous item in the menu. This is equivalent to pressing the UP button.

Parameters
menuThe menu to navigate in
Returns
A pointer to the menu to use for future function calls. It may be a sub or parent menu.

◆ menuNavigateToNextItem()

menu_t * menuNavigateToNextItem ( menu_t * menu)

Navigate to the next item in the menu. This is equivalent to pressing the DOWN button.

Parameters
menuThe menu to navigate in
Returns
A pointer to the menu to use for future function calls. It may be a sub or parent menu.

◆ menuNavigateToPrevOption()

menu_t * menuNavigateToPrevOption ( menu_t * menu)

Navigate to the previous option in a menu item. This is equivalent to pressing the LEFT button.

Parameters
menuThe menu to navigate in
Returns
A pointer to the menu to use for future function calls. It may be a sub or parent menu.

◆ menuNavigateToNextOption()

menu_t * menuNavigateToNextOption ( menu_t * menu)

Navigate to the next option in a menu item. This is equivalent to pressing the RIGHT button.

Parameters
menuThe menu to navigate in
Returns
A pointer to the menu to use for future function calls. It may be a sub or parent menu.

◆ menuSelectCurrentItem()

menu_t * menuSelectCurrentItem ( menu_t * menu)

Select the current item in a menu item. This is equivalent to pressing the A button.

Parameters
menuThe menu to select an item in
Returns
A pointer to the menu to use for future function calls. It may be a sub or parent menu.

◆ menuSetCurrentOption()

menu_t * menuSetCurrentOption ( menu_t * menu,
int32_t value )

Performs the equivalent of scrolling to the given setting value or option index for the currently selected menu item.

Parameters
menuThe menu to scroll the selected item of
valueThe setting value or option index to scroll to
Returns
menu_t* The menu

◆ menuButton()

menu_t * menuButton ( menu_t * menu,
buttonEvt_t evt )

This must be called to pass button event from the Swadge mode to the menu. If a button is passed here, it should not be handled anywhere else.

Parameters
menuThe menu to process button events for
evtThe button event that occurred
Returns
A pointer to the menu to use for future function calls. It may be a sub or parent menu.

◆ setShowBattery()

void setShowBattery ( menu_t * menu,
bool showBattery )

Show or hide the battery on the menu. This should be called from the root menu after the menu is constructed.

Parameters
menuThe menu to show a battery indicator on
showBatterytrue to show the battery, false to hide it

Variable Documentation

◆ mnuBackStr

const char* mnuBackStr
extern

A string used to return to super-menus that says "Back".