diff --git a/radio/src/gui/colorlcd/LvglWrapper.cpp b/radio/src/gui/colorlcd/LvglWrapper.cpp index b3dae722b..33092acfe 100644 --- a/radio/src/gui/colorlcd/LvglWrapper.cpp +++ b/radio/src/gui/colorlcd/LvglWrapper.cpp @@ -295,6 +295,21 @@ int8_t rotaryEncoderGetAccel() { return 0; } #endif // defined(ROTARY_ENCODER_NAVIGATION) +// Return 32 bit version of color (for recolor of buttons) +uint32_t makeLvColor32(uint32_t colorFlags) +{ + auto color = COLOR_VAL(colorFlags); + return (GET_RED(color) << 16u) | (GET_GREEN(color) << 8) | GET_BLUE(color); +} + +// Create recolor version of string value +std::string makeRecolor(std::string value, uint32_t colorFlags) +{ + char s[32]; + snprintf(s, 32, "#%06x %s#", makeLvColor32(colorFlags), value.c_str()); + return std::string(s); +} + /** * Helper function to translate a colorFlags value to a lv_color_t suitable * for passing to an lv_obj function diff --git a/radio/src/gui/colorlcd/LvglWrapper.h b/radio/src/gui/colorlcd/LvglWrapper.h index fbfc233ac..6b5f0887b 100644 --- a/radio/src/gui/colorlcd/LvglWrapper.h +++ b/radio/src/gui/colorlcd/LvglWrapper.h @@ -27,6 +27,8 @@ void initLvglTheme(); +uint32_t makeLvColor32(uint32_t colorFlags); +std::string makeRecolor(std::string value, uint32_t colorFlags); lv_color_t makeLvColor(uint32_t colorFlags); typedef std::function LvObjConstructor; diff --git a/radio/src/gui/colorlcd/fm_matrix.cpp b/radio/src/gui/colorlcd/fm_matrix.cpp index 150878c9d..c46e46834 100644 --- a/radio/src/gui/colorlcd/fm_matrix.cpp +++ b/radio/src/gui/colorlcd/fm_matrix.cpp @@ -32,11 +32,13 @@ FMMatrix::FMMatrix(Window* parent, const rect_t& r, T* input) : initBtnMap(3, MAX_FLIGHT_MODES); #endif - for (int i = 0; i < MAX_FLIGHT_MODES; i++) { - setText(i, std::to_string(i).c_str()); - } update(); + for (int i = 0; i < MAX_FLIGHT_MODES; i++) { + lv_btnmatrix_set_btn_ctrl(lvobj, i, LV_BTNMATRIX_CTRL_RECOLOR); + setTextWithColor(i); + } + #if LCD_W > LCD_H // hide last element lv_btnmatrix_set_btn_ctrl(lvobj, MAX_FLIGHT_MODES, LV_BTNMATRIX_CTRL_HIDDEN); @@ -57,11 +59,18 @@ FMMatrix::FMMatrix(Window* parent, const rect_t& r, T* input) : lv_obj_remove_style(lvobj, nullptr, LV_PART_MAIN | LV_STATE_EDITED); } +template +void FMMatrix::setTextWithColor(uint8_t btn_id) +{ + setText(btn_id, makeRecolor(std::to_string(btn_id), isActive(btn_id) ? COLOR_THEME_PRIMARY1 : COLOR_THEME_SECONDARY1).c_str()); +} + template void FMMatrix::onPress(uint8_t btn_id) { if (btn_id >= MAX_FLIGHT_MODES) return; BFBIT_FLIP(input->flightModes, bfBit(btn_id)); + setTextWithColor(btn_id); storageDirty(EE_MODEL); } diff --git a/radio/src/gui/colorlcd/fm_matrix.h b/radio/src/gui/colorlcd/fm_matrix.h index e987600a3..4e566205c 100644 --- a/radio/src/gui/colorlcd/fm_matrix.h +++ b/radio/src/gui/colorlcd/fm_matrix.h @@ -32,6 +32,7 @@ struct FMMatrix : public ButtonMatrix { FMMatrix(Window* parent, const rect_t& rect, T* input); void onPress(uint8_t btn_id); bool isActive(uint8_t btn_id); + void setTextWithColor(uint8_t btn_id); }; extern template struct FMMatrix; diff --git a/radio/src/gui/colorlcd/gvar_numberedit.cpp b/radio/src/gui/colorlcd/gvar_numberedit.cpp index 73dedd88a..2e43012e5 100644 --- a/radio/src/gui/colorlcd/gvar_numberedit.cpp +++ b/radio/src/gui/colorlcd/gvar_numberedit.cpp @@ -64,18 +64,21 @@ GVarNumberEdit::GVarNumberEdit(Window* parent, const rect_t& rect, int32_t vmin, }); gvar_field->setTextHandler( [=](int32_t value) { return getGVarString(value); }); + gvar_field->setWidth(70); num_field = new NumberEdit( this, rect_t{}, vmin, vmax, [=]() { return getValue() + voffset; }, nullptr, windowFlags, textFlags); + num_field->setWidth(70); #if defined(GVARS) // The GVAR button - auto btn = new TextButton(this, rect_t{}, STR_GV, [=]() { + m_gvBtn = new TextButton(this, rect_t{}, STR_GV, [=]() { switchGVarMode(); - return 0; + return GV_IS_GV_VALUE(getValue(), vmin, vmax); }); - lv_obj_set_height(btn->getLvObj(), lv_obj_get_height(gvar_field->getLvObj())); + m_gvBtn->check(GV_IS_GV_VALUE(getValue(), vmin, vmax)); + lv_obj_set_height(m_gvBtn->getLvObj(), lv_obj_get_height(gvar_field->getLvObj())); #endif lv_obj_add_event_cb(lvobj, GVarNumberEdit::value_changed, @@ -95,6 +98,8 @@ void GVarNumberEdit::switchGVarMode() : GET_GVAR(value, vmin, vmax, mixerCurrentFlightMode)) : GV_GET_GV1_VALUE(vmin, vmax)); + m_gvBtn->check(GV_IS_GV_VALUE(value, vmin, vmax)); + // update field type based on value update(); } diff --git a/radio/src/gui/colorlcd/gvar_numberedit.h b/radio/src/gui/colorlcd/gvar_numberedit.h index edc841acc..78501e7f7 100644 --- a/radio/src/gui/colorlcd/gvar_numberedit.h +++ b/radio/src/gui/colorlcd/gvar_numberedit.h @@ -29,6 +29,8 @@ constexpr coord_t GVAR_BUTTON_WIDTH = 30; +class TextButton; + class GVarNumberEdit : public Window { public: @@ -47,6 +49,9 @@ class GVarNumberEdit : public Window Choice* gvar_field = nullptr; NumberEdit* num_field = nullptr; FormField* act_field = nullptr; +#if defined(GVARS) + TextButton* m_gvBtn = nullptr; +#endif int32_t vmin; int32_t vmax; diff --git a/radio/src/gui/colorlcd/preflight_checks.cpp b/radio/src/gui/colorlcd/preflight_checks.cpp index c3a6ef1e1..de327c704 100644 --- a/radio/src/gui/colorlcd/preflight_checks.cpp +++ b/radio/src/gui/colorlcd/preflight_checks.cpp @@ -77,6 +77,7 @@ struct SwitchWarnMatrix : public ButtonMatrix { SwitchWarnMatrix(Window* parent, const rect_t& rect); void onPress(uint8_t btn_id); bool isActive(uint8_t btn_id); + void setTextWithColor(uint8_t btn_id); private: uint8_t sw_idx[NUM_SWITCHES]; }; @@ -85,6 +86,7 @@ struct PotWarnMatrix : public ButtonMatrix { PotWarnMatrix(Window* parent, const rect_t& rect); void onPress(uint8_t btn_id); bool isActive(uint8_t btn_id); + void setTextWithColor(uint8_t btn_id); private: uint8_t pot_idx[NUM_POTS + NUM_SLIDERS]; }; @@ -93,6 +95,7 @@ struct CenterBeepsMatrix : public ButtonMatrix { CenterBeepsMatrix(Window* parent, const rect_t& rect); void onPress(uint8_t btn_id); bool isActive(uint8_t btn_id); + void setTextWithColor(uint8_t btn_id); private: uint8_t ana_idx[NUM_STICKS + NUM_POTS + NUM_SLIDERS]; }; @@ -175,16 +178,16 @@ SwitchWarnMatrix::SwitchWarnMatrix(Window* parent, const rect_t& r) : } initBtnMap(4, btn_cnt); + update(); uint8_t btn_id = 0; for (uint8_t i = 0; i < NUM_SWITCHES; i++) { if (SWITCH_EXISTS(i)) { - std::string txt = switchWarninglabel(i); - setText(btn_id, txt.c_str()); + lv_btnmatrix_set_btn_ctrl(lvobj, btn_id, LV_BTNMATRIX_CTRL_RECOLOR); + setTextWithColor(i); btn_id++; } } - update(); lv_obj_set_width(lvobj, LV_DPI_DEF * 2); @@ -203,6 +206,11 @@ SwitchWarnMatrix::SwitchWarnMatrix(Window* parent, const rect_t& r) : lv_obj_remove_style(lvobj, nullptr, LV_PART_MAIN | LV_STATE_EDITED); } +void SwitchWarnMatrix::setTextWithColor(uint8_t btn_id) +{ + setText(btn_id, makeRecolor(switchWarninglabel(sw_idx[btn_id]), isActive(btn_id) ? COLOR_THEME_PRIMARY1 : COLOR_THEME_SECONDARY1).c_str()); +} + void SwitchWarnMatrix::onPress(uint8_t btn_id) { if (btn_id >= NUM_SWITCHES) return; @@ -219,8 +227,7 @@ void SwitchWarnMatrix::onPress(uint8_t btn_id) SET_DIRTY(); // TODO: save state in object - std::string txt = switchWarninglabel(sw); - setText(btn_id, txt.c_str()); + setTextWithColor(sw); } bool SwitchWarnMatrix::isActive(uint8_t btn_id) @@ -249,21 +256,23 @@ PotWarnMatrix::PotWarnMatrix(Window* parent, const rect_t& r) : } initBtnMap(3, btn_cnt); + update(); uint8_t btn_id = 0; for (uint16_t i = POT_FIRST; i <= POT_LAST; i++) { if ((IS_POT(i) || IS_POT_MULTIPOS(i)) && IS_POT_AVAILABLE(i)) { - setText(btn_id, STR_VSRCRAW[i + 1]); + lv_btnmatrix_set_btn_ctrl(lvobj, btn_id, LV_BTNMATRIX_CTRL_RECOLOR); + setTextWithColor(btn_id); btn_id++; } } for (int8_t i = SLIDER_FIRST; i <= SLIDER_LAST; i++) { if (IS_SLIDER(i)) { - setText(btn_id, STR_VSRCRAW[i + 1]); + lv_btnmatrix_set_btn_ctrl(lvobj, btn_id, LV_BTNMATRIX_CTRL_RECOLOR); + setTextWithColor(btn_id); btn_id++; } } - update(); lv_obj_set_width(lvobj, (LV_DPI_DEF * 3) / 2); @@ -282,6 +291,11 @@ PotWarnMatrix::PotWarnMatrix(Window* parent, const rect_t& r) : lv_obj_remove_style(lvobj, nullptr, LV_PART_MAIN | LV_STATE_EDITED); } +void PotWarnMatrix::setTextWithColor(uint8_t btn_id) +{ + setText(btn_id, makeRecolor(STR_VSRCRAW[pot_idx[btn_id] + POT_FIRST + 1], isActive(btn_id) ? COLOR_THEME_PRIMARY1 : COLOR_THEME_SECONDARY1).c_str()); +} + void PotWarnMatrix::onPress(uint8_t btn_id) { if (btn_id >= NUM_POTS + NUM_SLIDERS) return; @@ -292,6 +306,7 @@ void PotWarnMatrix::onPress(uint8_t btn_id) (g_model.potsWarnEnabled & (1 << pot))) { SAVE_POT_POSITION(pot); } + setTextWithColor(btn_id); SET_DIRTY(); } @@ -315,15 +330,16 @@ CenterBeepsMatrix::CenterBeepsMatrix(Window* parent, const rect_t& r) : } initBtnMap(4, btn_cnt); + update(); uint8_t btn_id = 0; for (uint8_t i = 0; i < NUM_STICKS + NUM_POTS + NUM_SLIDERS; i++) { if (i < NUM_STICKS || (IS_POT_SLIDER_AVAILABLE(i) && !IS_POT_MULTIPOS(i))) { - setText(btn_id, STR_RETA123[i]); + lv_btnmatrix_set_btn_ctrl(lvobj, btn_id, LV_BTNMATRIX_CTRL_RECOLOR); + setTextWithColor(btn_id); btn_id++; } } - update(); lv_obj_set_width(lvobj, (3 * LV_DPI_DEF) / 2); @@ -342,11 +358,17 @@ CenterBeepsMatrix::CenterBeepsMatrix(Window* parent, const rect_t& r) : lv_obj_remove_style(lvobj, nullptr, LV_PART_MAIN | LV_STATE_EDITED); } +void CenterBeepsMatrix::setTextWithColor(uint8_t btn_id) +{ + setText(btn_id, makeRecolor(STR_RETA123[ana_idx[btn_id]], isActive(btn_id) ? COLOR_THEME_PRIMARY1 : COLOR_THEME_SECONDARY1).c_str()); +} + void CenterBeepsMatrix::onPress(uint8_t btn_id) { if (btn_id >= NUM_STICKS + NUM_POTS + NUM_SLIDERS) return; uint8_t i = ana_idx[btn_id]; BFBIT_FLIP(g_model.beepANACenter, bfBit(i)); + setTextWithColor(btn_id); SET_DIRTY(); }