tcMenu
Public Member Functions | Static Public Attributes | Protected Member Functions | List of all members
MenuManager Class Reference

#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)
 
AuthenticationManagergetAuthenticator ()
 
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)
 
MenuItemfindCurrentActive ()
 
MenuItemgetRoot ()
 
MenuRenderergetRenderer ()
 
MenuItemgetCurrentEditor ()
 
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)
 
MenuItemgetCurrentMenu ()
 
MenuItemgetCurrentSubMenu ()
 
tcnav::MenuNavigationStoregetNavigationStore ()
 
MenuItemgetParentAndReset ()
 
int getCurrentRangeValue ()
 
SecuredMenuPopupsecureMenuInstance ()
 
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 CurrentEditorRenderingHintsgetEditorHints ()
 
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)
 

Detailed Description

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.

Member Function Documentation

◆ setUseWrapAroundEncoder()

void MenuManager::setUseWrapAroundEncoder ( bool  wrapAround)
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.

Parameters
wrapAroundshould values wrap

◆ addEncoderWrapOverride()

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.

Parameters
itemthe item for which the override is to be applied.
overridetrue if wrapping is needed, otherwise false.

◆ isWrapAroundEncoder()

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.

Parameters
menuIdthe menu id obtained using getId() on the menu item
Returns
true if wrapping is to be used, otherwise false

◆ initForEncoder()

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

Parameters
rendererthe renderer used for drawing
rootthe first menu item
encoderPinAencoder A pin
encorerPinBencoder B pin
encoderButtonthe OK button for the menu select / edit action
typeoptionally, you can provide the encoder type, only really needed for quarter cycle encoders.

◆ initForUpDownOk()

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

Parameters
rendererthe renderer used for drawing
rootthe first menu item
downPinthe button for down
upPinthe button on up
okPinthe OK button for the menu select / edit action
speedthe repeat key interval in ticks (lower is faster), default 20

◆ initFor4WayJoystick()

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.

Parameters
rendererthe renderer used for drawing
rootthe first menu item
downPinthe button for down
upPinthe button on up
leftPinthe button on left
rightPinthe button on right
okPinthe OK button for the menu select / edit action
speedthe repeat key interval in ticks (lower is faster), default 20

◆ initForTwoButton()

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.

Parameters
rendererthe renderer used for drawing
rootthe first menu item
upPinthe button on up
downPinthe button for down

◆ initWithoutInput()

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:

  1. something will call menuMgr.onMenuSelect(bool held) when the select button is pressed
  2. something will call menuMgr.valueChanged(int value) when the current value goes up / down.
Parameters
rendererthe renderer used for drawing
rootthe first menu item

◆ setBackButton()

void MenuManager::setBackButton ( pinid_t  backButtonPin)

You can add a back button that generally performs the back or left function

Parameters
backButtonPinthe pin on which the back button is assigned.

◆ setNextButton()

void MenuManager::setNextButton ( pinid_t  nextButtonPin)

YOu can add a next button that generally performs the next or right function

Parameters
nextButtonPinthe pin to which the next button is assigned

◆ setRootMenu()

void MenuManager::setRootMenu ( MenuItem menuItem)
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.

◆ setAuthenticator()

void MenuManager::setAuthenticator ( AuthenticationManager manager)
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.

Parameters
managerthe authentication manager to use for the submenu pin lock.

◆ getAuthenticator()

AuthenticationManager* MenuManager::getAuthenticator ( )
inline
Returns
the global authentication manager that has been set for this menu application, or nullptr otherwise

◆ setItemCommittedHook()

void MenuManager::setItemCommittedHook ( MenuCallbackFn  commitCallback)
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.

Parameters
commitCallbackthe callback to be notified when there is a commit event.

◆ valueChanged()

void MenuManager::valueChanged ( int  value)

called when the rotary encoder has moved to a new position to update the menu

Parameters
valuethe 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).

◆ onMenuSelect()

void MenuManager::onMenuSelect ( bool  held)

Called when the OK button has been pressed

Parameters
heldif 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.

◆ performDirectionMove()

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.

Parameters
dirIsBacktrue for back (left), false for next (right)

◆ setItemsInCurrentMenu()

void MenuManager::setItemsInCurrentMenu ( int  size,
int  offs = 0 
)

Sets the number of items and offset of the items in the current menu

Parameters
sizethe number of items
offsthe offset within the items

