
[tocstart]: # (toc start)

  * [MUI Naming Convention](#mui-naming-convention)
    * [Definitions](#definitions)
    * [FDS macros](#fds-macros)
    * [MUIF and MUIF Callbacks](#muif-and-muif-callbacks)
  * [MUIF, MUIF Callback and FDS Macro Reference](#muif-muif-callback-and-fds-macro-reference)
    * [Generic Style](#generic-style)
    * [Font Style](#font-style)
    * [Label](#label)
    * [Jump Button](#jump-button)
    * [Back Button](#back-button)
    * [Exit Button](#exit-button)
    * [Checkbox and Radiobutton](#checkbox-and-radiobutton)
    * [Numbers (uint8)](#numbers-uint8)
    * [Numbers (int8)](#numbers-int8)
    * [Bar Graph (uint8)](#bar-graph-uint8)
    * [Fixed Width Bar Graph (uint8)](#fixed-width-bar-graph-uint8)
    * [Character Input](#character-input)
    * [One of Many Selection (Cycle, uint8, static list)](#one-of-many-selection-cycle-uint8-static-list)
    * [One of Many Selection (Cycle, uint16, dynamic list)](#one-of-many-selection-cycle-uint16-dynamic-list)
    * [List Selection (Child form, uint8, static list)](#list-selection-child-form-uint8-static-list)
    * [List Selection (Child form, uint16, dynamic list)](#list-selection-child-form-uint16-dynamic-list)
    * [Scrollable Jump Table (static)](#scrollable-jump-table-static)
    * [Scrollable Jump Table (dynamic)](#scrollable-jump-table-dynamic)
  * [MUI API](#mui-api)
    * [begin](#begin)
    * [getCurrentCursorFocusPosition](#getcurrentcursorfocusposition)
    * [getCurrentFormId](#getcurrentformid)
    * [gotoForm](#gotoform)
    * [nextField](#nextfield)
    * [prevField](#prevfield)
    * [restoreForm](#restoreform)
    * [sendSelect](#sendselect)
    * [sendSelectWithExecuteOnSelectFieldSearch](#sendselectwithexecuteonselectfieldsearch)
  * [MUIF Helper Functions](#muif-helper-functions)
    * [mui_get_U8g2](#mui_get_u8g2)
    * [mui_get_x](#mui_get_x)
    * [mui_get_y](#mui_get_y)
    * [mui_get_arg](#mui_get_arg)

[tocend]: # (toc end)

# MUI Naming Convention

## Definitions

 * **Form**
    * A form describes the content of one full display screen. 
    * The user interface must include at least one form. 
    * Each form includes one or more fields (see below). 
    * MUI supports up to 255 forms. 
    * Each form in MUI has a unique number (1..255).
    * All forms are defined in **FDS** (Form Definition String)
    * Each form starts with the **FDS Macro** `MUI_FORM(x)` with x = 1..255.
  
 * **Field**
    * A field is an element of a form.
    * A field can be an interactive element, like a button or a selection box.
    * A field can be a static element, like a text label or an icon.
    * A field can modify a value (field value), like a field input for a numerical value.
    * A field often supports two different edit modes: **MSE** and **MUD**
    * A field is placed at a specific XY position.
    * Each field has a two char identifier, which connects the field to a field processing function (**MUIF**).
    * A field might have an extra argument, which could be used by the field processing function (**MUIF**).
    * A Field is defined with a **FDS Macro** as part of a Form within the **FDS**.
    * Example: `MUI_LABEL(5, 15, "Hello U8g2")` is a **FDS Macro** which defines a read only text field. The **FDS Macro** `MUI_XYT("BN",64, 30, " Exit ")` places a button with the text " Exit " on a form.
            
  * **FDS** (Form Definition String)
    * A normal C-String, which is usually composed with special macros (**FDS Macro**).
    * Defines all the forms along with all the fields.
    * The FDS is passed to the menu system during initalization (`mui.begin(u8g2, fds_data, muif_list, sizeof(muif_list)/sizeof(muif_t));` )
    * Example:
      ```
      fds_t fds_data[] = 
      MUI_FORM(1)                     // no comma allowed, because fds_data is a string
      MUI_STYLE(0)
      MUI_XYT("BN",64, 30, " Select Me ")
      ;
      ```
    
    
  * **FDS Macro**
    * A C macro which is part of the **FDS** (Form Definition String).
    * All FDS Macros start with `MUI_`.
    * A FDS Macro may define a field at a specific position on the form (for example `MUI_XYT("BN",64, 30, " Exit ")`).
    * There are some other FDS Macros, for example to start a new form (`MUI_FORM()`) or to change the current style (`MUI_STYLE()`).
    
  * **MUIF** (MUI Field Processing Function)
    * Each MUIF has a unique two char identifier (Exceptions: `MUIF_STYLE` will use a number,  `MUIF_U8G2_LABEL()` does not require a number or identifier)
    * A MUIF is often connected to a **MUIF callback** function. 
    * A MUIF can be connected to an outside variable (data pointer). Data input from the user can be stored in those variables.
    * A MUIF can be referenced by one or more **fields** via the field's definition in the **FDS Macro**
    * A MUIF can be a simple text output function such as `MUIF_U8G2_LABEL()`, which is placed with the **FDS Macro** `MUI_LABEL()` .
    * A MUIF can be a complex interactive numeric value input, which is rendered as a number field and writes the number to a corresponding data variable.
    * An array with all MUIFs (**MUIF List**) for the current menu is passed to the menu system during initalization.
    * MUIF always starts with `MUIF_`.
    * A MUIF is a C Macro (MUIF macro) which may have several arguments (like identifier, **MUIF callback** or the address of a variable).
    * Example: `MUIF_BUTTON("BN", mui_u8g2_btn_exit_wm_fi)` is a MUIF macro with **MUIF callback** `mui_u8g2_btn_exit_wm_fi`. `MUIF_U8G2_LABEL()` is a MUIF macro without **MUIF callback**. 

  * **MUIF Callback** 
    * A **MUIF** (MUI Field Processing Function) might refer to a callback function (MUIF Callback).
    * The MUIF Callback defines additional characteristics and behaviour of the field.
    * Custom MUIF Callbacks can be created: Existing MUIF Callbacks can be extended or modified, but also complete new MUIF Callbacks can be implemented.
    * Example: In the MUIF `MUIF_BUTTON("BN", mui_u8g2_btn_exit_wm_fi)`, the identifier `mui_u8g2_btn_exit_wm_fi` is called the MUIF Callback.
    
  * **MUIF List**
    *  A C array with all **MUIFs**, which are required for the menu system.
    * The MUIF List is passed to the menu system during initalization (`mui.begin(u8g2, fds, muif_list, sizeof(muif_list)/sizeof(muif_t));`).
    * Example:
      ```
      muif_t muif_list[] = {  
        MUIF_U8G2_FONT_STYLE(0, u8g2_font_helvR08_tr),  /* define style 0 */
        MUIF_U8G2_LABEL(),                              /* allow MUI_LABEL FDS Macro */
        MUIF_BUTTON("BN", mui_u8g2_btn_exit_wm_fi)      /* define exit button MUIF */
      };
      ```
      
  * **MUD**
    * Modify Up Down
    * **Field** data entry mode, where the user has to (a) select the field, (b) use prev/next button to change the value and (c) press select again to confirm the value and leave the value chang mode
    * See [MUI Callback Edit Mode](muiref#mui-callback-edit-mode)
  
  * **MSE**
    * Modify with SElect
    * **Field** data entry mode, where the user just moves the focus cursor into the field. Pressing "select" will increment the value
    * See [MUI Callback Edit Mode](muiref#mui-callback-edit-mode)
    

## FDS macros

This section describes all available **FDS Macros**.  The FDS Macros are used to describe the visual layout of the menu including the position of each text and button on a form.


  * `MUI_FORM(form_id)`: Start a new form with given `form_id` (0..255). A form ends with the next `MUI_FORM` or at the end of the FDS.
      * `form_id`: A value between 0..255. Value 0 is possible for `form_id` but should be avoided. The `form_id` is a plain number like `MUI_FORM(123)`.
  * `MUI_STYLE(style_id)`: Assign a style (0..9) to the following fields. 
      * `style_id`: The `style_id` is a plain number from 0 to 9. Example: `MUI_STYLE(0)`.
  * `MUI_DATA(muif_id, string)`: Places a data object into the form. Data objects are required for special MUIF. 
      * `muif_id`: A string  with exactly two chars (like "G0"), which referes to the corresping field function in MUIF array.
      * `string`: Additional data for some graphical user elements (see description for the MUIF below).
  * `MUI_XY(muif_id, x, y)`: Places field `muif_id` at the specified x,y position. 
      * `muif_id`: A string  with exactly two chars (like "G0"), which referes to the corresping field function in MUIF array.
      * `x`, `y`: Position for the field. Values are between 0 and 255. For bigger displays, the value is automatically multiplied with 2 (which means, that a field can be placed only at every
      second pixel on a 320x200 screen).
  * `MUI_XYT(muif_id, x, y, text)`: Places field `muif_id` with text argument at the specified x,y position.
      * `muif_id`: A string  with exactly two chars (like "G0"), which referes to the corresping field function in MUIF array.
      * `x`, `y`: Position for the field. Values are between 0 and 255. For bigger displays, the value is automatically multiplied with 2 (which means, that a field can be placed only at every
      second pixel on a 320x200 screen).
      * `text`: Contains additional data for the field. See the description for the MUIF below for details.
  * `MUI_XYA(muif_id, x, y, arg)`: Places field `muif_id` with additional `arg`information at the specified x,y position.
      * `muif_id`: A string  with exactly two chars (like "G0"), which referes to the corresping field function in MUIF array.
      * `x`, `y`: Position for the field. Values are between 0 and 255. For bigger displays, the value is automatically multiplied with 2 (which means, that a field can be placed only at every
      second pixel on a 320x200 screen).
      * `arg`: Additional value used by the field function. This might be the field width in pixel or the form id for a jump button, depending on the MUIF (see below).
  * `MUI_XYAT(muif_id, x, y, arg, text)`: Places field `muif_id` at the specified x,y position with additional `arg` and `text` information.
      * `muif_id`: A string  with exactly two chars (like "G0"), which referes to the corresping field function in MUIF array.
      * `x`, `y`: Position for the field. Values are between 0 and 255. For bigger displays, the value is automatically multiplied with 2 (which means, that a field can be placed only at every
      second pixel on a 320x200 screen).
      * `arg`: Additional value used by the field function. This might be the field width in pixel or the form id for a jump button, depending on the MUIF (see below).
      * `text`: Contains additional data for the field. See the description for the MUIF below for details.
  * `MUI_AUX(muif_id)`: Adds a (invisible) field to the form without providing a x,y position. See the [stopwatch example](muimanual#stopwatch-example).
      * `muif_id`: A string  with exactly two chars (like "G0"), which referes to the corresping field function in MUIF array.
    

All FDS Macros are written in a sequence in the form definition string (FDS).

Example:
```
fds_t fds_data[] = 
MUI_FORM(1)                     // no comma allowed, because fds_data is a string
MUI_STYLE(0)
MUI_XYT("BN",64, 30, " Select Me ")
;
```

Note: FDS is a C string, this means that there must be no comma to separate above macros.


## MUIF and MUIF Callbacks

MUIF (MUI Field Processing Function) define properties (display style, behavior, etc) for a field on the form 
(FDS Macro, see [above](#fds-macros)): Mosst FDS macros require a 
corresponding MUIF (with same `muif_id` or same number) . 
 
  * FDS macro `MUI_XYT("BN",64, 30, " Button ")` will use MUIF `MUIF_BUTTON("BN", mui_u8g2_btn_exit_wm_fi)` because they share the same `muif_id` `"BN"`
  * FDS macro `MUI_STYLE(0)` will use `MUIF_U8G2_FONT_STYLE(0, u8g2_font_helvR08_tr)` because they share the same number `0`.
  * FDS macro `MUI_LABEL(5, 15, "Hello U8g2")` will always use MUIF `MUIF_U8G2_LABEL()`. 

Some MUIF require an additional **MUIF callback** function. For example MUIF `MUIF_BUTTON("BN", mui_u8g2_btn_exit_wm_fi)` requires
the MUIF callback `mui_u8g2_btn_exit_wm_fi` which defines additional properties for the field.

The following sections will explain the naming convention for the **MUIF callbacks**.

The last section will provide an overview on the available **MUIF** (`MUIF_`).

### MUIF Callback Field Width Property

| hint | field width | example MUIF callback |
|---|---|---|
| `wm` |                minimum width (often defined by a text string)  | `mui_u8g2_btn_goto_wm_fi` |
| `wa`  |              width can be provided via **FDS Macro** argument | `mui_u8g2_u8_opt_line_wa_mse_pi` |
| `w1`  |              full display width | `mui_u8g2_btn_goto_w1_pi` |
| `w2`   |             half display size (minus some pixel) | `mui_u8g2_btn_goto_w2_fi` |
| `w3`   |             one/third of the dispay width (minus some pixel) | (not yet implemented) |

The field width hint is always part of the MUIF callback name (Only exceptions are MUIF callbacks 
for invisible fields, like `mui_u8g2_goto_data`).

### MUI Callback Edit Mode

Some **MUIF callbacks** include a hint for the data change method for the field value:

| hint | description |
|---|---|
| `mse` | edit Mode SElect: The select event will increment the value. |
| `mud` | edit Mode Up/Down: The select event will enter the edit mode for the field. Next/prev event will increment/decrement the value. |

If the `mse` or `mud` hint is missing in the MUI function name, then this function either  doesn't change 
a value (buttons) or the value change is trivial (checkbox). Examples:
 * `mui_u8g2_u8_min_max_wm_mse_pi`: The input function for a `uint8_t` value with `mse` input method .
 * `mui_u8g2_u8_chkbox_wm_pi`: There is no `mse` or `mud` mode for the checkbox, instead the select event will toggle the value directly.
 

### MUI Callback Display Style 
 
Each **MUIF Callback** has a postfix, which describes the display style of the field in different modes (focus, no focus, mud edit mode). 
Note: "mud" doesn't exist for buttons, so the styles "fi" and "if" don't have a separate "mud" edit mode style.

| postfix | field selection style | usually used for... | unselected style | selected style | edit mode (mud) |
|---|---|---|---|---|---|
| pi | inverted field | input elements | plain | inverted | inverted + gap + frame  |
| fi | inverted field | button elements | frame | frame+inverted | (frame) |
| pf | frame around field | input elements | plain | frame | inverted+frame  |
| if | frame around field | button elements | inverted | frame | (inverted + frame) |

### MUIF Overview

A field can be used in a form only, if a **MUIF** exists for that field.
All **MUIF** are collected in a list (**MUIF list**).
Most **MUIF** require a **MUIF callback** (`cb` in the below table) as part of the
MUIF arguments. The description of the callback function is provided below. MUIF macros are:

| MUIF Macro |  FDS Macros | Identifier | Description | 
|---|---|---|---|
| `MUIF_U8G2_FONT_STYLE(n,font)` | MUI_STYLE | Single number, no double quotes | Define a new font style |
| `MUIF_VARIABLE(id,var,cb)` | MUI_XY, MUI_XYT, MUI_XYA, MUI_XYAT | Two chars in double quotes | Input field for the user: [Exit Button](muiref#exit-button), [Checkbox and Radiobutton](muiref#checkbox-and-radiobutton), [Character Input](muiref#character-input), [One of Many Selection](muiref#one-of-many-selection-cycle-uint8-static-list), [List Selection](muiref#list-selection-child-form-uint8-static-list) |
| `MUIF_BUTTON(id,cb)` | MUI_XYAT | Two chars in double quotes | User selectable field: [Jump Button](muiref#jump-button), [Exit Button](muiref#exit-button), [Scrollable Jump Table](muiref#scrollable-jump-table-static) |
| `MUIF_EXECUTE_ON_SELECT_BUTTON(id,cb)` | MUI_XYAT | Two chars in double quotes | User selectable field, same as `MUIF_BUTTON(id,cb)`, see [here](muiref#sendSelectWithExecuteOnSelectFieldSearch)|
| `MUIF_U8G2_LABEL()` | MUI_LABEL | No identifier and no callback required | Place a text on the form |
| `MUIF_RO(id,cb)` | MUI_DATA, MUI_AUX, MUI_XY | Two chars in double quotes | Inactive or hidden field, also used to define extra data for [Scrollable Jump Table](muiref#scrollable-jump-table-static), see also [stopwatch example](muimanual#stopwatch-example) |
| `MUIF_U8G2_U8_MIN_MAX(id, var, min, max, cb)` | MUI_XY | Two chars in double quotes | Numeric input field: [Number Entry](muiref#numbers-uint8) |
| `MUIF_U8G2_U8_MIN_MAX_STEP(id, var, min, max, step, flags, cb)` | MUI_XY | Two chars in double quotes | Numeric input field: [Bar Graph](muiref#bar-graph-uint8) |
| `MUIF_U8G2_U8_MIN_MAX_STEP_WIDTH(id, var, min, max, step, width, flags, cb)` | MUI_XY | Two chars in double quotes | Numeric input field: [Fixed Width Bar Graph](muiref#fixed-width-bar-graph-uint8) |
| `MUIF_U8G2_U16_LIST(id, valptr, dataptr, getcb, cntcb, muif)` | MUI_XYA | Two chars in double quotes | List selection input field: [One of Many Selection](muiref#one-of-many-selection-cycle-uint16-dynamic-list), [List Selection](muiref#list-selection-child-form-uint16-dynamic-list), [Scrollable Jump Table](muiref#scrollable-jump-table-dynamic) |




There are some advanced MUIF macros, which are usually not required (because a simplified / predefined MUIF exists).

| MUIF Macro |  FDS Macros | Identifier | Description | Simplified MUIF Macro | 
|---|---|---|---|---|
| `MUIF_STYLE(n,cb)` | MUI_STYLE | Single number, no double quotes | Define a new generic style | `MUIF_U8G2_FONT_STYLE(n,font)` |
| `MUIF_LABEL(cb)` | MUI_LABEL | No identifier required | Place a text on the form | `MUIF_U8G2_LABEL()` | 


Each **FDS Macro** for a **field** requires a corresponding and fitting **MUIF** Macro. 
The reference part below describes which **MUIF** Macro (and **MUIF callback**) must be used for a **FDS Macro** (field).
For example the **MUIF Callback** `mui_u8g2_btn_exit_wm_fi` (exit button callback) should be used with the MUIF `MUIF_VARIABLE` 
so that the **FDS Macro*** `MUI_XYAT` field can be used within **FDS**.

# MUIF, MUIF Callback and FDS Macro Reference

## Generic Style

 * **Description:**
    
    Change the current drawing style. This will change the style for all MUI macros after this macro.
 * **MUIF Macro:**
 
    `MUIF_STYLE(style_id, style_callback)`
 * **FDS Macro:** 
 
    `MUI_STYLE(style_id)`: Change the current drawing style (usually the text font).
 * **Note:**
 
    A more simpler version is `MUIF_U8G2_FONT_STYLE` ([see below](#font-style)) if only the U8g2 font needs to be changed.
 * **Example:**
    ```
    uint8_t mui_style_helv_r_08(mui_t *ui, uint8_t msg) {  
      u8g2_t *u8g2 = mui_get_U8g2(ui);
      switch(msg) {
        case MUIF_MSG_DRAW:
          u8g2_SetFont(u8g2, u8g2_font_helvR08_tr);
          break;
      }
      return 0;
    }
    ...
    muif_t muif_list[] = {
      /* normal text style */
      MUIF_STYLE(0, mui_style_helv_r_08),
      ...
    }
    ```
    ```
    ...
    MUI_FORM(123)
    MUI_STYLE(0)
    ...
    ```

## Font Style

 * **Description:**
    
    The style FDS macro will change the style for all other FDS macros listed after the style FDS macro.
    The font style FDS macro will change the current U8g2 font. This is a more simpler version of `MUIF_STYLE` in cases where only the font needs to be changed. 
    The U8g2 font can be used as argument of the corresponding (same style id) MUIF style entry. No additional callback function is required for the MUIF macro.
 * **MUIF Macro:**
 
    `MUIF_U8G2_FONT_STYLE(style_id, u8g2_font))`
 * **FDS Macro:** 
 
    `MUI_STYLE(style_id)`: Change the current text font to the font which was assigned in the MUIF macro.
 * **Example**:
    ```
    muif_t muif_list[] = {
      /* normal text style */
      MUIF_U8G2_FONT_STYLE(0, u8g2_font_helvR08_tr),
      ...
    }
    ```
    ```
    ...
    MUI_FORM(1)                            /* This will start the definition of form 1 */
    MUI_STYLE(0)                           /* select the font defined with style 0: u8g2_font_helvR08_tr */
    MUI_LABEL(5, 15, "Hello U8g2")         /* place text at postion x=5, y=15, use style 0 */
    ...
    ```


## Label

 * **Description:**
    
    Write a text string at any position on the form. 
 * **MUIF Macro:**
 
    * `MUIF_U8G2_LABEL()`: The standard label draw MUIF
    * `MUIF_LABEL(mui_u8g2_draw_text)`: Same as `MUIF_U8G2_LABEL()` but you could exchange the standard label draw **MUIF Callback** `mui_u8g2_draw_text` with your own custom **MUIF Callback**.
 * **FDS Macro:** 
 
    `MUI_LABEL(x, y, "Text")`: The specified "Text" is placed at position x,y on the form.
 * **Example**:
    ```
    muif_t muif_list[] = {  
      MUIF_U8G2_FONT_STYLE(0, u8g2_font_helvR08_tr),   /* define style 0 */
      MUIF_U8G2_LABEL(),                               /* allow MUI_LABEL macro */
      MUIF_BUTTON("BN", mui_u8g2_btn_exit_wm_fi)       /* define exit button */
    };
    ```

    ```
    fds_t fds_data[] =                     /* Don't use comma between the commands! */
    MUI_FORM(1)                            /* This will start the definition of form 1 */
    MUI_STYLE(0)                           /* select the font defined with style 0 */
    MUI_LABEL(5, 15, "Hello U8g2")         /* place text at postion x=5, y=15 */
    MUI_XYT("BN",64, 30, " Exit ")         /* place the exit button at pos x=64, y=30 */
    ;
    ```

    ```
    mui.begin(u8g2, fds_data, muif_list, sizeof(muif_list)/sizeof(muif_t));
    mui.gotoForm(/* form_id= */ 1, /* initial_cursor_position= */ 0);
    ```

## Jump Button

 * **Description:**
    
    When selected, jump to the specified form. The form number is provided as argument to the **FDS Macro**.
    
 * **MUIF Macro:** ([pi/fi](muiref#mui-callback-display-style))
    * `MUIF_BUTTON("G0", mui_u8g2_btn_goto_wm_fi)`
    * `MUIF_BUTTON("G1", mui_u8g2_btn_goto_w1_fi)`
    * `MUIF_BUTTON("G2", mui_u8g2_btn_goto_w1_pi)`
    * `MUIF_BUTTON("G3", mui_u8g2_btn_goto_w2_fi)`
    * `MUIF_BUTTON("G4", mui_u8g2_btn_goto_w2_if)`
    * `MUIF_BUTTON("G5", mui_u8g2_btn_goto_wm_if)`
 * **FDS Macro:** 
 
    `MUI_XYAT("ID", x, y, destination_form, "Text")`: Draw the bottom at position x,y on the form. 
      If the button receives the select event, then the new form specified by `destination_form` will be activated.
 * **Example**:
    ```
    MUI_XYAT("G0", 1, 42, 10, "Press here")
    ```

## Back Button

 * **Description:**
    
    When selected, jump to a previously stored form. Forms are stored by the  [goto](#(#jump-button)) button and the 
    [Scrollable Jump Table](#scrollable-jump-table-static)
    
 * **MUIF Macro:** ([pi/fi](muiref#mui-callback-display-style))
    * `MUIF_BUTTON("G0", mui_u8g2_btn_back_wm_fi)`
    * `MUIF_BUTTON("G1", mui_u8g2_btn_back_w1_fi)`
    * `MUIF_BUTTON("G2", mui_u8g2_btn_back_w1_pi)`
    * `MUIF_BUTTON("G3", mui_u8g2_btn_back_w2_fi)`
    * `MUIF_BUTTON("G4", mui_u8g2_btn_back_w2_if)`
    * `MUIF_BUTTON("G5", mui_u8g2_btn_back_wm_if)`
    
 * **FDS Macro:** 
 
    `MUI_XYT("ID", x, y, "Text")`: Draw the bottom at position x,y on the form. 
      If the button receives the select event, then the previously stored form will be activated.
      
 * **Example**:
    ```
    MUI_XYT("BK", 1, 42, "Back")
    ```
 * **Note**:
    This MUIF will be available with u8g2 v2.35


## Exit Button

 * **Description:**
    
    When selected, stop the menu system. The current form and cursor position is stored and
    MUI can be reactivated with [restoreForm](#restoreForm).
    
 * **MUIF Macro:** ([fi](muiref#mui-callback-display-style))
    * `MUIF_VARIABLE("XX",&exit_code,mui_u8g2_btn_exit_wm_fi)`: Close the menu system, when selected. An exit code is stored in variable `exit_code` (`unit8_t`).    
    * `MUIF_BUTTON("XX", mui_u8g2_btn_exit_wm_fi)`: Can be used if the exit code is not required. 
    * `MUIF_BUTTON("XX", mui_u8g2_btn_exit_wm_if)` 
    * `MUIF_BUTTON("XX", mui_u8g2_btn_exit_w2_fi)` 
    * `MUIF_BUTTON("XX", mui_u8g2_btn_exit_w2_if)` 
    * `MUIF_BUTTON("XX", mui_u8g2_btn_exit_w1_pi)` 
    * `MUIF_BUTTON("XX", mui_u8g2_btn_exit_w1_fi)` 


 * **FDS Macro:** 
 
    * `MUI_XYAT("XX", x, y, exit_code, "Text")`: Draw the bottom at position x,y on the form. 
      If the button receives the select event, then the menu system will be closed. The exit code will be stored in the connected variable.
    * `MUI_XYT("XX", x, y, "Text")`: Draw the bottom at position x,y on the form. 
      If the button receives the select event, then the menu system will be closed. The exit code will be 0.
      
 * **Example**:
    ```
    muif_t muif_list[] = {  
      MUIF_U8G2_FONT_STYLE(0, u8g2_font_helvR08_tr),  /* define style 0 */
      MUIF_U8G2_LABEL(),                                                    /* allow MUI_LABEL command */
      MUIF_BUTTON("BN", mui_u8g2_btn_exit_wm_fi)        /* define exit button */
    };
    ```

    ```
    fds_t fds_data[] =                              /* Don't use comma between the commands! */
    MUI_FORM(1)                                     /* This will start the definition of form 1 */
    MUI_STYLE(0)                                    /* select the font defined with style 0 */
    MUI_LABEL(5, 15, "Hello U8g2")          /* place text at postion x=5, y=15 */
    MUI_XYT("BN",64, 30, " Exit ")     /* place the exit button at pos x=64, y=30 */
    ;
    ```

    ```
    mui.begin(u8g2, fds_data, muif_list, sizeof(muif_list)/sizeof(muif_t));
    mui.gotoForm(/* form_id= */ 1, /* initial_cursor_position= */ 0);
    ```


## Checkbox and Radiobutton
 * **Animation:**
 
    ![ref/mui_uint8_checkbox_radio.gif](ref/mui_uint8_checkbox_radio.gif)

 * **Description:**
    * Checkbox: A field which assignes 0 or 1 to a `uint8_t` `variable`.  If the field receives the select event, then the field value changes from 0 to 1 or from 1 to 0.
    * Radiobutton: A field which assigns the **FDS Macro** argument value (`MUI_XYA` or `MUI_XYAT`) to the `uint8_t` `variable`.
        If the field receives the select event, then this field is checked and all other radiobuttons on the same form with the same ID 
        are unchecked.  
 * **MUIF Macro:**
    * `MUIF_VARIABLE("CB",&variable,mui_u8g2_u8_chkbox_wm_pi)`
    * `MUIF_VARIABLE("RB",&variable,mui_u8g2_u8_radio_wm_pi)`
 * **FDS Macro:** 
    * `MUI_XY("CB", x, y)`: The check box field is placed at the specified x,y position. 
    * `MUI_XYAT("RB", x, y, value, "Radio Label")`:  The radiobutton is placed at x,y position. 
      `value` is assigned to `variable` if this field receives the select event. The "Radio Label" 
      text is placed after the radio checkbox but is optional (Use `MUI_XYA` if "Radio Label" is not required).
 * **Example**:
    ```
    uint8_t cb_variable = 0;
    uint8_t rb_variable = 0;
    ...
    muif_t muif_list[] = {  
    ...
      MUIF_VARIABLE("CB", &cb_variable, mui_u8g2_u8_chkbox_wm_pi),
      MUIF_VARIABLE("RB", &rb_variable, mui_u8g2_u8_radio_wm_pi),
    ...
    }
    ```
  
    ```
    fds_t fds_data[] =                    /* Don't use comma between the commands! */
    ...
    MUI_FORM(31)
    MUI_STYLE(0)
    MUI_LABEL(1,40, "Checkbox 1: ")
    MUI_XY("CB",66, 40)
    MUI_GOTO(110, 54, 30, "OK")

    MUI_FORM(32)
    MUI_STYLE(0)
    MUI_XYAT("RB", 1, 40, 1, "Radio 1")
    MUI_XYAT("RB", 1, 55, 2, "Radio 2")
    MUI_GOTO(110, 54, 30, "OK")
    ...
    ;
    ```

## Numbers (uint8)
 * **Animation:**
 
   ![ref/mui_uint8_number.gif](ref/mui_uint8_number.gif)

 * **Description:**
 
    Input of a number between a lower and an upper limit. The input will be  
    stored in a `uint8_t` variable.
      * `mse` mode: Select event selects the next number (2-button input).
      * `mud` mode: Select enters "mud" update mode. Within "mud" update mode use prev and next event to decrease/increase the number (3-button and rotary encoder input).
 * **MUIF Macro:**
 
    `MUIF_U8G2_U8_MIN_MAX(id, valptr, min, max, cb)`
    * `id`: Unique id for this field
    * `valptr`: The address of the `uint8_t` variable
    * `min`: Minimum value of the number (lower limit)
    * `max`: Maximum value of the number (upper limit)
    * `cb`: One of the following **MUIF Callbacks** ([mse/mud](muiref#mui-callback-edit-mode), [pi/pf](muiref#mui-callback-display-style)):
        * `mui_u8g2_u8_min_max_wm_mse_pi`
        * `mui_u8g2_u8_min_max_wm_mud_pi`
        * `mui_u8g2_u8_min_max_wm_mse_pf`
        * `mui_u8g2_u8_min_max_wm_mud_pf`
 
 * **FDS Macro:** 
 
    `MUI_XY("ID", x, y)`: Position of the number input field on the target form.
 * **Example**:
    ```
    uint8_t number = 0;
    ...
    MUIF_U8G2_U8_MIN_MAX("NR", &number, 0, 9, mui_u8g2_u8_min_max_wm_mse_pi),
    ```

    ```
    MUI_FORM(21)
    MUI_STYLE(0)
    MUI_LABEL(1,40, "Number: ")
    MUI_XY("NR",70, 40)
    MUI_GOTO(64, 59, 20, " Ok ")
    ```

## Numbers (int8)
 * **Description:**
 
    Input of a signed number between a lower and an upper limit. The input will be  
    stored in a `int8_t` variable. This input is very similar to the `uint8` number input from above.
      * `mse` mode: Select event selects the next number (2-button input).
      * `mud` mode: Select enters "mud" update mode. Within "mud" update mode use prev and next event to decrease/increase the number (3-button and rotary encoder input).
 * **MUIF Macro:**
 
    `MUIF_U8G2_S8_MIN_MAX(id, valptr, min, max, cb)`
    * `id`: Unique id for this field
    * `valptr`: The address of the `int8_t` variable
    * `min`: Minimum (signed `int8_t`) value of the number (lower limit)
    * `max`: Maximum (signed `int8_t`) value of the number (upper limit)
    * `cb`: One of the following **MUIF Callbacks** ([mse/mud](muiref#mui-callback-edit-mode), [pi/pf](muiref#mui-callback-display-style)):
        * `mui_u8g2_s8_min_max_wm_mse_pi`
        * `mui_u8g2_s8_min_max_wm_mud_pi`
        * `mui_u8g2_s8_min_max_wm_mse_pf`
        * `mui_u8g2_s8_min_max_wm_mud_pf`
 
 * **FDS Macro:** 
 
    `MUI_XY("ID", x, y)`: Position of the number input field on the target form.
 * **Example**:
    ```
    int8_t number = 0;
    ...
    MUIF_U8G2_S8_MIN_MAX("NR", &number, -9, 9, mui_u8g2_s8_min_max_wm_mse_pi),
    ```
    ```
    MUI_FORM(21)
    MUI_STYLE(0)
    MUI_LABEL(1,40, "Number: ")
    MUI_XY("NR",70, 40)
    MUI_GOTO(64, 59, 20, " Ok ")
    ```


## Bar Graph (uint8)
 * **Animation:**
 
   ![ref/mui_u8g2_u8_bar.gif](ref/mui_u8g2_u8_bar.gif)

 * **Description:**
 
    Input of a number between a lower and an upper limit. The input will be  
    stored in a `uint8_t` variable. The value is displayed as a horizontal bar graph. 
    
    Incrementing the max value will wrap over to the min value and
    decrementing the min value will wrap over to the max value. This can be avoided with the
      `MUI_MMS_NO_WRAP` option (Note: Using the `MUI_MMS_NO_WRAP` in two button "mse" mode does NOT make sense).
      
    The width of the bar graph is equal to the `max` argument of the MUIF Macro (see below).
      
    The height of the bar graph is defined by the ascent (height) of the current font.
      * `mse` mode: Select event selects the next number (2-button input).
      * `mud` mode: Select enters update mode. Within update mode use prev and next event to decrease/increase the number (3-button and rotary encoder input).
 * **MUIF Macro:**
 
    MUIF entry: `MUIF_U8G2_U8_MIN_MAX_STEP(id, valptr, min, max, step, flags, cb)`
    * `id`: Unique id for this field
    * `valptr`: The address of the `uint8_t` variable
    * `min`: Minimum value of the number (lower limit, `uint8_t`)
    * `max`: Maximum value of the number (upper limit, `uint8_t`)
    * `step`: Increment/decrement value (`uint8_t`)
    * `flags`: One or more of the following flags (multiple flags can be used with the "or" operator `|`):
        * `MUI_MMS_2X_BAR`: Horizontal scale by 2
        * `MUI_MMS_4X_BAR`: Horizontal scale by 4
        * `MUI_MMS_SHOW_VALUE`: Additionally show the current value
        * `MUI_MMS_NO_WRAP`: Increment (decrement) the max value (min value) will force the bar graph to stay at the max (min) value. Available with v2.34.
    * `cb`: One of the following **MUIF Callbacks** ([mse/mud](muiref#mui-callback-edit-mode), [pi/pf](muiref#mui-callback-display-style)):
        * `mui_u8g2_u8_bar_wm_mse_pi`
        * `mui_u8g2_u8_bar_wm_mud_pi`
        * `mui_u8g2_u8_bar_wm_mse_pf`
        * `mui_u8g2_u8_bar_wm_mud_pf`
 
 * **FDS Macro:** 
 
    `MUI_XY("ID", x, y)`: Position of the bar graph input field on the target form.
 * **Example**:
    ```
    uint8_t number = 0;
    ...
    MUIF_U8G2_U8_MIN_MAX_STEP("B0", &number, 0, 20, 2, MUI_MMS_2X_BAR|MUI_MMS_SHOW_VALUE, mui_u8g2_u8_bar_wm_mse_pi),
    ```
    ```
    MUI_FORM(91)
    MUI_STYLE(0)
    MUI_LABEL(1,40, "Bar: ")
    MUI_XY("B0",40, 40)
    MUI_GOTO(64, 59, 90, " Ok ")
    ```


## Fixed Width Bar Graph (uint8)
 * **Description:**
 
    Input of a number between a lower and an upper limit. The input will be  
    stored in a `uint8_t` variable. The value is displayed as a horizontal bar graph. 
    
    Incrementing the max value will wrap over to the min value and
    decrementing the min value will wrap over to the max value. This can be avoided with the
      `MUI_MMS_NO_WRAP` option (Note: Using the `MUI_MMS_NO_WRAP` in two button "mse" mode does NOT make sense).
      
    The width of the bar graph is defined by the `width` argument of the MUIF Macro (see below).
      
    The height of the bar graph is defined by the ascent (height) of the current font.
      * `mse` mode: Select event selects the next number (2-button input).
      * `mud` mode: Select enters update mode. Within update mode use prev and next event to decrease/increase the number (3-button and rotary encoder input).
 * **MUIF Macro:**
 
    MUIF entry: `MUIF_U8G2_U8_MIN_MAX_STEP_WIDTH(id, valptr, min, max, step, width, flags, cb)`
    * `id`: Unique id for this field
    * `valptr`: The address of the `uint8_t` variable
    * `min`: Minimum value of the number (lower limit, `uint8_t`)
    * `max`: Maximum value of the number (upper limit, `uint8_t`)
    * `step`: Increment/decrement value
    * `width`: Pixel size of the bar without any decoration (`uint8_t`)
    * `flags`: One or more of the following flags (multiple flags can be used with the "or" operator `|`):
        * `MUI_MMS_2X_BAR`: Multiply `width` with factor 2
        * `MUI_MMS_4X_BAR`: Multiply `width` with factor 4
        * `MUI_MMS_SHOW_VALUE`: Additionally show the current value
        * `MUI_MMS_NO_WRAP`: Increment (decrement) the max value (min value) will force the bar graph to stay at the max (min) value. 
    * `cb`: One of the following **MUIF Callbacks** ([mse/mud](muiref#mui-callback-edit-mode), [pi/pf](muiref#mui-callback-display-style)):
        * `mui_u8g2_u8_fixed_width_bar_wm_mse_pi`
        * `mui_u8g2_u8_fixed_width_bar_wm_mud_pi`
        * `mui_u8g2_u8_fixed_width_bar_wm_mse_pf`
        * `mui_u8g2_u8_fixed_width_bar_wm_mud_pf`
 
 * **FDS Macro:** 
 
    `MUI_XY("ID", x, y)`: Position of the bar graph input field on the target form.
 * **Example**:
    ```
    uint8_t number = 0;
    ...
    MUIF_U8G2_U8_MIN_MAX_STEP_WIDTH("B0", &number, 0, 20, 2, 50, MUI_MMS_2X_BAR|MUI_MMS_SHOW_VALUE, mui_u8g2_u8_fixed_width_bar_wm_mse_pi),
    ```
    ```
    MUI_FORM(91)
    MUI_STYLE(0)
    MUI_LABEL(1,40, "Bar: ")
    MUI_XY("B0",40, 40)
    MUI_GOTO(64, 59, 90, " Ok ")
    ```

 * **Note**:
  Available with v2.34

## Character Input
 * **Animation:**
 
    ![ref/mui_u8g2_u8_char_wm_mud_pi.gif](ref/mui_u8g2_u8_char_wm_mud_pi.gif)

 * **Description:**
    
    Input field for a single character. Characters are limited to ' ', 'A'-'Z', 'a'-'z' and '0'-'9'.
    The character will be stored in the specified variable. 
    Multiple MUIF Macros with different IDs can be used to input more than one
    character on the same form.
    
 * **MUIF Macro:** ([mud](muiref#mui-callback-edit-mode), [pi](muiref#mui-callback-display-style))
 
    `MUIF_VARIABLE("ID",&variable,mui_u8g2_u8_char_wm_mud_pi)`
 * **FDS Macro:** 
 
    `MUI_XY("ID", x, y)`:
      Place the field a the specified x,y position. Use a monospaced font for this field (for example `u8g2_font_profont12_tr`).
 * **Example**:
    ```
    char s[5] = "aaaa";
    ...
    MUIF_VARIABLE("T0",s+0,mui_u8g2_u8_char_wm_mud_pi),
    MUIF_VARIABLE("T1",s+1,mui_u8g2_u8_char_wm_mud_pi),
    MUIF_VARIABLE("T2",s+2,mui_u8g2_u8_char_wm_mud_pi),
    MUIF_VARIABLE("T3",s+3,mui_u8g2_u8_char_wm_mud_pi),
    ...
    MUI_FORM(61)
    MUI_STYLE(0)
    MUI_LABEL(5,40, "Text:")
    MUI_STYLE(5)                        /* use a monospaced font */
    MUI_XY("T0",40, 40)
    MUI_XY("T1",48, 40)
    MUI_XY("T2",56, 40)
    MUI_XY("T3",64, 40)
    MUI_STYLE(0)
    MUI_GOTO(64, 59, 60, " Ok ")
    ```

## One of Many Selection (Cycle, uint8, static list)
 * **Animation:**
 
    ![ref/mui_u8g2_u8_opt_line_wa.gif](ref/mui_u8g2_u8_opt_line_wa.gif)

 * **Description:**
  Select one option out of a list of options.  The number of the selected option 
  will be stored in `variable` (`uint8_t`, first option in the list has the number 0).
    * `mse` mode: Select event selects the next option (2-button input).
    * `mud` mode: Select enters update mode. Within update mode use prev and next event to cycle between options (3-button and rotary encoder input).
 * **MUIF Macro:** ([mse/mud](muiref#mui-callback-edit-mode), [pi/pf](muiref#mui-callback-display-style))
    * `MUIF_VARIABLE("ID",&variable,mui_u8g2_u8_opt_line_wa_mse_pi)`
    * `MUIF_VARIABLE("ID",&variable,mui_u8g2_u8_opt_line_wa_mse_pf)`
    * `MUIF_VARIABLE("ID",&variable,mui_u8g2_u8_opt_line_wa_mud_pi)`
    * `MUIF_VARIABLE("ID",&variable,mui_u8g2_u8_opt_line_wa_mud_pf)`
 * **FDS Macro:** 
 
    `MUI_XYAT("ID", x, y, arg, "Banana|Apple|Melon|Cranberry")`:
    Defines a list of options, separated with `|`. The user can select one option. The
    first option has the number 0. `arg` defines the pixel width of the field.
 * **Example**:
    ```
    MUI_FORM(41)
    MUI_STYLE(0)
    MUI_LABEL(5,40, "Fruit:")
    MUI_XYAT("ID",60, 40, 60, "Banana|Apple|Melon|Cranberry")
    MUI_STYLE(0)
    MUI_GOTO(64, 59, 40, " Ok ")
    ```

## One of Many Selection (Cycle, uint16, dynamic list)
 * **Animation:**
 
   ![ref/mui_u8g2_u16_list_line.gif](ref/mui_u8g2_u16_list_line.gif)

 * **Description:**
  Select one option out of a list of options.  The number of the selected option 
  will be stored in `variable` (`uint16_t`, first option in the list has the number 0).
  The options are provided by callback functions.
    * `mse` mode: Select event selects the next option (2-button input).
    * `mud` mode: Select enters update mode. Within update mode use prev and next event to cycle between options (3-button and rotary encoder input).
 * **MUIF Macro:**
 
    MUIF entry: `MUIF_U8G2_U16_LIST(id, valptr, dataptr, getcb, cntcb, cb)`
    * `id`: Unique id for this field
    * `valptr`: The address of the `uint16_t` variable
    * `dataptr`: Optional data pointer which will be passed to the callback functions (use `NULL` if not used)
    * `getcb`: A callback function, which should return a `\0` terminated string with the option name at the provided index. Prototype: `const char *get_str(void *data, uint16_t index)`
    * `cntcb`: A callback function, which should retun the total number of elements in the list. Prototype: `uint16_t get_cnt(void *data)`
    * `cb`: One of the following **MUIF Callbacks** ([mse/mud](muiref#mui-callback-edit-mode), [pi](muiref#mui-callback-display-style)):
        * `mui_u8g2_u16_list_line_wa_mse_pi`
        * `mui_u8g2_u16_list_line_wa_mud_pi`
 
 * **FDS Macro:** 
 
    `MUI_XYA("ID", x, y, arg)`:
    The user can select one option (string returned by `getcb` function). The
    first option has the number 0. `arg` defines the pixel width of the field.
 * **Example**:
    ``` C++
    static const char *animals[] = { 
      "Bird", "Bison", "Cat", "Crow", "Dog", "Elephant", "Fish", "Gnu", "Horse", 
      "Koala", "Lion", "Mouse", "Owl", "Rabbit", "Spider", "Turtle", "Zebra" };
      
    uint16_t animals_get_cnt(void *data) {
      return sizeof(animals)/sizeof(*animals);    /* number of animals */
    }
    const char *animals_get_str(void *data, uint16_t index) {
      return animals[index];
    }
    ...
    uint16_t selection = 0;
    ...
    MUIF_U8G2_U16_LIST("A1", &selection, NULL, animals_get_str, animals_get_cnt, mui_u8g2_u16_list_line_wa_mse_pi),
    ```
    ```
    MUI_FORM(71)
    MUI_STYLE(0)
    MUI_LABEL(5,40, "Animal:")
    MUI_XYA("A1",45, 40, 50)
    MUI_GOTO(64, 59, 70, " Ok ")
    ```

## List Selection (Child form, uint8, static list)
 * **Animation:**
 
    ![ref/mui_u8g2_u8_opt_parent.gif](ref/mui_u8g2_u8_opt_parent.gif)

 * **Description:**
  Select one option out of a list of options. 
  
    `mui_u8g2_u8_opt_parent_wm_pi` 
    will show the selected option in the parent form. The option number is stored
    in `variable` (`uint8_t`). The select event 
    for `mui_u8g2_u8_opt_parent_wm_pi` will open a child form. A different
    option can be selected in the child form.
    
    The child form must include on or more child fields (`MUI_XYA()`). Only one type of
    child field is allowed (all active child fields must have the same ID). 
    Other active elements than the child field should 
    not be used in the child form.
 * **MUIF Macro:** ([pi](muiref#mui-callback-display-style))
    * `MUIF_VARIABLE("PP",&variable,mui_u8g2_u8_opt_parent_wm_pi)`:
      The parent field which should appear on the parent form.
    * `MUIF_VARIABLE("CC",&variable,mui_u8g2_u8_opt_radio_child_w1_pi)`:
      The field for the child form. The current selected option is prefixed with a solid box.
    * `MUIF_VARIABLE("CC",&variable,mui_u8g2_u8_opt_child_wm_pi)`:
      The field for the child form. Options are just displayed.
 * **FDS Macro:** 
    *  `MUI_XYAT("PP", x, y, arg, "red|orange|yellow|green|cyan|azure|blue|violet|magenta|rose")`:
      Defines a list of options, separated with `|`. The user can select one option. The
      first option has the number 0. `arg` defines the form number of the child form.
    * `MUI_XYA("CC", x, y, n)`:
      Defines one or more fields on the child form. Each field must have the same
      id (here: "CC"), but must have a unique number `n` starting with 0. These fields
      define the scroll area for the list of options.
 * **Example**:
    ```
    MUI_FORM(51)        /* Parent Form */
    MUI_STYLE(0)
    MUI_LABEL(5,40, "Color:")
    MUI_XYAT("PP",60, 40, 52, "red|orange|yellow|green|cyan|azure|blue|violet|magenta|rose")
    MUI_STYLE(0)
    MUI_GOTO(64, 59, 50, " Ok ")

    MUI_FORM(52) /* Child Form, called by "PP" element */
    MUI_STYLE(0)
    MUI_XYA("CC", 5, 38, 0) /* Three child elements of the same type "CC" */
    MUI_XYA("CC", 5, 49, 1) 
    MUI_XYA("CC", 5, 60, 2) 
    ```

## List Selection (Child form, uint16, dynamic list)
 * **Animation:**

    ![ref/mui_u8g2_u16_list_child.gif](ref/mui_u8g2_u16_list_child.gif)

 * **Description:**
 
    Select one option out of a list of options.  The number of the selected option 
    will be stored via `valptr` (`uint16_t *`, first option in the list has the number 0).

    The selection will happen in a child form.
    The child form  must include on or more child fields 
    (`MUI_XYA()`). Only one type of
    child field is allowed (all active child fields must have the same ID). 
    Other active elements than the child field should 
    not be used in the child form.

 * **MUIF Macro:**
 
    MUIF entry: `MUIF_U8G2_U16_LIST(id, valptr, dataptr, getcb, cntcb, cb)`
    * `id`: Unique id for this field
    * `valptr`: The address of the `uint16_t` variable
    * `dataptr`: Optional data pointer which will be passed to the callback functions (use `NULL` if not used)
    * `getcb`: A callback function, which should return a `\0` terminated string with the option name at the provided index. Prototype: `const char *get_str(void *data, uint16_t index)`
    * `cntcb`: A callback function, which should retun the total number of elements in the list. Prototype: `uint16_t get_cnt(void *data)`
    * `cb`: One of the following **MUIF Callbacks** ([pi](muiref#mui-callback-display-style)):
        * `mui_u8g2_u16_list_parent_wm_pi`: Use this field on the parent form
        * `mui_u8g2_u16_list_child_w1_pi`: Use this field on the child form
    
 * **FDS Macro:** 
    *  `MUI_XYA("PP", x, y, arg)`:
      Defines a list of options, separated with `|`. The user can select one option. The
      first option has the number 0. `arg` defines the form number of the child form.
      Use this for `mui_u8g2_u16_list_parent_wm_pi`.
    * `MUI_XYA("CC", x, y, n)`:
      Defines one or more fields on the child form. Each field must have the same
      id (here: "CC"), but must have a unique number `n` starting with 0. These fields
      define the scroll area for the list of options.
      Use this for `mui_u8g2_u16_list_child_w1_pi`.
 * **Example**:
    ``` C++
    static const char *animals[] = { 
      "Bird", "Bison", "Cat", "Crow", "Dog", "Elephant", "Fish", "Gnu", "Horse", 
      "Koala", "Lion", "Mouse", "Owl", "Rabbit", "Spider", "Turtle", "Zebra" };
      
    uint16_t animals_get_cnt(void *data) {
      return sizeof(animals)/sizeof(*animals);    /* number of animals */
    }
    const char *animals_get_str(void *data, uint16_t index) {
      return animals[index];
    }
    ...
    uint16_t selection = 0;
    ```
    ```
    MUIF_U8G2_U16_LIST("PP", &selection, NULL, animals_get_str, animals_get_cnt, mui_u8g2_u16_list_parent_wm_pi)
    MUIF_U8G2_U16_LIST("CC", &selection, NULL, animals_get_str, animals_get_cnt, mui_u8g2_u16_list_child_w1_pi)
    ```
    ```
    MUI_FORM(81)
    MUI_STYLE(0)
    MUI_LABEL(5,40, "Animal:")
    MUI_XYA("PP",50, 40, 82)     /* jump to sub form 82 */
    MUI_GOTO(64, 59, 80, " Ok ")

    MUI_FORM(82)
    MUI_STYLE(0)
    MUI_XYA("CC", 5, 38, 0) 
    MUI_XYA("CC", 5, 49, 1) 
    MUI_XYA("CC", 5, 60, 2) 
    ```



## Scrollable Jump Table (static)
 * **Description:**
 
    Implements a scrollable list of buttons. Each button can be used to jump to a
    different form (Limitation: The forms 0, 124 and 255 can't be used as jump target,
    because these number have special meanings in the text argument). 
    
    If this function receives the "select" event then it will jump to the target form and 
    additionally store the current menu cursor position. A jump back to this form 
    (for example with the `mui_u8g2_btn_goto_xxx` MUIF Callback) 
    will restore the menu cursor position.  
 * **MUIF Macro:** ([pi](muiref#mui-callback-display-style))
    * `MUIF_RO("GP",mui_u8g2_goto_data)`: Create field for the definition of jump targets
    * `MUIF_BUTTON("GC", mui_u8g2_goto_form_w1_pi)`: Buttons for "inverted text cursor"
    * `MUIF_BUTTON("GC", mui_u8g2_goto_form_w1_pf)`: Buttons for "frame around text cursor"
 * **FDS Macro:** 
    * `MUI_DATA("GP", ...)`:
      Defines a list of jump targets (form number and form name). Entries in this list
      are separated with the `|` symbol. Each entry starts with the form number prefixed 
      with `MUI_`(see example below).
    * `MUI_XYA("GC", x, y, n)`:
      Defines one or more fields on the form. Each field must have the same
      id (here: "GC"), but must have a unique number `n` starting with 0. These fields
      define the scroll area for the jump targets.
 * **Note:** Do not use any other fields on the same form than the above mention MUIF fields.
 * **Example:**
    ```
    MUI_FORM(1)
    MUI_STYLE(0)
    MUI_DATA("GP", 
        MUI_10 "Goto Buttons|"
        MUI_20 "uint8 Number|"
        MUI_30 "uint8 Checkbox|"
        MUI_40 "uint8 Cycle Options|"
        MUI_50 "uint8 ParentChild Select|"
        MUI_60 "uint8 Char/Text Input|"
        MUI_70 "uint16 Cycle Options|"
        MUI_80 "uint16 ParentChild Select")
    MUI_XYA("GC", 5, 25, 0) 
    MUI_XYA("GC", 5, 37, 1) 
    MUI_XYA("GC", 5, 49, 2) 
    MUI_XYA("GC", 5, 61, 3) 
    ```

## Scrollable Jump Table (dynamic)
 * **Description:**
 
    Implements a scrollable list of buttons. Each button can be used to jump to a
    different form (Limitation: The form 0 can't be used as jump target,
    because this number has a special meanings in strings). 
    
    If this function receives the "select" event then it will jump to the target form and 
    additionally store the current menu cursor position. A jump back to this form 
    (for example with the `mui_u8g2_btn_goto_xxx` MUIF) 
    will restore the menu cursor position.  
 * **MUIF Macro:**
 
    MUIF entry: `MUIF_U8G2_U16_LIST(id, valptr, dataptr, getcb, cntcb, muifcb)`
    * `id`: Unique id for this field
    * `valptr`: The address of a `uint16_t` variable (optional, use `NULL` if not used)
    * `dataptr`: Optional data pointer which will be passed to the callback functions (use `NULL` if not used)
    * `getcb`: A callback function, which should return a `\0` terminated string with the form name at the provided index. The first char of this name must be the form number. Prototype: `const char *get_str(void *data, uint16_t index)`
    * `cntcb`: A callback function, which should retun the total number of elements in the list. Prototype: `uint16_t get_cnt(void *data)`
    * `muifcb`: `mui_u8g2_u16_list_goto_w1_pi` ([pi](muiref#mui-callback-display-style))
 * **FDS Macro:** 
 
      `MUI_XYA("ID", x, y, n)`:
      Defines one or more fields on the form. Each field must have the same
      id, but must have a unique number `n` starting with 0. These fields
      define the scroll area for the jump targets.
 * **Note:** Do not use any other fields on the same form than the above mention MUIF fields.
 * **Example**:
    ``` C++
    uint16_t menu_get_cnt(void *data) {
      return 10;    /* number of menu entries */
    }

    const char *menu_get_str(void *data, uint16_t index) {
      static const char *menu[] = { 
        MUI_1 "Goto Main Menu",
        MUI_10 "Enter a number",
        MUI_11 "Parent/Child Selection",
        MUI_13 "Checkbox",
        MUI_14 "Radio Selection",
        MUI_15 "Text Input",
        MUI_16 "Single Line Selection",
        MUI_17 "List Line Selection",
        MUI_18 "Parent/Child List",
        MUI_20 "Array Edit",
      };
      return menu[index];
    }
    ...
    uint16_t selection = 0;
    ...
    MUIF_U8G2_U16_LIST("ID", &selection, NULL, menu_get_str, menu_get_cnt, mui_u8g2_u16_list_goto_w1_pi),
    ```
    ```
    MUI_FORM(3)
    MUI_STYLE(0)
    MUI_XYA("ID", 5, 25, 0) 
    MUI_XYA("ID", 5, 37, 1) 
    MUI_XYA("ID", 5, 49, 2) 
    MUI_XYA("ID", 5, 61, 3) 
    ```
# MUI API

## begin

  * **C++/Arduino Prototype:**
```
void MUI::begin(U8G2 &u8g2, fds_t *fds, muif_t *muif_list, size_t muif_cnt)
void mui_Init(mui_t *ui, void *graphics_data, fds_t *fds, muif_t *muif_list, size_t muif_cnt)
 ```
  * **Description:** Setup MUI and connect MUI to u8g2. After the setup of MUI, the menu
    system is inactive and has no current form assigned. A call to [gotoForm](#gotoform) is required to activate MUI.
  * **Arguments:** -
    * `u8g2` : Pointer to the `u8g2` structure (C interface only).
    * `fds`: Address of the field definition string
    * `muif_list`: Address of the MUIF list
    * `muif_list`: Number of entries in the MUIF list
    * `ui`: Address of an empty and unused `mui_t` object.
    * `graphics_data`: Address of the u8g2 C structure (C++/Arduino: `(void *)u8g2.getU8g2()`).
  * **Returns:** -  
  * **Note:** MUI requires [setFontPosBaseline](u8g2reference#setfontposbaseline) (which is the default for u8g2). Any other font position alignment may not work.
  * **See also:** [Minimal Example](muimanual#minimal-example) 
  * **Example:**
```
U8G2_UC1701_EA_DOGS102_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
MUIU8G2 mui;

muif_t muif_list[] = {  
  MUIF_VARIABLE("BN", NULL, mui_u8g2_btn_exit_wm_fi)
};

fds_t fds_data[] = 
MUI_FORM(1)
MUI_XYT("BN", 64, 30, " Select Me ")
;

void setup(void) {
  u8g2.begin(/* menu_select_pin= */ 5, /* menu_next_pin= */ 4, /* menu_prev_pin= */ 2, /* menu_up_pin= */ U8X8_PIN_NONE, /* menu_down_pin= */ U8X8_PIN_NONE, /* menu_home_pin= */ 3);  
  mui.begin(u8g2, fds_data, muif_list, sizeof(muif_list)/sizeof(muif_t));
  mui.gotoForm(/* form_id= */ 1, /* initial_cursor_position= */ 0);
}
```

## getCurrentCursorFocusPosition

  * **C++/Arduino Prototype:**
```
int MUI::getCurrentCursorFocusPosition(void)
int mui_GetCurrentCursorFocusPosition(mui_t *ui)
```
  * **Description:** 
    Return the current cursor position. The return value can be used as second argument for the [gotoForm()](#gotoform) call. This function will return 0 if MUI is not active. 
  * **Arguments:** -
    * `ui` : Pointer to the `mui` structure (C interface only).
  * **Returns:** The current cursor position or 0

## getCurrentFormId

  * **C++/Arduino Prototype:**
```
int MUI::getCurrentFormId(void)
int mui_GetCurrentFormId(mui_t *ui)
```
  * **Description:** 
    Return the current form id (argument for MUI_FORM()). This function will return -1 if MUI is not active. 
  * **Arguments:** -
    * `ui` : Pointer to the `mui` structure (C interface only).
  * **Returns:** The current form id or -1

## gotoForm

  * **C++/Arduino Prototype:**
```
uint8_t MUI::gotoForm(uint8_t form_id, uint8_t initial_cursor_position)
uint8_t mui_GotoForm(mui_t *ui, uint8_t form_id, uint8_t initial_cursor_position)
```
  * **Description:** 
    Change the current form and cursor position. The cursor focus will be assigned to the 
    `initial_cursor_position`-th location which can receive cursor focus. Field locations 
      are enumerated in the sequence as they are defined in the FDS string.
      The value 0 will place the cursor forcus on the first selectable element of the
      given form with form number `id`. 
      
      Additionally: If MUI is inactive, then this call will activate MUI. 
      `gotoForm` is usually called after MUI [begin](#begin).
  * **Arguments:** -
    * `ui` : Pointer to the `mui` structure (C interface only).
    * `form_id` :  The form number (defined by FDS macro [`MUI_FORM`](muiref#fds-macros)
    * `initial_cursor_position` : The selectable field which should receive the cursor focus.  
  * **Returns:** 0, if the form with `id` doesn't exist.
  * **See also:** [Minimal Example](muimanual#minimal-example) 

## nextField

  * **C++/Arduino Prototype:**
```
void MUI::nextField(void)
void mui_NextField(mui_t *ui)
```
  * **Description:** 
    Send a "next field" event to the current form of the menu system. Usually this should be done, if the user hits the "next" button.
    The menu system will usually move the cursor to the next field on the form or increment a field value.
  * **Arguments:** -
    * `ui` : Pointer to the `mui` structure (C interface only).
  * **Returns:** -
  * **See also:** [Event Mapping](muimanual#event-mapping-and-action-execution) 

## prevField

  * **C++/Arduino Prototype:**
```
void MUI::prevField(void)
void mui_PrevField(mui_t *ui)
```
  * **Description:** 
    Send a "prev field" event to the current form of the menu system. Usually this should be done, if the user hits the "previous" button.
    The menu system will usually move the cursor to the previous field on the form or decrement a field value.
  * **Arguments:** -
    * `ui` : Pointer to the `mui` structure (C interface only).
  * **Returns:** -
  * **See also:** [Event Mapping](muimanual#event-mapping-and-action-execution) 

## restoreForm

  * **C++/Arduino Prototype:**
```
void MUI::restoreForm(void)
void mui_RestoreForm(mui_t *ui)
```
  * **Description:** 
    Jump to a previously saved form and cursor position. This is identical to [gotoForm](#gotoform) 
    except that a previously saved location is used. 
    
    The current form and cursor position is saved by the "exit" buttons.
  * **Arguments:** -
    * `ui` : Pointer to the `mui` structure (C interface only).
  * **Returns:** -
  * **See also:** [gotoForm](#gotoform) [Exit Button](#exit-button) `MUICountDown.ino`

## sendSelect

  * **C++/Arduino Prototype:**
```
void MUI::sendSelect(void)
void mui_SendSelect(mui_t *ui)
```
  * **Description:** 
    Send a "select" event to field which has the current cursor focus in the menu system. Usually this should be done, if the user hits the select button.
  * **Arguments:** -
    * `ui` : Pointer to the `mui` structure (C interface only).
  * **Returns:** -
  * **See also:** [Minimal Example](muimanual#minimal-example), [Event Mapping](muimanual#event-mapping-and-action-execution) 

## sendSelectWithExecuteOnSelectFieldSearch

  * **C++/Arduino Prototype:**
```
void MUI::sendSelectWithExecuteOnSelectFieldSearch(void)
void mui_SendSelectWithExecuteOnSelectFieldSearch(mui_t *ui)
```
  * **Description:** 
    This call will search for a EXECUTE_ON_SELECT button (a button which has been defined with `MUIF_EXECUTE_ON_SELECT_BUTTON`).
    Then the "select" event is sent to this button.
    If a EXECUTE_ON_SELECT button is not available on the form, then this function behaves like [sendSelect](#sendselect).
  * **Arguments:** -
    * `ui` : Pointer to the `mui` structure (C interface only).
  * **Returns:** -
  * **See also:** [sendSelect](#sendselect), [Event Mapping](muimanual#event-mapping-and-action-execution) , `MUIInputVersatileRotaryEncoder.ino`

# MUIF Helper Functions

The functions below should be used only within a field function (MUIF):
```
  typedef uint8_t (*muif_cb)(mui_t *ui, uint8_t msg);
```

## mui_get_U8g2

  * **Prototype:**
```
u8g2_t *mui_get_U8g2(mui_t *ui)
```
  * **Description:** 
    Return a pointer to the `u8g2_t` structure.
  * **Arguments:** -
    * `ui` : Pointer to the `mui` structure..
  * **Returns:**  Pointer to the `u8g2_t` structure
  * **See also:** [Stopwatch Example](muimanual#stopwatch-example) 

## mui_get_x

  * **Prototype:**
```
u8g2_uint_t mui_get_x(mui_t *ui)
```
  * **Description:** 
    Return the `x` position of a field (usually provided by `MUI_XY()`)
  * **Arguments:** -
    * `ui` : Pointer to the `mui` structure..
  * **Returns:** `x` position
  * **See also:** [Stopwatch Example](muimanual#stopwatch-example) 


## mui_get_y

  * **Prototype:**
```
u8g2_uint_t mui_get_y(mui_t *ui)
```
  * **Description:** 
    Return the `y` position of a field (usually provided by `MUI_XY()`)
  * **Arguments:** -
    * `ui` : Pointer to the `mui` structure..
  * **Returns:** `y` position
  * **See also:** [Stopwatch Example](muimanual#stopwatch-example) 


## mui_get_arg

  * **Prototype:**
```
u8g2_uint_t mui_get_arg(mui_t *ui)
```
  * **Description:** 
    Return the `arg` value of a field (usually provided by `MUI_XYA()` or `MUI_XYAT()`)
  * **Arguments:** -
    * `ui` : Pointer to the `mui` structure..
  * **Returns:** Argument value (as provided by `MUI_XYA()` or `MUI_XYAT()`) or 0 (`MUI_XY()`) 

