#include "ButtonMatrixWidget.hpp" #include "../WidgetManager.hpp" #include #include namespace { std::string trimToken(const std::string& token) { size_t start = 0; size_t end = token.size(); while (start < end && std::isspace(static_cast(token[start])) != 0) { start++; } while (end > start && std::isspace(static_cast(token[end - 1])) != 0) { end--; } return token.substr(start, end - start); } } ButtonMatrixWidget::ButtonMatrixWidget(const WidgetConfig& config) : Widget(config) { } ButtonMatrixWidget::~ButtonMatrixWidget() { if (obj_) { lv_obj_remove_event_cb(obj_, valueChangedCallback); } } void ButtonMatrixWidget::rebuildMapStorage() { mapStorage_.clear(); mapPointers_.clear(); auto addButton = [&](const std::string& token) { std::string trimmed = trimToken(token); if (!trimmed.empty()) { mapStorage_.push_back(trimmed); } }; if (config_.text[0] != '\0') { std::string token; for (size_t i = 0; config_.text[i] != '\0'; ++i) { const char ch = config_.text[i]; if (ch == ';' || ch == ',') { addButton(token); token.clear(); } else if (ch == '\n' || ch == '\r') { addButton(token); token.clear(); if (!mapStorage_.empty() && mapStorage_.back() != "\n") { mapStorage_.push_back("\n"); } if (ch == '\r' && config_.text[i + 1] == '\n') { ++i; } } else { token.push_back(ch); } } addButton(token); while (!mapStorage_.empty() && mapStorage_.back() == "\n") { mapStorage_.pop_back(); } } if (mapStorage_.empty()) { mapStorage_ = {"1", "2", "3", "\n", "4", "5", "6", "\n", "7", "8", "9"}; } mapPointers_.reserve(mapStorage_.size() + 1); for (const std::string& entry : mapStorage_) { mapPointers_.push_back(entry.c_str()); } mapPointers_.push_back(""); } lv_obj_t* ButtonMatrixWidget::create(lv_obj_t* parent) { obj_ = lv_buttonmatrix_create(parent); if (!obj_) return nullptr; lv_obj_set_pos(obj_, config_.x, config_.y); lv_obj_set_size(obj_, config_.width > 0 ? config_.width : 220, config_.height > 0 ? config_.height : 140); lv_obj_clear_flag(obj_, LV_OBJ_FLAG_SCROLLABLE); rebuildMapStorage(); lv_buttonmatrix_set_map(obj_, mapPointers_.data()); lv_buttonmatrix_set_button_ctrl_all(obj_, LV_BUTTONMATRIX_CTRL_CLICK_TRIG); if (config_.isToggle) { lv_buttonmatrix_set_button_ctrl_all(obj_, LV_BUTTONMATRIX_CTRL_CHECKABLE); } lv_obj_add_event_cb(obj_, valueChangedCallback, LV_EVENT_VALUE_CHANGED, this); return obj_; } void ButtonMatrixWidget::applyStyle() { if (!obj_) return; applyCommonStyle(); lv_color_t textColor = lv_color_make( config_.textColor.r, config_.textColor.g, config_.textColor.b); lv_color_t buttonColor = lv_color_make( config_.bgColor.r, config_.bgColor.g, config_.bgColor.b); uint8_t buttonOpa = config_.bgOpacity > 0 ? config_.bgOpacity : static_cast(LV_OPA_30); lv_obj_set_style_text_font(obj_, getFontBySize(config_.fontSize), LV_PART_ITEMS); lv_obj_set_style_text_color(obj_, textColor, LV_PART_ITEMS); lv_obj_set_style_bg_color(obj_, buttonColor, LV_PART_ITEMS); lv_obj_set_style_bg_opa(obj_, buttonOpa, LV_PART_ITEMS); if (config_.borderRadius > 0) { lv_obj_set_style_radius(obj_, config_.borderRadius, LV_PART_ITEMS); } if (config_.borderWidth > 0 && config_.borderOpacity > 0) { lv_obj_set_style_border_width(obj_, config_.borderWidth, LV_PART_ITEMS); lv_obj_set_style_border_color(obj_, lv_color_make( config_.borderColor.r, config_.borderColor.g, config_.borderColor.b), LV_PART_ITEMS); lv_obj_set_style_border_opa(obj_, config_.borderOpacity, LV_PART_ITEMS); } else { lv_obj_set_style_border_width(obj_, 0, LV_PART_ITEMS); } lv_style_selector_t pressedSel = static_cast(LV_PART_ITEMS) | static_cast(LV_STATE_PRESSED); lv_style_selector_t checkedSel = static_cast(LV_PART_ITEMS) | static_cast(LV_STATE_CHECKED); lv_obj_set_style_bg_color(obj_, textColor, pressedSel); lv_obj_set_style_bg_opa(obj_, LV_OPA_40, pressedSel); lv_obj_set_style_text_color(obj_, lv_color_white(), pressedSel); lv_obj_set_style_bg_color(obj_, textColor, checkedSel); lv_obj_set_style_bg_opa(obj_, LV_OPA_50, checkedSel); lv_obj_set_style_text_color(obj_, lv_color_white(), checkedSel); } void ButtonMatrixWidget::valueChangedCallback(lv_event_t* e) { ButtonMatrixWidget* widget = static_cast(lv_event_get_user_data(e)); if (!widget) return; lv_obj_t* target = static_cast(lv_event_get_target(e)); WidgetManager::instance().handleButtonAction(widget->getConfig(), target); }