more interaction

Signed-off-by: Peter Siegmund <developer@mars3142.org>
This commit is contained in:
2025-06-15 09:19:14 +02:00
parent 5464bacc52
commit ea0208083f
7 changed files with 222 additions and 179 deletions

View File

@@ -24,30 +24,30 @@
* with support for various types of interactive menu items. It handles user input
* through directional navigation and action buttons, provides visual feedback
* through selection highlighting, and supports scrolling for long menu lists.
*
*
* The menu system supports four types of menu items:
* - Text buttons: Simple selectable text items
* - Selection items: Dropdown/list selection with multiple options
* - Number inputs: Numeric value adjustment controls
* - Toggle items: Boolean on/off switches
*
*
* @note Menu items are identified by unique IDs and can be dynamically added
* after menu creation.
*
*
* @see Widget
* @see MenuItem
* @see menu_options_t
*/
class Menu : public Widget
{
public:
public:
/**
* @brief Constructs a new Menu instance with the specified configuration
* @param options Pointer to menu configuration options structure
*
*
* @pre options must not be nullptr and must remain valid for the menu's lifetime
* @post Menu is initialized with the provided configuration and ready for item addition
*
*
* @note The menu does not take ownership of the options structure and assumes
* it remains valid throughout the menu's lifetime.
*/
@@ -64,10 +64,10 @@ public:
* @brief Adds a text-based menu item (button) to the menu
* @param id Unique identifier for this menu item (must be unique within the menu)
* @param text Display text shown on the menu item
*
*
* @pre id must be unique within this menu instance
* @post A new text menu item is added to the menu's item collection
*
*
* @note Text items act as buttons and generate selection events when activated
*/
void addText(uint8_t id, const std::string &text);
@@ -83,7 +83,7 @@ public:
* @pre values vector must not be empty
* @pre value must be one of the strings in the values vector
* @post A new selection menu item is added with the specified options
*
*
* @note The value parameter is modified directly when the user changes the selection
*/
void addSelection(uint8_t id, const std::string &text, const std::vector<std::string> &values, int index);
@@ -93,24 +93,24 @@ public:
* @param id Unique identifier for this menu item (must be unique within the menu)
* @param text Display text/label for the toggle item
* @param selected Current state of the toggle (true = on/enabled, false = off/disabled)
*
*
* @pre id must be unique within this menu instance
* @post A new toggle menu item is added with the specified initial state
*
*
* @note Toggle state can be changed through user interaction with select button
*/
void addToggle(uint8_t id, const std::string &text, bool selected);
protected:
protected:
/**
* @brief Virtual callback method for handling button press events on specific menu items
* @param item The menu item that received the button press
* @param button The type of button that was pressed
*
*
* @details This method can be overridden by derived classes to implement custom
* button handling logic for specific menu items. The base implementation
* is empty, allowing derived classes to selectively handle events.
*
*
* @note Override this method in derived classes to implement custom menu item
* interaction behavior beyond the standard navigation and value modification.
*/
@@ -119,114 +119,103 @@ protected:
// Base implementation intentionally empty - override in derived classes as needed
}
/**
* @brief Retrieves a menu item by its index position
* @param index Zero-based index of the menu item to retrieve
* @return MenuItem object at the specified index
*
* @pre index must be within valid range [0, getItemCount()-1]
* @post Returns a copy of the menu item at the specified position
*
* @throws std::out_of_range if index is invalid
*
* @note This method returns a copy of the menu item, not a reference
*/
MenuItem getItem(int index);
/**
* @brief Gets the total number of menu items in the menu
* @return Size of the menu items collection
*
* @post Returns current count of menu items (>= 0)
*
* @note This count includes all types of menu items (text, selection, toggle)
*/
[[nodiscard]] size_t getItemCount() const;
/**
* @brief Dynamically adjusts the number of menu items to the specified size
* @param size Target number of menu items the menu should contain
*
* @details If the target size is larger than current item count, new selection
* items are added using the first item's values as template. If the
* target size is smaller, excess items are removed from the end.
*
* @pre size must be > 0 and at least one menu item must exist as template
* @post Menu contains exactly 'size' number of items
*
* @note New items are created as selection items with auto-generated names
* in the format "Section X" where X is the item number
*/
void setItemSize(size_t size);
/**
* @brief Toggles the boolean state of a toggle menu item
* @param menuItem The toggle menu item whose state should be flipped
*
* @pre menuItem must be of type TOGGLE
* @post The menu item's value is switched between "true" and "false"
*
* @details Changes "true" to "false" and "false" to "true" for toggle items.
* The modified item replaces the original in the menu's item collection.
*
* @note This method directly modifies the menu's internal state
*/
void toggle(const MenuItem &menuItem);
/**
* @brief Changes the selected value of a selection menu item based on button input
* @param menuItem The selection menu item to modify
* @param button The directional button pressed (LEFT or RIGHT)
*
* @pre menuItem must be of type SELECTION with valid values array
* @post The menu item's selected index is adjusted based on button direction
*
* @details LEFT button moves to previous option (wraps to end if at beginning),
* RIGHT button moves to next option (wraps to beginning if at end).
* Other button types are ignored.
*
* @note The modified item replaces the original in the menu's item collection
*/
void switchValue(const MenuItem &menuItem, ButtonType button);
private:
void replaceItem(int index, const MenuItem &item);
private:
/**
* @brief Renders the entire menu on screen
* @details Override from Widget base class. Handles the complete rendering process
* including menu items, selection highlighting, and scroll indicators.
*
* @note This method is called during each frame's render cycle
*/
void render() override;
/**
* @brief Handles button press events from the input system
* @param button The button that was pressed
* @details Override from Widget base class. Processes user input and delegates
* to appropriate handler methods based on button type.
*
* @see ButtonType for available button types
*/
void onButtonClicked(ButtonType button) override;
// Navigation event handlers
/**
* @brief Handles down arrow/stick input - moves selection down in the menu
* @details Moves the current selection to the next menu item, wrapping to the
* beginning if at the end of the list.
*/
void onPressedDown();
/**
* @brief Handles up arrow/stick input - moves selection up in the menu
* @details Moves the current selection to the previous menu item, wrapping to the
* end if at the beginning of the list.
*/
void onPressedUp();
/**
* @brief Handles left arrow/stick input - decreases value for current item
* @details For selection items: moves to previous option in the list
* For number items: decreases the numeric value
* For other items: no action
*/
void onPressedLeft() const;
/**
* @brief Handles right arrow/stick input - increases value for current item
* @details For selection items: moves to next option in the list
* For number items: increases the numeric value
* For other items: no action
*/
void onPressedRight() const;
/**
* @brief Handles select/confirm button press
* @details Activates the currently selected menu item:
* - Text items: triggers selection event
* - Toggle items: toggles the boolean state
* - Other items: context-dependent behavior
*/
void onPressedSelect() const;
/**
* @brief Handles back/cancel button press
* @details Typically used to exit the menu or return to a previous screen.
* The specific behavior depends on the menu configuration.
*/
void onPressedBack() const;
// Rendering helper methods
/**
* @brief Draws the scroll bar indicating position in long menus
* @details Renders a visual scroll indicator when the menu contains more items
* than can be displayed on screen simultaneously.
*/
void drawScrollBar() const;
/**
* @brief Draws the selection highlight box around current menu item
* @details Renders visual feedback showing which menu item is currently selected
* and will respond to user input.
*/
void drawSelectionBox() const;
/**
* @brief Renders an individual menu item widget
* @param item Pointer to the menu item to render (must not be nullptr)
* @param font Font to use for rendering text
* @param x X coordinate for rendering position
* @param y Y coordinate for rendering position
*
* @pre item must not be nullptr
* @pre font must be a valid u8g2 font
* @pre x and y must be valid screen coordinates
*
* @details Handles the rendering of a single menu item based on its type,
* including text, current values, and any type-specific visual elements.
*/
void renderWidget(const MenuItem *item, const uint8_t *font, int x, int y) const;
// Member variables
size_t m_selected_item = 0; ///< Index of currently selected menu item (0-based)
std::vector<MenuItem> m_items; ///< Collection of all menu items in display order
menu_options_t *m_options; ///< Pointer to menu configuration options (not owned)
size_t m_selected_item = 0;
std::vector<MenuItem> m_items;
menu_options_t *m_options;
};

