From 2932822e37a331d3c909fee8d587cb54dc6f39d3 Mon Sep 17 00:00:00 2001 From: Peter Feerick Date: Tue, 25 Nov 2025 13:17:06 +1000 Subject: [PATCH] chore(color): support for reverting UI for 2.12 (#6823) Co-authored-by: philmoz --- .../firmwares/edgetx/yaml_generalsettings.cpp | 2 +- companion/src/firmwares/generalsettings.cpp | 4 +- .../src/firmwares/opentx/opentxinterface.cpp | 4 +- .../src/generaledit/generalkeyshortcuts.cpp | 1 - radio/src/datastructs_private.h | 5 + radio/src/datastructs_radio.cpp | 8 +- radio/src/gui/colorlcd/libui/page.cpp | 6 + .../gui/colorlcd/mainview/screen_setup.cpp | 47 ++++- .../src/gui/colorlcd/mainview/screen_setup.h | 13 ++ .../gui/colorlcd/mainview/view_channels.cpp | 7 + .../mainview/view_logical_switches.cpp | 7 + .../colorlcd/mainview/view_logical_switches.h | 2 + .../gui/colorlcd/mainview/view_statistics.cpp | 11 ++ .../gui/colorlcd/mainview/view_statistics.h | 7 +- radio/src/gui/colorlcd/model/mixer_edit.cpp | 2 +- radio/src/gui/colorlcd/model/model_curves.cpp | 3 +- radio/src/gui/colorlcd/model/model_gvars.cpp | 2 +- radio/src/gui/colorlcd/model/model_select.cpp | 10 +- radio/src/gui/colorlcd/model/model_select.h | 1 + radio/src/gui/colorlcd/model/output_edit.cpp | 2 +- .../src/gui/colorlcd/radio/preview_window.cpp | 8 +- radio/src/gui/colorlcd/radio/radio_setup.cpp | 4 + .../src/gui/colorlcd/radio/radio_version.cpp | 6 +- .../gui/colorlcd/setup_menus/pagegroup.cpp | 185 ++++++++++++++++-- .../src/gui/colorlcd/setup_menus/pagegroup.h | 49 +++-- .../gui/colorlcd/setup_menus/quick_menu.cpp | 45 ++++- .../src/gui/colorlcd/setup_menus/quick_menu.h | 36 +++- .../colorlcd/setup_menus/quick_menu_data.cpp | 102 +++++++++- .../gui/colorlcd/setup_menus/quick_menu_def.h | 2 + .../colorlcd/setup_menus/quick_menu_group.cpp | 4 + .../src/gui/colorlcd/themes/theme_manager.cpp | 2 +- radio/src/gui/colorlcd/widgets/timer.cpp | 6 +- .../src/storage/yaml/yaml_datastructs_f16.cpp | 4 +- .../storage/yaml/yaml_datastructs_nb4p.cpp | 4 +- .../storage/yaml/yaml_datastructs_nv14.cpp | 4 +- .../storage/yaml/yaml_datastructs_pa01.cpp | 4 +- .../storage/yaml/yaml_datastructs_pl18.cpp | 4 +- .../storage/yaml/yaml_datastructs_pl18u.cpp | 4 +- .../storage/yaml/yaml_datastructs_st16.cpp | 4 +- .../src/storage/yaml/yaml_datastructs_t15.cpp | 4 +- .../storage/yaml/yaml_datastructs_t15pro.cpp | 4 +- .../storage/yaml/yaml_datastructs_tx15.cpp | 4 +- .../src/storage/yaml/yaml_datastructs_x10.cpp | 4 +- 43 files changed, 537 insertions(+), 100 deletions(-) diff --git a/companion/src/firmwares/edgetx/yaml_generalsettings.cpp b/companion/src/firmwares/edgetx/yaml_generalsettings.cpp index 343d1670e..3280f1580 100644 --- a/companion/src/firmwares/edgetx/yaml_generalsettings.cpp +++ b/companion/src/firmwares/edgetx/yaml_generalsettings.cpp @@ -386,7 +386,7 @@ Node convert::encode(const GeneralSettings& rhs) node["modelCustomScriptsDisabled"] = (int)rhs.modelCustomScriptsDisabled; node["modelTelemetryDisabled"] = (int)rhs.modelTelemetryDisabled; - if (hasColorLcd) { + if (hasColorLcd && VERSION_MAJOR > 2) { for (int i = 0; i < MAX_KEYSHORTCUTS; i += 1) if (rhs.keyShortcuts[i] != GeneralSettings::QM_NONE) node["keyShortcuts"][std::to_string(i)]["shortcut"] = QMPageLut << rhs.keyShortcuts[i]; diff --git a/companion/src/firmwares/generalsettings.cpp b/companion/src/firmwares/generalsettings.cpp index 3b0cbf011..6ffdbe615 100644 --- a/companion/src/firmwares/generalsettings.cpp +++ b/companion/src/firmwares/generalsettings.cpp @@ -1092,9 +1092,9 @@ void GeneralSettings::setDefaultFavorites() void GeneralSettings::setDefaultKeyShortcuts() { keyShortcuts[0] = QM_MODEL_SETUP; // MDL short - keyShortcuts[1] = QM_OPEN_QUICK_MENU; // SYS short + keyShortcuts[1] = (VERSION_MAJOR == 2) ? QM_TOOLS_APPS : QM_OPEN_QUICK_MENU; // SYS short keyShortcuts[2] = QM_UI_SCREEN1; // TELE short keyShortcuts[3] = QM_MANAGE_MODELS; // MDL long - keyShortcuts[4] = QM_TOOLS_APPS; // SYS long + keyShortcuts[4] = (VERSION_MAJOR == 2) ? QM_RADIO_SETUP : QM_TOOLS_APPS; // SYS long keyShortcuts[5] = QM_TOOLS_CHAN_MON; // TELE long } diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp index 4526e971f..9468940a6 100644 --- a/companion/src/firmwares/opentx/opentxinterface.cpp +++ b/companion/src/firmwares/opentx/opentxinterface.cpp @@ -358,9 +358,9 @@ int OpenTxFirmware::getCapability(::Capability capability) return 46; } case QMFavourites: - return Boards::getCapability(board, Board::HasColorLcd) ? MAX_QMFAVOURITES : 0; + return VERSION_MAJOR > 2 && Boards::getCapability(board, Board::HasColorLcd) ? MAX_QMFAVOURITES : 0; case KeyShortcuts: - return Boards::getCapability(board, Board::HasColorLcd) ? MAX_KEYSHORTCUTS : 0; + return VERSION_MAJOR > 2 && Boards::getCapability(board, Board::HasColorLcd) ? MAX_KEYSHORTCUTS : 0; default: return 0; } diff --git a/companion/src/generaledit/generalkeyshortcuts.cpp b/companion/src/generaledit/generalkeyshortcuts.cpp index d881d5be7..e0d71f4be 100644 --- a/companion/src/generaledit/generalkeyshortcuts.cpp +++ b/companion/src/generaledit/generalkeyshortcuts.cpp @@ -85,7 +85,6 @@ GeneralKeysPanel::GeneralKeysPanel(QWidget * parent, GeneralSettings & generalSe GeneralKeysPanel::~GeneralKeysPanel() { - } void GeneralKeysPanel::addLabel(QString text) diff --git a/radio/src/datastructs_private.h b/radio/src/datastructs_private.h index 3b22972bc..c18b936fe 100644 --- a/radio/src/datastructs_private.h +++ b/radio/src/datastructs_private.h @@ -1162,8 +1162,13 @@ PACK(struct RadioData { NOBACKUP(uint8_t pwrOffIfInactive); #if defined(COLORLCD) +#if VERSION_MAJOR == 2 + NOBACKUP(QuickMenuPage keyShortcuts[MAX_KEY_SHORTCUTS] SKIP); + NOBACKUP(QuickMenuPage qmFavorites[MAX_QM_FAVORITES] SKIP); +#else NOBACKUP(QuickMenuPage keyShortcuts[MAX_KEY_SHORTCUTS]); NOBACKUP(QuickMenuPage qmFavorites[MAX_QM_FAVORITES]); +#endif #endif NOBACKUP(uint8_t getBrightness() const diff --git a/radio/src/datastructs_radio.cpp b/radio/src/datastructs_radio.cpp index ab5f51863..30945af16 100644 --- a/radio/src/datastructs_radio.cpp +++ b/radio/src/datastructs_radio.cpp @@ -25,6 +25,7 @@ #include "tasks/mixer_task.h" #if defined(COLORLCD) +#include "quick_menu_def.h" #include "view_main.h" #endif @@ -159,9 +160,14 @@ void RadioData::defaultKeyShortcuts() { setKeyShortcut(EVT_KEY_BREAK(KEY_MODEL), QM_MODEL_SETUP); setKeyShortcut(EVT_KEY_LONG(KEY_MODEL), QM_MANAGE_MODELS); +#if VERSION_MAJOR == 2 + setKeyShortcut(EVT_KEY_BREAK(KEY_SYS), QM_TOOLS_APPS); + setKeyShortcut(EVT_KEY_LONG(KEY_SYS), QM_RADIO_SETUP); +#else setKeyShortcut(EVT_KEY_BREAK(KEY_SYS), QM_OPEN_QUICK_MENU); setKeyShortcut(EVT_KEY_LONG(KEY_SYS), QM_TOOLS_APPS); +#endif setKeyShortcut(EVT_KEY_BREAK(KEY_TELE), QM_UI_SCREEN1); setKeyShortcut(EVT_KEY_LONG(KEY_TELE), QM_TOOLS_CHAN_MON); } -#endif \ No newline at end of file +#endif diff --git a/radio/src/gui/colorlcd/libui/page.cpp b/radio/src/gui/colorlcd/libui/page.cpp index 86baff24f..991e69a07 100644 --- a/radio/src/gui/colorlcd/libui/page.cpp +++ b/radio/src/gui/colorlcd/libui/page.cpp @@ -78,11 +78,17 @@ Page::Page(EdgeTxIcon icon, PaddingSize padding, bool pauseRefresh) : header = new PageHeader(this, icon); +#if VERSION_MAJOR > 2 new HeaderBackIcon(header); +#endif #if defined(HARDWARE_TOUCH) +#if VERSION_MAJOR == 2 + addCustomButton(0, 0, [=]() { onCancel(); }); +#else addCustomButton(0, 0, [=]() { openMenu(); }); addCustomButton(LCD_W - EdgeTxStyles::MENU_HEADER_HEIGHT, 0, [=]() { onCancel(); }); +#endif #endif body = new Window(this, diff --git a/radio/src/gui/colorlcd/mainview/screen_setup.cpp b/radio/src/gui/colorlcd/mainview/screen_setup.cpp index bb7877be0..f1b4ff17e 100644 --- a/radio/src/gui/colorlcd/mainview/screen_setup.cpp +++ b/radio/src/gui/colorlcd/mainview/screen_setup.cpp @@ -186,8 +186,9 @@ void ScreenSetupPage::build(Window* window) #endif btn = new TextButton(line, rect_t{}, STR_SETUP_WIDGETS, [=]() -> uint8_t { + auto idx = customScreenIndex; window->getParent()->deleteLater(); - new SetupWidgetsPage(customScreenIndex); + new SetupWidgetsPage(idx); return 0; }); lv_obj_set_style_grid_cell_y_align(btn->getLvObj(), LV_GRID_ALIGN_CENTER, 0); @@ -274,3 +275,47 @@ void ScreenSetupPage::buildLayoutOptions() } } } + +#if VERSION_MAJOR == 2 +ScreenAddPage::ScreenAddPage(PageDef& pageDef) : PageGroupItem(pageDef) +{ +} + +void ScreenAddPage::build(Window* window) +{ + std::string s = replaceAll(STR_QM_ADD_SCREEN, "\n", " "); + + new TextButton(window, + rect_t{LCD_W / 2 - ADD_TXT_W / 2, window->height() / 2 - EdgeTxStyles::UI_ELEMENT_HEIGHT, ADD_TXT_W, EdgeTxStyles::UI_ELEMENT_HEIGHT}, + s, [this]() -> uint8_t { + int newIdx = 1; + for (; newIdx < MAX_CUSTOM_SCREENS; newIdx += 1) + if (customScreens[newIdx] == nullptr) + break; + + TRACE("Add screen: add screen: newIdx = %d", newIdx); + + auto& screen = customScreens[newIdx]; + + const LayoutFactory* factory = defaultLayout; + if (factory) { + TRACE("Add screen: add screen: factory = %p", factory); + + auto viewMain = ViewMain::instance(); + screen = factory->create(viewMain, newIdx); + viewMain->addMainView(screen, newIdx); + + g_model.setScreenLayoutId(newIdx, factory->getId()); + TRACE("Add screen: add screen: LayoutId = %s", g_model.getScreenLayoutId(newIdx)); + + Layer::getPageGroup()->deleteLater(); + QuickMenu::openPage((QMPage)(QM_UI_SCREEN1 + newIdx)); + + storageDirty(EE_MODEL); + } else { + TRACE("Add screen: factory is NULL"); + } + return 0; + }); +} +#endif diff --git a/radio/src/gui/colorlcd/mainview/screen_setup.h b/radio/src/gui/colorlcd/mainview/screen_setup.h index f70934e74..249cda217 100644 --- a/radio/src/gui/colorlcd/mainview/screen_setup.h +++ b/radio/src/gui/colorlcd/mainview/screen_setup.h @@ -25,6 +25,19 @@ #include "screen_user_interface.h" #include "radio_theme.h" +#if VERSION_MAJOR == 2 +class ScreenAddPage : public PageGroupItem +{ + public: + ScreenAddPage(PageDef& pageDef); + + void build(Window* window) override; + + protected: + static LAYOUT_VAL_SCALED(ADD_TXT_W, 200) +}; +#endif + class ScreenSetupPage : public PageGroupItem { public: diff --git a/radio/src/gui/colorlcd/mainview/view_channels.cpp b/radio/src/gui/colorlcd/mainview/view_channels.cpp index b808afbca..bfdb180dd 100644 --- a/radio/src/gui/colorlcd/mainview/view_channels.cpp +++ b/radio/src/gui/colorlcd/mainview/view_channels.cpp @@ -25,6 +25,9 @@ #include "libopenui.h" #include "model_select.h" #include "edgetx.h" +#if VERSION_MAJOR == 2 +#include "view_logical_switches.h" +#endif // TODO: find better way to detect only used channels! #define ALL_CHANNELS true @@ -161,5 +164,9 @@ ChannelsViewMenu::ChannelsViewMenu() : i = end; } +#if VERSION_MAJOR == 2 + addTab(new LogicalSwitchesViewPage()); +#endif + if (pages < 2) hidePageButtons(); } diff --git a/radio/src/gui/colorlcd/mainview/view_logical_switches.cpp b/radio/src/gui/colorlcd/mainview/view_logical_switches.cpp index 9e9dcfb09..ee166f130 100644 --- a/radio/src/gui/colorlcd/mainview/view_logical_switches.cpp +++ b/radio/src/gui/colorlcd/mainview/view_logical_switches.cpp @@ -24,6 +24,7 @@ #include "edgetx.h" #include "switches.h" #include "etx_lv_theme.h" +#include "quick_menu.h" #if PORTRAIT @@ -234,6 +235,12 @@ class LogicalSwitchDisplayButton : public TextButton bool value = false; }; +LogicalSwitchesViewPage::LogicalSwitchesViewPage() : + PageGroupItem(STR_MONITOR_SWITCHES, QM_TOOLS_LS_MON) +{ + setIcon(ICON_MONITOR_LOGICAL_SWITCHES); +} + LogicalSwitchesViewPage::LogicalSwitchesViewPage(PageDef& pageDef) : PageGroupItem(pageDef) { diff --git a/radio/src/gui/colorlcd/mainview/view_logical_switches.h b/radio/src/gui/colorlcd/mainview/view_logical_switches.h index 4a6c69b10..7f24251b7 100644 --- a/radio/src/gui/colorlcd/mainview/view_logical_switches.h +++ b/radio/src/gui/colorlcd/mainview/view_logical_switches.h @@ -28,6 +28,7 @@ class LogicalSwitchDisplayFooter; class LogicalSwitchesViewPage : public PageGroupItem { public: + LogicalSwitchesViewPage(); LogicalSwitchesViewPage(PageDef& pageDef); static LAYOUT_ORIENTATION_SCALED(FOOTER_HEIGHT, 20, 40) @@ -36,5 +37,6 @@ class LogicalSwitchesViewPage : public PageGroupItem protected: void build(Window* window) override; + LogicalSwitchDisplayFooter* footer = nullptr; }; diff --git a/radio/src/gui/colorlcd/mainview/view_statistics.cpp b/radio/src/gui/colorlcd/mainview/view_statistics.cpp index f396f796e..2ddc0b900 100644 --- a/radio/src/gui/colorlcd/mainview/view_statistics.cpp +++ b/radio/src/gui/colorlcd/mainview/view_statistics.cpp @@ -27,6 +27,7 @@ #include "tasks/mixer_task.h" #include "mixer_scheduler.h" #include "lua/lua_states.h" +#include "quick_menu.h" static const lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), @@ -128,6 +129,11 @@ class ThrottleCurveWindow : public Window int16_t graphSize = 0; }; +StatisticsViewPage::StatisticsViewPage(PageDef& pageDef) : + PageGroupItem(pageDef) +{ +} + void StatisticsViewPage::build(Window* window) { window->setFlexLayout(LV_FLEX_FLOW_COLUMN, PAD_ZERO); @@ -201,6 +207,11 @@ void StatisticsViewPage::build(Window* window) LV_GRID_ALIGN_START, 0, 1); } +DebugViewPage::DebugViewPage(PageDef& pageDef) : + PageGroupItem(pageDef) +{ +} + void DebugViewPage::build(Window* window) { window->setFlexLayout(LV_FLEX_FLOW_COLUMN, PAD_ZERO); diff --git a/radio/src/gui/colorlcd/mainview/view_statistics.h b/radio/src/gui/colorlcd/mainview/view_statistics.h index 784a1bda9..7e1482d9a 100644 --- a/radio/src/gui/colorlcd/mainview/view_statistics.h +++ b/radio/src/gui/colorlcd/mainview/view_statistics.h @@ -26,10 +26,7 @@ class StatisticsViewPage : public PageGroupItem { public: - StatisticsViewPage(PageDef& pageDef) : - PageGroupItem(pageDef, PAD_ZERO) - { - } + StatisticsViewPage(PageDef& pageDef); protected: void build(Window* window) override; @@ -38,7 +35,7 @@ class StatisticsViewPage : public PageGroupItem class DebugViewPage : public PageGroupItem { public: - DebugViewPage(PageDef& pageDef) : PageGroupItem(pageDef, PAD_ZERO) {} + DebugViewPage(PageDef& pageDef); protected: void build(Window* window) override; diff --git a/radio/src/gui/colorlcd/model/mixer_edit.cpp b/radio/src/gui/colorlcd/model/mixer_edit.cpp index c80458011..11c3187de 100644 --- a/radio/src/gui/colorlcd/model/mixer_edit.cpp +++ b/radio/src/gui/colorlcd/model/mixer_edit.cpp @@ -71,7 +71,7 @@ void MixEditWindow::buildHeader(Window *window) new MixerEditStatusBar( window, - {window->getRect().w - MIX_STATUS_BAR_WIDTH - PageGroup::PAGE_TOP_BAR_H, 0, + {window->getRect().w - MIX_STATUS_BAR_WIDTH - PageGroup::PAGE_GROUP_BACK_BTN_W, 0, MIX_STATUS_BAR_WIDTH, EdgeTxStyles::MENU_HEADER_HEIGHT}, channel); } diff --git a/radio/src/gui/colorlcd/model/model_curves.cpp b/radio/src/gui/colorlcd/model/model_curves.cpp index 17f13b716..973d1b282 100644 --- a/radio/src/gui/colorlcd/model/model_curves.cpp +++ b/radio/src/gui/colorlcd/model/model_curves.cpp @@ -51,7 +51,8 @@ class CurveButton : public Button hdrLeft = new StaticIcon(this, 0, 0, ICON_ROUND_TITLE_LEFT, COLOR_THEME_SECONDARY2_INDEX); - hdrRight = new StaticIcon(this, width() - PAD_LARGE, 0, + auto mask = getBuiltinIcon(ICON_ROUND_TITLE_RIGHT); + hdrRight = new StaticIcon(this, width() - mask->width - PAD_BORDER * 2, 0, ICON_ROUND_TITLE_RIGHT, COLOR_THEME_SECONDARY2_INDEX); diff --git a/radio/src/gui/colorlcd/model/model_gvars.cpp b/radio/src/gui/colorlcd/model/model_gvars.cpp index f710e76e6..a9def005b 100644 --- a/radio/src/gui/colorlcd/model/model_gvars.cpp +++ b/radio/src/gui/colorlcd/model/model_gvars.cpp @@ -534,7 +534,7 @@ void ModelGVarsPage::build(Window* window) if (modelFMEnabled()) { window->padTop(PAD_OUTLINE); hdr = new GVarHeader(window->getParent()); - lv_obj_set_pos(hdr->getLvObj(), 0, PageGroup::PAGE_TOP_BAR_H); + lv_obj_set_pos(hdr->getLvObj(), 0, PageGroup::PAGE_GROUP_BODY_Y); yo = GVarHeader::HDR_H; } diff --git a/radio/src/gui/colorlcd/model/model_select.cpp b/radio/src/gui/colorlcd/model/model_select.cpp index 0866ff5cf..18f10f313 100644 --- a/radio/src/gui/colorlcd/model/model_select.cpp +++ b/radio/src/gui/colorlcd/model/model_select.cpp @@ -39,11 +39,11 @@ struct ModelButtonLayout { uint16_t columns; }; -static constexpr coord_t L0_W = (ModelLabelsWindow::MDLS_W - PAD_BORDER * 3) / 2; +static constexpr coord_t L0_W = (ModelLabelsWindow::MDLS_W - PAD_OUTLINE * 3) / 2; static constexpr coord_t L0_H = L0_W * 11 / 20; -static constexpr coord_t L1_W = (ModelLabelsWindow::MDLS_W - PAD_BORDER * 4) / 3; +static constexpr coord_t L1_W = (ModelLabelsWindow::MDLS_W - PAD_OUTLINE * 4) / 3; static constexpr coord_t L1_H = L1_W * 11 / 20; -static constexpr coord_t L3_W = ModelLabelsWindow::MDLS_W - PAD_BORDER * 2; +static constexpr coord_t L3_W = ModelLabelsWindow::MDLS_W - PAD_OUTLINE * 2; ModelButtonLayout modelLayouts[] = { {L0_W, L0_H, true, FONT(STD), 2}, @@ -679,7 +679,7 @@ void ModelLabelsWindow::buildHead(Window *hdr) #if !PORTRAIT // new model button - new TextButton(hdr, {LCD_W - PageGroup::PAGE_TOP_BAR_H - NEW_BTN_W - PAD_LARGE, PAD_MEDIUM, NEW_BTN_W, EdgeTxStyles::UI_ELEMENT_HEIGHT}, STR_NEW, [=]() { + new TextButton(hdr, {LCD_W - PageGroup::PAGE_GROUP_BACK_BTN_W - NEW_BTN_W - PAD_LARGE, PAD_MEDIUM, NEW_BTN_W, EdgeTxStyles::UI_ELEMENT_HEIGHT}, STR_NEW, [=]() { auto menu = new Menu(); menu->setTitle(STR_CREATE_NEW); menu->addLine(STR_NEW_MODEL, [=]() { newModel(); }); @@ -687,7 +687,7 @@ void ModelLabelsWindow::buildHead(Window *hdr) return 0; }); - mdlLayout = new ModelLayoutButton(this, LCD_W - PageGroup::PAGE_TOP_BAR_H - LAYOUT_BTN_XO, PAD_MEDIUM, g_eeGeneral.modelSelectLayout, [=]() { + mdlLayout = new ModelLayoutButton(this, LCD_W - PageGroup::PAGE_GROUP_BACK_BTN_W - LAYOUT_BTN_XO, PAD_MEDIUM, g_eeGeneral.modelSelectLayout, [=]() { uint8_t l = mdlLayout->getLayout(); l = (l + 1) & 3; mdlLayout->setLayout(l); diff --git a/radio/src/gui/colorlcd/model/model_select.h b/radio/src/gui/colorlcd/model/model_select.h index f55ef99be..a14b01705 100644 --- a/radio/src/gui/colorlcd/model/model_select.h +++ b/radio/src/gui/colorlcd/model/model_select.h @@ -23,6 +23,7 @@ #include "listbox.h" #include "storage/modelslist.h" +#include "pagegroup.h" #include "page.h" #include "etx_lv_theme.h" diff --git a/radio/src/gui/colorlcd/model/output_edit.cpp b/radio/src/gui/colorlcd/model/output_edit.cpp index 1e85e3d87..5524ed497 100644 --- a/radio/src/gui/colorlcd/model/output_edit.cpp +++ b/radio/src/gui/colorlcd/model/output_edit.cpp @@ -96,7 +96,7 @@ void OutputEditWindow::buildHeader(Window *window) { statusBar = new OutputEditStatusBar( window, - {window->getRect().w - OUTPUT_EDIT_STATUS_BAR_WIDTH - PageGroup::PAGE_TOP_BAR_H, + {window->getRect().w - OUTPUT_EDIT_STATUS_BAR_WIDTH - PageGroup::PAGE_GROUP_BACK_BTN_W, 0, OUTPUT_EDIT_STATUS_BAR_WIDTH, EdgeTxStyles::MENU_HEADER_HEIGHT}, channel); } diff --git a/radio/src/gui/colorlcd/radio/preview_window.cpp b/radio/src/gui/colorlcd/radio/preview_window.cpp index c6a72c244..b1df7c029 100644 --- a/radio/src/gui/colorlcd/radio/preview_window.cpp +++ b/radio/src/gui/colorlcd/radio/preview_window.cpp @@ -179,18 +179,18 @@ PreviewWindow::PreviewWindow(Window *window, rect_t rect, etx_obj_add_style(qmb->getLvObj(), styles->rounded, LV_PART_MAIN); etx_txt_color(qmb->getLvObj(), COLOR_THEME_QM_FG_INDEX, LV_PART_MAIN); etx_solid_bg(qmb->getLvObj(), COLOR_THEME_QM_BG_INDEX, LV_PART_MAIN); - auto iconPtr = new StaticIcon(qmb, (QuickMenuGroup::QM_BUTTON_WIDTH - QuickMenuGroup::QM_ICON_SIZE) / 2, PAD_SMALL, + new StaticIcon(qmb, (QuickMenuGroup::QM_BUTTON_WIDTH - QuickMenuGroup::QM_ICON_SIZE) / 2, PAD_SMALL, ICON_MODEL_SELECT, COLOR_THEME_QM_FG_INDEX); - auto textPtr = new StaticText(qmb, {0, QuickMenuGroup::QM_ICON_SIZE + PAD_TINY * 2, QuickMenuGroup::QM_BUTTON_WIDTH - 1, 0}, + new StaticText(qmb, {0, QuickMenuGroup::QM_ICON_SIZE + PAD_TINY * 2, QuickMenuGroup::QM_BUTTON_WIDTH - 1, 0}, STR_QM_MANAGE_MODELS, COLOR_THEME_QM_FG_INDEX, CENTERED | FONT(XS)); qmb = new Window(qm, {QuickMenuGroup::QM_BUTTON_WIDTH + PAD_SMALL * 2, mask->height + PAD_SMALL, QuickMenuGroup::QM_BUTTON_WIDTH, QuickMenuGroup::QM_BUTTON_HEIGHT}); etx_obj_add_style(qmb->getLvObj(), styles->rounded, LV_PART_MAIN); etx_txt_color(qmb->getLvObj(), COLOR_THEME_QM_BG_INDEX, LV_PART_MAIN); etx_solid_bg(qmb->getLvObj(), COLOR_THEME_QM_FG_INDEX, LV_PART_MAIN); - iconPtr = new StaticIcon(qmb, (QuickMenuGroup::QM_BUTTON_WIDTH - QuickMenuGroup::QM_ICON_SIZE) / 2, PAD_SMALL, + new StaticIcon(qmb, (QuickMenuGroup::QM_BUTTON_WIDTH - QuickMenuGroup::QM_ICON_SIZE) / 2, PAD_SMALL, ICON_MODEL, COLOR_THEME_QM_BG_INDEX); - textPtr = new StaticText(qmb, {0, QuickMenuGroup::QM_ICON_SIZE + PAD_TINY * 2, QuickMenuGroup::QM_BUTTON_WIDTH - 1, 0}, + new StaticText(qmb, {0, QuickMenuGroup::QM_ICON_SIZE + PAD_TINY * 2, QuickMenuGroup::QM_BUTTON_WIDTH - 1, 0}, STR_QM_MODEL_SETUP, COLOR_THEME_QM_BG_INDEX, CENTERED | FONT(XS)); lv_group_set_default(def_group); diff --git a/radio/src/gui/colorlcd/radio/radio_setup.cpp b/radio/src/gui/colorlcd/radio/radio_setup.cpp index ebedd552b..9d7b809d2 100644 --- a/radio/src/gui/colorlcd/radio/radio_setup.cpp +++ b/radio/src/gui/colorlcd/radio/radio_setup.cpp @@ -957,6 +957,7 @@ static SetupLineDef setupLines[] = { RadioSetupPage::RadioSetupPage(PageDef& pageDef) : PageGroupItem(pageDef, PAD_TINY) {} +#if VERSION_MAJOR > 2 static bool hasShortcutKeys() { #if defined(USE_HATS_AS_KEYS) @@ -965,6 +966,7 @@ static bool hasShortcutKeys() return keysGetSupported() & ((1 << KEY_MODEL) | (1 << KEY_SYS) | (1 << KEY_TELE)); #endif } +#endif void RadioSetupPage::build(Window* window) { @@ -991,8 +993,10 @@ void RadioSetupPage::build(Window* window) {STR_DEF(STR_GPS), []() { new SubPage(ICON_RADIO_SETUP, STR_MAIN_MENU_RADIO_SETTINGS, STR_GPS, gpsPageSetupLines, DIM(gpsPageSetupLines)); }}, {STR_DEF(STR_ENABLED_FEATURES), []() { new SubPage(ICON_RADIO_SETUP, STR_MAIN_MENU_RADIO_SETTINGS, STR_ENABLED_FEATURES, viewOptionsPageSetupLines, DIM(viewOptionsPageSetupLines)); }}, {STR_DEF(STR_MAIN_MENU_MANAGE_MODELS), []() { new ManageModelsSetupPage(); }}, +#if VERSION_MAJOR > 2 {STR_DEF(STR_KEY_SHORTCUTS), []() { new QMKeyShortcutsPage(); }, nullptr, [=]() { return hasShortcutKeys(); }}, {STR_DEF(STR_QUICK_MENU_FAVORITES), []() { new QMFavoritesPage(); }, nullptr}, +#endif }, BTN_H); y += w->height() + padding; diff --git a/radio/src/gui/colorlcd/radio/radio_version.cpp b/radio/src/gui/colorlcd/radio/radio_version.cpp index 43083da0f..868d22f72 100644 --- a/radio/src/gui/colorlcd/radio/radio_version.cpp +++ b/radio/src/gui/colorlcd/radio/radio_version.cpp @@ -332,7 +332,11 @@ class VersionDialog : public BaseDialog #endif }; +#if VERSION_MAJOR == 2 && LCD_H == 272 +const std::string copyright_str = "(C) " BUILD_YEAR " EdgeTX"; +#else const std::string copyright_str = "Copyright (C) " BUILD_YEAR " EdgeTX"; +#endif const std::string edgetx_url = "https://edgetx.org"; RadioVersionPage::RadioVersionPage(PageDef& pageDef) : @@ -415,7 +419,7 @@ void RadioVersionPage::build(Window* window) new StaticText(infoBox, {0, 0, LV_PCT(100), LV_SIZE_CONTENT}, version); // Module and receivers versions - new TextButton(infoBox, {0, ih - EdgeTxStyles::UI_ELEMENT_HEIGHT - PAD_LARGE-PAD_SMALL, LV_PCT(100), 0}, + new TextButton(infoBox, {0, ih - EdgeTxStyles::UI_ELEMENT_HEIGHT - PAD_LARGE - PAD_SMALL, LV_PCT(100), 0}, STR_MODULES_RX_VERSION, [=]() { new VersionDialog(); return 0; diff --git a/radio/src/gui/colorlcd/setup_menus/pagegroup.cpp b/radio/src/gui/colorlcd/setup_menus/pagegroup.cpp index 6fdc2014d..f4d652ff0 100644 --- a/radio/src/gui/colorlcd/setup_menus/pagegroup.cpp +++ b/radio/src/gui/colorlcd/setup_menus/pagegroup.cpp @@ -52,6 +52,60 @@ static void on_draw_end(lv_event_t* e) //----------------------------------------------------------------------------- +#if VERSION_MAJOR == 2 +class SelectedTabIcon : public StaticIcon +{ + public: + SelectedTabIcon(Window* parent) : + StaticIcon(parent, 0, 0, ICON_CURRENTMENU_SHADOW, COLOR_THEME_PRIMARY1_INDEX) + { + new StaticIcon(this, 0, 0, ICON_CURRENTMENU_BG, COLOR_THEME_FOCUS_INDEX); + new StaticIcon(this, SEL_DOT_X, SEL_DOT_Y, ICON_CURRENTMENU_DOT, COLOR_THEME_PRIMARY2_INDEX); + } + +#if defined(DEBUG_WINDOWS) + std::string getName() const override { return "SelectedTabIcon"; } +#endif + + static LAYOUT_VAL_SCALED(SEL_DOT_X, 10) + static LAYOUT_VAL_SCALED(SEL_DOT_Y, 39) +}; + +class PageGroupIconButton : public ButtonBase +{ + public: + PageGroupIconButton(Window* parent, const rect_t& rect, PageGroupItem* page, int idx) : + ButtonBase(parent, rect, nullptr, window_create), pageTab(page), index(idx) + { + new StaticIcon(this, 2, ICON_Y, pageTab->getIcon(), COLOR_THEME_PRIMARY2_INDEX); + show(isVisible()); + } + +#if defined(DEBUG_WINDOWS) + std::string getName() const override + { + return "PageGroupIconButton(" + std::to_string(index) + ")"; + } +#endif + + bool isVisible() const { return pageTab->isVisible(); } + + static LAYOUT_VAL_SCALED(ICON_Y, 7) + + protected: + PageGroupItem* pageTab; + int index; + + void checkEvents() override + { + show(isVisible()); + ButtonBase::checkEvents(); + } +}; +#endif + +//----------------------------------------------------------------------------- + PageGroupHeaderBase::PageGroupHeaderBase(Window* parent, coord_t height, EdgeTxIcon icon, const char* parentTitle, PageGroupBase* menu) : Window(parent, {0, 0, LCD_W, height}), menu(menu) { @@ -59,24 +113,90 @@ PageGroupHeaderBase::PageGroupHeaderBase(Window* parent, coord_t height, EdgeTxI hdrIcon = new HeaderIcon(this, icon); +#if VERSION_MAJOR > 2 new HeaderBackIcon(this); parentLabel = etx_label_create(lvobj); etx_txt_color(parentLabel, COLOR_THEME_PRIMARY2_INDEX); lv_obj_set_pos(parentLabel, PageHeader::PAGE_TITLE_LEFT, PageHeader::PAGE_TITLE_TOP); - lv_obj_set_size(parentLabel, LCD_W - PageHeader::PAGE_TITLE_LEFT - PageGroup::PAGE_TOP_BAR_H * 2 - PAD_LARGE * 2, EdgeTxStyles::STD_FONT_HEIGHT); + lv_obj_set_size(parentLabel, LCD_W - PageHeader::PAGE_TITLE_LEFT - PageGroup::PAGE_GROUP_BACK_BTN_W * 2 - PAD_LARGE * 2, EdgeTxStyles::STD_FONT_HEIGHT); lv_label_set_text(parentLabel, parentTitle); +#endif titleLabel = etx_label_create(lvobj); etx_txt_color(titleLabel, COLOR_THEME_PRIMARY2_INDEX); + +#if VERSION_MAJOR == 2 + auto sep = lv_obj_create(lvobj); + etx_solid_bg(sep); + lv_obj_set_pos(sep, 0, EdgeTxStyles::MENU_HEADER_HEIGHT); + lv_obj_set_size(sep, LCD_W, PageGroup::PAGE_GROUP_TOP_BAR_H - EdgeTxStyles::MENU_HEADER_HEIGHT); + + lv_obj_set_style_pad_left(titleLabel, PAD_MEDIUM, LV_PART_MAIN); + lv_obj_set_style_pad_top(titleLabel, 1, LV_PART_MAIN); + lv_obj_set_pos(titleLabel, 0, PageGroup::PAGE_GROUP_TOP_BAR_H); + lv_obj_set_size(titleLabel, LCD_W, PageGroup::PAGE_GROUP_ALT_TITLE_H); +#else lv_obj_set_pos(titleLabel, PageHeader::PAGE_TITLE_LEFT, PageHeader::PAGE_TITLE_TOP + EdgeTxStyles::STD_FONT_HEIGHT); - lv_obj_set_size(titleLabel, LCD_W - PageHeader::PAGE_TITLE_LEFT - PageGroup::PAGE_TOP_BAR_H * 2 - PAD_LARGE * 2, EdgeTxStyles::STD_FONT_HEIGHT); + lv_obj_set_size(titleLabel, LCD_W - PageHeader::PAGE_TITLE_LEFT - PageGroup::PAGE_GROUP_BACK_BTN_W * 2 - PAD_LARGE * 2, EdgeTxStyles::STD_FONT_HEIGHT); +#endif + setTitle(""); + +#if VERSION_MAJOR == 2 + carousel = new Window(this, + {MENU_HEADER_BUTTONS_LEFT, 0, + LCD_W - MENU_HEADER_BUTTONS_LEFT, EdgeTxStyles::MENU_HEADER_HEIGHT + ICON_EXTRA_H}); + carousel->padAll(PAD_ZERO); + carousel->setWindowFlag(NO_FOCUS); + + selectedIcon = new SelectedTabIcon(carousel); +#endif } -void PageGroupHeaderBase:: setTitle(const char* title) +#if VERSION_MAJOR == 2 +coord_t PageGroupHeaderBase::getX(uint8_t idx) { - if (titleLabel) lv_label_set_text(titleLabel, title); + coord_t x = 0; + for (uint8_t i = 0; i < idx; i += 1) + if (buttons[i]->isVisible()) + x += MENU_HEADER_BUTTON_WIDTH; + return x; +} +#endif + +void PageGroupHeaderBase::setCurrentIndex(uint8_t index) +{ + if (index < pages.size()) { + currentIndex = index; +#if VERSION_MAJOR == 2 + if (index < buttons.size()) { + buttons[currentIndex]->check(false); + currentIndex = index; + buttons[currentIndex]->check(true); + coord_t x = getX(currentIndex); + selectedIcon->setPos(x, 0); + coord_t sx = lv_obj_get_scroll_x(carousel->getLvObj()); + if (x + MENU_HEADER_BUTTON_WIDTH - sx > carousel->width()) { + lv_obj_scroll_to(carousel->getLvObj(), x + MENU_HEADER_BUTTON_WIDTH - carousel->width(), 0, LV_ANIM_OFF); + } else if (x < sx) { + lv_obj_scroll_to(carousel->getLvObj(), x, 0, LV_ANIM_OFF); + } + } +#endif + } +} + +void PageGroupHeaderBase::setTitle(const char* title) +{ + if (titleLabel) { +#if VERSION_MAJOR == 2 + std::string s = replaceAll(title, "\n", " "); + lv_label_set_text(titleLabel, s.c_str()); +#else + lv_label_set_text(titleLabel, title); +#endif + } } void PageGroupHeaderBase::setIcon(EdgeTxIcon newIcon) @@ -87,6 +207,18 @@ void PageGroupHeaderBase::setIcon(EdgeTxIcon newIcon) void PageGroupHeaderBase::addTab(PageGroupItem* page) { pages.emplace_back(page); + +#if VERSION_MAJOR == 2 + uint8_t idx = buttons.size(); + auto btn = new PageGroupIconButton( + carousel, {getX(idx), 0, MENU_HEADER_BUTTON_WIDTH + PAD_THREE, PageGroup::PAGE_GROUP_TOP_BAR_H + PAD_THREE + PAD_TINY}, page, idx); + btn->setPressHandler([=]() { + menu->setCurrentTab(idx); + return true; + }); + btn->show(btn->isVisible()); + buttons.emplace_back(btn); +#endif } bool PageGroupHeaderBase::hasSubMenu(QMPage qmPage) @@ -109,13 +241,24 @@ void PageGroupHeaderBase::deleteLater(bool detach, bool trash) Window::deleteLater(detach, trash); } +#if VERSION_MAJOR == 2 +void PageGroupHeaderBase::checkEvents() +{ + for (uint8_t i = 0; i < buttons.size(); i += 1) { + buttons[i]->setPos(getX(i), 0); + } + + Window::checkEvents(); +} +#endif + //----------------------------------------------------------------------------- class PageGroupHeader : public PageGroupHeaderBase { public: PageGroupHeader(PageGroup* menu, EdgeTxIcon icon, const char* parentTitle) : - PageGroupHeaderBase(menu, PageGroup::PAGE_TOP_BAR_H, icon, parentTitle, menu) + PageGroupHeaderBase(menu, PageGroup::PAGE_GROUP_BODY_Y, icon, parentTitle, menu) { } @@ -153,7 +296,7 @@ class PageGroupHeader : public PageGroupHeaderBase void checkEvents() override { updateLayout(); - Window::checkEvents(); + PageGroupHeaderBase::checkEvents(); } }; @@ -231,7 +374,9 @@ void PageGroupBase::setCurrentTab(unsigned index) if (tab != currentTab && !deleted()) { header->setTitle(tab->getTitle().c_str()); +#if VERSION_MAJOR > 2 header->setIcon(tab->getIcon()); +#endif QuickMenu::setCurrentPage(tab->pageId(), icon); @@ -315,7 +460,7 @@ void PageGroupBase::setScrollY(coord_t y) //----------------------------------------------------------------------------- PageGroup::PageGroup(EdgeTxIcon icon, const char* title, PageDef* pages) : - PageGroupBase(PAGE_TOP_BAR_H, icon) + PageGroupBase(PAGE_GROUP_BODY_Y, icon) { header = new PageGroupHeader(this, icon, title); @@ -325,8 +470,12 @@ PageGroup::PageGroup(EdgeTxIcon icon, const char* title, PageDef* pages) : } #if defined(HARDWARE_TOUCH) +#if VERSION_MAJOR == 2 + addCustomButton(0, 0, [=]() { onCancel(); }); +#else addCustomButton(0, 0, [=]() { openMenu(); }); addCustomButton(LCD_W - EdgeTxStyles::MENU_HEADER_HEIGHT, 0, [=]() { onCancel(); }); +#endif #endif setCloseHandler([]{ @@ -359,30 +508,32 @@ class TabsGroupHeader : public PageGroupHeaderBase TabsGroupHeader(TabsGroup* menu, EdgeTxIcon icon, const char* parentTitle) : PageGroupHeaderBase(menu, TabsGroup::TABS_GROUP_BODY_Y, icon, parentTitle, menu) { -#if PORTRAIT - lv_obj_set_pos(parentLabel, PageGroup::PAGE_TOP_BAR_H + PAD_LARGE, PAD_MEDIUM * 2); - lv_obj_set_size(parentLabel, LCD_W - PageGroup::PAGE_TOP_BAR_H * 2 - PAD_LARGE * 2, PageGroup::PAGE_TOP_BAR_H - PAD_MEDIUM * 2); +#if PORTRAIT && VERSION_MAJOR > 2 + lv_obj_set_pos(parentLabel, PageGroup::PAGE_GROUP_TOP_BAR_H + PAD_LARGE, PAD_MEDIUM * 2); + lv_obj_set_size(parentLabel, LCD_W - PageGroup::PAGE_GROUP_TOP_BAR_H * 2 - PAD_LARGE * 2, PageGroup::PAGE_GROUP_TOP_BAR_H - PAD_MEDIUM * 2); auto sep = lv_obj_create(lvobj); etx_solid_bg(sep); lv_obj_set_pos(sep, 0, EdgeTxStyles::MENU_HEADER_HEIGHT); - lv_obj_set_size(sep, LCD_W, TabsGroup::PAGE_TOP_BAR_H - EdgeTxStyles::MENU_HEADER_HEIGHT); + lv_obj_set_size(sep, LCD_W, TabsGroup::TABS_GROUP_TOP_BAR_H - EdgeTxStyles::MENU_HEADER_HEIGHT); lv_obj_set_style_pad_left(titleLabel, PAD_MEDIUM, LV_PART_MAIN); lv_obj_set_style_pad_top(titleLabel, 1, LV_PART_MAIN); - lv_obj_set_pos(titleLabel, 0, TabsGroup::PAGE_TOP_BAR_H); - lv_obj_set_size(titleLabel, LCD_W, TabsGroup::PAGE_ALT_TITLE_H); + lv_obj_set_pos(titleLabel, 0, TabsGroup::TABS_GROUP_TOP_BAR_H); + lv_obj_set_size(titleLabel, LCD_W, TabsGroup::TABS_GROUP_ALT_TITLE_H); #endif - prevBtn = new IconButton(this, ICON_BTN_PREV, LCD_W - PageGroup::PAGE_TOP_BAR_H * 3, PAD_MEDIUM, [=]() { +#if VERSION_MAJOR > 2 + prevBtn = new IconButton(this, ICON_BTN_PREV, LCD_W - PageGroup::PAGE_GROUP_BACK_BTN_W * 3, PAD_MEDIUM, [=]() { prevTab(); return 0; }); - nextBtn = new IconButton(this, ICON_BTN_NEXT, LCD_W - PageGroup::PAGE_TOP_BAR_H * 2, PAD_MEDIUM, [=]() { + nextBtn = new IconButton(this, ICON_BTN_NEXT, LCD_W - PageGroup::PAGE_GROUP_BACK_BTN_W * 2, PAD_MEDIUM, [=]() { nextTab(); return 0; }); +#endif } #if defined(DEBUG_WINDOWS) @@ -417,9 +568,13 @@ TabsGroup::TabsGroup(EdgeTxIcon icon, const char* parentLabel) : header = new TabsGroupHeader(this, icon, parentLabel); #if defined(HARDWARE_TOUCH) +#if VERSION_MAJOR == 2 + addCustomButton(0, 0, [=]() { onCancel(); }); +#else addCustomButton(0, 0, [=]() { openMenu(); }); addCustomButton(LCD_W - EdgeTxStyles::MENU_HEADER_HEIGHT, 0, [=]() { onCancel(); }); #endif +#endif } void TabsGroup::openMenu() diff --git a/radio/src/gui/colorlcd/setup_menus/pagegroup.h b/radio/src/gui/colorlcd/setup_menus/pagegroup.h index 7210632ac..2eac861e5 100644 --- a/radio/src/gui/colorlcd/setup_menus/pagegroup.h +++ b/radio/src/gui/colorlcd/setup_menus/pagegroup.h @@ -27,7 +27,10 @@ class HeaderIcon; class PageGroupItem; class PageGroupBase; - +#if VERSION_MAJOR == 2 +class SelectedTabIcon; +class PageGroupIconButton; +#endif //----------------------------------------------------------------------------- enum PageDefAction { @@ -46,7 +49,9 @@ struct PageDef { std::function action; }; +#if VERSION_MAJOR > 2 extern PageDef favoritesMenuItems[]; +#endif enum QMTopDefAction { QM_SUBMENU, @@ -127,12 +132,7 @@ class PageGroupHeaderBase : public Window virtual void removeTab(unsigned index) {} void addTab(PageGroupItem* page); - void setCurrentIndex(uint8_t index) - { - if (index < pages.size()) { - currentIndex = index; - } - } + void setCurrentIndex(uint8_t index); bool hasSubMenu(QMPage n); @@ -142,6 +142,11 @@ class PageGroupHeaderBase : public Window void deleteLater(bool detach = true, bool trash = true) override; +#if VERSION_MAJOR == 2 + static LAYOUT_VAL_SCALED(ICON_EXTRA_H, 10) + static LAYOUT_VAL_SCALED(MENU_HEADER_BUTTON_WIDTH, 33) +#endif + protected: uint8_t currentIndex = 0; lv_obj_t* titleLabel = nullptr; @@ -149,6 +154,14 @@ class PageGroupHeaderBase : public Window HeaderIcon* hdrIcon = nullptr; std::vector pages; PageGroupBase* menu; +#if VERSION_MAJOR ==2 + SelectedTabIcon* selectedIcon = nullptr; + Window* carousel = nullptr; + std::vector buttons; + + coord_t getX(uint8_t idx); + void checkEvents() override; +#endif }; //----------------------------------------------------------------------------- @@ -220,7 +233,16 @@ class PageGroup : public PageGroupBase bool isPageGroup() override { return true; } - static LAYOUT_VAL_SCALED(PAGE_TOP_BAR_H, 45) +#if VERSION_MAJOR == 2 + static LAYOUT_VAL_SCALED(PAGE_GROUP_TOP_BAR_H, 48) + static constexpr coord_t PAGE_GROUP_ALT_TITLE_H = EdgeTxStyles::STD_FONT_HEIGHT; + static constexpr coord_t PAGE_GROUP_BACK_BTN_W = 0; +#else + static LAYOUT_VAL_SCALED(PAGE_GROUP_TOP_BAR_H, 45) + static constexpr coord_t PAGE_GROUP_ALT_TITLE_H = 0; + static constexpr coord_t PAGE_GROUP_BACK_BTN_W = PAGE_GROUP_TOP_BAR_H; +#endif + static constexpr coord_t PAGE_GROUP_BODY_Y = PAGE_GROUP_TOP_BAR_H + PAGE_GROUP_ALT_TITLE_H; protected: @@ -240,9 +262,14 @@ class TabsGroup : public PageGroupBase void hidePageButtons(); - static LAYOUT_ORIENTATION_SCALED(PAGE_TOP_BAR_H, 45, 48) - static LAYOUT_ORIENTATION(PAGE_ALT_TITLE_H, 0, EdgeTxStyles::STD_FONT_HEIGHT) - static constexpr coord_t TABS_GROUP_BODY_Y = PAGE_TOP_BAR_H + PAGE_ALT_TITLE_H; +#if VERSION_MAJOR == 2 + static LAYOUT_VAL_SCALED(TABS_GROUP_TOP_BAR_H, 48) + static constexpr coord_t TABS_GROUP_ALT_TITLE_H = EdgeTxStyles::STD_FONT_HEIGHT; +#else + static LAYOUT_ORIENTATION_SCALED(TABS_GROUP_TOP_BAR_H, 45, 48) + static LAYOUT_ORIENTATION(TABS_GROUP_ALT_TITLE_H, 0, EdgeTxStyles::STD_FONT_HEIGHT) +#endif + static constexpr coord_t TABS_GROUP_BODY_Y = TABS_GROUP_TOP_BAR_H + TABS_GROUP_ALT_TITLE_H; protected: diff --git a/radio/src/gui/colorlcd/setup_menus/quick_menu.cpp b/radio/src/gui/colorlcd/setup_menus/quick_menu.cpp index a671f7b14..8e021721b 100644 --- a/radio/src/gui/colorlcd/setup_menus/quick_menu.cpp +++ b/radio/src/gui/colorlcd/setup_menus/quick_menu.cpp @@ -32,6 +32,7 @@ //----------------------------------------------------------------------------- +#if VERSION_MAJOR > 2 class QuickSubMenu { public: @@ -196,6 +197,7 @@ class QuickSubMenu QuickMenuGroup* subMenu = nullptr; ButtonBase* menuButton = nullptr; }; +#endif //----------------------------------------------------------------------------- @@ -221,7 +223,7 @@ void QuickMenu::shutdownQuickMenu() } QuickMenu::QuickMenu() : - NavWindow(MainWindow::instance(), {0, 0, LCD_W, LCD_H}) + NavWindow(MainWindow::instance(), {QM_X, QM_Y, QM_W, QM_H}) { setWindowFlag(OPAQUE); @@ -230,13 +232,13 @@ QuickMenu::QuickMenu() : auto sep = lv_obj_create(lvobj); etx_solid_bg(sep, COLOR_THEME_QM_FG_INDEX); - lv_obj_set_size(sep, LCD_W, PAD_THREE); + lv_obj_set_size(sep, QM_W, PAD_THREE); auto mask = getBuiltinIcon(ICON_TOP_LOGO); - new StaticIcon(this, (LCD_W - mask->width) / 2, 0, ICON_TOP_LOGO, COLOR_THEME_QM_FG_INDEX); + new StaticIcon(this, (QM_W - mask->width) / 2, 0, ICON_TOP_LOGO, COLOR_THEME_QM_FG_INDEX); new ButtonBase( - this, {0, 0, LCD_W, EdgeTxStyles::UI_ELEMENT_HEIGHT}, + this, {0, 0, QM_W, EdgeTxStyles::UI_ELEMENT_HEIGHT}, [=]() -> uint8_t { inSubMenu = false; onCancel(); @@ -248,6 +250,7 @@ QuickMenu::QuickMenu() : mainMenu = new QuickMenuGroup(box); +#if VERSION_MAJOR > 2 box = new Window(this, {QM_SUB_X, QM_SUB_Y, QM_SUB_W, QM_SUB_H}); int f = 0; @@ -258,15 +261,18 @@ QuickMenu::QuickMenu() : } } favoritesMenuItems[f].icon = EDGETX_ICONS_COUNT; +#endif for (int i = 0; qmTopItems[i].icon != EDGETX_ICONS_COUNT; i += 1) { if ((qmTopItems[i].enabled == nullptr) || qmTopItems[i].enabled()) { if (qmTopItems[i].pageAction == QM_ACTION) { mainMenu->addButton(qmTopItems[i].icon, STR_VAL(qmTopItems[i].qmTitle), qmTopItems[i].action); +#if VERSION_MAJOR > 2 } else { auto sub = new QuickSubMenu(box, this, qmTopItems[i].icon, STR_VAL(qmTopItems[i].qmTitle), STR_VAL(qmTopItems[i].title), qmTopItems[i].subMenuItems); sub->addButton(); subMenus.emplace_back(sub); +#endif } } } @@ -287,9 +293,15 @@ void QuickMenu::openQM(std::function cancelHandler, { Layer::push(this); +#if VERSION_MAJOR == 2 + curPage = QM_NONE; +#endif + mainMenu->doLayout(QM_MAIN_COLS); +#if VERSION_MAJOR > 2 for (size_t i = 0; i < subMenus.size(); i += 1) subMenus[i]->doLayout(); +#endif this->cancelHandler = std::move(cancelHandler); this->selectHandler = std::move(selectHandler); @@ -309,8 +321,10 @@ void QuickMenu::openQM(std::function cancelHandler, mainMenu->clearFocus(); setFocus(curPage); } else { +#if VERSION_MAJOR > 2 if (curPage == QM_MANAGE_MODELS) mainMenu->setCurrent(favoritesMenuItems[0].icon == EDGETX_ICONS_COUNT ? 0 : 1); +#endif focusMainMenu(); } } @@ -324,9 +338,10 @@ void QuickMenu::selected() void QuickMenu::openPage(QMPage page) { - for (int i = 1; qmTopItems[i].icon != EDGETX_ICONS_COUNT; i += 1) { + for (int i = FIRST_SEARCH_IDX; qmTopItems[i].icon != EDGETX_ICONS_COUNT; i += 1) { if (qmTopItems[i].pageAction == QM_ACTION) { if (qmTopItems[i].qmPage == page) { + QuickMenu::selected(); qmTopItems[i].action(); return; } @@ -335,8 +350,10 @@ void QuickMenu::openPage(QMPage page) for (int j = 0, k = 0; sub[j].icon != EDGETX_ICONS_COUNT; j += 1) { if (sub[j].qmPage == page) { if (sub[j].pageAction == PAGE_ACTION) { + QuickMenu::selected(); sub[j].action(); } else { + QuickMenu::selected(); auto pg = new PageGroup(qmTopItems[i].icon, STR_VAL(qmTopItems[i].title), sub); pg->setCurrentTab(k); return; @@ -351,7 +368,7 @@ void QuickMenu::openPage(QMPage page) EdgeTxIcon QuickMenu::pageIcon(QMPage page) { - for (int i = 1; qmTopItems[i].icon != EDGETX_ICONS_COUNT; i += 1) { + for (int i = FIRST_SEARCH_IDX; qmTopItems[i].icon != EDGETX_ICONS_COUNT; i += 1) { if (qmTopItems[i].pageAction == QM_ACTION) { if (qmTopItems[i].qmPage == page) { return qmTopItems[i].icon; @@ -370,7 +387,7 @@ EdgeTxIcon QuickMenu::pageIcon(QMPage page) int QuickMenu::pageIndex(QMPage page) { - for (int i = 1; qmTopItems[i].icon != EDGETX_ICONS_COUNT; i += 1) { + for (int i = FIRST_SEARCH_IDX; qmTopItems[i].icon != EDGETX_ICONS_COUNT; i += 1) { if (qmTopItems[i].pageAction == QM_ACTION) { if (qmTopItems[i].qmPage == page) { return 0; @@ -392,7 +409,7 @@ int QuickMenu::pageIndex(QMPage page) return 0; } -static std::string replaceAll(std::string str, const std::string& from, const std::string& to) +std::string replaceAll(std::string str, const std::string& from, const std::string& to) { auto&& pos = str.find(from, size_t{}); while (pos != std::string::npos) @@ -411,7 +428,7 @@ std::vector QuickMenu::menuPageNames(bool forFavorites) qmPages.emplace_back(STR_NONE); qmPages.emplace_back(STR_OPEN_QUICK_MENU); - for (int i = 1; qmTopItems[i].icon != EDGETX_ICONS_COUNT; i += 1) { + for (int i = FIRST_SEARCH_IDX; qmTopItems[i].icon != EDGETX_ICONS_COUNT; i += 1) { if (qmTopItems[i].pageAction == QM_ACTION) { qmPages.emplace_back(STR_VAL(qmTopItems[i].title)); } else { @@ -432,11 +449,12 @@ std::vector QuickMenu::menuPageNames(bool forFavorites) return qmPages; } +#if VERSION_MAJOR > 2 void QuickMenu::setupFavorite(QMPage page, int f) { PageDef& fav = favoritesMenuItems[f]; - for (int i = 1; qmTopItems[i].icon != EDGETX_ICONS_COUNT; i += 1) { + for (int i = FIRST_SEARCH_IDX; qmTopItems[i].icon != EDGETX_ICONS_COUNT; i += 1) { if (qmTopItems[i].pageAction == QM_ACTION) { if (qmTopItems[i].qmPage == page) { fav.icon = qmTopItems[i].icon; @@ -467,6 +485,7 @@ void QuickMenu::setupFavorite(QMPage page, int f) } } } +#endif void QuickMenu::setCurrentPage(QMPage newPage, EdgeTxIcon newIcon) { @@ -480,8 +499,10 @@ void QuickMenu::focusMainMenu() mainMenu->setFocus(); mainMenu->setEnabled(); mainMenu->setGroup(); +#if VERSION_MAJOR > 2 for(auto sub : subMenus) sub->setDisabled(true); +#endif } void QuickMenu::onSelect(bool close) @@ -509,12 +530,14 @@ void QuickMenu::onCancel() void QuickMenu::setFocus(QMPage selection) { +#if VERSION_MAJOR > 2 for(auto sub : subMenus) { if (sub->isSubMenu(selection, curIcon)) { sub->setCurrent(selection); return; } } +#endif } void QuickMenu::enableSubMenu() @@ -545,12 +568,14 @@ void QuickMenu::afterPG() { auto b = mainMenu->getFocusedButton(); if (b) { +#if VERSION_MAJOR > 3 for(auto sub : subMenus) { if (sub->isSubMenu(b)) { sub->activate(); return; } } +#endif focusMainMenu(); curPage = QM_NONE; } diff --git a/radio/src/gui/colorlcd/setup_menus/quick_menu.h b/radio/src/gui/colorlcd/setup_menus/quick_menu.h index e73af19bd..61b78d474 100644 --- a/radio/src/gui/colorlcd/setup_menus/quick_menu.h +++ b/radio/src/gui/colorlcd/setup_menus/quick_menu.h @@ -27,11 +27,15 @@ #include "quick_menu_group.h" #include "quick_menu_def.h" +std::string replaceAll(std::string str, const std::string& from, const std::string& to); + class PageGroup; class PageGroupBase; class ButtonBase; -class QuickSubMenu; struct PageDef; +#if VERSION_MAJOR > 2 +class QuickSubMenu; +#endif #define GRP_W(n) ((QuickMenuGroup::QM_BUTTON_WIDTH + PAD_MEDIUM) * n - PAD_MEDIUM + PAD_OUTLINE * 2) #if LANDSCAPE @@ -69,7 +73,6 @@ class QuickMenu : public NavWindow static EdgeTxIcon pageIcon(QMPage page); static int pageIndex(QMPage page); static std::vector menuPageNames(bool forFavorites); - static void setupFavorite(QMPage page, int f); #if defined(HARDWARE_KEYS) void doKeyShortcut(event_t event); @@ -85,8 +88,17 @@ class QuickMenu : public NavWindow void afterPG(); #endif - static constexpr int QM_MAIN_BTNS = 6; - static constexpr int QM_SUB_BTNS = 12; +#if VERSION_MAJOR == 2 + static LAYOUT_ORIENTATION(QM_MAIN_COLS, 5, 3) + static LAYOUT_ORIENTATION(QM_MAIN_ROWS, 2, 4) + static constexpr int QM_MAIN_W = GRP_W(QM_MAIN_COLS); + static constexpr int QM_MAIN_H = GRP_H(QM_MAIN_ROWS); + static constexpr coord_t QM_W = QM_MAIN_W + PAD_LARGE * 2; + static constexpr coord_t QM_H = QM_MAIN_H + EdgeTxStyles::UI_ELEMENT_HEIGHT + PAD_MEDIUM * 2; + static constexpr coord_t QM_MAIN_X = (QM_W - QM_MAIN_W) / 2; + static constexpr coord_t QM_MAIN_Y = EdgeTxStyles::UI_ELEMENT_HEIGHT + PAD_OUTLINE; + static constexpr int FIRST_SEARCH_IDX = 0; +#else static LAYOUT_ORIENTATION(QM_MAIN_COLS, 6, 1) static LAYOUT_ORIENTATION(QM_MAIN_ROWS, 1, 6) static LAYOUT_ORIENTATION(QM_SUB_COLS, 6, 3) @@ -95,10 +107,16 @@ class QuickMenu : public NavWindow static constexpr int QM_MAIN_H = GRP_H(QM_MAIN_ROWS); static constexpr int QM_SUB_W = GRP_W(QM_SUB_COLS); static constexpr int QM_SUB_H = GRP_H(QM_SUB_ROWS); - static LAYOUT_ORIENTATION(QM_MAIN_X, (LCD_W - QM_MAIN_W) / 2, (LCD_W - QM_MAIN_W - QM_SUB_W - PAD_SMALL) / 2) - static constexpr coord_t QM_MAIN_Y = EdgeTxStyles::UI_ELEMENT_HEIGHT + PAD_TINY; + static constexpr coord_t QM_W = LCD_W; + static constexpr coord_t QM_H = LCD_H; + static LAYOUT_ORIENTATION(QM_MAIN_X, (QM_W - QM_MAIN_W) / 2, (QM_W - QM_MAIN_W - QM_SUB_W - PAD_SMALL) / 2) + static constexpr coord_t QM_MAIN_Y = EdgeTxStyles::UI_ELEMENT_HEIGHT + PAD_OUTLINE; static LAYOUT_ORIENTATION(QM_SUB_X, QM_MAIN_X, QM_MAIN_X + QM_MAIN_W + PAD_SMALL) static LAYOUT_ORIENTATION(QM_SUB_Y, QM_MAIN_Y + QM_MAIN_H + PAD_LARGE, QM_MAIN_Y) + static constexpr int FIRST_SEARCH_IDX = 1; // Skip favorites +#endif + static constexpr coord_t QM_X = (LCD_W - QM_W) / 2; + static constexpr coord_t QM_Y = (LCD_H - QM_H) / 2; protected: static QuickMenu* instance; @@ -106,7 +124,9 @@ class QuickMenu : public NavWindow std::function selectHandler = nullptr; bool inSubMenu = false; QuickMenuGroup* mainMenu = nullptr; +#if VERSION_MAJOR > 2 std::vector subMenus; +#endif PageGroupBase* pageGroup = nullptr; static QMPage curPage; static EdgeTxIcon curIcon; @@ -118,4 +138,8 @@ class QuickMenu : public NavWindow void focusMainMenu(); void deleteLater(bool detach = true, bool trash = true) override; + +#if VERSION_MAJOR > 2 + static void setupFavorite(QMPage page, int f); +#endif }; diff --git a/radio/src/gui/colorlcd/setup_menus/quick_menu_data.cpp b/radio/src/gui/colorlcd/setup_menus/quick_menu_data.cpp index 632b0d2e4..633aa4597 100644 --- a/radio/src/gui/colorlcd/setup_menus/quick_menu_data.cpp +++ b/radio/src/gui/colorlcd/setup_menus/quick_menu_data.cpp @@ -47,6 +47,98 @@ #include "view_logical_switches.h" #include "view_channels.h" +#if VERSION_MAJOR == 2 + +PageDef modelMenuItems[] = { + { ICON_MODEL_SETUP, STR_DEF(STR_QM_MODEL_SETTINGS), STR_DEF(STR_MAIN_MODEL_SETTINGS), PAGE_CREATE, QM_MODEL_SETUP, [](PageDef& pageDef) { return new ModelSetupPage(pageDef); }}, +#if defined(FLIGHT_MODES) + { ICON_MODEL_FLIGHT_MODES, STR_DEF(STR_QM_FLIGHT_MODES), STR_DEF(STR_MENUFLIGHTMODES), PAGE_CREATE, QM_MODEL_FLIGHTMODES, [](PageDef& pageDef) { return new ModelFlightModesPage(pageDef); }, modelFMEnabled}, +#endif + { ICON_MODEL_INPUTS, STR_DEF(STR_QM_INPUTS), STR_DEF(STR_MENUINPUTS), PAGE_CREATE, QM_MODEL_INPUTS, [](PageDef& pageDef) { return new ModelInputsPage(pageDef); }}, + { ICON_MODEL_MIXER, STR_DEF(STR_QM_MIXES), STR_DEF(STR_MIXES), PAGE_CREATE, QM_MODEL_MIXES, [](PageDef& pageDef) { return new ModelMixesPage(pageDef); }}, + { ICON_MODEL_OUTPUTS, STR_DEF(STR_QM_OUTPUTS), STR_DEF(STR_MENULIMITS), PAGE_CREATE, QM_MODEL_OUTPUTS, [](PageDef& pageDef) { return new ModelOutputsPage(pageDef); }}, + { ICON_MODEL_CURVES, STR_DEF(STR_QM_CURVES), STR_DEF(STR_MENUCURVES), PAGE_CREATE, QM_MODEL_CURVES, [](PageDef& pageDef) { return new ModelCurvesPage(pageDef); }, modelCurvesEnabled}, +#if defined(GVARS) + { ICON_MODEL_GVARS, STR_DEF(STR_QM_GLOBAL_VARS), STR_DEF(STR_MENU_GLOBAL_VARS), PAGE_CREATE, QM_MODEL_GVARS, [](PageDef& pageDef) { return new ModelGVarsPage(pageDef); }, modelGVEnabled}, +#endif + { ICON_MODEL_LOGICAL_SWITCHES, STR_DEF(STR_QM_LOGICAL_SW), STR_DEF(STR_MENULOGICALSWITCHES), PAGE_CREATE, QM_MODEL_LS, [](PageDef& pageDef) { return new ModelLogicalSwitchesPage(pageDef); }, modelLSEnabled}, + { ICON_MODEL_SPECIAL_FUNCTIONS, STR_DEF(STR_QM_SPEC_FUNC), STR_DEF(STR_MENUCUSTOMFUNC), PAGE_CREATE, QM_MODEL_SF, [](PageDef& pageDef) { return new SpecialFunctionsPage(pageDef); }, modelSFEnabled}, +#if defined(LUA_MODEL_SCRIPTS) + { ICON_MODEL_LUA_SCRIPTS, STR_DEF(STR_QM_CUSTOM_LUA), STR_DEF(STR_MENUCUSTOMSCRIPTS), PAGE_CREATE, QM_MODEL_SCRIPTS, [](PageDef& pageDef) { return new ModelMixerScriptsPage(pageDef); }, modelCustomScriptsEnabled}, +#endif + { ICON_MODEL_TELEMETRY, STR_DEF(STR_QM_TELEM), STR_DEF(STR_MENUTELEMETRY), PAGE_CREATE, QM_MODEL_TELEMETRY, [](PageDef& pageDef) { return new ModelTelemetryPage(pageDef); }, modelTelemetryEnabled}, + { EDGETX_ICONS_COUNT } +}; + +PageDef radioMenuItems[] = { + { ICON_TOOLS_APPS, STR_DEF(STR_QM_APPS), STR_DEF(STR_MAIN_MENU_APPS), PAGE_CREATE, QM_TOOLS_APPS, [](PageDef& pageDef) { return new RadioToolsPage(pageDef); }}, + { ICON_RADIO_SD_MANAGER, STR_DEF(STR_QM_STORAGE), STR_DEF(STR_SD_CARD), PAGE_CREATE, QM_TOOLS_STORAGE, [](PageDef& pageDef) { return new RadioSdManagerPage(pageDef); }}, + { ICON_RADIO_SETUP, STR_DEF(STR_QM_RADIO_SETTINGS), STR_DEF(STR_MAIN_RADIO_SETTINGS), PAGE_CREATE, QM_RADIO_SETUP, [](PageDef& pageDef) { return new RadioSetupPage(pageDef); }}, + { ICON_RADIO_EDIT_THEME, STR_DEF(STR_QM_THEMES), STR_DEF(STR_MAIN_MENU_THEMES), PAGE_CREATE, QM_UI_THEMES, [](PageDef& pageDef) { return new ThemeSetupPage(pageDef); }, radioThemesEnabled}, + { ICON_RADIO_GLOBAL_FUNCTIONS, STR_DEF(STR_QM_GLOB_FUNC), STR_DEF(STR_MENUSPECIALFUNCS), PAGE_CREATE, QM_RADIO_GF, [](PageDef& pageDef) { return new GlobalFunctionsPage(pageDef); }, radioGFEnabled}, + { ICON_RADIO_TRAINER, STR_DEF(STR_QM_TRAINER), STR_DEF(STR_MENUTRAINER), PAGE_CREATE, QM_RADIO_TRAINER, [](PageDef& pageDef) { return new RadioTrainerPage(pageDef); }, radioTrainerEnabled}, + { ICON_RADIO_HARDWARE, STR_DEF(STR_QM_HARDWARE), STR_DEF(STR_HARDWARE), PAGE_CREATE, QM_RADIO_HARDWARE, [](PageDef& pageDef) { return new RadioHardwarePage(pageDef); }}, + { ICON_RADIO_VERSION, STR_DEF(STR_QM_ABOUT), STR_DEF(STR_MAIN_MENU_ABOUT_EDGETX), PAGE_CREATE, QM_RADIO_VERSION, [](PageDef& pageDef) { return new RadioVersionPage(pageDef); }}, + { EDGETX_ICONS_COUNT } +}; + +PageDef screensMenuItems[] = { + { ICON_THEME_SETUP, STR_DEF(STR_QM_TOP_BAR), STR_DEF(STR_USER_INTERFACE), PAGE_CREATE, QM_UI_SETUP, [](PageDef& pageDef) { return new ScreenUserInterfacePage(pageDef); }}, + { ICON_THEME_VIEW1, STR_DEF(STR_QM_SCREEN_1), STR_DEF(STR_MAIN_VIEW_1), PAGE_CREATE, QM_UI_SCREEN1, [](PageDef& pageDef) { return new ScreenSetupPage(0, pageDef); }}, + { ICON_THEME_VIEW2, STR_DEF(STR_QM_SCREEN_2), STR_DEF(STR_MAIN_VIEW_2), PAGE_CREATE, QM_UI_SCREEN2, [](PageDef& pageDef) { return new ScreenSetupPage(1, pageDef); }, []() { return customScreens[1] != nullptr; }}, + { ICON_THEME_VIEW3, STR_DEF(STR_QM_SCREEN_3), STR_DEF(STR_MAIN_VIEW_3), PAGE_CREATE, QM_UI_SCREEN3, [](PageDef& pageDef) { return new ScreenSetupPage(2, pageDef); }, []() { return customScreens[2] != nullptr; }}, + { ICON_THEME_VIEW4, STR_DEF(STR_QM_SCREEN_4), STR_DEF(STR_MAIN_VIEW_4), PAGE_CREATE, QM_UI_SCREEN4, [](PageDef& pageDef) { return new ScreenSetupPage(3, pageDef); }, []() { return customScreens[3] != nullptr; }}, + { ICON_THEME_VIEW5, STR_DEF(STR_QM_SCREEN_5), STR_DEF(STR_MAIN_VIEW_5), PAGE_CREATE, QM_UI_SCREEN5, [](PageDef& pageDef) { return new ScreenSetupPage(4, pageDef); }, []() { return customScreens[4] != nullptr; }}, + { ICON_THEME_VIEW6, STR_DEF(STR_QM_SCREEN_6), STR_DEF(STR_MAIN_VIEW_6), PAGE_CREATE, QM_UI_SCREEN6, [](PageDef& pageDef) { return new ScreenSetupPage(5, pageDef); }, []() { return customScreens[5] != nullptr; }}, + { ICON_THEME_VIEW7, STR_DEF(STR_QM_SCREEN_7), STR_DEF(STR_MAIN_VIEW_7), PAGE_CREATE, QM_UI_SCREEN7, [](PageDef& pageDef) { return new ScreenSetupPage(6, pageDef); }, []() { return customScreens[6] != nullptr; }}, + { ICON_THEME_VIEW8, STR_DEF(STR_QM_SCREEN_8), STR_DEF(STR_MAIN_VIEW_8), PAGE_CREATE, QM_UI_SCREEN8, [](PageDef& pageDef) { return new ScreenSetupPage(7, pageDef); }, []() { return customScreens[7] != nullptr; }}, + { ICON_THEME_VIEW9, STR_DEF(STR_QM_SCREEN_9), STR_DEF(STR_MAIN_VIEW_9), PAGE_CREATE, QM_UI_SCREEN9, [](PageDef& pageDef) { return new ScreenSetupPage(8, pageDef); }, []() { return customScreens[8] != nullptr; }}, + { ICON_THEME_VIEW10, STR_DEF(STR_QM_SCREEN_10), STR_DEF(STR_MAIN_VIEW_10), PAGE_CREATE, QM_UI_SCREEN10, [](PageDef& pageDef) { return new ScreenSetupPage(9, pageDef); }, []() { return customScreens[9] != nullptr; }}, + { ICON_THEME_ADD_VIEW, STR_DEF(STR_QM_ADD_SCREEN), STR_DEF(STR_QM_ADD_SCREEN), PAGE_CREATE, QM_UI_ADD_PG, [](PageDef& pageDef) { return new ScreenAddPage(pageDef); }, []() { return customScreens[9] == nullptr; }}, + { EDGETX_ICONS_COUNT } +}; + +PageDef statsMenuItems[] = { + { ICON_STATS, STR_DEF(STR_QM_STATS), STR_DEF(STR_MAIN_MENU_STATISTICS), PAGE_CREATE, QM_TOOLS_STATS, [](PageDef& pageDef) { return new StatisticsViewPage(pageDef); }}, + { ICON_STATS_DEBUG, STR_DEF(STR_QM_DEBUG), STR_DEF(STR_DEBUG), PAGE_CREATE, QM_TOOLS_DEBUG, [](PageDef& pageDef) { return new DebugViewPage(pageDef); }}, + { EDGETX_ICONS_COUNT } +}; + +QMTopDef qmTopItems[] = { + { ICON_MODEL_SELECT, STR_DEF(STR_QM_MANAGE_MODELS), STR_DEF(STR_MANAGE_MODELS), QM_ACTION, QM_MANAGE_MODELS, nullptr, []() { QuickMenu::selected(); new ModelLabelsWindow(); }}, + { ICON_MODEL_NOTES, STR_DEF(STR_MAIN_MENU_MODEL_NOTES), STR_DEF(STR_MAIN_MENU_MODEL_NOTES), QM_ACTION, QM_NONE, nullptr, []() { QuickMenu::openPage(QM_MODEL_NOTES); }, modelHasNotes}, + { ICON_MONITOR, STR_DEF(STR_QM_CHAN_MON), STR_DEF(STR_QM_CHAN_MON), QM_ACTION, QM_TOOLS_CHAN_MON, nullptr, + []() { + QuickMenu::selected(); + new ChannelsViewMenu(); + } + }, + { ICON_MODEL_SETUP, STR_DEF(STR_QM_MODEL_SETTINGS), STR_DEF(STR_MAIN_MODEL_SETTINGS), QM_ACTION, QM_NONE, nullptr, []() { QuickMenu::openPage(QM_MODEL_SETUP); }}, + { ICON_RADIO_SETUP, STR_DEF(STR_QM_RADIO_SETTINGS), STR_DEF(STR_MAIN_RADIO_SETTINGS), QM_ACTION, QM_NONE, nullptr, []() { QuickMenu::openPage(QM_RADIO_SETUP); }}, + { ICON_THEME, STR_DEF(STR_MAIN_MENU_SCREEN_SETTINGS), STR_DEF(STR_MAIN_MENU_SCREEN_SETTINGS), QM_ACTION, QM_NONE, nullptr, []() { QuickMenu::openPage(QM_UI_SCREEN1); }}, + { ICON_TOOLS_RESET, STR_DEF(STR_QM_RESET), STR_DEF(STR_QM_RESET), QM_ACTION, QM_TOOLS_RESET, nullptr, + []() { + QuickMenu::selected(); + Menu* resetMenu = new Menu(); + resetMenu->addLine(STR_RESET_FLIGHT, []() { flightReset(); }); + resetMenu->addLine(STR_RESET_TIMER1, []() { timerReset(0); }); + resetMenu->addLine(STR_RESET_TIMER2, []() { timerReset(1); }); + resetMenu->addLine(STR_RESET_TIMER3, []() { timerReset(2); }); + resetMenu->addLine(STR_RESET_TELEMETRY, []() { telemetryReset(); }); + } + }, + { ICON_STATS, STR_DEF(STR_QM_STATS), STR_DEF(STR_MAIN_MENU_STATISTICS), QM_ACTION, QM_NONE, nullptr, []() { QuickMenu::openPage(QM_TOOLS_STATS); }}, + { ICON_RADIO_VERSION, STR_DEF(STR_QM_ABOUT), STR_DEF(STR_MAIN_MENU_ABOUT_EDGETX), QM_ACTION, QM_NONE, nullptr, []() { QuickMenu::openPage(QM_RADIO_VERSION); }}, + // Not displayed - search / run only + { ICON_MODEL, STR_DEF(STR_QM_MODEL_SETUP), STR_DEF(STR_MAIN_MENU_MODEL_SETTINGS), QM_SUBMENU, QM_NONE, modelMenuItems}, + { ICON_RADIO, STR_DEF(STR_QM_RADIO_SETUP), STR_DEF(STR_MAIN_MENU_RADIO_SETTINGS), QM_SUBMENU, QM_NONE, radioMenuItems}, + { ICON_THEME, STR_DEF(STR_QM_UI_SETUP), STR_DEF(STR_MAIN_MENU_SCREEN_SETTINGS), QM_SUBMENU, QM_NONE, screensMenuItems}, + { ICON_STATS, STR_DEF(STR_QM_STATS), STR_DEF(STR_MAIN_MENU_STATISTICS), QM_SUBMENU, QM_NONE, statsMenuItems}, + { EDGETX_ICONS_COUNT } +}; + +#else + PageDef favoritesMenuItems[] = { { EDGETX_ICONS_COUNT, nullptr, nullptr, PAGE_CREATE, QM_NONE, nullptr}, { EDGETX_ICONS_COUNT, nullptr, nullptr, PAGE_CREATE, QM_NONE, nullptr}, @@ -145,6 +237,7 @@ PageDef toolsMenuItems[] = { { ICON_RADIO_SD_MANAGER, STR_DEF(STR_QM_STORAGE), STR_DEF(STR_SD_CARD), PAGE_CREATE, QM_TOOLS_STORAGE, [](PageDef& pageDef) { return new RadioSdManagerPage(pageDef); }}, { ICON_TOOLS_RESET, STR_DEF(STR_QM_RESET), STR_DEF(STR_QM_RESET), PAGE_ACTION, QM_TOOLS_RESET, nullptr, nullptr, []() { + QuickMenu::selected(); Menu* resetMenu = new Menu(); resetMenu->addLine(STR_RESET_FLIGHT, []() { flightReset(); }); resetMenu->addLine(STR_RESET_TIMER1, []() { timerReset(0); }); @@ -155,6 +248,7 @@ PageDef toolsMenuItems[] = { }, { ICON_MONITOR, STR_DEF(STR_QM_CHAN_MON), STR_DEF(STR_QM_CHAN_MON), PAGE_ACTION, QM_TOOLS_CHAN_MON, nullptr, nullptr, []() { + QuickMenu::selected(); new ChannelsViewMenu(); } }, @@ -166,14 +260,12 @@ PageDef toolsMenuItems[] = { QMTopDef qmTopItems[] = { { ICON_QM_FAVORITES, STR_DEF(STR_FAVORITE_LABEL), STR_DEF(STR_FAVORITE_LABEL), QM_SUBMENU, QM_NONE, favoritesMenuItems, nullptr, []() { return favoritesMenuItems[0].icon != EDGETX_ICONS_COUNT; }}, - { ICON_MODEL_SELECT, STR_DEF(STR_QM_MANAGE_MODELS), STR_DEF(STR_MANAGE_MODELS), QM_ACTION, QM_MANAGE_MODELS, nullptr, - []() { - QuickMenu::selected(); - new ModelLabelsWindow(); - }}, + { ICON_MODEL_SELECT, STR_DEF(STR_QM_MANAGE_MODELS), STR_DEF(STR_MANAGE_MODELS), QM_ACTION, QM_MANAGE_MODELS, nullptr, []() { QuickMenu::selected(); new ModelLabelsWindow(); }}, { ICON_MODEL, STR_DEF(STR_QM_MODEL_SETUP), STR_DEF(STR_MAIN_MENU_MODEL_SETTINGS), QM_SUBMENU, QM_NONE, modelMenuItems}, { ICON_RADIO, STR_DEF(STR_QM_RADIO_SETUP), STR_DEF(STR_MAIN_MENU_RADIO_SETTINGS), QM_SUBMENU, QM_NONE, radioMenuItems}, { ICON_THEME, STR_DEF(STR_QM_UI_SETUP), STR_DEF(STR_MAIN_MENU_SCREEN_SETTINGS), QM_SUBMENU, QM_NONE, screensMenuItems}, { ICON_RADIO_TOOLS, STR_DEF(STR_QM_TOOLS), STR_DEF(STR_QM_TOOLS), QM_SUBMENU, QM_NONE, toolsMenuItems}, { EDGETX_ICONS_COUNT } }; + +#endif diff --git a/radio/src/gui/colorlcd/setup_menus/quick_menu_def.h b/radio/src/gui/colorlcd/setup_menus/quick_menu_def.h index 0335519e3..4ad3bfbca 100644 --- a/radio/src/gui/colorlcd/setup_menus/quick_menu_def.h +++ b/radio/src/gui/colorlcd/setup_menus/quick_menu_def.h @@ -21,6 +21,8 @@ #pragma once +#include "stamp.h" + enum QMPage { QM_NONE = 0, QM_OPEN_QUICK_MENU, diff --git a/radio/src/gui/colorlcd/setup_menus/quick_menu_group.cpp b/radio/src/gui/colorlcd/setup_menus/quick_menu_group.cpp index 130d0e28e..5fc6d5bb1 100644 --- a/radio/src/gui/colorlcd/setup_menus/quick_menu_group.cpp +++ b/radio/src/gui/colorlcd/setup_menus/quick_menu_group.cpp @@ -64,12 +64,16 @@ class QuickMenuButton : public ButtonBase visibleHandler(std::move(visibleHandler)) { iconPtr = new StaticIcon(this, (QuickMenuGroup::QM_BUTTON_WIDTH - QuickMenuGroup::QM_ICON_SIZE) / 2, PAD_SMALL, icon, COLOR_THEME_QM_FG_INDEX); +#if VERSION_MAJOR > 2 etx_obj_add_style(iconPtr->getLvObj(), styles->qmdisabled, LV_PART_MAIN | LV_STATE_DISABLED); +#endif etx_img_color(iconPtr->getLvObj(), COLOR_THEME_QM_BG_INDEX, LV_STATE_USER_1); textPtr = new StaticText(this, {0, QuickMenuGroup::QM_ICON_SIZE + PAD_TINY * 2, QuickMenuGroup::QM_BUTTON_WIDTH - 1, 0}, title, COLOR_THEME_QM_FG_INDEX, CENTERED | FONT(XS)); +#if VERSION_MAJOR > 2 etx_obj_add_style(textPtr->getLvObj(), styles->qmdisabled, LV_PART_MAIN | LV_STATE_DISABLED); +#endif etx_txt_color(textPtr->getLvObj(), COLOR_THEME_QM_BG_INDEX, LV_STATE_USER_1); lv_obj_add_event_cb(lvobj, QuickMenuButton::focused_cb, LV_EVENT_FOCUSED, nullptr); diff --git a/radio/src/gui/colorlcd/themes/theme_manager.cpp b/radio/src/gui/colorlcd/themes/theme_manager.cpp index 93cc5eead..bcb8c5a58 100644 --- a/radio/src/gui/colorlcd/themes/theme_manager.cpp +++ b/radio/src/gui/colorlcd/themes/theme_manager.cpp @@ -573,7 +573,7 @@ HeaderIcon::HeaderIcon(Window* parent, const char* iconFile, std::function action) : - StaticIcon(parent, LCD_W - PageGroup::PAGE_TOP_BAR_H, 0, ICON_TOPRIGHT_BG, COLOR_THEME_FOCUS_INDEX), + StaticIcon(parent, LCD_W - PageGroup::PAGE_GROUP_BACK_BTN_W, 0, ICON_TOPRIGHT_BG, COLOR_THEME_FOCUS_INDEX), action(std::move(action)) { (new StaticIcon(this, 0, 0, ICON_BTN_CLOSE, COLOR_THEME_PRIMARY2_INDEX))->center(width() + PAD_MEDIUM, height()); diff --git a/radio/src/gui/colorlcd/widgets/timer.cpp b/radio/src/gui/colorlcd/widgets/timer.cpp index d34903476..baeb02875 100644 --- a/radio/src/gui/colorlcd/widgets/timer.cpp +++ b/radio/src/gui/colorlcd/widgets/timer.cpp @@ -212,11 +212,11 @@ class TimerWidget : public Widget static LAYOUT_VAL_SCALED(NM_LRG_W, 93) static LAYOUT_VAL_SCALED(U0_X, 111) static LAYOUT_VAL_SCALED(U0_Y, 33) - static LAYOUT_VAL_SCALED(U1_X, 161) + static LAYOUT_VAL_SCALED(U1_X, 162) static LAYOUT_VAL_SCALED(U1_Y, 33) - static LAYOUT_VAL_SCALED(D0_X, 76) + static LAYOUT_VAL_SCALED(D0_X, 74) static LAYOUT_VAL_SCALED(D0_Y, 31) - static LAYOUT_VAL_SCALED(D1_X, 126) + static LAYOUT_VAL_SCALED(D1_X, 125) static LAYOUT_VAL_SCALED(D1_Y, 31) protected: diff --git a/radio/src/storage/yaml/yaml_datastructs_f16.cpp b/radio/src/storage/yaml/yaml_datastructs_f16.cpp index 3d6ee52e4..34ab7ef7a 100644 --- a/radio/src/storage/yaml/yaml_datastructs_f16.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_f16.cpp @@ -447,8 +447,8 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "modelQuickSelect", 1 ), YAML_PADDING( 5 ), YAML_UNSIGNED( "pwrOffIfInactive", 8 ), - YAML_ARRAY("keyShortcuts", 8, 6, struct_QuickMenuPage, NULL), - YAML_ARRAY("qmFavorites", 8, 12, struct_QuickMenuPage, NULL), + YAML_PADDING( 48 ), + YAML_PADDING( 96 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_nb4p.cpp b/radio/src/storage/yaml/yaml_datastructs_nb4p.cpp index 8db206445..522e53b26 100644 --- a/radio/src/storage/yaml/yaml_datastructs_nb4p.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_nb4p.cpp @@ -438,8 +438,8 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "modelQuickSelect", 1 ), YAML_PADDING( 5 ), YAML_UNSIGNED( "pwrOffIfInactive", 8 ), - YAML_ARRAY("keyShortcuts", 8, 6, struct_QuickMenuPage, NULL), - YAML_ARRAY("qmFavorites", 8, 12, struct_QuickMenuPage, NULL), + YAML_PADDING( 48 ), + YAML_PADDING( 96 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_nv14.cpp b/radio/src/storage/yaml/yaml_datastructs_nv14.cpp index 20a04c459..32920543f 100644 --- a/radio/src/storage/yaml/yaml_datastructs_nv14.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_nv14.cpp @@ -445,8 +445,8 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "modelQuickSelect", 1 ), YAML_PADDING( 5 ), YAML_UNSIGNED( "pwrOffIfInactive", 8 ), - YAML_ARRAY("keyShortcuts", 8, 6, struct_QuickMenuPage, NULL), - YAML_ARRAY("qmFavorites", 8, 12, struct_QuickMenuPage, NULL), + YAML_PADDING( 48 ), + YAML_PADDING( 96 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_pa01.cpp b/radio/src/storage/yaml/yaml_datastructs_pa01.cpp index 5f3392a05..49ec3819a 100644 --- a/radio/src/storage/yaml/yaml_datastructs_pa01.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_pa01.cpp @@ -470,8 +470,8 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "modelQuickSelect", 1 ), YAML_PADDING( 5 ), YAML_UNSIGNED( "pwrOffIfInactive", 8 ), - YAML_ARRAY("keyShortcuts", 8, 6, struct_QuickMenuPage, NULL), - YAML_ARRAY("qmFavorites", 8, 12, struct_QuickMenuPage, NULL), + YAML_PADDING( 48 ), + YAML_PADDING( 96 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_pl18.cpp b/radio/src/storage/yaml/yaml_datastructs_pl18.cpp index 6c3bb5fc7..4710850b8 100644 --- a/radio/src/storage/yaml/yaml_datastructs_pl18.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_pl18.cpp @@ -445,8 +445,8 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "modelQuickSelect", 1 ), YAML_PADDING( 5 ), YAML_UNSIGNED( "pwrOffIfInactive", 8 ), - YAML_ARRAY("keyShortcuts", 8, 6, struct_QuickMenuPage, NULL), - YAML_ARRAY("qmFavorites", 8, 12, struct_QuickMenuPage, NULL), + YAML_PADDING( 48 ), + YAML_PADDING( 96 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_pl18u.cpp b/radio/src/storage/yaml/yaml_datastructs_pl18u.cpp index 8dfd18c66..a55311fdd 100644 --- a/radio/src/storage/yaml/yaml_datastructs_pl18u.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_pl18u.cpp @@ -438,8 +438,8 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "modelQuickSelect", 1 ), YAML_PADDING( 5 ), YAML_UNSIGNED( "pwrOffIfInactive", 8 ), - YAML_ARRAY("keyShortcuts", 8, 6, struct_QuickMenuPage, NULL), - YAML_ARRAY("qmFavorites", 8, 12, struct_QuickMenuPage, NULL), + YAML_PADDING( 48 ), + YAML_PADDING( 96 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_st16.cpp b/radio/src/storage/yaml/yaml_datastructs_st16.cpp index a59adaa6a..57ab249a2 100644 --- a/radio/src/storage/yaml/yaml_datastructs_st16.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_st16.cpp @@ -470,8 +470,8 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "modelQuickSelect", 1 ), YAML_PADDING( 5 ), YAML_UNSIGNED( "pwrOffIfInactive", 8 ), - YAML_ARRAY("keyShortcuts", 8, 6, struct_QuickMenuPage, NULL), - YAML_ARRAY("qmFavorites", 8, 12, struct_QuickMenuPage, NULL), + YAML_PADDING( 48 ), + YAML_PADDING( 96 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_t15.cpp b/radio/src/storage/yaml/yaml_datastructs_t15.cpp index bab90cd29..3d3662040 100644 --- a/radio/src/storage/yaml/yaml_datastructs_t15.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_t15.cpp @@ -455,8 +455,8 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "modelQuickSelect", 1 ), YAML_PADDING( 5 ), YAML_UNSIGNED( "pwrOffIfInactive", 8 ), - YAML_ARRAY("keyShortcuts", 8, 6, struct_QuickMenuPage, NULL), - YAML_ARRAY("qmFavorites", 8, 12, struct_QuickMenuPage, NULL), + YAML_PADDING( 48 ), + YAML_PADDING( 96 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_t15pro.cpp b/radio/src/storage/yaml/yaml_datastructs_t15pro.cpp index a59adaa6a..57ab249a2 100644 --- a/radio/src/storage/yaml/yaml_datastructs_t15pro.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_t15pro.cpp @@ -470,8 +470,8 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "modelQuickSelect", 1 ), YAML_PADDING( 5 ), YAML_UNSIGNED( "pwrOffIfInactive", 8 ), - YAML_ARRAY("keyShortcuts", 8, 6, struct_QuickMenuPage, NULL), - YAML_ARRAY("qmFavorites", 8, 12, struct_QuickMenuPage, NULL), + YAML_PADDING( 48 ), + YAML_PADDING( 96 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_tx15.cpp b/radio/src/storage/yaml/yaml_datastructs_tx15.cpp index a59adaa6a..57ab249a2 100644 --- a/radio/src/storage/yaml/yaml_datastructs_tx15.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_tx15.cpp @@ -470,8 +470,8 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "modelQuickSelect", 1 ), YAML_PADDING( 5 ), YAML_UNSIGNED( "pwrOffIfInactive", 8 ), - YAML_ARRAY("keyShortcuts", 8, 6, struct_QuickMenuPage, NULL), - YAML_ARRAY("qmFavorites", 8, 12, struct_QuickMenuPage, NULL), + YAML_PADDING( 48 ), + YAML_PADDING( 96 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_x10.cpp b/radio/src/storage/yaml/yaml_datastructs_x10.cpp index 2a219413e..158a8911b 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x10.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x10.cpp @@ -446,8 +446,8 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "modelQuickSelect", 1 ), YAML_PADDING( 5 ), YAML_UNSIGNED( "pwrOffIfInactive", 8 ), - YAML_ARRAY("keyShortcuts", 8, 6, struct_QuickMenuPage, NULL), - YAML_ARRAY("qmFavorites", 8, 12, struct_QuickMenuPage, NULL), + YAML_PADDING( 48 ), + YAML_PADDING( 96 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = {