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

@@ -67,6 +67,47 @@ void Menu::setItemSize(const size_t size)
m_items.erase(m_items.begin() + static_cast<int>(size + 1), m_items.end());
}
}
void Menu::toggle(const MenuItem &menuItem)
{
const auto item =
menuItem.copyWith(menuItem.getValue() == std::to_string(true) ? std::to_string(false) : std::to_string(true));
replaceItem(menuItem.getId(), item);
}
void Menu::switchValue(const MenuItem& menuItem, ButtonType button)
{
switch (button)
{
case ButtonType::LEFT:
if (menuItem.getIndex() > 0)
{
const auto item = menuItem.copyWith(menuItem.getIndex() - 1);
replaceItem(menuItem.getId(), item);
}
else
{
const auto item = menuItem.copyWith(menuItem.getItemCount() - 1);
replaceItem(menuItem.getId(), item);
}
break;
case ButtonType::RIGHT:
if (menuItem.getIndex() < menuItem.getItemCount() - 1)
{
const auto item = menuItem.copyWith(menuItem.getIndex() + 1);
replaceItem(menuItem.getId(), item);
}
else
{
const auto item = menuItem.copyWith(0);
replaceItem(menuItem.getId(), item);
}
break;
default:
break;
}
}
void Menu::replaceItem(const int index, const MenuItem &item)
{
@@ -145,7 +186,7 @@ void Menu::renderWidget(const MenuItem *item, const uint8_t *font, const int x,
u8g2_DrawFrame(u8g2, frameX, frameY, UIConstants::FRAME_BOX_SIZE, UIConstants::FRAME_BOX_SIZE);
// Draw checkmark (X) if toggle is true
if (item->getValue() == "true")
if (item->getValue() == std::to_string(true))
{
const int checkX1 = frameX + 2;
const int checkY1 = frameY + 2;
@@ -276,7 +317,7 @@ void Menu::addToggle(uint8_t id, const std::string &text, bool selected)
auto callback = [this](const MenuItem &menuItem, const ButtonType button) -> void {
onButtonPressed(menuItem, button);
};
m_items.emplace_back(id, MenuItemTypes::TOGGLE, text, selected, callback);
m_items.emplace_back(id, MenuItemTypes::TOGGLE, text, std::to_string(selected), callback);
}
void Menu::drawScrollBar() const

View File

@@ -1,16 +1,19 @@
#include "data/MenuItem.h"
// Constructor for basic menu items (text buttons)
MenuItem::MenuItem(const uint8_t id, const uint8_t type, std::string text, ButtonCallback callback)
: m_id(id), m_type(type), m_text(std::move(text)), m_callback(std::move(callback))
{
}
// Constructor for menu items with a single value (toggles)
MenuItem::MenuItem(const uint8_t id, const uint8_t type, std::string text, std::string value,
ButtonCallback callback)
: m_id(id), m_type(type), m_text(std::move(text)), m_value(std::move(value)), m_callback(std::move(callback))
{
}
// Constructor for menu items with multiple values (selections)
MenuItem::MenuItem(const uint8_t id, const uint8_t type, std::string text, std::vector<std::string> values, int index,
ButtonCallback callback)
: m_id(id), m_type(type), m_text(std::move(text)), m_values(std::move(values)), m_index(index),
@@ -18,13 +21,6 @@ MenuItem::MenuItem(const uint8_t id, const uint8_t type, std::string text, std::
{
}
MenuItem::MenuItem(const uint8_t id, const uint8_t type, std::string text, const bool selected,
ButtonCallback callback)
: m_id(id), m_type(type), m_text(std::move(text)), m_value(selected ? "true" : "false"),
m_callback(std::move(callback))
{
}
uint8_t MenuItem::getId() const
{
return m_id;
@@ -42,10 +38,12 @@ const std::string &MenuItem::getText() const
const std::string &MenuItem::getValue() const
{
// Return the selected value from values array if available and index is valid
if (!m_values.empty() && m_index >= 0 && m_index < m_values.size())
{
return m_values.at(m_index);
}
// Otherwise return the direct value
return m_value;
}
@@ -56,6 +54,7 @@ void MenuItem::setValue(const std::string &value)
void MenuItem::onButtonPressed(const ButtonType button) const
{
// Execute the callback function if one is registered
if (m_callback)
{
m_callback(*this, button);
@@ -82,9 +81,20 @@ size_t MenuItem::getItemCount() const
return m_values.size();
}
MenuItem MenuItem::copyWith(const std::string &value) const
{
// Create a copy of this menu item with a new value
MenuItem copy = *this;
copy.m_value = value;
return copy;
}
MenuItem MenuItem::copyWith(const size_t index) const
{
// Create a copy of this menu item with a new selected index
MenuItem copy = *this;
// Check for potential overflow when converting size_t to int
if (index > std::numeric_limits<int>::max())
{
throw std::overflow_error("index is too large");

View File

@@ -2,36 +2,69 @@
#include "ui/LightSettingsMenu.h"
/**
* @namespace LightMenuItem
* @brief Constants for light menu item identifiers
*/
namespace LightMenuItem
{
constexpr uint8_t MODE = 1;
constexpr uint8_t TOGGLE = 2;
constexpr uint8_t LED_SETTINGS = 3;
}
constexpr uint8_t ACTIVATE = 0; ///< ID for the light activation toggle
constexpr uint8_t MODE = 1; ///< ID for the light mode selection
constexpr uint8_t LED_SETTINGS = 2; ///< ID for the LED settings menu item
} // namespace LightMenuItem
LightMenu::LightMenu(menu_options_t *options) : Menu(options), m_options(options)
{
// Add toggle for enabling/disabling the light system
addToggle(LightMenuItem::ACTIVATE, "Einschalten", true);
// Create mode selection options (Day/Night modes)
std::vector<std::string> values;
values.emplace_back("Tag");
values.emplace_back("Nacht");
values.emplace_back("Tag"); // Day mode
values.emplace_back("Nacht"); // Night mode
addSelection(LightMenuItem::MODE, "Modus", values, 0);
// Add menu item for accessing LED settings submenu
addText(LightMenuItem::LED_SETTINGS, "LED Einstellungen");
}
void LightMenu::onButtonPressed(const MenuItem &menuItem, const ButtonType button)
{
std::shared_ptr<Widget> widget;
// Handle different menu items based on their ID
switch (menuItem.getId())
{
case LightMenuItem::LED_SETTINGS:
widget = std::make_shared<LightSettingsMenu>(m_options);
break;
default:
case LightMenuItem::ACTIVATE: {
// Toggle the light activation state when SELECT is pressed
if (button == ButtonType::SELECT)
{
toggle(menuItem);
}
break;
}
case LightMenuItem::MODE: {
// Switch between day/night modes using left/right buttons
switchValue(menuItem, button);
break;
}
case LightMenuItem::LED_SETTINGS: {
// Open the LED settings submenu when SELECT is pressed
if (button == ButtonType::SELECT)
{
widget = std::make_shared<LightSettingsMenu>(m_options);
}
break;
}
default:
// Handle unknown menu items (no action required)
break;
}
// Push the new widget to the screen stack if one was created
if (m_options && m_options->pushScreen)
{
m_options->pushScreen(widget);

View File

@@ -1,61 +1,39 @@
#include "ui/LightSettingsMenu.h"
/**
* @namespace LightSettingsMenuItem
* @brief Constants for light settings menu item identifiers
*/
namespace LightSettingsMenuItem
{
constexpr uint8_t SECTION_COUNTER = 0;
constexpr uint8_t SECTION_COUNTER = 0; ///< ID for the section counter menu item
}
LightSettingsMenu::LightSettingsMenu(menu_options_t *options) : Menu(options), m_options(options)
{
// Create values vector for section counts (1-99)
std::vector<std::string> values;
for (size_t i = 1; i <= 99; i++)
{
values.emplace_back(std::to_string(i));
}
// Add section counter selection (allows choosing number of sections)
addSelection(LightSettingsMenuItem::SECTION_COUNTER, "Sektionen", values, 0);
// Add first section configuration item
addSelection(1, "Sektion 1", values, 0);
}
void LightSettingsMenu::onButtonPressed(const MenuItem &menuItem, const ButtonType button)
{
/// change visible counter
switch (button)
{
case ButtonType::LEFT:
if (menuItem.getIndex() > 0)
{
const auto item = menuItem.copyWith(menuItem.getIndex() - 1);
replaceItem(menuItem.getId(), item);
}
else
{
const auto item = menuItem.copyWith(menuItem.getItemCount() - 1);
replaceItem(menuItem.getId(), item);
}
break;
// Handle value switching for the current menu item
switchValue(menuItem, button);
case ButtonType::RIGHT:
if (menuItem.getIndex() < menuItem.getItemCount() - 1)
{
const auto item = menuItem.copyWith(menuItem.getIndex() + 1);
replaceItem(menuItem.getId(), item);
}
else
{
const auto item = menuItem.copyWith(0);
replaceItem(menuItem.getId(), item);
}
break;
default:
break;
}
/// change section list
// Update the section list size based on the section counter value
setItemSize(std::stoull(getItem(0).getValue()));
/// persist section values
// Persist the changed section values if persistence is available
if (m_options && m_options->persistence && m_options->persistence->save)
{
const auto key = "section_" + std::to_string(menuItem.getId());