By dave | November 11, 2020

Scroll Choice menu items allow for a single choice from a list of choices. Unlike enum menu item the choices may not be known until runtime, and could change at any time. There are several ways that choices can be stored either in a fixed width memory character array, EEPROM fixed width array, or lastly using a custom callback for each item.

Class types for ScrollChoiceMenuItem

Creating a Scroll Choice item from the designer

From the add dialog choose the “Scroll Choice” option. The form will look similar to the following:

image showing the scroll choice editor

Scroll Choice Editor UI

See the section further down on dealing with scroll items in code for the specifics, but here’s how to configure for all three cases

To set up for EEPROM storage, you choose data mode as EEPROM, the item width is the maximum width of the text for an item, and initial items is how many items are in the array (can be changed at runtime). EEPROM offset is the position in the EEPROM storage where the array starts. You must call menuMgr.setEepromRef(ptrToEeprom) during setup. See the menu manager docs

To set up for RAM storage, you choose data mode as RAM, the item width is again the maximum width and initial items works as per EEPROM mode. In this case you must specify the array variable, which is a character array in memory large enough to account for width * numItems.

To set up for custom, you choose custom data mode, at this point only initial items needs setting, the designer will add a custom callback to your code, see the section below on implementing it.

Dealing with a scroll choice item in code

EEPROM and RAM option

When using either EEPROM or RAM storage of items, we use a flat array of items the same size for each item. Let’s say each item is 10 long, they will follow each other sequentially in memory like the illustration below. We use ~ to represent the zero termination. For EEPROM storage you specify the location at which the array starts, whereas for RAM you provide the variable name of the array.

For EEPROM storage, you absolutely must call menuMgr.setEepromRef(ptrToEeprom) first. See the menu manager docs

    item space    
    0 1 2 3 4 5 6 7 8 9
r 0 H e l l o ~
o 1 B o n j o u r ~
w 2 G u t e n t a g ~ 

Caching: To cache EEPROM values into RAM call cacheEepromValues on the item, in this case the array size must not exceed 255 characters. Performance will be significantly improved, especially on I2C EEPROMs.

Custom rendering option

In this case you use a custom rendering function that will be called back to get the name of the item, the location in EEPROM, and also to get the value of each choice. Here is an example to get you started:

int CALLBACK_FUNCTION fnChoiceCustomCallback(RuntimeMenuItem * item, uint8_t row, 
                                             RenderFnMode mode, char * buffer, int bufferSize) {
    switch(mode) {
           return myEepromLocation; // here return the EEPROM location to store the value
        case RENDERFN_INVOKE:
            // when using custom mode, this is how you detect a change in the value
            serdebugF2("Num Choice changed to ", row);
            return true;
        case RENDERFN_NAME:
            // this is how to provide the display name of the item 
            strcpy(buffer, "Num Choices");
            return true;
        case RENDERFN_VALUE:
            // this is how to provide the choice, the zero based index is in row  
            buffer[0] = 'V'; buffer[1]=0;
            fastltoa(buffer, row, 3, NOT_PADDED, bufferSize);
            return true;
        default: return false;

General purpose functions

To get the text of a particular choice

item.valueAtPosition(buffer, bufferSize, idx);

To get and set the current choice index

void setCurrentValue(newIdx, silent = false);
int idx = getCurrentValue();

Creating a scroll choice menu item from the CLI

To create a scroll choice menu item from the CLI here is a template command (options in square brackets are optional):

tcmenu create-item --parent 0 --type choice --name ChoiceName [--localonly --readonly --hide]

The structure of a scroll choice menu item in the EMF file is:

  "parentId": 0,
  "type": "scrollItem",
  "item": {
    "itemWidth": 0,
    "eepromOffset": 0,
    "numEntries": 0,
    "choiceMode": "ARRAY_IN_EEPROM",
    "name": "ChoiceName",
    "variableName": "ChoiceName",
    "id": 14,
    "eepromAddress": -1,
    "readOnly": false,
    "localOnly": false,
    "visible": true

Where choice mode is one of:


Manually creating a ScrollChoice item

RENDERING_CALLBACK_NAME_INVOKE(fnScrollChoiceCb, enumItemRenderFn, "Choice", 
                               myEepromLocation, NO_CALLBACK)
ScrollChoiceMenuItem menuScrollChoice(myId, fnScrollChoiceCb, 0, 
                               romLocation, itemWidth, noItem, &nextMenuItem);

Above we create a Choice item with the choices in EEPROM, the name of the callback method is fnScrollChoiceCb and most requests pass through to enumItemRenderFn. The menu item name will be “Choice” and its menu changed callback is NO_CALLBACK, you could instead define a callback. Change myId to the desired ID and myEepromLocation to a suitable storage location or 0xFFFF.

We then specify the location in ROM where the array starts, and the width of each item and number of items. You can see the reference docs (link at top of page) for the RAM and custom constructors.

Other pages within this category

comments powered by Disqus

This site uses cookies to analyse traffic, serve ads by Google AdSense (non-personalized in EEA/UK), and to record consent. We also embed Twitter, Youtube and Disqus content on some pages, these companies have their own privacy policies.

Our privacy policy applies to all pages on our site

Should you need further guidance on how to proceed: External link for information about cookie management.