◆ setEepromRef()

void MenuManager::setEepromRef ( EepromAbstraction *  globalRom)
inline

Sets the global eeprom reference that tcMenu and other apps can use throughout the program.

Parameters
globalRom

◆ load() [1/2]

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().

◆ load() [2/2]

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().

◆ save() [1/2]

void MenuManager::save ( uint16_t  magicKey = 0xfade)
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.

Parameters
magicKeythe key that indicates the values are valid.

◆ save() [2/2]

void MenuManager::save ( EepromAbstraction &  eeprom,
uint16_t  magicKey = 0xfade 
)
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

◆ findCurrentActive()

MenuItem * MenuManager::findCurrentActive ( )

Find the menu item that is currently active.

◆ getRoot()

MenuItem* MenuManager::getRoot ( )
inline

Get the root of all menus, the first menu item basically

◆ getRenderer()

MenuRenderer* MenuManager::getRenderer ( )
inline

Get the renderer that this menu is using

◆ getCurrentEditor()

MenuItem* MenuManager::getCurrentEditor ( )
inline

Get the current MenuItem that is being edited (or null)

◆ setCurrentEditor()

void MenuManager::setCurrentEditor ( MenuItem editor)

Change the editor control that is receiving changes to apply to the menu item.

Parameters
editorthe new editor or NULL

◆ setItemActive()

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.

Parameters
itemthe item to active.

◆ changeMenu()

void MenuManager::changeMenu ( MenuItem possibleActive = nullptr)

Set the root item of either the first menu or any sub menu

Parameters
theItemthe item to become the current root of the menu.

◆ navigateToMenu()

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

Parameters
theNewItemthe first child menu item of the submenu (or root item)
possibleActivethe item to activate or null for default
skipHistoryset to true if this menu is custom and should not be stored in the history

◆ resetMenu()

void MenuManager::resetMenu ( bool  completeReset)

Force a complete reset of the menu

◆ getCurrentMenu()

MenuItem* MenuManager::getCurrentMenu ( )
inline
Returns
the first menu item in the linked list that is being rendered

◆ getCurrentSubMenu()

MenuItem* MenuManager::getCurrentSubMenu ( )
inline
Returns
the submenu for the currently on display menu. If root is on display it will be nullptr.

◆ getNavigationStore()

tcnav::MenuNavigationStore& MenuManager::getNavigationStore ( )
inline
Returns
the underlying navigation store that manages navigation activity for this menu manager.

◆ getParentAndReset()

MenuItem * MenuManager::getParentAndReset ( )
Returns
the parent of the current menu clearing all active flags too

◆ getCurrentRangeValue()

int MenuManager::getCurrentRangeValue ( )
inline
Returns
the range of the encoder or other device that is providing the equivalent function as the encoder.

◆ secureMenuInstance()

SecuredMenuPopup * MenuManager::secureMenuInstance ( )

gets the secure menu popup instance that can be used to ask for a password on the device.

Returns
the single instance of this popup.

◆ stopEditingCurrentItem()

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.

Parameters
checkMultiParttrue to move to the next on multipart instead of ending completely

◆ addMenuAfter()

void MenuManager::addMenuAfter ( MenuItem existing,
MenuItem toAdd,
bool  silent = false 
)

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.

Parameters
existingwhere in the tree the new item is to be added.
toAddthe item that should be added, must not be in the tree already.
silentdo not run the structure changed callback.

◆ notifyStructureChanged()

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.

◆ addChangeNotification()

void MenuManager::addChangeNotification ( MenuManagerObserver observer)

Adds an observer that will be notified of structure changes in the menu

Parameters
observerto be notified of structure changes.

◆ recalculateListIfOnDisplay()

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.

Parameters
runtimeItem

◆ setEditorHints()

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.

Parameters
hintthe type of edit taking place
startthe starting point within the text
endthe ending point within the text

◆ setEditorHintsLocked()

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.

Parameters
lockedtrue to lock, otherwise false.

◆ resetObservers()

void MenuManager::resetObservers ( )

Use this with caution. Resets the entire list of observers that have previously been registered.

◆ setupForEditing()

void MenuManager::setupForEditing ( MenuItem item)

Allows you to enable an item for editing directly without going through the UI

Parameters
itemthe item to become the active edit, the right submenu should have already been enabled first

The documentation for this class was generated from the following files: