LcdMenu Arduino Library

repository·master·Indexed 42 days ago

https://github.com/forntoh/lcdmenu

An open-source Arduino library for creating menu systems on character LCDs and graphical/OLED displays. It features a flexible architecture using display interfaces, renderers, and input adapters for hardware such as rotary encoders, joysticks, and buttons (including AnalogButtonAdapter and ButtonAdapter).

Tokens
26.7K
Snippets
96
Records
122
Agent score
53%

What's inside LcdMenu

  1. Overview of lcdmenu capabilities

    master

    lcdmenu is an open-source Arduino library used to create menu systems. It provides a simple API for menu creation and user input handling. The library is designed to be flexible, supporting various display types through built-in display interfaces:

    • Character LCD displays: Supports targets like 16x2-style displays.
    • Graphical displays: Supports targets like OLED displays.
  2. What is MenuScreen and how does it work?

    master

    The MenuScreen class is the core component of the menu system. It represents a single screen within a menu hierarchy and is responsible for:

    • Managing Menu Items: Holding a collection of MenuItem objects.
    • Handling Navigation: Managing movement between screens (submenus) using BACK and RIGHT commands.
    • Cursor & View Management: Automatically handling cursor movement and ensuring only the visible portion of the menu is rendered.
    • Dynamic Updates: Supporting periodic polling to update menu items with real-time data or animations.

    MenuScreen is designed to work in conjunction with LcdMenu (for input/lifecycle) and MenuRenderer (for display output).

  3. Use ItemRange to create range-based menu items

    master

    The ItemRange class is a wrapper around ItemWidget designed to simplify the creation of menu items that allow users to select a value within a specific range (e.g., volume, brightness, or temperature). It reduces boilerplate when an item only requires a single WidgetRange.

    There are two primary ways to implement this:

    1. ITEM_RANGE<T>(...): Creates a standalone item with a range of values.
    2. ITEM_RANGE_REF<T>(...): Creates an item that uses a reference to track and update the currently selected value, allowing the value to be updated or accessed externally.

    Best Practices:

    • Ensure the step size divides evenly into the range to prevent unexpected behavior at boundaries.
    • Use simple numeric types like int or float for performance-critical applications.
    • When using ITEM_RANGE_REF, remember that external changes to the referenced variable will automatically be reflected in the menu display.
    // Simple range usage
    ITEM_RANGE<int>("Volume", 50, 5, 0, 100, [](const int value) {
        Serial.println(value);
    }, "%d%%")
    
    // Range with reference usage
    int selectedTemperature = 20;
    ITEM_RANGE_REF<int>("Temperature", selectedTemperature, 1, 0, 40, [](const Ref<int> value) {
        Serial.println(value.value);
    }, "%d°C")
  4. Understand the Menu Item building block

    master
    A menu item is the fundamental building block of a menu screen in lcdmenu. Each menu item is an interactive element that can contain zero or more widgets. You can use built-in menu items to construct your menu structure or create custom items by extending the base menu item class or existing items.
  5. Understand the role of Widgets in LCDMenu

    master

    Widgets are interactive components that are added to menu items to provide user input and display capabilities. They allow menu items to support features such as boolean toggles, list selections, and range inputs while ensuring a consistent interface across the menu system.

    Common widget types include:

    • Boolean toggles: For on/off or true/false settings.
    • List selection: For choosing from a predefined set of options.
    • Range inputs: For selecting values within a specific numerical range.
  6. Use extension hooks for advanced renderer capabilities

    master

    To keep the base API lightweight for simple character displays while supporting advanced features, |project| uses an extension model.

    Advanced renderers can expose specialized features (such as explicit frame lifecycle hooks) by implementing MenuRenderer::queryExtension().

    Similarly, menu items can expose optional capabilities using MenuItem::queryCapability(). This allows renderers to query whether a specific item or the renderer itself supports a particular advanced functionality.

  7. Use the WidgetList widget to select items from a list

    master

    The WidgetList widget allows users to select an item from a list of options (up to 255 items). The list can contain any data type that can be converted to a string (e.g., const char*, uint8_t).

    Properties

    • values: A std::vector of the items to choose from.
    • activePosition: The index of the currently selected item (default: 0).
    • format: A format string used to display the selected item (default: "%s").
    • cursorOffset: The offset of the cursor from the end of the widget when focused (default: 0).
    • cycle: If true, selection cycles back to the start when reaching the end of the list (default: false).
    • callback: A function called when an item is selected. If using multiple widgets within a WidgetItem, you may prefer to handle selection in the WidgetItem callback instead.
    std::vector<const char*> listItems = { "Item 1", "Item 2", "Item 3", "Item 4" };
    
    WIDGET_LIST(listItems, 0, "%s", 0, false, [](const char* item) {
        // Callback function to handle item selection
    })
  8. Using input adapters for menu control

    master

    The menu system does not interact with physical hardware directly. Instead, it relies on input adapters to translate physical user input (like a button press or a rotary encoder turn) into the control commands (UP, DOWN, etc.) understood by LcdMenu::process.

    To make your menu interactive, you must use or implement an input adapter. The system provides several built-in adapters out of the box:

    • keyboard
    • button
    • rotary-encoder
    • analogButton
    • joystick
  9. Understand GraphicalDisplayRenderer item capabilities

    master

    The renderer uses GraphicalMenuItem to provide enhanced visual states for items without requiring RTTI. The following capabilities are supported:

    • Highlighting: The focused row is shown with an inverted background. Active values/characters are highlighted during editing.
    • Boolean/Toggle: ITEM_BOOL and ITEM_TOGGLE render graphical checkbox or toggle boxes.
    • Indicators: ITEM_LIST and ITEM_RANGE render list indicators. Submenu items render a submenu indicator.
    • Layout: ITEM_VALUE provides width information to allow for right-aligned value layouts.
    • Scrollbars: Automatically rendered when the menu content exceeds the visible viewport.

    Advanced features like specific indicator styles or value selection highlighting can be accessed via queryExtension() using GraphicalIndicatorRenderer or GraphicalValueSelectionRenderer.

  10. Configure button repeat behavior in ButtonAdapter

    master

    When creating a ButtonAdapter, you can enable auto-repeat functionality for commands (useful for scrolling through menus).

    By providing two additional integer parameters (in milliseconds) after the command, you define how the button behaves when held:

    1. Repeat Delay: The amount of time (ms) the button must be held before repeating starts.
    2. Repeat Interval: The frequency (ms) at which the command is sent while the button remains held.

    Example: ButtonAdapter(&menu, &button, UP, 500, 200) will wait 500ms after the initial press, then send the UP command every 200ms until released.