View File

@@ -142,35 +142,6 @@ public:
MenuItem(uint8_t id, uint8_t type, std::string text, std::vector<std::string> values, int index,
ButtonCallback callback);
/**
* @brief Constructs a boolean/toggle menu item with on/off state
* @param id Unique identifier for this menu item within its parent menu
* @param type Type identifier defining the item's behavior and visual appearance
* @param text Display text shown to the user for this menu item
* @param selected Whether this item is currently selected/enabled/checked
* @param callback Function to call when the item is activated
*
* @pre id must be unique within the parent menu context
* @pre text should not be empty for proper user interface display
* @pre callback should be a valid callable object
* @post MenuItem is initialized as a boolean toggle item
*
* @details Creates a menu item that represents a boolean state (on/off, enabled/disabled,
* checked/unchecked). This type is ideal for settings that have binary states
* and need to show their current status visually.
*
* Typical use cases include:
* - Feature toggles (e.g., "Auto-save: ON")
* - Enable/disable settings (e.g., "Sound: ENABLED")
* - Checkbox-style options (e.g., "Show notifications: ✓")
* - Boolean configurations (e.g., "Dark mode: OFF")
*
* @note The selected state is converted to a string value internally for
* consistent value handling across all menu item types.
* @note The callback typically implements toggle logic to switch between states.
*/
MenuItem(uint8_t id, uint8_t type, std::string text, bool selected, ButtonCallback callback);
/**
* @brief Gets the unique identifier of this menu item
* @return The menu item's unique ID as assigned during construction
@@ -282,10 +253,12 @@ public:
[[nodiscard]] int getIndex() const;
std::vector<std::string> getValues() const;
[[nodiscard]] std::vector<std::string> getValues() const;
[[nodiscard]] size_t getItemCount() const;
[[nodiscard]] MenuItem copyWith(const std::string &value) const;
[[nodiscard]] MenuItem copyWith(size_t index) const;
private:

View File

@@ -2,13 +2,32 @@
#include "common/Menu.h"
/**
* @class LightSettingsMenu
* @brief Menu for configuring light system settings including sections and LED parameters
* @details This menu extends the base Menu class to provide specialized functionality
* for managing light system configurations. It handles dynamic section management
* and provides persistence for user settings.
*/
class LightSettingsMenu final : public Menu
{
public:
/**
* @brief Constructs a LightSettingsMenu with the specified options
* @param options Pointer to menu configuration options structure
* @details Initializes the menu with section counter and default section settings
*/
explicit LightSettingsMenu(menu_options_t *options);
private:
/**
* @brief Handles button press events for light settings menu items
* @param menuItem The menu item that received the button press
* @param button The type of button that was pressed
* @details Manages value switching, dynamic section list updates, and
* persistence of section values when settings are modified
*/
void onButtonPressed(const MenuItem& menuItem, ButtonType button) override;
menu_options_t *m_options;
menu_options_t *m_options; ///< Pointer to menu configuration options
};