From 942255d93ff6efc190c2dfbe4a463478aaeb52a4 Mon Sep 17 00:00:00 2001 From: philmoz Date: Sat, 26 Sep 2026 08:05:11 +1000 Subject: [PATCH] chore(color): simplify the code for the mix line multiplex icon (#7820) --- .../gui/colorlcd/libui/list_line_button.cpp | 14 +++ .../src/gui/colorlcd/libui/list_line_button.h | 2 +- radio/src/gui/colorlcd/libui/static.cpp | 11 ++- radio/src/gui/colorlcd/libui/static.h | 1 + radio/src/gui/colorlcd/model/model_inputs.cpp | 16 ---- radio/src/gui/colorlcd/model/model_mixes.cpp | 92 +++---------------- radio/src/tests/modelslist_manager.cpp | 1 + 7 files changed, 37 insertions(+), 100 deletions(-) diff --git a/radio/src/gui/colorlcd/libui/list_line_button.cpp b/radio/src/gui/colorlcd/libui/list_line_button.cpp index e82474fbc..19cb94641 100644 --- a/radio/src/gui/colorlcd/libui/list_line_button.cpp +++ b/radio/src/gui/colorlcd/libui/list_line_button.cpp @@ -218,6 +218,20 @@ void InputMixButtonBase::updateHeight() #endif } +void InputMixButtonBase::swapLvglGroup(InputMixButtonBase* swapWith) +{ + // Swap elements (focus + line list) + lv_obj_t* obj1 = getLvObj(); + lv_obj_t* obj2 = swapWith->getLvObj(); + if (lv_obj_get_parent(obj1) == lv_obj_get_parent(obj2)) { + // same input group: swap obj + focus group + lv_obj_swap(obj1, obj2); + } else { + // different input group: swap only focus group + lv_group_swap_obj(obj1, obj2); + } +} + static void group_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj) { etx_std_style(obj, LV_PART_MAIN, PAD_TINY); diff --git a/radio/src/gui/colorlcd/libui/list_line_button.h b/radio/src/gui/colorlcd/libui/list_line_button.h index ae715881d..ec43a28bd 100644 --- a/radio/src/gui/colorlcd/libui/list_line_button.h +++ b/radio/src/gui/colorlcd/libui/list_line_button.h @@ -58,7 +58,7 @@ class InputMixButtonBase : public ListLineButton void updateHeight(); virtual void updatePos(coord_t x, coord_t y) = 0; - virtual void swapLvglGroup(InputMixButtonBase* line2) = 0; + void swapLvglGroup(InputMixButtonBase* swapWith); void checkEvents() override; diff --git a/radio/src/gui/colorlcd/libui/static.cpp b/radio/src/gui/colorlcd/libui/static.cpp index b9d6645b2..1b6d6219e 100644 --- a/radio/src/gui/colorlcd/libui/static.cpp +++ b/radio/src/gui/colorlcd/libui/static.cpp @@ -193,10 +193,13 @@ void StaticIcon::setColor(LcdColorIndex color) void StaticIcon::setIcon(EdgeTxIcon icon) { - auto newMask = getBuiltinIcon(icon); - setSize(newMask->width, newMask->height); - lv_canvas_set_buffer(lvobj, (void*)newMask->data, newMask->width, newMask->height, - LV_IMG_CF_ALPHA_8BIT); + if (currentIcon != icon) { + currentIcon = icon; + auto newMask = getBuiltinIcon(icon); + setSize(newMask->width, newMask->height); + lv_canvas_set_buffer(lvobj, (void*)newMask->data, newMask->width, newMask->height, + LV_IMG_CF_ALPHA_8BIT); + } } void StaticIcon::center(coord_t w, coord_t h) diff --git a/radio/src/gui/colorlcd/libui/static.h b/radio/src/gui/colorlcd/libui/static.h index d2c977fc4..6627ca919 100644 --- a/radio/src/gui/colorlcd/libui/static.h +++ b/radio/src/gui/colorlcd/libui/static.h @@ -136,6 +136,7 @@ class StaticIcon : public Window protected: LcdColorIndex currentColor; + EdgeTxIcon currentIcon = EDGETX_ICONS_COUNT; MaskBitmap* mask = nullptr; }; diff --git a/radio/src/gui/colorlcd/model/model_inputs.cpp b/radio/src/gui/colorlcd/model/model_inputs.cpp index cac1cf743..69f23f882 100644 --- a/radio/src/gui/colorlcd/model/model_inputs.cpp +++ b/radio/src/gui/colorlcd/model/model_inputs.cpp @@ -166,22 +166,6 @@ class InputLineButton : public InputMixButtonBase setPos(x, y); } - void swapLvglGroup(InputMixButtonBase* line2) override - { - InputLineButton* swapWith = (InputLineButton*)line2; - - // Swap elements (focus + line list) - lv_obj_t* obj1 = getLvObj(); - lv_obj_t* obj2 = swapWith->getLvObj(); - if (lv_obj_get_parent(obj1) == lv_obj_get_parent(obj2)) { - // same input group: swap obj + focus group - lv_obj_swap(obj1, obj2); - } else { - // different input group: swap only focus group - lv_group_swap_obj(obj1, obj2); - } - } - bool isActive() const override { return isExpoActive(index); } protected: diff --git a/radio/src/gui/colorlcd/model/model_mixes.cpp b/radio/src/gui/colorlcd/model/model_mixes.cpp index 2a0c5f530..6204583f8 100644 --- a/radio/src/gui/colorlcd/model/model_mixes.cpp +++ b/radio/src/gui/colorlcd/model/model_mixes.cpp @@ -33,65 +33,25 @@ #define SET_DIRTY() storageDirty(EE_MODEL) -class MPlexIcon : public Window -{ - public: - MPlexIcon(Window* parent, uint8_t index) : - Window(parent, {0, 0, MPLEX_ICON_W, MPLEX_ICON_H}), - index(index) - { - } - - void refresh() - { - MixData* mix = mixAddress(index); - EdgeTxIcon n = ICON_MPLEX_ADD; - if (mix->mltpx == MLTPX_MUL) { - n = ICON_MPLEX_MULTIPLY; - } else if (mix->mltpx == MLTPX_REPL) { - n = ICON_MPLEX_REPLACE; - } - - if (!icon) { - icon = new StaticIcon(this, 0, 0, n, COLOR_THEME_SECONDARY1_INDEX); - icon->center(width(), height()); - } - - icon->show(lv_obj_get_index(lvobj) != 0); - icon->setIcon(n); - } - - void setIndex(uint8_t i) - { - index = i; - } - - static LAYOUT_VAL_SCALED(MPLEX_ICON_W, 25) - static LAYOUT_VAL_SCALED(MPLEX_ICON_H, 29) - - protected: - uint8_t index; - StaticIcon* icon = nullptr; -}; - class MixLineButton : public InputMixButtonBase { public: MixLineButton(Window* parent, uint8_t index) : InputMixButtonBase(parent, index) { - mplex = new MPlexIcon(parent, index); - - // mplex is a sibling (not a child) so must be closed explicitly - onClosing([=]() { - mplex->closeWindow(); - }); + // Allow multiplex icon to render outside this window + lv_obj_add_flag(lvobj, LV_OBJ_FLAG_OVERFLOW_VISIBLE); delayLoad(); } void delayedInit() override { + // Add multiplex icon + mplex = new StaticIcon(this, 0, 0, ICON_MPLEX_ADD, COLOR_THEME_SECONDARY1_INDEX); + // Position multiplex icon to the left of the parent mix line + mplex->setPos(-mplex->width() - PAD_MEDIUM, PAD_SMALL); + refresh(); ((InputMixGroupBase*)parent)->adjustHeight(); } @@ -125,50 +85,24 @@ class MixLineButton : public InputMixButtonBase setOpts(tmp_str); - mplex->refresh(); + if (mplex) + mplex->setIcon((EdgeTxIcon)(ICON_MPLEX_ADD + line.mltpx)); setFlightModes(line.flightModes); } - void setIndex(uint8_t i) override - { - ListLineButton::setIndex(i); - mplex->setIndex(i); - } - void updatePos(coord_t x, coord_t y) override { setPos(x, y); - mplex->setPos(x - MPLEX_XO, y); - mplex->show(y > ListLineButton::BTN_H); - } - - lv_obj_t* mplexLvObj() const { return mplex->getLvObj(); } - - void swapLvglGroup(InputMixButtonBase* line2) override - { - MixLineButton* swapWith = (MixLineButton*)line2; - - // Swap elements (focus + line list) - lv_obj_t* obj1 = getLvObj(); - lv_obj_t* obj2 = swapWith->getLvObj(); - if (lv_obj_get_parent(obj1) == lv_obj_get_parent(obj2)) { - // same input group: swap obj + focus group - lv_obj_swap(obj1, obj2); - lv_obj_swap(mplexLvObj(), swapWith->mplexLvObj()); - } else { - // different input group: swap only focus group - lv_group_swap_obj(obj1, obj2); - lv_group_swap_obj(mplexLvObj(), swapWith->mplexLvObj()); - } + // Don't show multiplex icon for first line + if (mplex) + mplex->show(y > ListLineButton::BTN_H); } bool isActive() const override { return isMixActive(index); } - static LAYOUT_VAL_SCALED(MPLEX_XO, 28) - protected: - MPlexIcon* mplex = nullptr; + StaticIcon* mplex = nullptr; }; class MixGroup : public InputMixGroupBase diff --git a/radio/src/tests/modelslist_manager.cpp b/radio/src/tests/modelslist_manager.cpp index c99335a1b..87e46ed2c 100644 --- a/radio/src/tests/modelslist_manager.cpp +++ b/radio/src/tests/modelslist_manager.cpp @@ -636,6 +636,7 @@ TEST_F(ModelCellManagerFsTest, RenameLabelOntoExistingLabelWithProgressDialog) // Dialogs are always shown over the main view ViewMain::instance(); MainWindow::instance()->run(); + lcdFlushed(); auto rndialog = new ProgressDialog(STR_RENAME_LABEL, [=]() {}); lv_obj_t* bar = findProgressBar(rndialog->getLvObj());