From 75a9f14a366fc64a9932df448e18ff279b3c8c5a Mon Sep 17 00:00:00 2001 From: philmoz Date: Mon, 1 Dec 2025 14:47:36 +1100 Subject: [PATCH] fix(color): various minor UI issues (#6840) --- radio/src/gui/colorlcd/libui/etx_lv_theme.h | 6 + .../gui/colorlcd/libui/list_line_button.cpp | 51 +++++-- .../src/gui/colorlcd/libui/list_line_button.h | 15 ++- .../colorlcd/mainview/datastructs_screen.h | 4 +- radio/src/gui/colorlcd/model/input_edit.cpp | 127 ++++++++---------- radio/src/gui/colorlcd/model/input_edit.h | 9 +- radio/src/gui/colorlcd/model/model_mixes.cpp | 2 + 7 files changed, 122 insertions(+), 92 deletions(-) diff --git a/radio/src/gui/colorlcd/libui/etx_lv_theme.h b/radio/src/gui/colorlcd/libui/etx_lv_theme.h index 1b6016f97..c1546ee01 100644 --- a/radio/src/gui/colorlcd/libui/etx_lv_theme.h +++ b/radio/src/gui/colorlcd/libui/etx_lv_theme.h @@ -45,8 +45,14 @@ class Window; #if PORTRAIT || LCD_W == 320 #define NARROW_LAYOUT true + #define WIDE_LAYOUT false #else #define NARROW_LAYOUT false + #if LCD_W >= 800 + #define WIDE_LAYOUT true + #else + #define WIDE_LAYOUT false + #endif #endif #if LANDSCAPE diff --git a/radio/src/gui/colorlcd/libui/list_line_button.cpp b/radio/src/gui/colorlcd/libui/list_line_button.cpp index 46447f940..7cc260143 100644 --- a/radio/src/gui/colorlcd/libui/list_line_button.cpp +++ b/radio/src/gui/colorlcd/libui/list_line_button.cpp @@ -140,9 +140,7 @@ void InputMixButtonBase::setFlightModes(uint16_t modes) free(fm_buffer); fm_canvas = nullptr; fm_buffer = nullptr; -#if NARROW_LAYOUT - setHeight(ListLineButton::BTN_H); -#endif + updateHeight(); return; } @@ -152,13 +150,11 @@ void InputMixButtonBase::setFlightModes(uint16_t modes) lv_canvas_set_buffer(fm_canvas, fm_buffer, FM_CANVAS_WIDTH, FM_CANVAS_HEIGHT, LV_IMG_CF_ALPHA_8BIT); lv_obj_set_pos(fm_canvas, FM_X, FM_Y); -#if NARROW_LAYOUT - setHeight(ListLineButton::BTN_H + FM_CANVAS_HEIGHT + 2); -#endif - lv_obj_set_style_img_recolor(fm_canvas, makeLvColor(COLOR_THEME_SECONDARY1), - 0); - lv_obj_set_style_img_recolor_opa(fm_canvas, LV_OPA_COVER, 0); + lv_obj_set_style_img_recolor(fm_canvas, makeLvColor(COLOR_THEME_SECONDARY1), LV_PART_MAIN); + lv_obj_set_style_img_recolor_opa(fm_canvas, LV_OPA_COVER, LV_PART_MAIN); + lv_obj_set_style_img_recolor(fm_canvas, makeLvColor(COLOR_THEME_PRIMARY1), LV_PART_MAIN | LV_STATE_CHECKED); + lv_obj_set_style_img_recolor_opa(fm_canvas, LV_OPA_COVER, LV_PART_MAIN | LV_STATE_CHECKED); } lv_canvas_fill_bg(fm_canvas, lv_color_black(), LV_OPA_TRANSP); @@ -193,6 +189,34 @@ void InputMixButtonBase::setFlightModes(uint16_t modes) lv_canvas_draw_text(fm_canvas, x, 0, FM_W, &label_dsc, s); x += FM_W; } + + updateHeight(); +} + +void InputMixButtonBase::checkEvents() +{ + ListLineButton::checkEvents(); + if (!_deleted) { + if (fm_canvas) { + bool chkd = lv_obj_get_state(fm_canvas) & LV_STATE_CHECKED; + if (chkd != this->checked()) { + if (chkd) + lv_obj_clear_state(fm_canvas, LV_STATE_CHECKED); + else + lv_obj_add_state(fm_canvas, LV_STATE_CHECKED); + } + } + } +} + +void InputMixButtonBase::updateHeight() +{ +#if NARROW_LAYOUT + coord_t h = ListLineButton::BTN_H; + if (fm_canvas) + h += FM_CANVAS_HEIGHT + PAD_TINY; + setHeight(h); +#endif } static void group_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj) @@ -227,6 +251,7 @@ InputMixGroupBase::InputMixGroupBase(Window* parent, mixsrc_t idx) : padAll(PAD_ZERO); label = etx_label_create(lvobj); + etx_font(label, FONT_XS_INDEX, LV_STATE_USER_1); } void InputMixGroupBase::adjustHeight() @@ -236,6 +261,7 @@ void InputMixGroupBase::adjustHeight() coord_t y = PAD_OUTLINE; for (auto it = lines.cbegin(); it != lines.cend(); ++it) { auto line = *it; + line->updateHeight(); line->updatePos(InputMixButtonBase::LN_X, y); y += line->height() + PAD_OUTLINE; } @@ -274,7 +300,12 @@ bool InputMixGroupBase::removeLine(InputMixButtonBase* line) void InputMixGroupBase::refresh() { - lv_label_set_text(label, getSourceString(idx)); + char* s = getSourceString(idx); + if (getTextWidth(s, 0, FONT(STD)) > InputMixButtonBase::LN_X - PAD_TINY) + lv_obj_add_state(label, LV_STATE_USER_1); + else + lv_obj_clear_state(label, LV_STATE_USER_1); + lv_label_set_text(label, s); } InputMixGroupBase* InputMixPageBase::getGroupBySrc(mixsrc_t src) diff --git a/radio/src/gui/colorlcd/libui/list_line_button.h b/radio/src/gui/colorlcd/libui/list_line_button.h index 6e4847789..677d70fc0 100644 --- a/radio/src/gui/colorlcd/libui/list_line_button.h +++ b/radio/src/gui/colorlcd/libui/list_line_button.h @@ -57,14 +57,21 @@ class InputMixButtonBase : public ListLineButton void setOpts(const char* s); void setFlightModes(uint16_t modes); + void updateHeight(); virtual void updatePos(coord_t x, coord_t y) = 0; virtual void swapLvglGroup(InputMixButtonBase* line2) = 0; + void checkEvents() override; + // total: 90 x 17 static LAYOUT_VAL_SCALED(FM_CANVAS_HEIGHT, 17) static LAYOUT_VAL_SCALED(FM_CANVAS_WIDTH, 90) +#if WIDE_LAYOUT + static LAYOUT_VAL_SCALED(LN_X, 78) +#else static LAYOUT_VAL_SCALED(LN_X, 73) +#endif static constexpr coord_t BTN_W = ListLineButton::GRP_W - LN_X - PAD_BORDER * 2 - PAD_OUTLINE; static constexpr coord_t WGT_X = PAD_TINY; static constexpr coord_t WGT_Y = PAD_TINY; @@ -72,11 +79,15 @@ class InputMixButtonBase : public ListLineButton static LAYOUT_VAL_SCALED(WGT_H, 21) static constexpr coord_t SRC_X = WGT_X + WGT_W + PAD_TINY; static constexpr coord_t SRC_Y = WGT_Y; - static LAYOUT_SIZE_SCALED(SRC_W, 70, 69) +#if WIDE_LAYOUT + static LAYOUT_VAL_SCALED(SRC_W, 80) +#else + static LAYOUT_VAL_SCALED(SRC_W, 72) +#endif static constexpr coord_t SRC_H = WGT_H; static constexpr coord_t OPT_X = SRC_X + SRC_W + PAD_TINY; static constexpr coord_t OPT_Y = WGT_Y; - static LAYOUT_SIZE(OPT_W, BTN_W - PAD_BORDER * 2 - WGT_W - SRC_W - FM_CANVAS_WIDTH - PAD_TINY * 5, LAYOUT_SCALE(99)) + static LAYOUT_SIZE(OPT_W, BTN_W - PAD_BORDER * 2 - WGT_W - SRC_W - FM_CANVAS_WIDTH - PAD_TINY * 5, BTN_W - PAD_BORDER * 2 - WGT_W - SRC_W - PAD_TINY * 4) static constexpr coord_t OPT_H = WGT_H; static LAYOUT_SIZE(FM_X, BTN_W - PAD_BORDER * 2 - PAD_TINY - FM_CANVAS_WIDTH, PAD_LARGE + PAD_SMALL) static LAYOUT_SIZE(FM_Y, (WGT_Y + PAD_TINY), (WGT_Y + WGT_H + PAD_TINY)) diff --git a/radio/src/gui/colorlcd/mainview/datastructs_screen.h b/radio/src/gui/colorlcd/mainview/datastructs_screen.h index aa4014a7b..5b0fdfd2d 100644 --- a/radio/src/gui/colorlcd/mainview/datastructs_screen.h +++ b/radio/src/gui/colorlcd/mainview/datastructs_screen.h @@ -192,8 +192,8 @@ struct CustomScreenData { static LAYOUT_VAL_SCALED(MENU_HEADER_BUTTONS_LEFT, 47) -#if LCD_W == 800 // TODO: handle this better -static constexpr int TOPBAR_ZONE_WIDTH = 102; +#if WIDE_LAYOUT +static LAYOUT_VAL_SCALED(TOPBAR_ZONE_WIDTH, 74) #else static LAYOUT_VAL_SCALED(TOPBAR_ZONE_WIDTH, 70) #endif diff --git a/radio/src/gui/colorlcd/model/input_edit.cpp b/radio/src/gui/colorlcd/model/input_edit.cpp index 39058cb68..341e84042 100644 --- a/radio/src/gui/colorlcd/model/input_edit.cpp +++ b/radio/src/gui/colorlcd/model/input_edit.cpp @@ -33,6 +33,61 @@ #define SET_DIRTY() storageDirty(EE_MODEL) +static const lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(2), + LV_GRID_TEMPLATE_LAST}; +static const lv_coord_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST}; + +class InputEditAdvanced : public Page +{ + public: + InputEditAdvanced(InputEditWindow* parent, uint8_t input_n, uint8_t index) : Page(ICON_MODEL_INPUTS) + { + std::string title2(getSourceString(MIXSRC_FIRST_INPUT + input_n)); + header->setTitle(STR_MENUINPUTS); + header->setTitle2(title2); + + FlexGridLayout grid(col_dsc, row_dsc, PAD_TINY); + body->setFlexLayout(); + + ExpoData* input = expoAddress(index); + + // Side + auto line = body->newLine(grid); + new StaticText(line, rect_t{}, STR_SIDE); + new Choice( + line, rect_t{}, STR_VCURVEFUNC, 1, 3, + [=]() -> int16_t { return 4 - input->mode; }, + [=](int16_t newValue) { + input->mode = 4 - newValue; + parent->previewUpdate(); + SET_DIRTY(); + }); + + // Trim + line = body->newLine(grid); + new StaticText(line, rect_t{}, STR_TRIM); + const auto trimLast = TRIM_OFF + keysGetMaxTrims() - 1; + auto c = new Choice(line, rect_t{}, -TRIM_OFF, trimLast, + GET_VALUE(-input->trimSource), + SET_VALUE(input->trimSource, -newValue)); + + uint16_t srcRaw = input->srcRaw; + c->setAvailableHandler([=](int value) { + return value != TRIM_ON || srcRaw <= MIXSRC_LAST_STICK; + }); + c->setTextHandler([=](int value) -> std::string { + return getTrimSourceLabel(srcRaw, -value); + }); + + // Flight modes + if (modelFMEnabled()) { + line = body->newLine(grid); + new StaticText(line, rect_t{}, STR_FLMODE); + new FMMatrix(line, rect_t{}, input); + } + } +}; + InputEditWindow::InputEditWindow(int8_t input, uint8_t index) : Page(ICON_MODEL_INPUTS), input(input), index(index) { @@ -86,10 +141,6 @@ void InputEditWindow::setTitle() headerSwitchName->setText(getSourceString(MIXSRC_FIRST_INPUT + input)); } -static const lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(2), - LV_GRID_TEMPLATE_LAST}; -static const lv_coord_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST}; - void InputEditWindow::buildBody(Window* form) { FlexGridLayout grid(col_dsc, row_dsc, PAD_TINY); @@ -171,68 +222,12 @@ void InputEditWindow::buildBody(Window* form) line->padAll(PAD_LARGE); auto btn = new TextButton(line, rect_t{}, LV_SYMBOL_SETTINGS, [=]() -> uint8_t { - showAdvanced(); + new InputEditAdvanced(this, this->input, index); return 0; }); lv_obj_set_width(btn->getLvObj(), lv_pct(100)); } -void InputEditWindow::showAdvanced() -{ - if (!advWindow) { - advWindow = new Window(this, - {0, EdgeTxStyles::MENU_HEADER_HEIGHT, LCD_W, LCD_H - EdgeTxStyles::MENU_HEADER_HEIGHT}); - advWindow->setWindowFlag(NO_FOCUS); - advWindow->padAll(PAD_SMALL); - - etx_solid_bg(advWindow->getLvObj()); - - FlexGridLayout grid(col_dsc, row_dsc, PAD_TINY); - advWindow->setFlexLayout(); - advWindow->setHeight(LCD_H - EdgeTxStyles::MENU_HEADER_HEIGHT); - - ExpoData* input = expoAddress(index); - - // Side - auto line = advWindow->newLine(grid); - new StaticText(line, rect_t{}, STR_SIDE); - new Choice( - line, rect_t{}, STR_VCURVEFUNC, 1, 3, - [=]() -> int16_t { return 4 - input->mode; }, - [=](int16_t newValue) { - input->mode = 4 - newValue; - updatePreview = true; - SET_DIRTY(); - }); - - // Trim - line = advWindow->newLine(grid); - new StaticText(line, rect_t{}, STR_TRIM); - const auto trimLast = TRIM_OFF + keysGetMaxTrims() - 1; - auto c = new Choice(line, rect_t{}, -TRIM_OFF, trimLast, - GET_VALUE(-input->trimSource), - SET_VALUE(input->trimSource, -newValue)); - - uint16_t srcRaw = input->srcRaw; - c->setAvailableHandler([=](int value) { - return value != TRIM_ON || srcRaw <= MIXSRC_LAST_STICK; - }); - c->setTextHandler([=](int value) -> std::string { - return getTrimSourceLabel(srcRaw, -value); - }); - - // Flight modes - if (modelFMEnabled()) { - line = advWindow->newLine(grid); - new StaticText(line, rect_t{}, STR_FLMODE); - new FMMatrix(line, rect_t{}, input); - } - } - - advWindow->show(); - advEdit = true; -} - void InputEditWindow::checkEvents() { ExpoData* input = expoAddress(index); @@ -295,13 +290,3 @@ void InputEditWindow::checkEvents() Page::checkEvents(); } - -void InputEditWindow::onCancel() -{ - if (advEdit) { - advEdit = false; - advWindow->hide(); - } else { - Page::onCancel(); - } -} diff --git a/radio/src/gui/colorlcd/model/input_edit.h b/radio/src/gui/colorlcd/model/input_edit.h index e46c8087b..b32a2898c 100644 --- a/radio/src/gui/colorlcd/model/input_edit.h +++ b/radio/src/gui/colorlcd/model/input_edit.h @@ -25,13 +25,13 @@ #include "curve.h" #include "choice.h" -struct ExpoData; - class InputEditWindow : public Page { public: InputEditWindow(int8_t input, uint8_t index); + void previewUpdate() { updatePreview = true; } + static LAYOUT_ORIENTATION_SCALED(INPUT_EDIT_CURVE_WIDTH, 138, 176) static LAYOUT_ORIENTATION(INPUT_EDIT_CURVE_HEIGHT, INPUT_EDIT_CURVE_WIDTH, LAYOUT_SCALE(132)) @@ -45,14 +45,9 @@ class InputEditWindow : public Page getvalue_t lastCurveVal = 0; uint8_t lastActiveIndex = 255; StaticText * headerSwitchName = nullptr; - Window* advWindow = nullptr; - bool advEdit = false; void setTitle(); void buildBody(Window *window); - void showAdvanced(); - - void onCancel() override; void checkEvents() override; }; diff --git a/radio/src/gui/colorlcd/model/model_mixes.cpp b/radio/src/gui/colorlcd/model/model_mixes.cpp index 8e301ef59..8a7df44df 100644 --- a/radio/src/gui/colorlcd/model/model_mixes.cpp +++ b/radio/src/gui/colorlcd/model/model_mixes.cpp @@ -90,6 +90,7 @@ class MixLineButton : public InputMixButtonBase void delayedInit() override { refresh(); + ((InputMixGroupBase*)parent)->adjustHeight(); } void refresh() override @@ -212,6 +213,7 @@ class MixGroup : public InputMixGroupBase coord_t y = monitorVisible ? CHNUM_Y : PAD_OUTLINE; for (auto it = lines.cbegin(); it != lines.cend(); ++it) { auto line = *it; + line->updateHeight(); line->updatePos(InputMixButtonBase::LN_X, y); y += line->height() + PAD_OUTLINE; }