#include <tcMenu.h>
Public Member Functions | |
void | setUseWrapAroundEncoder (bool wrapAround) |
void | addEncoderWrapOverride (MenuItem &item, bool override) |
bool | isWrapAroundEncoder (MenuItem *item) |
void | initForEncoder (MenuRenderer *renderer, MenuItem *root, pinid_t encoderPinA, pinid_t encoderPinB, pinid_t encoderButton, EncoderType type=FULL_CYCLE) |
void | initForUpDownOk (MenuRenderer *renderer, MenuItem *root, pinid_t downPin, pinid_t upPin, pinid_t okPin, int speed=20) |
void | initFor4WayJoystick (MenuRenderer *renderer, MenuItem *root, pinid_t downPin, pinid_t upPin, pinid_t leftPin, pinid_t rightPin, pinid_t okPin, int speed=20) |
void | initForTwoButton (MenuRenderer *renderer, MenuItem *root, pinid_t upPin, pinid_t downPin) |
void | initWithoutInput (MenuRenderer *renderer, MenuItem *root) |
void | setBackButton (pinid_t backButtonPin) |
void | setNextButton (pinid_t nextButtonPin) |
void | setRootMenu (MenuItem *menuItem) |
void | setAuthenticator (AuthenticationManager *manager) |
AuthenticationManager * | getAuthenticator () |
void | setItemCommittedHook (MenuCallbackFn commitCallback) |
void | valueChanged (int value) |
void | onMenuSelect (bool held) |
void | performDirectionMove (bool dirIsBack) |
void | setItemsInCurrentMenu (int size, int offs=0) |
EepromAbstraction * | getEepromAbstraction () |
void | setEepromRef (EepromAbstraction *globalRom) |
void | load (EepromAbstraction &eeprom, uint16_t magicKey=0xfade, TimerFn onEepromEmpty=nullptr) |
void | load (uint16_t magicKey=0xfade, TimerFn onEepromEmpty=nullptr) |
void | save (uint16_t magicKey=0xfade) |
void | save (EepromAbstraction &eeprom, uint16_t magicKey=0xfade) |
MenuItem * | findCurrentActive () |
MenuItem * | getRoot () |
MenuRenderer * | getRenderer () |
MenuItem * | getCurrentEditor () |
void | setCurrentEditor (MenuItem *editor) |
void | setItemActive (MenuItem *item) |
void | changeMenu (MenuItem *possibleActive=nullptr) |
void | navigateToMenu (MenuItem *theNewItem, MenuItem *possibleActive=nullptr, bool skipHistory=false) |
void | resetMenu (bool completeReset) |
MenuItem * | getCurrentMenu () |
MenuItem * | getCurrentSubMenu () |
tcnav::MenuNavigationStore & | getNavigationStore () |
MenuItem * | getParentAndReset () |
int | getCurrentRangeValue () |
SecuredMenuPopup * | secureMenuInstance () |
void | stopEditingCurrentItem (bool doMultiPartNext) |
void | addMenuAfter (MenuItem *existing, MenuItem *toAdd, bool silent=false) |
void | notifyStructureChanged () |
void | addChangeNotification (MenuManagerObserver *observer) |
void | recalculateListIfOnDisplay (RuntimeMenuItem *runtimeItem) |
void | setEditorHints (CurrentEditorRenderingHints::EditorRenderingType hint, size_t start=0, size_t end=0) |
const CurrentEditorRenderingHints & | getEditorHints () |
void | setEditorHintsLocked (bool locked) |
void | resetObservers () |
void | setupForEditing (MenuItem *item) |
Static Public Attributes | |
static SubMenuItem | ROOT |
Protected Member Functions | |
void | actionOnCurrentItem (MenuItem *toEdit) |
void | actionOnSubMenu (MenuItem *nextSub) |
void | notifyEditEnd (MenuItem *pItem) |
bool | notifyEditStarting (MenuItem *pItem) |
void | setRootItem (MenuItem *pItem) |
MenuManager ties together all the parts of the menu app, it looks after the menu structure that's being presented, the renderer, security, and optionally an eeprom.
|
inline |
This method tells tcMenu to always attempt to use wrap around with the encoder, IE when value reaches max it goes back to min, and vica-versa. The default is NOT to wrap.
wrapAround | should values wrap |
void MenuManager::addEncoderWrapOverride | ( | MenuItem & | item, |
bool | override | ||
) |
In many cases some items would suit wrap around encoder mode and some would not. For example nearly all enum and scroll items suit wrap around. Items that require many turns of the encoder also suit it, but volume for example really wouldn't suit it. Imagine hitting 0 volume and wrapping back to maximum in an amplifier.
To set the default wrap around mode call setUseWrapAroundEncoder
first, the default is no wrapping.
item | the item for which the override is to be applied. |
override | true if wrapping is needed, otherwise false. |
bool MenuManager::isWrapAroundEncoder | ( | MenuItem * | item | ) |
Check if the encoder should use wrapping for a given menu item or not. We use a pointer here because it can legally be nullptr too.
menuId | the menu id obtained using getId() on the menu item |
void MenuManager::initForEncoder | ( | MenuRenderer * | renderer, |
MenuItem * | root, | ||
pinid_t | encoderPinA, | ||
pinid_t | encoderPinB, | ||
pinid_t | encoderButton, | ||
EncoderType | type = FULL_CYCLE |
||
) |
Initialise the menu manager to use a hardware rotary encoder
renderer | the renderer used for drawing |
root | the first menu item |
encoderPinA | encoder A pin |
encorerPinB | encoder B pin |
encoderButton | the OK button for the menu select / edit action |
type | optionally, you can provide the encoder type, only really needed for quarter cycle encoders. |
void MenuManager::initForUpDownOk | ( | MenuRenderer * | renderer, |
MenuItem * | root, | ||
pinid_t | downPin, | ||
pinid_t | upPin, | ||
pinid_t | okPin, | ||
int | speed = 20 |
||
) |
Initialise for up down and OK button, instead of using hardware changeEncoderPrecision
renderer | the renderer used for drawing |
root | the first menu item |
downPin | the button for down |
upPin | the button on up |
okPin | the OK button for the menu select / edit action |
speed | the repeat key interval in ticks (lower is faster), default 20 |
void MenuManager::initFor4WayJoystick | ( | MenuRenderer * | renderer, |
MenuItem * | root, | ||
pinid_t | downPin, | ||
pinid_t | upPin, | ||
pinid_t | leftPin, | ||
pinid_t | rightPin, | ||
pinid_t | okPin, | ||
int | speed = 20 |
||
) |
Initialise for up a 4 way digital joystick that has up, down, left and right. With this it is possible for the joystick to properly handle scrolling, sideways scrolling, and regular change.
renderer | the renderer used for drawing |
root | the first menu item |
downPin | the button for down |
upPin | the button on up |
leftPin | the button on left |
rightPin | the button on right |
okPin | the OK button for the menu select / edit action |
speed | the repeat key interval in ticks (lower is faster), default 20 |
void MenuManager::initForTwoButton | ( | MenuRenderer * | renderer, |
MenuItem * | root, | ||
pinid_t | upPin, | ||
pinid_t | downPin | ||
) |
Initialise for up a 2 button joystick where the up doubles as back, and the down doubles as OK when held.
renderer | the renderer used for drawing |
root | the first menu item |
upPin | the button on up |
downPin | the button for down |
void MenuManager::initWithoutInput | ( | MenuRenderer * | renderer, |
MenuItem * | root | ||
) |
Initialise in situations where local input is not needed or where a custom type of input is needed that is not one of the common types.
In the case of custom input make sure that:
menuMgr.onMenuSelect(bool held)
when the select button is pressedmenuMgr.valueChanged(int value)
when the current value goes up / down.renderer | the renderer used for drawing |
root | the first menu item |
void MenuManager::setBackButton | ( | pinid_t | backButtonPin | ) |
You can add a back button that generally performs the back or left function
backButtonPin | the pin on which the back button is assigned. |
void MenuManager::setNextButton | ( | pinid_t | nextButtonPin | ) |
YOu can add a next button that generally performs the next or right function
nextButtonPin | the pin to which the next button is assigned |
|
inline |
Sometimes you need to use the menu structure before everything is initialised, in this case you can call this function early on to set up the root menu item.
|
inline |
If you want to be able to secure sub menus you have to provide an authentication manger. Normally create a global authentication manager and pass it into menuMgr and your remote server if you have one.
manager | the authentication manager to use for the submenu pin lock. |
|
inline |
|
inline |
This is a special callback, one per menu that indicates when a commit has taken place rather than when there has been a change. It uses the same callback signature as the standard change callback.
commitCallback | the callback to be notified when there is a commit event. |
void MenuManager::valueChanged | ( | int | value | ) |
called when the rotary encoder has moved to a new position to update the menu
value | the new changed value |
Called when the rotary encoder value has changed, if we are editing this changes the value in the current editor, if we are showing menu items, it changes the index of the active item (renderer will move into display if needed).
void MenuManager::onMenuSelect | ( | bool | held | ) |
Called when the OK button has been pressed
held | if the button is held down |
Called when the button on the encoder (OK button) is pressed. Most of this is left to the renderer to decide.
void MenuManager::performDirectionMove | ( | bool | dirIsBack | ) |
This provides support for next and back (left, right) functionality by making the menu structure respond to such functions in a reasonable way.
dirIsBack | true for back (left), false for next (right) |
void MenuManager::setItemsInCurrentMenu | ( | int | size, |
int | offs = 0 |
||
) |
Sets the number of items and offset of the items in the current menu
size | the number of items |
offs | the offset within the items |
|
inline |
Sets the global eeprom reference that tcMenu and other apps can use throughout the program.
globalRom |
void MenuManager::load | ( | EepromAbstraction & | eeprom, |
uint16_t | magicKey = 0xfade , |
||
TimerFn | onEepromEmpty = nullptr |
||
) |
Used during initialisation to load the previously stored state. Only if the magic key matches at location 0. It will also set the global eeprom variable like calling setEepromRef().
void MenuManager::load | ( | uint16_t | magicKey = 0xfade , |
TimerFn | onEepromEmpty = nullptr |
||
) |
Used during initialisation to load the previously stored state. Only if the magic key matches at location 0. This version requires that you have first set the eeprom abstraction using setEepromRef().
|
inline |
Saves the menu using the EEPROM ref that was set up either during load, or by calling setEepromRef(). To use this version you must ensure the eeprom was previously set. The magic key is saved first, followed by each item that has an eeprom location set. Only changes are saved because before each write we check if the value has actually changed.
magicKey | the key that indicates the values are valid. |
|
inline |
Call to save all item values into eeprom. The magic key is saved at location 0 if not already set. This is a lazy save that reads the eeprom values first, and only saves to eeprom when there are changes. Use this version when you want to override the eeprom used
MenuItem * MenuManager::findCurrentActive | ( | ) |
Find the menu item that is currently active.
|
inline |
Get the root of all menus, the first menu item basically
|
inline |
Get the renderer that this menu is using
|
inline |
Get the current MenuItem that is being edited (or null)
void MenuManager::setCurrentEditor | ( | MenuItem * | editor | ) |
Change the editor control that is receiving changes to apply to the menu item.
editor | the new editor or NULL |
void MenuManager::setItemActive | ( | MenuItem * | item | ) |
Set item to be the active item on the renderer. This also ensure any notifications are run too. It does clear any currently active item. This DOES NOT update the encoder, it is only to update the active status.
item | the item to active. |
void MenuManager::changeMenu | ( | MenuItem * | possibleActive = nullptr | ) |
Set the root item of either the first menu or any sub menu
theItem | the item to become the current root of the menu. |
void MenuManager::navigateToMenu | ( | MenuItem * | theNewItem, |
MenuItem * | possibleActive = nullptr , |
||
bool | skipHistory = false |
||
) |
Make the menu item theNewItem
the ROOT of the current menu on display, this item should be either the item referred to by rootMenuItem()
or the first child item of a submenu, normally obtained by calling menuSub.getChild()
on the submenu. When we navigate to a new item, by default menu manager keeps breadcrumbs to be able to go back nicely afterwards. If you are navigiating to a dynamic menu that should not go into this history, set skipHistory to true.
There is more information about this online see: https://www.thecoderscorner.com/products/arduino-libraries/tc-menu/menumanager-and-iteration/#navigation-around-menus
theNewItem | the first child menu item of the submenu (or root item) |
possibleActive | the item to activate or null for default |
skipHistory | set to true if this menu is custom and should not be stored in the history |
void MenuManager::resetMenu | ( | bool | completeReset | ) |
Force a complete reset of the menu
|
inline |
|
inline |
|
inline |
MenuItem * MenuManager::getParentAndReset | ( | ) |
|
inline |
SecuredMenuPopup * MenuManager::secureMenuInstance | ( | ) |
gets the secure menu popup instance that can be used to ask for a password on the device.
void MenuManager::stopEditingCurrentItem | ( | bool | doMultiPartNext | ) |
Stop editing the current item, if doMultiPartNext is true and we are editing a multi part field , then this will instead move editing to the next part. Otherwise, editing will end.
checkMultiPart | true to move to the next on multipart instead of ending completely |
Adds a menu item into the tree directly after the existing item provided. Never add an item that's already in the tree. Don't forget that if you use silent, to call menuStructureChanged() after you're done adding items.
existing | where in the tree the new item is to be added. |
toAdd | the item that should be added, must not be in the tree already. |
silent | do not run the structure changed callback. |
void MenuManager::notifyStructureChanged | ( | ) |
Call this method after making any structural change to the menu tree. For example adding a new menu item, changing the item name or static data such as size parameters. For example: modifying an items name, etc.
void MenuManager::addChangeNotification | ( | MenuManagerObserver * | observer | ) |
Adds an observer that will be notified of structure changes in the menu
observer | to be notified of structure changes. |
void MenuManager::recalculateListIfOnDisplay | ( | RuntimeMenuItem * | runtimeItem | ) |
This provides support for when lists are on the display, to allow the encoder to be updated so it can present the new items. If the list is not on display, nothing is done.
runtimeItem |
void MenuManager::setEditorHints | ( | CurrentEditorRenderingHints::EditorRenderingType | hint, |
size_t | start = 0 , |
||
size_t | end = 0 |
||
) |
This sets rendering hints, so that the renderer knows that something is being edited. When the rendering hints are set, they refer to the item that is currently being edited.
hint | the type of edit taking place |
start | the starting point within the text |
end | the ending point within the text |
void MenuManager::setEditorHintsLocked | ( | bool | locked | ) |
Lock the editor hints such that nobody can change them, useful for complex editing where more than one field is being edited at once.
locked | true to lock, otherwise false. |
void MenuManager::resetObservers | ( | ) |
Use this with caution. Resets the entire list of observers that have previously been registered.
void MenuManager::setupForEditing | ( | MenuItem * | item | ) |
Allows you to enable an item for editing directly without going through the UI
item | the item to become the active edit, the right submenu should have already been enabled first |