MD_Menu Library
2.1
Library for 1 or 2 line display menu management
|
The MD_Menu library allows definition and navigation of a menu system by moving between the menu nodes. At a leaf node, MD_Menu can either manage editing values or call user code.
Menu structures are defined in PROGMEM memory. They are linked into tree structures relationships using the IDs of other menu nodes nodes or leaf nodes. Leaf nodes are always associated with a user variable.
Extensive use is made of callbacks to user code to manage user input, display output and getting/setting values for variables.
Menu navigation is carried out under the control of user code invoked as a callback routine. The code must comply with the cbUserNav function prototype. This callback routine implementation is dependent on the type of input hardware, but the return codes for the required actions must be one of the standardized userNavAction_t enumerated type.
Navigation is carried out with 4 keys:
A variety of input hardware setups are demonstrated in the Test example code provided.
Menu display is enabled by user code as a callback routine from the library. The callback must comply with the cbUserDisplay function prototype.
The callback is provided with a request of type userDisplayAction_t and a message to display.
Display hardware must be able to display one or two lines for the menu display. All menu screens are structured with the first line as title and the second as the current menu selection or currently edited value, as appropriate. If the display can only support one line, the first line is discarded and only the second line displayed.
A variety of display hardware setups are demonstrated in the Test example code provided.
The limited amount of RAM available in micro controllers is a challenge for menu systems, as they often contain large amounts of 'static' data as text labels and other status information.
The MD_Menu library uses statically allocated data located in PROGMEM for the menu system and only copies the current menu record into RAM. All user values reside in user code and are not duplicated in the library.
As shown in the figure above, the library uses three types of objects, each identified with a unique id within the object type. A menu header (of type mnuHeader_t) defines a menu. The header contains a label for the title and the range of menu items (of type mnuItem_t) that should be displayed for the menu. Menu item ids between the start and end id locations include all the ids in locations in between, and should be in number sequence.
A menu item may lead to another menu (MNU_MENU, if it is a node in the menu tree) an input item (of type mnuInput_t) if it is a leaf of the menu system (MNU_INPUT), or an input item with real-time feedback (MNU_INPUT_FB) that reports the value each time with every change of value. The depth of the menu tree is restricted by the defined MENU_STACK_SIZE constant. When this limit is exceeded, the library will just ignore requests that cause additional menu depth but continues to run.
Menu input items define the type of value that is to be edited by the user and parameters associated with managing the input for that value. Before the value is edited a callback following the cbValueRequest prototype is called to 'get' the pointer to the variable with the current value. The input item id is provided to identify which value is being requested. The data must be loaded into a value_t data structure that remains in scope while the data is being edited, and the pointer to the structure passed back to the library. This copy of the user variable is used for editing and a second cbValueRequest (conceptually a 'set') is invoked after the value is updated, enabling the user code to take action on the change. If the variable edit is cancelled, the second cbValueRequest 'set' call does not occur and no further action is required from the user code. If the edit is specified with real-time feedback, the value is 'set' for each change in value.
Variable data input may be of the following types: