From b8dc50562e30106d6755ab7daf77314adb1a8fa0 Mon Sep 17 00:00:00 2001 From: philmoz Date: Fri, 21 Jun 2024 09:57:03 +1000 Subject: [PATCH] fix(color): wrong file chooser icon, portrait layout and other (#5201) --- radio/src/gui/colorlcd/model_setup.cpp | 56 +++++------- radio/src/thirdparty/libopenui/src/choice.cpp | 85 +++++++------------ radio/src/thirdparty/libopenui/src/choice.h | 71 ++++++++-------- .../thirdparty/libopenui/src/filechoice.cpp | 13 +-- .../thirdparty/libopenui/src/menutoolbar.cpp | 4 +- 5 files changed, 96 insertions(+), 133 deletions(-) diff --git a/radio/src/gui/colorlcd/model_setup.cpp b/radio/src/gui/colorlcd/model_setup.cpp index 82fc28c45..e10e68e63 100644 --- a/radio/src/gui/colorlcd/model_setup.cpp +++ b/radio/src/gui/colorlcd/model_setup.cpp @@ -58,45 +58,18 @@ ModelSetupPage::ModelSetupPage() : { } -static void onModelNameChanged() -{ - auto model = modelslist.getCurrentModel(); - if (model) { - model->setModelName(g_model.header.name); - } - SET_DIRTY(); -} - struct ModelNameEdit : public ModelTextEdit { ModelNameEdit(Window *parent, const rect_t &rect) : ModelTextEdit(parent, rect, g_model.header.name, sizeof(g_model.header.name)) { - setChangeHandler(onModelNameChanged); - } -}; - -static std::string getModelBitmap() -{ - return std::string(g_model.header.bitmap, LEN_BITMAP_NAME); -} - -static void setModelBitmap(std::string newValue) -{ - strncpy(g_model.header.bitmap, newValue.c_str(), LEN_BITMAP_NAME); - auto model = modelslist.getCurrentModel(); - if (model) { - strncpy(model->modelBitmap, newValue.c_str(), LEN_BITMAP_NAME); - model->modelBitmap[LEN_BITMAP_NAME] = '\0'; - } - SET_DIRTY(); -} - -struct ModelBitmapEdit : public FileChoice { - ModelBitmapEdit(Window *parent, const rect_t &rect) : - FileChoice(parent, rect, BITMAPS_PATH, BITMAPS_EXT, LEN_BITMAP_NAME, - getModelBitmap, setModelBitmap, false, STR_BITMAP) - { + setChangeHandler([=]() { + auto model = modelslist.getCurrentModel(); + if (model) { + model->setModelName(g_model.header.name); + } + SET_DIRTY(); + }); } }; @@ -364,8 +337,19 @@ static SetupLineDef setupLines[] = { // Model bitmap STR_BITMAP, [](Window* parent, coord_t x, coord_t y) { - // TODO: show bitmap thumbnail instead? - new ModelBitmapEdit(parent, {x, y, 0, 0}); + new FileChoice(parent, {x, y, 0, 0}, BITMAPS_PATH, BITMAPS_EXT, LEN_BITMAP_NAME, + [=]() { + return std::string(g_model.header.bitmap, LEN_BITMAP_NAME); + }, + [=](std::string newValue) { + strncpy(g_model.header.bitmap, newValue.c_str(), LEN_BITMAP_NAME); + auto model = modelslist.getCurrentModel(); + if (model) { + strncpy(model->modelBitmap, newValue.c_str(), LEN_BITMAP_NAME); + model->modelBitmap[LEN_BITMAP_NAME] = '\0'; + } + SET_DIRTY(); + }, false, STR_BITMAP); } }, }; diff --git a/radio/src/thirdparty/libopenui/src/choice.cpp b/radio/src/thirdparty/libopenui/src/choice.cpp index e26c68011..b3d503c01 100644 --- a/radio/src/thirdparty/libopenui/src/choice.cpp +++ b/radio/src/thirdparty/libopenui/src/choice.cpp @@ -46,38 +46,25 @@ static lv_obj_t* choice_create(lv_obj_t* parent) return etx_create(&choice_class, parent); } -void choice_changed_cb(lv_event_t* e) +ChoiceBase::ChoiceBase(Window* parent, const rect_t& rect, + int vmin, int vmax, const char* title, + std::function _getValue, + std::function _setValue, + ChoiceType type) : + FormField(parent, rect, 0, choice_create), + vmin(vmin), vmax(vmax), menuTitle(title), + _getValue(std::move(_getValue)), + _setValue(std::move(_setValue)) { - auto code = lv_event_get_code(e); - - if (code == LV_EVENT_VALUE_CHANGED) { - lv_obj_t* target = lv_event_get_target(e); - if (target != nullptr) { - ChoiceBase* cb = (ChoiceBase*)lv_obj_get_user_data(target); - if (cb) { - std::string text = cb->getLabelText(); - lv_label_set_text(cb->label, text.c_str()); - } - } - } -} - -ChoiceBase::ChoiceBase(Window* parent, const rect_t& rect, ChoiceType type) : - FormField(parent, rect, 0, choice_create), type(type) -{ - // add the image + // Add image lv_obj_t* img = lv_img_create(lvobj); lv_img_set_src( img, type == CHOICE_TYPE_DROPOWN ? LV_SYMBOL_DOWN : LV_SYMBOL_DIRECTORY); lv_obj_set_pos(img, 0, PAD_TINY); - lv_obj_add_event_cb(lvobj, choice_changed_cb, LV_EVENT_VALUE_CHANGED, lvobj); + // Add label label = lv_label_create(lvobj); lv_obj_set_pos(label, ICON_W, PAD_TINY); - - lv_group_t* def_group = lv_group_get_default(); - if (def_group) - lv_group_add_obj(def_group, lvobj); } std::string Choice::getLabelText() @@ -101,46 +88,36 @@ std::string Choice::getLabelText() return text; } -Choice::Choice(Window* parent, const rect_t& rect, int vmin, int vmax, - std::function _getValue, - std::function _setValue, const char* title) : - ChoiceBase(parent, rect, CHOICE_TYPE_DROPOWN), - vmin(vmin), - vmax(vmax), - menuTitle(title), - _getValue(std::move(_getValue)), - _setValue(std::move(_setValue)) +void ChoiceBase::update() { - lv_event_send(lvobj, LV_EVENT_VALUE_CHANGED, nullptr); + lv_label_set_text(label, getLabelText().c_str()); +} + +Choice::Choice(Window* parent, const rect_t& rect, int vmin, int vmax, + std::function getValue, + std::function setValue, const char* title, ChoiceType type) : + ChoiceBase(parent, rect, vmin, vmax, title, getValue, setValue, type) +{ + update(); } Choice::Choice(Window* parent, const rect_t& rect, const char* const values[], - int vmin, int vmax, std::function _getValue, - std::function _setValue, const char* title) : - ChoiceBase(parent, rect, CHOICE_TYPE_DROPOWN), - vmin(vmin), - vmax(vmax), - menuTitle(title), - _getValue(std::move(_getValue)), - _setValue(std::move(_setValue)) + int vmin, int vmax, std::function getValue, + std::function setValue, const char* title) : + ChoiceBase(parent, rect, vmin, vmax, title, getValue, setValue, CHOICE_TYPE_DROPOWN) { setValues(values); - lv_event_send(lvobj, LV_EVENT_VALUE_CHANGED, nullptr); + update(); } Choice::Choice(Window* parent, const rect_t& rect, std::vector values, int vmin, int vmax, - std::function _getValue, - std::function _setValue, const char* title) : - ChoiceBase(parent, rect, CHOICE_TYPE_DROPOWN), - values(std::move(values)), - vmin(vmin), - vmax(vmax), - menuTitle(title), - _getValue(std::move(_getValue)), - _setValue(std::move(_setValue)) + std::function getValue, + std::function setValue, const char* title) : + ChoiceBase(parent, rect, vmin, vmax, title, getValue, setValue, CHOICE_TYPE_DROPOWN), + values(std::move(values)) { - lv_event_send(lvobj, LV_EVENT_VALUE_CHANGED, nullptr); + update(); } void Choice::addValue(const char* value) @@ -169,7 +146,7 @@ void Choice::setValue(int val) { if (_setValue) { _setValue(val); - lv_event_send(lvobj, LV_EVENT_VALUE_CHANGED, nullptr); + update(); } } diff --git a/radio/src/thirdparty/libopenui/src/choice.h b/radio/src/thirdparty/libopenui/src/choice.h index 96bea3a49..6bc84b19f 100644 --- a/radio/src/thirdparty/libopenui/src/choice.h +++ b/radio/src/thirdparty/libopenui/src/choice.h @@ -32,19 +32,39 @@ enum ChoiceType { class ChoiceBase : public FormField { public: - ChoiceBase(Window *parent, const rect_t &rect, + ChoiceBase(Window *parent, const rect_t &rect, int vmin, int vmax, const char* title, + std::function _getValue, std::function _setValue, ChoiceType type = CHOICE_TYPE_DROPOWN); - void setChoiceType(ChoiceType t) { type = t; } + void update(); + + void setTextHandler(std::function handler) + { + textHandler = std::move(handler); + update(); + } + + int getMin() const { return vmin; } + void setMin(int value) { vmin = value; } + + int getMax() const { return vmax; } + void setMax(int value) { vmax = value; } + + const char* getTitle() const { return menuTitle; } static LAYOUT_VAL(ICON_W, 18, 18) protected: - ChoiceType type; lv_obj_t *label; + int vmin = 0; + int vmax = 0; + const char *menuTitle = nullptr; - friend void choice_changed_cb(lv_event_t *e); - virtual std::string getLabelText() { return ""; }; + std::function _getValue; + std::function _setValue; + std::function textHandler; + + virtual std::string getLabelText() = 0; }; class Choice : public ChoiceBase @@ -53,7 +73,7 @@ class Choice : public ChoiceBase Choice(Window *parent, const rect_t &rect, int vmin, int vmax, std::function _getValue, std::function _setValue = nullptr, - const char *title = nullptr); + const char *title = nullptr, ChoiceType type = CHOICE_TYPE_DROPOWN); Choice(Window *parent, const rect_t &rect, std::vector values, int vmin, int vmax, std::function _getValue, std::function _setValue = nullptr, @@ -63,16 +83,15 @@ class Choice : public ChoiceBase std::function _setValue = nullptr, const char *title = nullptr); - void addValue(const char *value); - - void setValues(std::vector values); - - void setValues(const char *const values[]); - #if defined(DEBUG_WINDOWS) std::string getName() const override { return "Choice"; } #endif + void addValue(const char *value); + + void setValues(std::vector values); + void setValues(const char *const values[]); + void onClicked() override; void setFillMenuHandler(std::function handler) @@ -130,41 +149,23 @@ class Choice : public ChoiceBase virtual void setValue(int val); virtual int getIntValue() const { return _getValue(); } - void setTextHandler(std::function handler) - { - textHandler = std::move(handler); - lv_event_send(lvobj, LV_EVENT_VALUE_CHANGED, nullptr); - } - - void setMin(int value) { vmin = value; } - - void setMax(int value) { vmax = value; } - - int getMin() const { return vmin; } - int getMax() const { return vmax; } - std::string getString(int val) { return values[val]; } - int selectedIx0 = 0; + typedef std::function FilterFct; + + void fillMenu(Menu *menu, const FilterFct &filter = nullptr); protected: friend class MenuToolbar; bool inverted = false; + int selectedIx0 = 0; - std::string getLabelText() override; std::vector values; - int vmin = 0; - int vmax = 0; - const char *menuTitle = nullptr; - std::function _getValue; - std::function _setValue; std::function isValueAvailable; - std::function textHandler; std::function fillMenuHandler; - typedef std::function FilterFct; - void fillMenu(Menu *menu, const FilterFct &filter = nullptr); + std::string getLabelText() override; virtual void openMenu(); }; diff --git a/radio/src/thirdparty/libopenui/src/filechoice.cpp b/radio/src/thirdparty/libopenui/src/filechoice.cpp index bbeac9640..f1c20647a 100644 --- a/radio/src/thirdparty/libopenui/src/filechoice.cpp +++ b/radio/src/thirdparty/libopenui/src/filechoice.cpp @@ -29,7 +29,7 @@ class FileChoiceMenuToolbar : public MenuToolbar { public: FileChoiceMenuToolbar(FileChoice *choice, Menu *menu) : - MenuToolbar(choice, menu, 3) + MenuToolbar(choice, menu, FC_COLS) { filterButton(choice, 'a', 'd', "aA-dD"); filterButton(choice, 'e', 'h', "eE-hH"); @@ -40,7 +40,7 @@ class FileChoiceMenuToolbar : public MenuToolbar filterButton(choice, '0', '9', "0-9"); bool found = false; - for (int i = 0; i < choice->getMax(); i += 1) { + for (int i = 0; i <= choice->getMax(); i += 1) { char c = choice->getString(i)[0]; if (c && !isdigit(c) && !isalpha(c)) { found = true; @@ -64,7 +64,7 @@ class FileChoiceMenuToolbar : public MenuToolbar void filterButton(FileChoice *choice, char from, char to, const char* title) { bool found = false; - for (int i = 0; i < choice->getMax(); i += 1) { + for (int i = 0; i <= choice->getMax(); i += 1) { char c = choice->getString(i)[0]; if (isupper(c)) c += 0x20; if (c >= from && c <= to) { @@ -87,6 +87,8 @@ class FileChoiceMenuToolbar : public MenuToolbar } } + static LAYOUT_VAL(FC_COLS, 3, 2) + protected: }; @@ -97,7 +99,7 @@ FileChoice::FileChoice(Window *parent, const rect_t &rect, std::string folder, bool stripExtension, const char *title) : Choice( parent, rect, 0, 0, [=]() { return selectedIdx; }, - [=](int val) { setValue(getString(val)); }, title), + [=](int val) { setValue(getString(val)); }, title, CHOICE_TYPE_FOLDER), folder(std::move(folder)), extension(extension), maxlen(maxlen), @@ -105,8 +107,7 @@ FileChoice::FileChoice(Window *parent, const rect_t &rect, std::string folder, setValue(std::move(setValue)), stripExtension(stripExtension) { - setChoiceType(CHOICE_TYPE_FOLDER); - lv_event_send(lvobj, LV_EVENT_VALUE_CHANGED, nullptr); + update(); } std::string FileChoice::getLabelText() { return getValue(); } diff --git a/radio/src/thirdparty/libopenui/src/menutoolbar.cpp b/radio/src/thirdparty/libopenui/src/menutoolbar.cpp index d9edc9602..80e0060e0 100644 --- a/radio/src/thirdparty/libopenui/src/menutoolbar.cpp +++ b/radio/src/thirdparty/libopenui/src/menutoolbar.cpp @@ -89,7 +89,7 @@ void MenuToolbar::resetFilter() if (lv_group_get_focused(group) != lvobj) { lv_group_focus_obj(lvobj); choice->fillMenu(menu); - menu->setTitle(choice->menuTitle); + menu->setTitle(choice->getTitle()); } } @@ -134,7 +134,7 @@ bool MenuToolbar::filterMenu(MenuToolbarButton* btn, int16_t filtermin, if (title) menu->setTitle(title); else - menu->setTitle(choice->menuTitle); + menu->setTitle(choice->getTitle()); filter = [=](int16_t index) { if (filterFunc) return filterFunc(index); return index == 0 || (abs(index) >= filtermin && abs(index) <= filtermax);