diff --git a/radio/src/gui/colorlcd/model_logical_switches.cpp b/radio/src/gui/colorlcd/model_logical_switches.cpp index 647588b7321..92e0c3f88ee 100644 --- a/radio/src/gui/colorlcd/model_logical_switches.cpp +++ b/radio/src/gui/colorlcd/model_logical_switches.cpp @@ -268,13 +268,6 @@ void getsEdgeDelayParam(char* s, LogicalSwitchData * ls) ); } -void putsEdgeDelayParam(BitmapBuffer * dc, coord_t x, coord_t y, LogicalSwitchData * ls, LcdFlags flags = 0) -{ - char s[20]; - getsEdgeDelayParam(s, ls); - dc->drawText(x, y, s, flags); -} - #if LCD_W > LCD_H // Landscape #define TXT_ALIGN LV_GRID_ALIGN_CENTER diff --git a/radio/src/gui/colorlcd/view_logical_switches.cpp b/radio/src/gui/colorlcd/view_logical_switches.cpp index 122fe7fe6ad..c7b72cc5e26 100644 --- a/radio/src/gui/colorlcd/view_logical_switches.cpp +++ b/radio/src/gui/colorlcd/view_logical_switches.cpp @@ -21,20 +21,180 @@ #include "opentx.h" #include "view_logical_switches.h" -#include "gridlayout.h" - -#include #if LCD_W > LCD_H // Landscape - #define BTN_MATRIX_COL 8 + +#define BTN_MATRIX_COL 8 +#define BTN_HEIGHT 20 +#define FOOTER_HEIGHT 20 +#define DURSW_ROW 0 +#define DURSW_COL 3 + +// Switch grid +static const lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), + LV_GRID_TEMPLATE_LAST}; + +// Footer grid +static const lv_coord_t f_col_dsc[] = {60, LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), 50, 50, + LV_GRID_TEMPLATE_LAST}; + #else // Portrait - #define BTN_MATRIX_COL 4 + +#define BTN_MATRIX_COL 4 +#define BTN_HEIGHT 21 +#define FOOTER_HEIGHT 40 +#define DURSW_ROW 1 +#define DURSW_COL 2 + +static const lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), + LV_GRID_TEMPLATE_LAST}; + +// Footer grid +static const lv_coord_t f_col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), + LV_GRID_TEMPLATE_LAST}; + #endif +static const lv_coord_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_CONTENT, + LV_GRID_TEMPLATE_LAST}; + +void getsEdgeDelayParam(char* s, LogicalSwitchData * ls); + +class LogicalSwitchDisplayFooter : public Window +{ + public: + explicit LogicalSwitchDisplayFooter(Window* parent, rect_t rect) : + Window(parent, rect, OPAQUE) + { + padAll(0); + padLeft(4); + padRight(4); + lv_obj_set_style_bg_color(lvobj, makeLvColor(COLOR_THEME_SECONDARY1), 0); + + lv_obj_set_layout(lvobj, LV_LAYOUT_GRID); + lv_obj_set_grid_dsc_array(lvobj, f_col_dsc, row_dsc); + lv_obj_set_style_pad_row(lvobj, 0, 0); + lv_obj_set_style_pad_column(lvobj, 2, 0); + + lsFunc = lv_label_create(lvobj); + lv_obj_set_style_text_align(lsFunc, LV_TEXT_ALIGN_LEFT, 0); + lv_obj_set_grid_cell(lsFunc, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 0, 1); + lv_obj_set_style_text_color(lsFunc, makeLvColor(COLOR_THEME_PRIMARY2), 0); + + lsV1 = lv_label_create(lvobj); + lv_obj_set_style_text_align(lsV1, LV_TEXT_ALIGN_LEFT, 0); + lv_obj_set_grid_cell(lsV1, LV_GRID_ALIGN_STRETCH, 1, 1, LV_GRID_ALIGN_CENTER, 0, 1); + lv_obj_set_style_text_color(lsV1, makeLvColor(COLOR_THEME_PRIMARY2), 0); + + lsV2 = lv_label_create(lvobj); + lv_obj_set_style_text_align(lsV2, LV_TEXT_ALIGN_LEFT, 0); + lv_obj_set_grid_cell(lsV2, LV_GRID_ALIGN_STRETCH, 2, 1, LV_GRID_ALIGN_CENTER, 0, 1); + lv_obj_set_style_text_color(lsV2, makeLvColor(COLOR_THEME_PRIMARY2), 0); + + lsAnd = lv_label_create(lvobj); + lv_obj_set_style_text_align(lsAnd, LV_TEXT_ALIGN_LEFT, 0); + lv_obj_set_grid_cell(lsAnd, LV_GRID_ALIGN_STRETCH, 3, 1, LV_GRID_ALIGN_CENTER, 0, 1); + lv_obj_set_style_text_color(lsAnd, makeLvColor(COLOR_THEME_PRIMARY2), 0); + + lsDuration = lv_label_create(lvobj); + lv_obj_set_style_text_align(lsDuration, LV_TEXT_ALIGN_LEFT, 0); + lv_obj_set_grid_cell(lsDuration, LV_GRID_ALIGN_STRETCH, DURSW_COL, 1, LV_GRID_ALIGN_CENTER, DURSW_ROW, 1); + lv_obj_set_style_text_color(lsDuration, makeLvColor(COLOR_THEME_PRIMARY2), 0); + + lsDelay = lv_label_create(lvobj); + lv_obj_set_style_text_align(lsDelay, LV_TEXT_ALIGN_LEFT, 0); + lv_obj_set_grid_cell(lsDelay, LV_GRID_ALIGN_STRETCH, DURSW_COL+1, 1, LV_GRID_ALIGN_CENTER, DURSW_ROW, 1); + lv_obj_set_style_text_color(lsDelay, makeLvColor(COLOR_THEME_PRIMARY2), 0); + + lv_obj_update_layout(parent->getLvObj()); + + refresh(); + } + + void refresh() + { + LogicalSwitchData* ls = lswAddress(lsIndex); + uint8_t lsFamily = lswFamily(ls->func); + + char s[20]; + + lv_label_set_text(lsFunc, STR_VCSWFUNC[ls->func]); + + // CSW params - V1 + switch (lsFamily) { + case LS_FAMILY_BOOL: + case LS_FAMILY_STICKY: + case LS_FAMILY_EDGE: + lv_label_set_text(lsV1, getSwitchPositionName(ls->v1)); + break; + case LS_FAMILY_TIMER: + lv_label_set_text(lsV1, formatNumberAsString(lswTimerValue(ls->v1), PREC1, 0, nullptr, "s").c_str()); + break; + default: + lv_label_set_text(lsV1, getSourceString(ls->v1)); + break; + } + + // CSW params - V2 + strcat(s, " "); + switch (lsFamily) { + case LS_FAMILY_BOOL: + case LS_FAMILY_STICKY: + lv_label_set_text(lsV2, getSwitchPositionName(ls->v2)); + break; + case LS_FAMILY_EDGE: + getsEdgeDelayParam(s, ls); + lv_label_set_text(lsV2, s); + break; + case LS_FAMILY_TIMER: + lv_label_set_text(lsV2, formatNumberAsString(lswTimerValue(ls->v2), PREC1, 0, nullptr, "s").c_str()); + break; + case LS_FAMILY_COMP: + lv_label_set_text(lsV2, getSourceString(ls->v2)); + break; + default: + lv_label_set_text(lsV2, getSourceCustomValueString(ls->v1, (ls->v1 <= MIXSRC_LAST_CH ? calc100toRESX(ls->v2) : ls->v2), 0)); + break; + } + + // AND switch + lv_label_set_text(lsAnd, getSwitchPositionName(ls->andsw)); + + // CSW duration + if (ls->duration > 0) { + lv_label_set_text(lsDuration, formatNumberAsString(ls->duration, PREC1, 0, nullptr, "s").c_str()); + } else { + lv_label_set_text(lsDuration, ""); + } + + // CSW delay + if (lsFamily != LS_FAMILY_EDGE && ls->delay > 0) { + lv_label_set_text(lsDelay, formatNumberAsString(ls->delay, PREC1, 0, nullptr, "s").c_str()); + } else { + lv_label_set_text(lsDelay, ""); + } + } + + void setIndex(unsigned value) + { + lsIndex = value; + refresh(); + } + + protected: + unsigned lsIndex = 0; + lv_obj_t* lsFunc = nullptr; + lv_obj_t* lsV1 = nullptr; + lv_obj_t* lsV2 = nullptr; + lv_obj_t* lsAnd = nullptr; + lv_obj_t* lsDuration = nullptr; + lv_obj_t* lsDelay = nullptr; +}; + class LogicalSwitchDisplayButton : public TextButton { public: - LogicalSwitchDisplayButton(FormGroup* parent, const rect_t& rect, + LogicalSwitchDisplayButton(Window* parent, const rect_t& rect, std::string text, unsigned index) : TextButton(parent, rect, std::move(text), nullptr, OPAQUE), index(index) { @@ -62,34 +222,52 @@ class LogicalSwitchDisplayButton : public TextButton void LogicalSwitchesViewPage::build(FormWindow * window) { - constexpr coord_t LSW_VIEW_FOOTER_HEIGHT = 20; - FormGridLayout grid; - grid.spacer(PAGE_PADDING); - grid.setLabelWidth(BTN_MATRIX_COL); window->padAll(0); + auto form = new FormWindow(window, rect_t{}); + form->setFlexLayout(); + form->padAll(0); + form->padTop(3); + + FlexGridLayout grid(col_dsc, row_dsc, 2); + FormWindow::Line* line; + // Footer - footer = new LogicalSwitchDisplayFooter( - window, {0, window->height() - LSW_VIEW_FOOTER_HEIGHT, window->width(), - LSW_VIEW_FOOTER_HEIGHT}); + footer = new LogicalSwitchDisplayFooter(window, {0, window->height() - FOOTER_HEIGHT, window->width(), FOOTER_HEIGHT}); // LSW table - std::string lsString("LS64"); - lcdColorTable[CUSTOM_COLOR_INDEX] = RGB(160, 160, 160); + std::string lsString("L64"); for (uint8_t i = 0; i < MAX_LOGICAL_SWITCHES; i++) { + if ((i % BTN_MATRIX_COL) == 0) { + line = form->newLine(&grid); + line->padAll(1); + line->padLeft(4); + line->padRight(4); + } + + LogicalSwitchData* ls = lswAddress(i); + bool isActive = (ls->func != LS_FUNC_NONE); strAppendSigned(&lsString[1], i + 1, 2); - auto button = new LogicalSwitchDisplayButton( - window, grid.getFieldSlot(BTN_MATRIX_COL, i % BTN_MATRIX_COL), lsString, i); - - button->setFocusHandler([=](bool focus) { - if (focus) { - footer->setIndex(i); - footer->invalidate(); - } - return 0; - }); - if ((i + 1) % BTN_MATRIX_COL == 0) grid.nextLine(); + if (isActive) { + auto button = new LogicalSwitchDisplayButton(line, rect_t{0, 0, 0, BTN_HEIGHT}, lsString, i); + lv_obj_set_grid_cell(button->getLvObj(), LV_GRID_ALIGN_STRETCH, i % BTN_MATRIX_COL, 1, LV_GRID_ALIGN_CENTER, 0, 1); + + button->setFocusHandler([=](bool focus) { + if (focus) { + footer->setIndex(i); + footer->invalidate(); + } + return 0; + }); + } else { + auto lbl = lv_label_create(line->getLvObj()); + lv_obj_set_height(lbl, BTN_HEIGHT); + lv_obj_set_style_text_color(lbl, makeLvColor(COLOR_THEME_DISABLED), 0); + lv_obj_set_style_text_align(lbl, LV_TEXT_ALIGN_CENTER, 0); + lv_obj_set_grid_cell(lbl, LV_GRID_ALIGN_STRETCH, i % BTN_MATRIX_COL, 1, LV_GRID_ALIGN_CENTER, 0, 1); + lv_label_set_text(lbl, lsString.c_str()); + } } } diff --git a/radio/src/gui/colorlcd/view_logical_switches.h b/radio/src/gui/colorlcd/view_logical_switches.h index 74836c8e14b..aaa76d200f3 100644 --- a/radio/src/gui/colorlcd/view_logical_switches.h +++ b/radio/src/gui/colorlcd/view_logical_switches.h @@ -25,82 +25,7 @@ #include "tabsgroup.h" #include "switches.h" -constexpr coord_t CSW_1ST_COLUMN = 50; -constexpr coord_t CSW_2ND_COLUMN = 120; -constexpr coord_t CSW_3RD_COLUMN = 200; -constexpr coord_t CSW_4TH_COLUMN = 280; -constexpr coord_t CSW_5TH_COLUMN = 340; -constexpr coord_t CSW_6TH_COLUMN = 390; - -void putsEdgeDelayParam(BitmapBuffer* dc, coord_t x, coord_t y, - LogicalSwitchData* ls, LcdFlags flags); - -class LogicalSwitchDisplayFooter : public Window -{ - public: - explicit LogicalSwitchDisplayFooter(Window* parent, rect_t rect) : - Window(parent, rect, OPAQUE), rect(rect) - { - } - - void setIndex(unsigned value) { index = value; } - - void paint(BitmapBuffer* dc) override - { - dc->clear(COLOR_THEME_SECONDARY1); - LogicalSwitchData* cs = lswAddress(index); - - LcdFlags textColor = COLOR_THEME_PRIMARY2; - dc->drawTextAtIndex(10, 1, STR_VCSWFUNC, cs->func, textColor); - // CSW params - unsigned int cstate = lswFamily(cs->func); - - if (cstate == LS_FAMILY_BOOL || cstate == LS_FAMILY_STICKY) { - drawSwitch(dc, CSW_2ND_COLUMN, 1, cs->v1, textColor); - drawSwitch(dc, CSW_3RD_COLUMN, 1, cs->v2, textColor); - } else if (cstate == LS_FAMILY_EDGE) { - drawSwitch(dc, CSW_2ND_COLUMN, 1, cs->v1, textColor); - putsEdgeDelayParam(dc, CSW_3RD_COLUMN, 1, cs, textColor); - } else if (cstate == LS_FAMILY_COMP) { - drawSource(dc, CSW_2ND_COLUMN, 1, cs->v1, textColor); - drawSource(dc, CSW_3RD_COLUMN, 1, cs->v2, textColor); - } else if (cstate == LS_FAMILY_TIMER) { - dc->drawNumber(CSW_2ND_COLUMN, 1, lswTimerValue(cs->v1), - LEFT | PREC1 | textColor); - dc->drawNumber(CSW_3RD_COLUMN, 1, lswTimerValue(cs->v2), - LEFT | PREC1 | textColor); - } else { - drawSource(dc, CSW_2ND_COLUMN, 1, cs->v1, textColor); - drawSourceCustomValue( - dc, CSW_3RD_COLUMN, 1, cs->v1, - cs->v1 <= MIXSRC_LAST_CH ? calc100toRESX(cs->v2) : cs->v2, - LEFT | textColor); - } - - // CSW AND switch - drawSwitch(dc, CSW_4TH_COLUMN, 1, cs->andsw, textColor); - - // CSW duration - if (cs->duration > 0) - dc->drawNumber(CSW_5TH_COLUMN, 1, cs->duration, - PREC1 | LEFT | textColor); - else - dc->drawTextAtIndex(CSW_5TH_COLUMN, 1, STR_MMMINV, 0, textColor); - - // CSW delay - if (cstate == LS_FAMILY_EDGE) { - dc->drawText(CSW_6TH_COLUMN, 1, STR_NA, textColor); - } else if (cs->delay > 0) { - dc->drawNumber(CSW_6TH_COLUMN, 1, cs->delay, PREC1 | LEFT | textColor); - } else { - dc->drawTextAtIndex(CSW_6TH_COLUMN, 1, STR_MMMINV, 0, textColor); - } - } - - protected: - rect_t rect; - unsigned index = 0; -}; +class LogicalSwitchDisplayFooter; class LogicalSwitchesViewPage : public PageTab {