158 lines
5.2 KiB
C++
158 lines
5.2 KiB
C++
#include "ButtonMatrixWidget.hpp"
|
|
|
|
#include "../WidgetManager.hpp"
|
|
|
|
#include <algorithm>
|
|
#include <cctype>
|
|
|
|
namespace {
|
|
std::string trimToken(const std::string& token) {
|
|
size_t start = 0;
|
|
size_t end = token.size();
|
|
|
|
while (start < end && std::isspace(static_cast<unsigned char>(token[start])) != 0) {
|
|
start++;
|
|
}
|
|
while (end > start && std::isspace(static_cast<unsigned char>(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<uint8_t>(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_style_selector_t>(LV_PART_ITEMS) |
|
|
static_cast<lv_style_selector_t>(LV_STATE_PRESSED);
|
|
lv_style_selector_t checkedSel = static_cast<lv_style_selector_t>(LV_PART_ITEMS) |
|
|
static_cast<lv_style_selector_t>(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<ButtonMatrixWidget*>(lv_event_get_user_data(e));
|
|
if (!widget) return;
|
|
|
|
lv_obj_t* target = static_cast<lv_obj_t*>(lv_event_get_target(e));
|
|
WidgetManager::instance().handleButtonAction(widget->getConfig(), target);
|
|
}
|