Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/The-Young-Maker/OpenMenuOS/llms.txt

Use this file to discover all available pages before exploring further.

Navigation in OpenMenuOS is stack-based. Every time the user moves forward to a new screen, the previous screen is pushed onto a history stack so it can be restored when the user goes back. This model supports menus of unlimited depth and requires no manual bookkeeping on your part — the library manages the stack automatically as the user interacts with items.

How the history stack works

ScreenManager maintains a std::vector<Screen*> called screenHistory. When a new screen becomes active:
  1. The current screen is appended to screenHistory.
  2. The new screen becomes currentScreen and its draw() method is called immediately.
  3. The global ::currentScreen pointer is updated to match.
Going back reverses the process: the last entry in screenHistory is popped off and restored as the active screen.
screenHistory (stack)        currentScreen
─────────────────────        ─────────────
[mainMenu]                   settingsScreen   ← active
[mainMenu, settingsScreen]   speakerScreen    ← after drilling in further
The stack has no fixed depth limit; getDepth() returns the current number of entries.

Linking screens via addItem()

The most common way to connect screens is through MenuScreen::addItem(). When the user selects an item that has a nextScreen pointer, the library calls pushScreen() automatically.
MenuScreen mainMenu("Main Menu");
MenuScreen deviceMenu("Device Control");
SettingsScreen settingsScreen("Settings");

// Explicit label
mainMenu.addItem("Device Control", &deviceMenu);
mainMenu.addItem("Settings", &settingsScreen);

// Auto-use the target screen's own title as the label
mainMenu.addItem(&deviceMenu);
The second overload — addItem(Screen*) — reads getTitle() from the target screen and uses it as the list label, keeping titles consistent without repetition.

Programmatic navigation

Two methods on OpenMenuOS let you navigate from code, for example inside action callbacks or a CustomScreen.
// Jump to any screen, pushing the current one onto the stack
menu.redirectToScreen(&customScreen);

// Return to the previous screen (equivalent to a back button)
menu.navigateBack();
Both methods are thin wrappers around ScreenManager::pushScreen() and ScreenManager::popScreen() and update the global currentScreen variable.
Calling redirectToScreen() from a callback still respects the stack — the user can press the select button long-press or any “back” gesture to return to the calling screen.

The global currentScreen variable

OpenMenuOS exposes a global pointer:
extern Screen *currentScreen;
This always reflects the screen that is currently being displayed and handling input. You can read it to determine context, but you should use redirectToScreen() and navigateBack() rather than assigning to it directly.
1

Create your screens

Declare each screen at global scope (or as long-lived objects) so their pointers remain valid for the lifetime of the program.
MenuScreen mainMenu("Main Menu");
MenuScreen settingsMenu("Settings");
SettingsScreen appSettings("App Settings");
CustomScreen aboutScreen("About");
2

Link screens together

Use addItem() to wire screens into a hierarchy. Items without a nextScreen can still execute a callback or have no action.
mainMenu.addItem("Settings", &settingsMenu);
mainMenu.addItem("About", &aboutScreen);

settingsMenu.addItem("App Settings", &appSettings);
settingsMenu.addItem("Back", nullptr, []() { menu.navigateBack(); });
3

Set the root screen and start

Pass the root screen to begin(). This screen is the bottom of the history stack and cannot be popped.
menu.begin(&mainMenu);
4

Navigate programmatically when needed

Use redirectToScreen() inside callbacks for non-linear flows, such as jumping to a confirmation screen or a context-specific sub-page.
void onSavePressed() {
    menu.redirectToScreen(&confirmScreen);
}
5

Call `menu.loop()` every iteration

The library handles all input events, pushScreen / popScreen calls, and screen redraws inside loop(). No additional navigation code is required.
void loop() {
    menu.loop();
}

pushScreen and popScreen behavior

MethodEffectReturns
pushScreen(screen)Saves current screen to history, activates screenvoid
popScreen()Restores previous screen from historytrue on success, false if already at root
canGoBack()Checks whether history is non-emptybool
getDepth()Returns the number of screens in historysize_t
Do not push nullptr. pushScreen() silently returns without action if the pointer is null, which can leave the display in an undefined state.

Build docs developers (and LLMs) love