From 72d290f89f6775b41b8da3f245eddff00b8337d4 Mon Sep 17 00:00:00 2001 From: philmoz Date: Wed, 19 Nov 2025 19:40:23 +1100 Subject: [PATCH] feat(color): allow user to change key shortcut action; add Favorites quick menu (#6753) Co-authored-by: elecpower --- .../firmwares/edgetx/yaml_generalsettings.cpp | 61 ++ companion/src/firmwares/eeprominterface.h | 2 + companion/src/firmwares/generalsettings.cpp | 138 +++++ companion/src/firmwares/generalsettings.h | 63 +++ .../src/firmwares/opentx/opentxinterface.cpp | 4 + companion/src/generaledit/CMakeLists.txt | 2 + companion/src/generaledit/generaledit.cpp | 6 + .../src/generaledit/generalfavorites.cpp | 124 +++++ companion/src/generaledit/generalfavorites.h | 50 ++ .../src/generaledit/generalkeyshortcuts.cpp | 135 +++++ .../src/generaledit/generalkeyshortcuts.h | 50 ++ .../320x240/default_theme/mask_menu_favs.png | Bin 0 -> 661 bytes .../default_theme/mask_model_setup.png | Bin 1147 -> 1061 bytes .../default_theme/mask_radio_setup.png | Bin 1150 -> 1159 bytes .../480x272/default_theme/mask_menu_favs.png | Bin 0 -> 649 bytes .../default_theme/mask_model_setup.png | Bin 1379 -> 1265 bytes .../default_theme/mask_radio_setup.png | Bin 1387 -> 1405 bytes .../800x480/default_theme/mask_menu_favs.png | Bin 0 -> 1031 bytes .../default_theme/mask_model_setup.png | Bin 1910 -> 1709 bytes .../default_theme/mask_radio_setup.png | Bin 1884 -> 2004 bytes .../img-src/default_theme/mask_menu_favs.svg | 7 + .../default_theme/mask_model_setup.svg | 88 +-- .../default_theme/mask_radio_setup.svg | 97 +--- radio/src/datastructs.h | 4 +- radio/src/datastructs_model.cpp | 5 +- radio/src/datastructs_private.h | 21 + radio/src/datastructs_radio.cpp | 80 +++ radio/src/edgetx.cpp | 3 + radio/src/gui/colorlcd/bitmaps.cpp | 5 + radio/src/gui/colorlcd/bitmaps.h | 1 + radio/src/gui/colorlcd/libui/page.cpp | 17 +- radio/src/gui/colorlcd/libui/view_text.h | 2 - .../gui/colorlcd/mainview/screen_setup.cpp | 6 +- .../src/gui/colorlcd/mainview/screen_setup.h | 4 - radio/src/gui/colorlcd/mainview/topbar.cpp | 2 +- .../gui/colorlcd/mainview/view_channels.cpp | 2 +- radio/src/gui/colorlcd/mainview/view_main.cpp | 43 +- radio/src/gui/colorlcd/mainview/view_main.h | 1 + .../gui/colorlcd/mainview/widgets_setup.cpp | 2 +- radio/src/gui/colorlcd/model/model_curves.h | 2 - .../gui/colorlcd/model/model_flightmodes.h | 2 - radio/src/gui/colorlcd/model/model_gvars.h | 2 - .../colorlcd/model/model_logical_switches.h | 2 - .../gui/colorlcd/model/model_mixer_scripts.h | 2 - radio/src/gui/colorlcd/model/model_select.cpp | 11 +- radio/src/gui/colorlcd/model/model_select.h | 1 + .../src/gui/colorlcd/model/model_telemetry.h | 2 - .../gui/colorlcd/model/special_functions.h | 4 - .../src/gui/colorlcd/radio/radio_diaganas.cpp | 26 +- radio/src/gui/colorlcd/radio/radio_diaganas.h | 2 +- .../src/gui/colorlcd/radio/radio_hardware.cpp | 2 +- radio/src/gui/colorlcd/radio/radio_setup.cpp | 15 +- radio/src/gui/colorlcd/radio/radio_theme.h | 2 - radio/src/gui/colorlcd/radio/radio_trainer.h | 2 - .../colorlcd/setup_menus/key_shortcuts.cpp | 88 +++ .../gui/colorlcd/setup_menus/key_shortcuts.h | 33 ++ .../gui/colorlcd/setup_menus/menu_model.cpp | 58 -- .../gui/colorlcd/setup_menus/menu_radio.cpp | 36 -- .../gui/colorlcd/setup_menus/menu_screen.cpp | 71 --- .../gui/colorlcd/setup_menus/menu_tools.cpp | 53 -- .../gui/colorlcd/setup_menus/pagegroup.cpp | 89 +-- .../src/gui/colorlcd/setup_menus/pagegroup.h | 54 +- .../gui/colorlcd/setup_menus/quick_menu.cpp | 521 ++++++++++++------ .../src/gui/colorlcd/setup_menus/quick_menu.h | 112 +--- .../colorlcd/setup_menus/quick_menu_data.cpp | 179 ++++++ .../gui/colorlcd/setup_menus/quick_menu_def.h | 69 +++ .../setup_menus/quick_menu_favorites.cpp | 72 +++ .../setup_menus/quick_menu_favorites.h | 37 ++ .../colorlcd/setup_menus/quick_menu_group.cpp | 6 +- .../colorlcd/setup_menus/quick_menu_group.h | 2 +- radio/src/storage/sdcard_yaml.cpp | 3 + .../src/storage/yaml/yaml_datastructs_f16.cpp | 50 ++ .../storage/yaml/yaml_datastructs_nb4p.cpp | 50 ++ .../storage/yaml/yaml_datastructs_nv14.cpp | 50 ++ .../storage/yaml/yaml_datastructs_pa01.cpp | 50 ++ .../storage/yaml/yaml_datastructs_pl18.cpp | 50 ++ .../storage/yaml/yaml_datastructs_pl18u.cpp | 50 ++ .../storage/yaml/yaml_datastructs_st16.cpp | 50 ++ .../src/storage/yaml/yaml_datastructs_t15.cpp | 50 ++ .../storage/yaml/yaml_datastructs_t15pro.cpp | 50 ++ .../storage/yaml/yaml_datastructs_tx15.cpp | 50 ++ .../src/storage/yaml/yaml_datastructs_x10.cpp | 50 ++ radio/src/translations/i18n/cn.h | 13 +- radio/src/translations/i18n/cz.h | 13 +- radio/src/translations/i18n/da.h | 13 +- radio/src/translations/i18n/de.h | 13 +- radio/src/translations/i18n/en.h | 13 +- radio/src/translations/i18n/es.h | 13 +- radio/src/translations/i18n/fi.h | 13 +- radio/src/translations/i18n/fr.h | 13 +- radio/src/translations/i18n/he.h | 13 +- radio/src/translations/i18n/it.h | 13 +- radio/src/translations/i18n/jp.h | 13 +- radio/src/translations/i18n/ko.h | 13 +- radio/src/translations/i18n/nl.h | 13 +- radio/src/translations/i18n/pl.h | 13 +- radio/src/translations/i18n/pt.h | 13 +- radio/src/translations/i18n/ru.h | 13 +- radio/src/translations/i18n/se.h | 13 +- radio/src/translations/i18n/tw.h | 89 +-- radio/src/translations/i18n/ua.h | 13 +- radio/src/translations/sim_string_list.h | 34 +- radio/src/translations/string_list.h | 34 +- 103 files changed, 2605 insertions(+), 921 deletions(-) create mode 100644 companion/src/generaledit/generalfavorites.cpp create mode 100644 companion/src/generaledit/generalfavorites.h create mode 100644 companion/src/generaledit/generalkeyshortcuts.cpp create mode 100644 companion/src/generaledit/generalkeyshortcuts.h create mode 100644 radio/src/bitmaps/320x240/default_theme/mask_menu_favs.png create mode 100644 radio/src/bitmaps/480x272/default_theme/mask_menu_favs.png create mode 100644 radio/src/bitmaps/800x480/default_theme/mask_menu_favs.png create mode 100644 radio/src/bitmaps/img-src/default_theme/mask_menu_favs.svg create mode 100644 radio/src/gui/colorlcd/setup_menus/key_shortcuts.cpp create mode 100644 radio/src/gui/colorlcd/setup_menus/key_shortcuts.h delete mode 100644 radio/src/gui/colorlcd/setup_menus/menu_model.cpp delete mode 100644 radio/src/gui/colorlcd/setup_menus/menu_radio.cpp delete mode 100644 radio/src/gui/colorlcd/setup_menus/menu_screen.cpp delete mode 100644 radio/src/gui/colorlcd/setup_menus/menu_tools.cpp create mode 100644 radio/src/gui/colorlcd/setup_menus/quick_menu_data.cpp create mode 100644 radio/src/gui/colorlcd/setup_menus/quick_menu_def.h create mode 100644 radio/src/gui/colorlcd/setup_menus/quick_menu_favorites.cpp create mode 100644 radio/src/gui/colorlcd/setup_menus/quick_menu_favorites.h diff --git a/companion/src/firmwares/edgetx/yaml_generalsettings.cpp b/companion/src/firmwares/edgetx/yaml_generalsettings.cpp index 54e4a0080..343d1670e 100644 --- a/companion/src/firmwares/edgetx/yaml_generalsettings.cpp +++ b/companion/src/firmwares/edgetx/yaml_generalsettings.cpp @@ -136,6 +136,49 @@ static const YamlLookupTable hatsModeLut = { { GeneralSettings::HATSMODE_SWITCHABLE, "SWITCHABLE" }, }; +static const YamlLookupTable QMPageLut = { + { GeneralSettings::QM_NONE, "NONE" }, + { GeneralSettings::QM_OPEN_QUICK_MENU, "OPEN_QUICK_MENU" }, + { GeneralSettings::QM_MANAGE_MODELS, "MANAGE_MODELS" }, + { GeneralSettings::QM_MODEL_SETUP, "MODEL_SETUP" }, + { GeneralSettings::QM_MODEL_FLIGHTMODES, "MODEL_FLIGHTMODES" }, + { GeneralSettings::QM_MODEL_INPUTS, "MODEL_INPUTS" }, + { GeneralSettings::QM_MODEL_MIXES, "MODEL_MIXES" }, + { GeneralSettings::QM_MODEL_OUTPUTS, "MODEL_OUTPUTS" }, + { GeneralSettings::QM_MODEL_CURVES, "MODEL_CURVES" }, + { GeneralSettings::QM_MODEL_GVARS, "MODEL_GVARS" }, + { GeneralSettings::QM_MODEL_LS, "MODEL_LS" }, + { GeneralSettings::QM_MODEL_SF, "MODEL_SF" }, + { GeneralSettings::QM_MODEL_SCRIPTS, "MODEL_SCRIPTS" }, + { GeneralSettings::QM_MODEL_TELEMETRY, "MODEL_TELEMETRY" }, + { GeneralSettings::QM_MODEL_NOTES, "MODEL_NOTES" }, + { GeneralSettings::QM_RADIO_SETUP, "RADIO_SETUP" }, + { GeneralSettings::QM_RADIO_GF, "RADIO_GF" }, + { GeneralSettings::QM_RADIO_TRAINER, "RADIO_TRAINER" }, + { GeneralSettings::QM_RADIO_HARDWARE, "RADIO_HARDWARE" }, + { GeneralSettings::QM_RADIO_VERSION, "RADIO_VERSION" }, + { GeneralSettings::QM_UI_THEMES, "UI_THEMES" }, + { GeneralSettings::QM_UI_SETUP, "UI_SETUP" }, + { GeneralSettings::QM_UI_SCREEN1, "UI_SCREEN1" }, + { GeneralSettings::QM_UI_SCREEN2, "UI_SCREEN2" }, + { GeneralSettings::QM_UI_SCREEN3, "UI_SCREEN3" }, + { GeneralSettings::QM_UI_SCREEN4, "UI_SCREEN4" }, + { GeneralSettings::QM_UI_SCREEN5, "UI_SCREEN5" }, + { GeneralSettings::QM_UI_SCREEN6, "UI_SCREEN6" }, + { GeneralSettings::QM_UI_SCREEN7, "UI_SCREEN7" }, + { GeneralSettings::QM_UI_SCREEN8, "UI_SCREEN8" }, + { GeneralSettings::QM_UI_SCREEN9, "UI_SCREEN9" }, + { GeneralSettings::QM_UI_SCREEN10, "UI_SCREEN10" }, + { GeneralSettings::QM_UI_ADD_PG, "UI_ADD_PG" }, + { GeneralSettings::QM_TOOLS_APPS, "TOOLS_APPS" }, + { GeneralSettings::QM_TOOLS_STORAGE, "TOOLS_STORAGE" }, + { GeneralSettings::QM_TOOLS_RESET, "TOOLS_RESET" }, + { GeneralSettings::QM_TOOLS_CHAN_MON, "TOOLS_CHAN_MON" }, + { GeneralSettings::QM_TOOLS_LS_MON, "TOOLS_LS_MON" }, + { GeneralSettings::QM_TOOLS_STATS, "TOOLS_STATS" }, + { GeneralSettings::QM_TOOLS_DEBUG, "TOOLS_DEBUG" }, +}; + YamlTelemetryBaudrate::YamlTelemetryBaudrate( const unsigned int* moduleBaudrate) { @@ -343,6 +386,15 @@ Node convert::encode(const GeneralSettings& rhs) node["modelCustomScriptsDisabled"] = (int)rhs.modelCustomScriptsDisabled; node["modelTelemetryDisabled"] = (int)rhs.modelTelemetryDisabled; + if (hasColorLcd) { + 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]; + for (int i = 0; i < MAX_QMFAVOURITES; i += 1) + if (rhs.qmFavorites[i] != GeneralSettings::QM_NONE) + node["qmFavorites"][std::to_string(i)]["shortcut"] = QMPageLut << rhs.qmFavorites[i]; + } + return node; } @@ -653,6 +705,15 @@ bool convert::decode(const Node& node, GeneralSettings& rhs) node["labelMultiMode"] >> rhs.labelMultiMode; node["favMultiMode"] >> rhs.favMultiMode; + if (node["keyShortcuts"]) { + for (int i = 0; i < MAX_KEYSHORTCUTS; i += 1) + node["keyShortcuts"][std::to_string(i)]["shortcut"] >> QMPageLut >> rhs.keyShortcuts[i]; + } + if (node["qmFavorites"]) { + for (int i = 0; i < MAX_QMFAVOURITES; i += 1) + node["qmFavorites"][std::to_string(i)]["shortcut"] >> QMPageLut >> rhs.qmFavorites[i]; + } + // override critical settings after import // TODO: for consistency move up call stack to use existing eeprom and profile conversions if (needsConversion) diff --git a/companion/src/firmwares/eeprominterface.h b/companion/src/firmwares/eeprominterface.h index 973a950b4..4377e5009 100644 --- a/companion/src/firmwares/eeprominterface.h +++ b/companion/src/firmwares/eeprominterface.h @@ -172,6 +172,8 @@ enum Capability { HasIntModuleELRS, HasIntModuleFlySky, BacklightLevelMin, + QMFavourites, + KeyShortcuts, }; float ValToTim(int value); diff --git a/companion/src/firmwares/generalsettings.cpp b/companion/src/firmwares/generalsettings.cpp index 8038c33d5..3b0cbf011 100644 --- a/companion/src/firmwares/generalsettings.cpp +++ b/companion/src/firmwares/generalsettings.cpp @@ -241,6 +241,8 @@ void GeneralSettings::init() } stickDeadZone = (IS_FLYSKY_NV14(board) || IS_FAMILY_PL18(board)) ? 2 : 0; + setDefaultFavorites(); + setDefaultKeyShortcuts(); } void GeneralSettings::setDefaultControlTypes(Board::Type board) @@ -960,3 +962,139 @@ AbstractStaticItemModel * GeneralSettings::backlightModeItemModel() mdl->loadItemList(); return mdl; } + +// static +QString GeneralSettings::quickMenuToString(int value, bool keys) +{ + switch(value) { + case QM_NONE: + return tr("None"); + case QM_OPEN_QUICK_MENU: + return tr("Open Quick Menu"); + case QM_MANAGE_MODELS: + return tr("MANAGE MODELS"); + // Model menu + case QM_MODEL_SETUP: + return tr("Model Setup - Model Settings"); + case QM_MODEL_FLIGHTMODES: + return tr("Model Setup - Flight Modes"); + case QM_MODEL_INPUTS: + return tr("Model Setup - Inputs"); + case QM_MODEL_MIXES: + return tr("Model Setup - Mixes"); + case QM_MODEL_OUTPUTS: + return tr("Model Setup - Outputs"); + case QM_MODEL_CURVES: + return tr("Model Setup - Curves"); + case QM_MODEL_GVARS: + return tr("Model Setup - Global Variables"); + case QM_MODEL_LS: + return tr("Model Setup - Logical Switches"); + case QM_MODEL_SF: + return tr("Model Setup - Special Functions"); + case QM_MODEL_SCRIPTS: + return tr("Model Setup - Mixer Scripts"); + case QM_MODEL_TELEMETRY: + return tr("Model Setup - Telemetry"); + case QM_MODEL_NOTES: + return tr("Model Setup - Notes"); + // Radio menu + case QM_RADIO_SETUP: + return tr("Radio Setup - Radio Settings"); + case QM_RADIO_GF: + return tr("Radio Setup - Global Functions"); + case QM_RADIO_TRAINER: + return tr("Radio Setup - Trainer"); + case QM_RADIO_HARDWARE: + return tr("Radio Setup - Hardware"); + case QM_RADIO_VERSION: + return tr("Radio Setup - About EdgeTX"); + // UI menu + case QM_UI_THEMES: + return tr("UI Setup - Themes"); + case QM_UI_SETUP: + return tr("UI Setup - Top Bar"); + case QM_UI_SCREEN1: + return keys ? tr("UI Setup - Current Screen") : tr("UI Setup - Screen 1"); + case QM_UI_SCREEN2: + return tr("UI Setup - Screen 2"); + case QM_UI_SCREEN3: + return tr("UI Setup - Screen 3"); + case QM_UI_SCREEN4: + return tr("UI Setup - Screen 4"); + case QM_UI_SCREEN5: + return tr("UI Setup - Screen 5"); + case QM_UI_SCREEN6: + return tr("UI Setup - Screen 6"); + case QM_UI_SCREEN7: + return tr("UI Setup - Screen 7"); + case QM_UI_SCREEN8: + return tr("UI Setup - Screen 8"); + case QM_UI_SCREEN9: + return tr("UI Setup - Screen 9"); + case QM_UI_SCREEN10: + return tr("UI Setup - Screen 10"); + case QM_UI_ADD_PG: + return tr("UI Setup - Add Screen"); + // Tools menu + case QM_TOOLS_APPS: + return tr("Tools - Apps"); + case QM_TOOLS_STORAGE: + return tr("Tools - Storage"); + case QM_TOOLS_RESET: + return tr("Tools - Flight Reset"); + case QM_TOOLS_CHAN_MON: + return tr("Tools - Channel Monitor"); + case QM_TOOLS_LS_MON: + return tr("Tools - Logical Switch Monitor"); + case QM_TOOLS_STATS: + return tr("Tools - Statistics"); + case QM_TOOLS_DEBUG: + return tr("Tools - Debug"); + default: + return CPN_STR_UNKNOWN_ITEM; + } +} + +// static +bool GeneralSettings::isQuickMenuAvailable(int value, bool keys) +{ + if (keys) { + if (value >= QM_UI_SCREEN2 && value <= QM_UI_ADD_PG) + return false; + } else if (value == QM_OPEN_QUICK_MENU) + return false; + + return true; +} + +// static +AbstractStaticItemModel * GeneralSettings::quickMenuItemModel(bool keys) +{ + AbstractStaticItemModel * mdl = new AbstractStaticItemModel(); + mdl->setName(AIM_GS_QUICKMENU); + + for (int i = 0; i < QM_COUNT; i++) { + if (isQuickMenuAvailable(i, keys)) + mdl->appendToItemList(quickMenuToString(i, keys), i); + } + + mdl->loadItemList(); + return mdl; +} + +void GeneralSettings::setDefaultFavorites() +{ + for (int i = 0; i < MAX_QMFAVOURITES; i++) + qmFavorites[i] = QM_NONE; +} + +void GeneralSettings::setDefaultKeyShortcuts() +{ + keyShortcuts[0] = QM_MODEL_SETUP; // MDL short + keyShortcuts[1] = 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[5] = QM_TOOLS_CHAN_MON; // TELE long +} diff --git a/companion/src/firmwares/generalsettings.h b/companion/src/firmwares/generalsettings.h index 674b77205..a0d25dcdc 100644 --- a/companion/src/firmwares/generalsettings.h +++ b/companion/src/firmwares/generalsettings.h @@ -47,13 +47,18 @@ constexpr char AIM_GS_HATSMODE[] {"gs.hatsmode"}; constexpr char AIM_GS_STICKMODE[] {"gs.stickmode"}; constexpr char AIM_GS_TEMPLATESETUP[] {"gs.templatesetup"}; constexpr char AIM_GS_BACKLIGHTMODE[] {"gs.backlightmode"}; +constexpr char AIM_GS_QUICKMENU[] {"gs.quickmenu"}; constexpr char AIM_TRAINERMIX_MODE[] {"trainermix.mode"}; constexpr char AIM_TRAINERMIX_SRC[] {"trainermix.src"}; +constexpr int MAX_KEYSHORTCUTS {6}; +constexpr int MAX_QMFAVOURITES {12}; + static const QStringList moduleBaudratesList({"115K", "400K", "921K", "1.87M", "3.75M", "5.25M"}); + enum UartModes { UART_MODE_NONE, UART_MODE_TELEMETRY_MIRROR, @@ -225,6 +230,55 @@ class GeneralSettings { BACKLIGHT_MODE_COUNT, }; + // Match equivalent enum in radio/src/gui/colorlcd/setup_menus/quick_menu.h + enum QMPage { + QM_NONE = 0, + QM_OPEN_QUICK_MENU, + QM_MANAGE_MODELS, + // Model menu + QM_MODEL_SETUP, + QM_MODEL_FLIGHTMODES, + QM_MODEL_INPUTS, + QM_MODEL_MIXES, + QM_MODEL_OUTPUTS, + QM_MODEL_CURVES, + QM_MODEL_GVARS, + QM_MODEL_LS, + QM_MODEL_SF, + QM_MODEL_SCRIPTS, + QM_MODEL_TELEMETRY, + QM_MODEL_NOTES, + // Radio menu + QM_RADIO_SETUP, + QM_RADIO_GF, + QM_RADIO_TRAINER, + QM_RADIO_HARDWARE, + QM_RADIO_VERSION, + // UI menu + QM_UI_THEMES, + QM_UI_SETUP, + QM_UI_SCREEN1, + QM_UI_SCREEN2, + QM_UI_SCREEN3, + QM_UI_SCREEN4, + QM_UI_SCREEN5, + QM_UI_SCREEN6, + QM_UI_SCREEN7, + QM_UI_SCREEN8, + QM_UI_SCREEN9, + QM_UI_SCREEN10, + QM_UI_ADD_PG, + // Tools menu + QM_TOOLS_APPS, + QM_TOOLS_STORAGE, + QM_TOOLS_RESET, + QM_TOOLS_CHAN_MON, + QM_TOOLS_LS_MON, + QM_TOOLS_STATS, + QM_TOOLS_DEBUG, + QM_COUNT, + }; + GeneralSettings() { clear(); } void clear(); void init(); @@ -235,6 +289,8 @@ class GeneralSettings { RawSource getDefaultSource(unsigned int channel) const; int getDefaultChannel(unsigned int stick) const; bool fix6POSCalibration(); + void setDefaultFavorites(); + void setDefaultKeyShortcuts(); bool manuallyEdited; @@ -394,6 +450,10 @@ class GeneralSettings { }; SwitchConfig switchConfig[CPN_MAX_SWITCHES]; + + unsigned int keyShortcuts[MAX_KEYSHORTCUTS]; + unsigned int qmFavorites[MAX_QMFAVOURITES]; + void switchConfigClear(); bool switchPositionAllowed(int index) const; @@ -410,6 +470,7 @@ class GeneralSettings { bool isSwitchFunc(int index) const; bool unassignedInputFlexSwitches() const; static bool isBacklightModeAvailable(int index); + static bool isQuickMenuAvailable(int value, bool keys); QString antennaModeToString() const; QString bluetoothModeToString() const; @@ -432,6 +493,7 @@ class GeneralSettings { static QString stickModeToString(int value); static QString templateSetupToString(int value, bool isBoardAir); static QString backlightModeToString(int value); + static QString quickMenuToString(int value, bool keys); static AbstractStaticItemModel * antennaModeItemModel(bool model_setup = false); static AbstractStaticItemModel * bluetoothModeItemModel(); @@ -443,6 +505,7 @@ class GeneralSettings { static AbstractStaticItemModel * stickModeItemModel(); static AbstractStaticItemModel * templateSetupItemModel(); static AbstractStaticItemModel * backlightModeItemModel(); + static AbstractStaticItemModel * quickMenuItemModel(bool keys); void validateFlexSwitches(); }; diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp index bb901c22f..4526e971f 100644 --- a/companion/src/firmwares/opentx/opentxinterface.cpp +++ b/companion/src/firmwares/opentx/opentxinterface.cpp @@ -357,6 +357,10 @@ int OpenTxFirmware::getCapability(::Capability capability) } else { return 46; } + case QMFavourites: + return Boards::getCapability(board, Board::HasColorLcd) ? MAX_QMFAVOURITES : 0; + case KeyShortcuts: + return Boards::getCapability(board, Board::HasColorLcd) ? MAX_KEYSHORTCUTS : 0; default: return 0; } diff --git a/companion/src/generaledit/CMakeLists.txt b/companion/src/generaledit/CMakeLists.txt index 97c8cc89d..7eeea296d 100644 --- a/companion/src/generaledit/CMakeLists.txt +++ b/companion/src/generaledit/CMakeLists.txt @@ -3,6 +3,8 @@ project(generaledit) set(${PROJECT_NAME}_NAMES generaledit + generalfavorites + generalkeyshortcuts generaloptions generalsetup hardware diff --git a/companion/src/generaledit/generaledit.cpp b/companion/src/generaledit/generaledit.cpp index 5a41e6880..5bfad3249 100644 --- a/companion/src/generaledit/generaledit.cpp +++ b/companion/src/generaledit/generaledit.cpp @@ -31,6 +31,8 @@ #include "scrollarea.h" #include "compounditemmodels.h" #include "firmwares/edgetx/edgetxinterface.h" +#include "generalfavorites.h" +#include "generalkeyshortcuts.h" GeneralEdit::GeneralEdit(QWidget * parent, RadioData & radioData, Firmware * firmware) : QDialog(parent), @@ -56,6 +58,10 @@ GeneralEdit::GeneralEdit(QWidget * parent, RadioData & radioData, Firmware * fir auto hwpnl = new HardwarePanel(this, generalSettings, firmware, editorItemModels); addTab(hwpnl, tr("Hardware")); addTab(new GeneralOptionsPanel(this, generalSettings, firmware), tr("Enabled Features")); + if (firmware->getCapability(QMFavourites)) + addTab(new GeneralFavsPanel(this, generalSettings, firmware), tr("Favourites")); + if (firmware->getCapability(KeyShortcuts)) + addTab(new GeneralKeysPanel(this, generalSettings, firmware), tr("Key Shortcuts")); connect(hwpnl, &HardwarePanel::internalModuleChanged, this, [&] { intModChanged = true; }); diff --git a/companion/src/generaledit/generalfavorites.cpp b/companion/src/generaledit/generalfavorites.cpp new file mode 100644 index 000000000..3e40f437c --- /dev/null +++ b/companion/src/generaledit/generalfavorites.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "generalfavorites.h" +#include "autocombobox.h" +#include "compounditemmodels.h" +#include "exclusivecombogroup.h" + +#include +#include + +GeneralFavsPanel::GeneralFavsPanel(QWidget * parent, GeneralSettings & generalSettings, Firmware * firmware): + GeneralPanel(parent, generalSettings, firmware), + board(firmware->getBoard()), + params(new QList), + row(0), + col(0) +{ + grid = new QGridLayout(this); + // All values except QM_NONE are mutually exclusive + cboQMGrp = new ExclusiveComboGroup(this, + [=](const QVariant &value) { return value == GeneralSettings::QM_NONE; }); + const int cnt = firmware->getCapability(QMFavourites); + + for (int i = 0; i < cnt; i++) { + addLabel(tr("# %1").arg(i + 1)); + AutoComboBox *cbo = new AutoComboBox(this); + // separate item model per combo box due to mutual exclusivity + cbo->setModel(generalSettings.quickMenuItemModel(false)); + cbo->setField(generalSettings.qmFavorites[i], this); + cboQMGrp->addCombo(cbo); + params->append(cbo); + addParams(); + } + + addLine(); + + QPushButton *reset = new QPushButton(tr("Reset")); + connect(reset, &QPushButton::clicked, [&] () + { + generalSettings.setDefaultFavorites(); + + foreach(AutoComboBox *cb, findChildren()) + cb->updateValue(); + + initComboQMGroup(); + }); + params->append(reset); + addParams(); + + initComboQMGroup(); + addVSpring(grid, 0, grid->rowCount()); + addHSpring(grid, grid->columnCount(), 0); + disableMouseScrolling(); +} + +GeneralFavsPanel::~GeneralFavsPanel() +{ + +} + +void GeneralFavsPanel::addLabel(QString text) +{ + QLabel *label = new QLabel(this); + label->setText(text); + grid->addWidget(label, row, col); +} + +void GeneralFavsPanel::addLine() +{ + QFrame *line = new QFrame(this); + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Sunken); + line->setLineWidth(1); + line->setMidLineWidth(0); + grid->addWidget(line, row++, 0, 1, grid->columnCount()); +} + +void GeneralFavsPanel::addParams() +{ + int col = 0; + QGridLayout *subgrid = new QGridLayout(); + + for (int i = 0; i < params->size(); i++) { + subgrid->addWidget(params->at(i), 0, col++); + } + + addHSpring(subgrid, col, 0); + grid->addLayout(subgrid, row++, this->col + 1); + params->clear(); +} + +void GeneralFavsPanel::addSection(QString text) +{ + addLabel(QString("%1").arg(text)); + row++; +} + +void GeneralFavsPanel::initComboQMGroup() +{ + // force mutually exclusive update to lists + for (int i = 0; i < cboQMGrp->getComboBoxes()->size(); i++) { + QComboBox *cbo = cboQMGrp->getComboBoxes()->at(i); + cboQMGrp->handleActivated(cbo, cbo->currentIndex()); + } +} diff --git a/companion/src/generaledit/generalfavorites.h b/companion/src/generaledit/generalfavorites.h new file mode 100644 index 000000000..8f3127ed3 --- /dev/null +++ b/companion/src/generaledit/generalfavorites.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#pragma once + +#include "generaledit.h" + +class ExclusiveComboGroup; +class QGridLayout; + +class GeneralFavsPanel : public GeneralPanel +{ + Q_OBJECT + + public: + GeneralFavsPanel(QWidget * parent, GeneralSettings & generalSettings, Firmware * firmware); + virtual ~GeneralFavsPanel(); + + private: + Board::Type board; + QGridLayout *grid; + QList *params; + int row; + int col; + ExclusiveComboGroup *cboQMGrp; + + void addLabel(QString text); + void addLine(); + void addParams(); + void addSection(QString text); + void initComboQMGroup(); +}; diff --git a/companion/src/generaledit/generalkeyshortcuts.cpp b/companion/src/generaledit/generalkeyshortcuts.cpp new file mode 100644 index 000000000..d881d5be7 --- /dev/null +++ b/companion/src/generaledit/generalkeyshortcuts.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "generalkeyshortcuts.h" +#include "autocombobox.h" +#include "compounditemmodels.h" +#include "exclusivecombogroup.h" + +#include +#include + +GeneralKeysPanel::GeneralKeysPanel(QWidget * parent, GeneralSettings & generalSettings, Firmware * firmware): + GeneralPanel(parent, generalSettings, firmware), + board(firmware->getBoard()), + params(new QList), + row(0), + col(0) +{ + grid = new QGridLayout(this); + // All values except QM_NONE are mutually exclusive + cboQMGrp = new ExclusiveComboGroup(this, + [=](const QVariant &value) { return value == GeneralSettings::QM_NONE; }); + const int cnt = firmware->getCapability(KeyShortcuts); + + const int split = 2; + + for (int i = 0; i < split; i++) { + if (i == 0) { + addSection(tr("Short Press")); + } else { + addLine(); + addSection(tr("Long Press")); + } + + for (int j = 0; j < (cnt / split); j++) { + addLabel(j == 0 ? tr("MDL") : (j == 1 ? tr("SYS") : tr("TELE"))); + AutoComboBox *cbo = new AutoComboBox(this); + // separate item model per combo box due to mutual exclusivity + cbo->setModel(generalSettings.quickMenuItemModel(true)); + cbo->setField(generalSettings.keyShortcuts[(i * (split + 1)) + j], this); + cboQMGrp->addCombo(cbo); + params->append(cbo); + addParams(); + } + } + + addLine(); + + QPushButton *reset = new QPushButton(tr("Reset")); + connect(reset, &QPushButton::clicked, [&] () + { + generalSettings.setDefaultKeyShortcuts(); + + foreach(AutoComboBox *cb, findChildren()) + cb->updateValue(); + + initComboQMGroup(); + }); + params->append(reset); + addParams(); + + initComboQMGroup(); + addVSpring(grid, 0, grid->rowCount()); + addHSpring(grid, grid->columnCount(), 0); + disableMouseScrolling(); +} + +GeneralKeysPanel::~GeneralKeysPanel() +{ + +} + +void GeneralKeysPanel::addLabel(QString text) +{ + QLabel *label = new QLabel(this); + label->setText(text); + grid->addWidget(label, row, col); +} + +void GeneralKeysPanel::addLine() +{ + QFrame *line = new QFrame(this); + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Sunken); + line->setLineWidth(1); + line->setMidLineWidth(0); + grid->addWidget(line, row++, 0, 1, grid->columnCount()); +} + +void GeneralKeysPanel::addParams() +{ + int col = 0; + QGridLayout *subgrid = new QGridLayout(); + + for (int i = 0; i < params->size(); i++) { + subgrid->addWidget(params->at(i), 0, col++); + } + + addHSpring(subgrid, col, 0); + grid->addLayout(subgrid, row++, this->col + 1); + params->clear(); +} + +void GeneralKeysPanel::addSection(QString text) +{ + addLabel(QString("%1").arg(text)); + row++; +} + +void GeneralKeysPanel::initComboQMGroup() +{ + // force mutually exclusive update to lists + for (int i = 0; i < cboQMGrp->getComboBoxes()->size(); i++) { + QComboBox *cbo = cboQMGrp->getComboBoxes()->at(i); + cboQMGrp->handleActivated(cbo, cbo->currentIndex()); + } +} diff --git a/companion/src/generaledit/generalkeyshortcuts.h b/companion/src/generaledit/generalkeyshortcuts.h new file mode 100644 index 000000000..b28ebc2a6 --- /dev/null +++ b/companion/src/generaledit/generalkeyshortcuts.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#pragma once + +#include "generaledit.h" + +class ExclusiveComboGroup; +class QGridLayout; + +class GeneralKeysPanel : public GeneralPanel +{ + Q_OBJECT + + public: + GeneralKeysPanel(QWidget * parent, GeneralSettings & generalSettings, Firmware * firmware); + virtual ~GeneralKeysPanel(); + + private: + Board::Type board; + QGridLayout *grid; + QList *params; + int row; + int col; + ExclusiveComboGroup *cboQMGrp; + + void addLabel(QString text); + void addLine(); + void addParams(); + void addSection(QString text); + void initComboQMGroup(); +}; diff --git a/radio/src/bitmaps/320x240/default_theme/mask_menu_favs.png b/radio/src/bitmaps/320x240/default_theme/mask_menu_favs.png new file mode 100644 index 0000000000000000000000000000000000000000..4224f562db26c1af01c13781652f58eea4290bf4 GIT binary patch literal 661 zcmV;G0&4wnGbKU${eCi;l*?uDu~aI}=kvqi@D^w~o%(z}gTbIwDj9}x zxm>5yNepc^8@t`ER;!gtrNLnE`~8c>LK5V3I#a3C>2$hWE>b&RE|>H9oJysvR;yfT z!Cs*LyskN59YK z(`YnLmq>oKcDwziQx3FVub0cEXh);bNF*ZKuh)LR{{d(?943>=>2w+nheb~?7#xj8>2z8gJCAyP))I-t&(F_4PK83jah%jI zMiD{)KoEq#y^j>B5YO`fKnNk*?N+PRQWO=7#pKWTqj;XrX0wR6TCD&P3x&eh!(X9L v6pKYfB;pv|@Ao{yfpo600000NkvXXu0mjf&b=y) literal 0 HcmV?d00001 diff --git a/radio/src/bitmaps/320x240/default_theme/mask_model_setup.png b/radio/src/bitmaps/320x240/default_theme/mask_model_setup.png index bc6633952b4d28cd0a99887a3b86f5a68063981c..0e61bd4dd3e56a168771f877f6a0dece312e410a 100644 GIT binary patch delta 997 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 N002ovPDHLkV1oLy8Cd`T delta 1086 zcmV-E1i|}<3H}I>D+>qT000Ny0nbHAg^@NWe+x-OK~y-6eN@X!GH(<yAwdkT4gi&;{qM#@YLDUu% zMHfhC-f!{toBaHK-*;B?zUQ20p66U%K!34#JZ>}^DT;#s%wRD5Ef^sLN$11EL;SI} zf3^kyYPFhWS(arPhLK98UteDcq07rlm&^4pps}$r0BC7xi9{lUgM$DtH#dh}&CSgK z;P?Bdr>7Z)5s5@gOH2O`G%+zj5Cm3{o}RAJXaL~!^b~tXM@Ipmpr8N%Xqu*Jnk32P z<>h1`yWLKbWNK=v$K&bi>th%OQ;Wyre>fl-jaF1t06=YR?fLon=H{kMCSw>z_|rE~ zMn(or(>psmLYm+2=Qu8rJjZdNP)NAExw%PAP1Wo5JkKM9L;yeP($mwiw49uroSdB3 z*Vm1WjqB@cilVBks~Z~|^YinCCa$ckyuH0OH8p(~1Vbz=EC4`dWu>6SZntM83g#hsQ_=pf%T3R9qA|)lIySv-zblPmT z*49=4U>N4)lfS#Tn^oP~e)d9fy`8lrr)zy{F zW>YGa6h(nZBq}K>NsKm`OaQR4vGFHRe}6v!B#oj@ry~f0q$rBxxWuAjrLkBH{xE!* zxPbVG5F({g>C4N@>gsAB5WtSAswx0*xm-yoJkPJMuj4WS!1MF-%*;$%e_LB15Xj2P zg7)@yA+)`{o#VK-w>OnaMUte$;Sl)qJa0Ce0idCw0U`AD^`+PAah6;zx7lnEkH;Mj zhuLh#%Z1lxYimm^783+vG#V`y%kc1Ub#*lWD3!{)yE}wXBoYCD;^JbT&liiuepck^ z=_xlimn6yE-Cca+^?J2he{G^PgTZindyBmSqxJRmpMgXO_4f7xfXQS^Y)3pE-`m@p znwpxQpTD@cNb2DJ{=P&a(dl&fkpessd3kwhX=&kb7ze$-zi)4ECoL_{^NWj%!n)tw z+!PfRsZ=UFecy~+E*D9X1qB7cV9@XPW7;(}H4hIDIDq50&dyFef5Za=1EEkTJ3E^s zNsq_#n>2*b(9jS7l$MstWHMYx0I*mr*n4(%hL=k&m*Y-R6lJwqh4kN^TBp+~m&?^^ zwcTz%IywS?wzf9xnw*>jfRT}ra5&u6)umFY+-`SbZt~+F3S^QM_d_JKMC`pOQK#5jgUoZ4tCX<=X=6?kL0=F#XQ(#<(4FCWD07*qoM6N<$ Ef_@edGynhq diff --git a/radio/src/bitmaps/480x272/default_theme/mask_menu_favs.png b/radio/src/bitmaps/480x272/default_theme/mask_menu_favs.png new file mode 100644 index 0000000000000000000000000000000000000000..a4240cd04c9dbf5d635ac637b42ca9b79dd51eea GIT binary patch literal 649 zcmV;40(Sk0P)pF8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H10v1U` zK~zYIy_P@k=};KQRYTH9G=?VCg_SqZL1Nahn7jjnp`+ssm@JseA`+toZvczUDvbS; zNQyKOnvlptIzS(Y&kAw(dA2!gGs#FuLbA8~L+&Eu1| z+wH5Z-EQX|>)|?+$-D~WdEVW%8~S)W;zx>=&*yobx2Mr)^m@I%iJnfUc#CD(;c#eK zmStJP;gDe%ygr}L-$Vld!r^eWS~U#AxqdpGL{TJ3ve|69pxw$y5X5@D?)7>!O*_{U ziA1N5CZ(P%u;5JCU| j_8w5q#*Fw>_5Rcs&bH$@&vtkt00000NkvXXu0mjf@7yn7 literal 0 HcmV?d00001 diff --git a/radio/src/bitmaps/480x272/default_theme/mask_model_setup.png b/radio/src/bitmaps/480x272/default_theme/mask_model_setup.png index 5f61b4c474f2f2fdc62962dfdd89d922e404604a..4d26068fe48ec1ab33d4880970a6723173b01898 100644 GIT binary patch delta 1202 zcmV;j1Wo(n3h@b$D+><8000id0mpBsWRW%~e|||sK~zYIwU)_Cx?L23KEOOGMVh; zf8@kBoA{EftSnEj?(S}?{rvp2*=$}Ny+p0o>k|?ZR##W)!Dh1=K!1P#?(VM9Xw+)8 z0QUFy0o>f&6c!eyrly{rp8Ag3WHQNQG5`$2G&D3=EEf9v@$r!wOiWAwh>MHU>2wN( zfoZLxnjf>>W7C10D*yl(b3T4lgYl({{H>|e+~`~xS9GN zXhMj=U;rSINC+W*0Qh{q)9HMFf9E<34i0jcqobpHdwT%t>gqBwGX8XopPwIq@7fST zXd}R8%U}^Yb(7e`dGatyXJUSsB%Kc6M5=R;Sa+8oa;1({ZL$D$C2u+uPgM z*47C3lX-f2T3A?M7=~t+-S6$~^~~wk))s5va=FA}v6~m+&Jd|oIz2s22vMn26%`eK zDwL-Pg~FDW768r7%@-FJKMMAcm6a8SVHk#4SXkg5?lWo{cv4ale}LlRVs`TfT~$>D zAUr($<>iIlG@H%bB`XexV|aL&Es5Q3PfJS!5EB#Q1--t$PA6Y}e!j!uczu0sYir~2 zcyhUXU|@jDH5d$PwHiP~M8xLiro-XL&dvrPkw^>%gBLU*M5oiy8!Iz2lkG?V48xqA zov~&)IXPTacz8Gfe}O=-yu8e%xnH|FosNF@G>Vat5qdd|jg3(Qr_)Ji&c?<@b#*nh z6p2JLGc#@|FYl0@ot?0-u%e=(^Ye2;NNsH`fcpA+lgVT>8mFeFDC^_ngAlU3yj)#f zy}iBd$?^Tf@!BDYiHSZP{d~49n^}=aN998X7v{I%!gKN;=jl2Hl% Qy8r+H07*qoM6N<$f>E?awEzGB delta 1317 zcmV+=1={-Y3F8WoD+>wN000Ts0kLiuw~;m|fAC2}K~zYIjaFYsQ*Ri4&vDD?#7P;h zLQ27uL=l#Gv5TZOu#7;(RfLF||1JbU3bjo{i4c-Vg+N8RaT|_M91eA~wwV_?FGPzZ z@<64CsDyve=GoczyLkP59(UHC=W6Hup7;5__j$kbo&otA%x3fD%a`FKy1Kglnh1Yh zf8N>IIdkR=NMJA+C}(41OV0C4Hj zCFENyme|=sj^mU{B>;4G zc4A~?WQ1i|+^@8>w5zM@#fumDfBE?g!=QUhOH0VCt*r$BwOZZN)8lr#S5{UCAz(6@ z3JMC6lauL*CMG5bA)A|<=v{hxI>&M1@;x38mZH&U1VJE#IGxUrvXn|C$Ye75ER)IV z>gv#}*49>JeEarI+BAp5fhl8SV;Hg7YacKgwm+1c3u5E&Vn zk&#heUhZ@{(Xx(?4vc^LfAmReG#v~smkT4$pFbD(P^Z(u;NT!$XIh2V>m`Kj?Cc~Y zBmlt0ix=nS=ES--n+;QPb8|7`a=EC2TCINc=+WxxDiA`}*4E5sv&m$_5qjgs4NP#m z-FSakmd(q{Ga8Lgo;<;e0RZREpa1dW2QoW5I{`qUQ22a4dV=G(fAPzgFF1mWii&7( zdU`r3DM@OyR;&H~{X3<7{PZfN5}_-{6ECya{1@apHE27%*-$hBbUo3Cnu#%`xo#$uhnV+;Qsyl7&*F? zTU%QI5ET{m>(?(@fAzw`LRD3j&*zgGvbeaY)9D^ReoXm&eSNdDvnF@6+guHt7N}*6-4_jMX#Rqh`T<9zST)A>(VPWCz+qd{=G#bNrEeOJ`Tet8o z0)Y7VczoSrVq)Ur;sD_8-Mc)`e}|DKg!ujby1F_PWfT)mYbV9H8q8gILfQ4s_-w) z(9jU>{o%t0LP#(e92y!5`Q-mrIt2Ib-IKQQ!i5V52M2#n44qq2==J)Lh(@EaSS;A& bKj1%=mY17~5BM@p00000NkvXXu0mjfZ7Y;n diff --git a/radio/src/bitmaps/480x272/default_theme/mask_radio_setup.png b/radio/src/bitmaps/480x272/default_theme/mask_radio_setup.png index 70d2d88d54e3e0524122c99a64a87f9ddb49343b..222d5918de5214f790475e638ee7ad9f1a7da189 100644 GIT binary patch delta 1344 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 diff --git a/radio/src/bitmaps/800x480/default_theme/mask_menu_favs.png b/radio/src/bitmaps/800x480/default_theme/mask_menu_favs.png new file mode 100644 index 0000000000000000000000000000000000000000..642e61874995d9409362961b9f9c6ef5ade70162 GIT binary patch literal 1031 zcmV+i1o-=jP)s%Cu_ldy)u*Swlr_q+uH_%p?p+L27`g7X%z|}gtxc1l>uw` zL?QtpL;(PSKtPft004@jv$M0~U!0L!Vlxj7Z&a=9Rc2mm0P&8kgPQ&XjV+#K2Mb~R9m$k%Holc}t1v)TMLMgHW| zqvPY_zq$SAY>wk5Cnp6#_y_Ebjg6O=7r)6mxW2xw5PNNH?Q04l+}zwOFI$%7R4T=?EKSon zmwY~7EEeN9?*08;e?c^F>;3(`&*#fzGU;^s>FFtx$vi$j7Ff!HAoTR~sIk>*#c>?R zae^QSg1~WnW@g4}wd!RzH#gVU*Do$EDvF~2IaKjH&-47{fU^ts#Z z4u``vH8tO5Ycd**dwYA+)6;)46dLcbv9Xhr6M`Uq0B&k(Iz2rd85t?yDKgi3dwW@y z?da(E7PzyslV#biuCBti;`6+zrSxZ8ugUbyS}Tdt8pAJYHMg{sH&>cS@Rov3&Sua@qC-j^Squ-I~t9OqF7=! z!!UZjo+L?%L?WeUe@#&or6}s|?vA3UoB`I~?LT1;3=Bl0QIE&d($eDbc+Sty`}+ER zzy=UPk|fnQl}hD3(~F{rVHg0wVzI2Qt}2R>V^9>u@As?ww#8z}X0v(gq*5srM3Us^ zw?R=|TwKVq>~uQg@wnUVMv&aQ5CkDfG9Hgp6eS44)zy`rviaX*ITA%N5{YzocNeyq z&1R3sW4GI%pPx&{9vT|bV^h`N->=j8zuxgwuBOMQKP4TVB0D=TXHNrV;u?|@-gGMR+xKMx2YP1BXZV;B|+ zg;eM-ZI@0alfhu{;o+ftV4Kb6a5%If{*PUG{RRU3E-19-5ljF8002ovPDHLkV1n_8 B?ce|a literal 0 HcmV?d00001 diff --git a/radio/src/bitmaps/800x480/default_theme/mask_model_setup.png b/radio/src/bitmaps/800x480/default_theme/mask_model_setup.png index 0646e6decb7e82b3ab596b8b28451f9d78a99348..1a86dccd4b805a458765239ceabf01125a72e473 100644 GIT binary patch delta 1650 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 diff --git a/radio/src/bitmaps/800x480/default_theme/mask_radio_setup.png b/radio/src/bitmaps/800x480/default_theme/mask_radio_setup.png index 494a503467238f201a8cbe6f2f11617eeb7ee500..079f692fe7386d6a516642abb550b45c426c2cda 100644 GIT binary patch delta 1948 zcmV;N2V?l$4%82jD+?4Y000y%0r|t}(vdbNe+OYnL_t(og~eEHNR!_bKoX^Gei1`$pvTLUpaSgq1DN{f(8n~HBM zW}pb*}68JNI?2^LA4RA^1N*;BCO?&!0Ow ze>xTx7Hl@#uV23qLT0lW0J5^OcJAEi9T)NjZ{NNZ3WY9tBoc|mV)2U2JMG=OcYFAZ z?(S};^VHOoXEvS(uDf^d9z1w(c6OFnhK7c4_G(NR{^&6_uw!g+alCX;D;dOA5dnS8^G7cV?%fBEtyFfb5% zCnY7B&1P)Z>-D+0xsj2Pxw*Oh{rxTz*wN8(?AWpW`}Z>^n5JpDT#gAvB2iyopIhw% z2M%Dr=;&yZ$>dT4A+)%-ILm>%f5lDH^okWLFl~8xxm)eLygckAlgVs0n@g^Sh6b@% z%q;>wpMUb?Nv{9n$B#+c4F-c-ZKKgBkw~!X`Sa(wL=J}|ARvG%Owilg%k(#!&EetU zxa-1&3oJHvt!cGd>?#ll1_uXOy>oMO9)tmawVckJIfLy{QBipFXM(-2f92=r<5_n& z9CdYd#EuYp^X84i;qa^t0D8S1{e3pRdi4r7PMS9z0N~RAl2M ztK4WbDin&%n>Rb1PS3(T9#5%MZrZeIdU_fFNRgj9bxJH2M@L6zWo4;Us_yRY-yft> zsknpU^Z5e<0|+6L$wcPNe_${~M@PF877B$E6B7vu2>_6hk%15zA0KyFn7Eh(0AMzo zmzI{8eSv|2m6er=iHQJk>C&Zd-@ajcRaMoaM~^BhD)479Args{N+m+bU@!ncTU(pK zV2F*4?d|PVtJQkFerRY2pY#BLNoK666|Ni~S z$;q6YoRE+ZmbTSu?dj=JDwT_ii`X(YHWnKj8y6Q>Q&WR2H8nLQB_#lW>qdani~9-+ z3dj;CASn?D1Z&o;>FMct{rWXGjQ}8(N{KK4*zI;B}EY|6Ce_y|T{qf_+y?gh#)k8+l6ygEnuwssy1&u~iRaF%p9xju~u3o*m zcI{ebZ&_IxLMSLGC?q5#At9ltsK_M=z7W9Qx#R(WNF>50o6Y7jMkEr&$H!|l8UXn8 z>C^l7?~{^}m<|esqQ1V~VzJOP-PqWel9Iw=plQ0bwY9aif0g~+{{H^hbne_axmw06;`UgiIzI9v)^=kB*M+*s%iu_PksT zkxHeRnVF4^jZAGo2z7UNQxwG-X-G)ORgB{8?63#&VWQ zrGtZm!^6Wyf1|Ohs|zQxsi|pnbd-DhpeX9>*|Y!I&$U|Z`t|F{y23bo_%P810EtAB znwm=X85V>>VQOlsTrMY*+SJsfQmJq|I5;>vJG-KyqP@L+c6QdqSz@=_M@B|&+_-@Q ze0+Q+CMLFR+vZa2k7#RaBP*h~xR`q?y11|H*|P@+f2>=#&SJ4NG&KAJVTnXCH#gVQ z(}QP|qNw)v_CIJpeE1Lt3j~4>A3h+2oKEMFBS*Z|R;$&Ru(-GwTf)M^W@cvGYST0w z8XAgSFJ8RJ?9%CU8#Zjea+YBobY_cFk(F?%lf=TPTXEtE*#0f4Qjh($Z4Gl97=S6BEOl(Phh)+3j{_ z2$?JKuP!v^MTudH$tXn=w?CsmP)6>&gv8AP@Tou>a7}u{~ zCsn;_)vDIkR)o;;2zwfTKpcMD5|Qe%AJI#w|`SpQ+#~9 ze^RNWX&PH6 i_OVXFe_8uq#9!U}Pg>qI_;>&S002ov22Mn-LSTa68O<>O delta 1827 zcmV+;2i*A758MurD+>*C000eh0SeBsZIL!7e+KDEL_t(og{@d!OcPBP?%$TSNYy}z zDPBlWYZE0JM6ExFq6wuT5Sl8)1Sru+nue-3HPLEI3`FsQXrp+c(HLXJ-++G?l~j#f z6lz6H#ajLXZP5e}1Jstb^Ic57!@j%QqHo^kYWK`@&NDl6X6DSY(BI(W$Bznyg3V^L zf0!^dH1t=|Sbt89#bT>huVz%mxPANfUukoa#2OtPCBOFd_4$0hB>Z>p-jQGJcDuvj zNWxF}-4=_5&*wKcH%FsUY_ZvF*hMCjO_I>m)P(K%`T3YRKRym*mF zf?2zzr3E^tP$;}!FGA?txpUZ}QmM$~f9~#XY!?Uwkw|28bhMzL0NhhjQXW5k{HNMh ztCf;XLZR@&g$u>S#rXBqsZ(VB?Ch*SAizy0PMlc2d^u%k34*ZMY>R8(ym=FZmn>Pr zI8D!#N;HTBxHYX~8y(|PphQEcS%`IJsCX!rE=2!%q-lSm{Uj|bbofB)Xl z(2$v#nURs9)oO#mAbs?(yH=|$C@9eD^&=xAFHq< z_}5S>l{k1qLj!~MrcIl0^WMFCf8+7^e<cx!f;bzA$K8tyY*YtJRt)kjLXO znM_-@Y+12lg+L%!wQ7}0rD|(yo1UI#DtGSABSA?`FzaU2%$hAke;57sdaUAf8?fb-@dI~ zyOvRvjGCI7`T2SB_dxzzEEY<){-OQz=TDtZhpDhZB7`O;Cdj9VOeQ;j{`~9LuU#%z zXJ@BguTM=)g;t$T2aYo{GcZmiB_(FF*=Do#_V!LqO(BF>ot>RcO-+@Rm2$b9!&x|5 zYHMpDL{(K4HnQ1llgUK>e=-ce-@j|uF7SQwnOv35E>pH#?L!;>|mZD5`Z%_G{i^%xmYa5A-~Y6 zp-?Cs4&!I~;YbH?rlzJC3FLI0K)ruI2`Wk>bi94l1``Fx^*k&ak*Svo+5-Ik;tAsdmw~JBszHT zU~6mZjT<)_8ymN8-%jrI<;$1J-GUD@7z`5=6XYgpt$6+Vb%=83&KFVSe!YPBX>JPL(^ypICDe*FsRVlWsI zYU}lSOcIO5!^6Y$KnS7P+1W>r9@W>^E0xM^+qRXLmzzu`r_;$u#(+x&K@iL})4;$0 zpU=k`aqr%}B(eS$u~@9EtPIPSl$0=N*VotM=BlbHf4cwg-@g-8$7Hx%uBT6*QjCLx zgRqNewOR)4TeogOhCg`lfb8t?cs6d_n39rGTU*=T-_NKzIXQXw@L{}VR##U;S_J|D zsCl?tF1cj;$9$X3W=!Jq`4)=>Z!c|aZE$D63+&CCHx%JWBm#>QBP%P*;cx_l!3`TW zfRR%Ee^S?&!C=5V4u_MIlLHe$Mny#h#p~tEmvkCI5Nfp=&WpyzMv50zJ06c)ES9vi zG)kcK^mHg-L?Tf*94332OeWm4Z{I$P#X`QDVNkBF%-R@kw>vvK8@sXD>;nf5jE#-W z&CS6_xZQ3tzo@7P+nbx45kmd_{c5!uS9xqUf7@&}GpZ!~@9^WtkKMa>=jG+Seft)S zQ1xBBcyZwW@Or(=mMz0}yWI|Cr_-s?Xzt&?pGYFvzn(}WLOHc+YHH~73gGd0iEc)W zNcOLXAP91q!D6wPb#-E~I0=D@Kkp_&$nW + + + + + + diff --git a/radio/src/bitmaps/img-src/default_theme/mask_model_setup.svg b/radio/src/bitmaps/img-src/default_theme/mask_model_setup.svg index 7fe0048aa..159729b75 100644 --- a/radio/src/bitmaps/img-src/default_theme/mask_model_setup.svg +++ b/radio/src/bitmaps/img-src/default_theme/mask_model_setup.svg @@ -1,81 +1,7 @@ - - - - + + + + + + + diff --git a/radio/src/bitmaps/img-src/default_theme/mask_radio_setup.svg b/radio/src/bitmaps/img-src/default_theme/mask_radio_setup.svg index b7e2ad906..b5aaa3d25 100644 --- a/radio/src/bitmaps/img-src/default_theme/mask_radio_setup.svg +++ b/radio/src/bitmaps/img-src/default_theme/mask_radio_setup.svg @@ -1,89 +1,8 @@ - - - - + + + + + + + + diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index 8ffdf29ad..178025db4 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -79,9 +79,9 @@ static inline void check_struct() #if defined(PCBXLITES) CHKSIZE(RadioData, 945); #elif defined(RADIO_ST16) || defined(PCBPA01) || defined(RADIO_TX15) || defined(RADIO_T15PRO) - CHKSIZE(RadioData, 1159); + CHKSIZE(RadioData, 1177); #elif defined(COLORLCD) - CHKSIZE(RadioData, 1039); + CHKSIZE(RadioData, 1057); #elif defined(RADIO_GX12) CHKSIZE(RadioData, 1063); #else diff --git a/radio/src/datastructs_model.cpp b/radio/src/datastructs_model.cpp index 68984a11b..3470675ff 100644 --- a/radio/src/datastructs_model.cpp +++ b/radio/src/datastructs_model.cpp @@ -20,10 +20,7 @@ */ #include "edgetx.h" -#include "tasks/mixer_task.h" -#include "hal/adc_driver.h" - -//----------------------------------------------------------------------------- +#include "hal/switch_driver.h" SwitchConfig ModelData::getSwitchType(uint8_t n) { diff --git a/radio/src/datastructs_private.h b/radio/src/datastructs_private.h index eb418d6b9..3b22972bc 100644 --- a/radio/src/datastructs_private.h +++ b/radio/src/datastructs_private.h @@ -36,6 +36,7 @@ #if defined(COLORLCD) #include "datastructs_screen.h" +#include "quick_menu_def.h" #endif #if defined(PCBTARANIS) @@ -996,6 +997,14 @@ PACK(struct switchDef { #endif }); +#if defined(COLORLCD) +#define MAX_KEY_SHORTCUTS 6 +#define MAX_QM_FAVORITES 12 +PACK(struct QuickMenuPage { + uint8_t shortcut ENUM(QMPage); +}); +#endif + PACK(struct RadioData { // Real attributes @@ -1152,6 +1161,11 @@ PACK(struct RadioData { NOBACKUP(uint8_t pwrOffIfInactive); +#if defined(COLORLCD) + NOBACKUP(QuickMenuPage keyShortcuts[MAX_KEY_SHORTCUTS]); + NOBACKUP(QuickMenuPage qmFavorites[MAX_QM_FAVORITES]); +#endif + NOBACKUP(uint8_t getBrightness() const { #if defined(OLED_SCREEN) @@ -1179,6 +1193,13 @@ PACK(struct RadioData { void cfsSetOffColorLuaOverride(uint8_t n, bool v); #endif #endif + +#if defined(COLORLCD) + QMPage getKeyShortcut(event_t event); + bool hasKeyShortcut(QMPage shortcut); + void setKeyShortcut(event_t event, QMPage shortcut); + void defaultKeyShortcuts(); +#endif }); #undef SWITCHES_WARNING_DATA diff --git a/radio/src/datastructs_radio.cpp b/radio/src/datastructs_radio.cpp index c54cb2001..ab5f51863 100644 --- a/radio/src/datastructs_radio.cpp +++ b/radio/src/datastructs_radio.cpp @@ -24,6 +24,10 @@ #include "hal/switch_driver.h" #include "tasks/mixer_task.h" +#if defined(COLORLCD) +#include "view_main.h" +#endif + char* RadioData::getSwitchCustomName(uint8_t n) { return switchConfig[n].name; @@ -85,3 +89,79 @@ void RadioData::cfsSetOffColorLuaOverride(uint8_t n, bool v) { } #endif #endif + +#if defined(COLORLCD) +QMPage RadioData::getKeyShortcut(event_t event) +{ + QMPage page = QM_NONE; + switch(event) { + case EVT_KEY_BREAK(KEY_MODEL): + page = (QMPage)keyShortcuts[0].shortcut; + break; + case EVT_KEY_BREAK(KEY_SYS): + page = (QMPage)keyShortcuts[1].shortcut; + break; + case EVT_KEY_BREAK(KEY_TELE): + page = (QMPage)keyShortcuts[2].shortcut; + break; + case EVT_KEY_LONG(KEY_MODEL): + page = (QMPage)keyShortcuts[3].shortcut; + break; + case EVT_KEY_LONG(KEY_SYS): + page = (QMPage)keyShortcuts[4].shortcut; + break; + case EVT_KEY_LONG(KEY_TELE): + page = (QMPage)keyShortcuts[5].shortcut; + break; + default: + break; + } + if (page >= QM_UI_SCREEN1 && page <= QM_UI_SCREEN10) + page = (QMPage)(QM_UI_SCREEN1 + ViewMain::instance()->getCurrentMainView()); + return page; +} + +void RadioData::setKeyShortcut(event_t event, QMPage shortcut) +{ + switch(event) { + case EVT_KEY_BREAK(KEY_MODEL): + keyShortcuts[0].shortcut = shortcut; + break; + case EVT_KEY_BREAK(KEY_SYS): + keyShortcuts[1].shortcut = shortcut; + break; + case EVT_KEY_BREAK(KEY_TELE): + keyShortcuts[2].shortcut = shortcut; + break; + case EVT_KEY_LONG(KEY_MODEL): + keyShortcuts[3].shortcut = shortcut; + break; + case EVT_KEY_LONG(KEY_SYS): + keyShortcuts[4].shortcut = shortcut; + break; + case EVT_KEY_LONG(KEY_TELE): + keyShortcuts[5].shortcut = shortcut; + break; + default: + break; + } +} + +bool RadioData::hasKeyShortcut(QMPage shortcut) +{ + for (int i = 0; i < MAX_KEY_SHORTCUTS; i += 1) + if (keyShortcuts[i].shortcut == shortcut) + return true; + return false; +} + +void RadioData::defaultKeyShortcuts() +{ + setKeyShortcut(EVT_KEY_BREAK(KEY_MODEL), QM_MODEL_SETUP); + setKeyShortcut(EVT_KEY_LONG(KEY_MODEL), QM_MANAGE_MODELS); + setKeyShortcut(EVT_KEY_BREAK(KEY_SYS), QM_OPEN_QUICK_MENU); + setKeyShortcut(EVT_KEY_LONG(KEY_SYS), QM_TOOLS_APPS); + 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 diff --git a/radio/src/edgetx.cpp b/radio/src/edgetx.cpp index f070a3834..0f7da1c95 100644 --- a/radio/src/edgetx.cpp +++ b/radio/src/edgetx.cpp @@ -335,6 +335,9 @@ void generalDefault() g_eeGeneral.potsConfig = adcGetDefaultPotsConfig(); generalDefaultSwitches(); +#if defined(COLORLCD) + g_eeGeneral.defaultKeyShortcuts(); +#endif #if defined(STICK_DEAD_ZONE) g_eeGeneral.stickDeadZone = DEFAULT_STICK_DEADZONE; diff --git a/radio/src/gui/colorlcd/bitmaps.cpp b/radio/src/gui/colorlcd/bitmaps.cpp index 22813cb5c..c41728d97 100644 --- a/radio/src/gui/colorlcd/bitmaps.cpp +++ b/radio/src/gui/colorlcd/bitmaps.cpp @@ -69,6 +69,10 @@ MaskBitmap* _decompressed_mask(const uint8_t* lz4_compressed) return raw; } +static const uint8_t mask_menu_favs[] = { +#include "mask_menu_favs.lbm" +}; + static const uint8_t mask_menu_model[] = { #include "mask_menu_model.lbm" }; @@ -388,6 +392,7 @@ struct _BuiltinIcon { // Note: Order must match EdgeTxIcon enum static const _BuiltinIcon _builtinIcons[EDGETX_ICONS_COUNT] = { BI(ICON_EDGETX, mask_edgetx), + BI(ICON_QM_FAVORITES, mask_menu_favs), BI(ICON_RADIO, mask_menu_radio), BI(ICON_RADIO_SETUP, mask_radio_setup), BI(ICON_RADIO_SD_MANAGER, mask_radio_sd_browser), diff --git a/radio/src/gui/colorlcd/bitmaps.h b/radio/src/gui/colorlcd/bitmaps.h index b4aad8642..a410735d9 100644 --- a/radio/src/gui/colorlcd/bitmaps.h +++ b/radio/src/gui/colorlcd/bitmaps.h @@ -25,6 +25,7 @@ enum EdgeTxIcon { ICON_EDGETX, + ICON_QM_FAVORITES, ICON_RADIO, ICON_RADIO_SETUP, ICON_RADIO_SD_MANAGER, diff --git a/radio/src/gui/colorlcd/libui/page.cpp b/radio/src/gui/colorlcd/libui/page.cpp index 5e06c4c2f..86baff24f 100644 --- a/radio/src/gui/colorlcd/libui/page.cpp +++ b/radio/src/gui/colorlcd/libui/page.cpp @@ -111,9 +111,9 @@ void Page::deleteLater(bool detach, bool trash) void Page::openMenu() { PageGroup* p = (PageGroup*)Layer::getPageGroup(); - QuickMenu::SubMenu subMenu = QuickMenu::NONE; + QMPage qmPage = QM_NONE; if (p) - subMenu = p->getCurrentTab()->subMenu(); + qmPage = p->getCurrentTab()->pageId(); quickMenu = QuickMenu::openQuickMenu([=]() { quickMenu = nullptr; }, [=](bool close) { onCancel(); @@ -124,7 +124,7 @@ void Page::openMenu() if (close) Layer::back()->onCancel(); } - }, p, subMenu); + }, p, qmPage); } void Page::onCancel() @@ -158,7 +158,16 @@ NavWindow* Page::navWindow() #if defined(HARDWARE_KEYS) void Page::onPressSYS() { - if (!quickMenu) openMenu(); + QMPage pg = g_eeGeneral.getKeyShortcut(EVT_KEY_BREAK(KEY_SYS)); + if (pg == QM_OPEN_QUICK_MENU) { + if (!quickMenu) openMenu(); + } else { + auto p = navWindow(); + if (p) { + onCancel(); + p->onPressSYS(); + } + } } void Page::onLongPressSYS() diff --git a/radio/src/gui/colorlcd/libui/view_text.h b/radio/src/gui/colorlcd/libui/view_text.h index 8f575bf78..c7b835e89 100644 --- a/radio/src/gui/colorlcd/libui/view_text.h +++ b/radio/src/gui/colorlcd/libui/view_text.h @@ -54,8 +54,6 @@ class ModelNotesPage : public PageGroupItem public: ModelNotesPage(PageDef& pageDef); - bool isVisible() const override { return modelHasNotes(); } - void build(Window* window) override; void cleanup() override; diff --git a/radio/src/gui/colorlcd/mainview/screen_setup.cpp b/radio/src/gui/colorlcd/mainview/screen_setup.cpp index 2e5ca5e94..bb7877be0 100644 --- a/radio/src/gui/colorlcd/mainview/screen_setup.cpp +++ b/radio/src/gui/colorlcd/mainview/screen_setup.cpp @@ -115,12 +115,12 @@ static const lv_coord_t line_row_dsc[] = {LV_GRID_CONTENT, ScreenSetupPage::ScreenSetupPage(unsigned index, PageDef& pageDef) : PageGroupItem(pageDef) { - update(index + FIRST_SCREEN_OFFSET); + update(index + QuickMenu::pageIndex(QM_UI_SCREEN1)); } void ScreenSetupPage::update(uint8_t index) { - customScreenIndex = index - FIRST_SCREEN_OFFSET; + customScreenIndex = index - QuickMenu::pageIndex(QM_UI_SCREEN1); } void ScreenSetupPage::build(Window* window) @@ -214,7 +214,7 @@ void ScreenSetupPage::build(Window* window) // Reset to first screen so user knows something has happened PageGroup* menu = (PageGroup*)window->getParent(); - menu->setCurrentTab(FIRST_SCREEN_OFFSET); + menu->setCurrentTab(QuickMenu::pageIndex(QM_UI_SCREEN1)); storageDirty(EE_MODEL); return 0; diff --git a/radio/src/gui/colorlcd/mainview/screen_setup.h b/radio/src/gui/colorlcd/mainview/screen_setup.h index e1510f2f6..f70934e74 100644 --- a/radio/src/gui/colorlcd/mainview/screen_setup.h +++ b/radio/src/gui/colorlcd/mainview/screen_setup.h @@ -34,10 +34,6 @@ class ScreenSetupPage : public PageGroupItem void update(uint8_t index) override; - bool isVisible() const override { return customScreens[customScreenIndex] != nullptr; } - - static constexpr int FIRST_SCREEN_OFFSET = 2; - protected: unsigned customScreenIndex; Window* layoutOptions = nullptr; diff --git a/radio/src/gui/colorlcd/mainview/topbar.cpp b/radio/src/gui/colorlcd/mainview/topbar.cpp index 8c964ef08..ad91036b1 100644 --- a/radio/src/gui/colorlcd/mainview/topbar.cpp +++ b/radio/src/gui/colorlcd/mainview/topbar.cpp @@ -112,7 +112,7 @@ void SetupTopBarWidgetsPage::deleteLater(bool detach, bool trash) Layer::pop(this); // restore screen setting tab on top - (PageGroup::ScreenMenu())->setCurrentTab(1); + QuickMenu::openPage(QM_UI_SETUP); storageDirty(EE_MODEL); } diff --git a/radio/src/gui/colorlcd/mainview/view_channels.cpp b/radio/src/gui/colorlcd/mainview/view_channels.cpp index 410c36c98..8e791b355 100644 --- a/radio/src/gui/colorlcd/mainview/view_channels.cpp +++ b/radio/src/gui/colorlcd/mainview/view_channels.cpp @@ -120,7 +120,7 @@ class ChannelsViewPage : public PageGroupItem ChannelsViewMenu::ChannelsViewMenu() : TabsGroup(ICON_MONITOR, STR_MAIN_MENU_CHANNEL_MONITOR) { - QuickMenu::setCurrentPage(QuickMenu::TOOLS_CHAN_MON); + QuickMenu::setCurrentPage(QM_TOOLS_CHAN_MON); #if PORTRAIT int cols = 1; diff --git a/radio/src/gui/colorlcd/mainview/view_main.cpp b/radio/src/gui/colorlcd/mainview/view_main.cpp index 147455d48..bc36cdee2 100644 --- a/radio/src/gui/colorlcd/mainview/view_main.cpp +++ b/radio/src/gui/colorlcd/mainview/view_main.cpp @@ -245,36 +245,23 @@ void ViewMain::updateTopbarVisibility() } #if defined(HARDWARE_KEYS) -void ViewMain::onPressSYS() +void ViewMain::doKeyShortcut(event_t event) { - if (!viewMainMenu) openMenu(); -} -void ViewMain::onLongPressSYS() -{ - if (viewMainMenu) viewMainMenu->closeMenu(); - // Radio setup - PageGroup::ToolsMenu(); -} -void ViewMain::onPressMDL() -{ - if (viewMainMenu) viewMainMenu->closeMenu(); - PageGroup::ModelMenu(); -} -void ViewMain::onLongPressMDL() -{ - if (viewMainMenu) viewMainMenu->closeMenu(); - new ModelLabelsWindow(); -} -void ViewMain::onPressTELE() -{ - if (viewMainMenu) viewMainMenu->closeMenu(); - (PageGroup::ScreenMenu())->setCurrentTab(getCurrentMainView() + ScreenSetupPage::FIRST_SCREEN_OFFSET); -} -void ViewMain::onLongPressTELE() -{ - if (viewMainMenu) viewMainMenu->closeMenu(); - new ChannelsViewMenu(); + QMPage pg = g_eeGeneral.getKeyShortcut(event); + if (pg == QM_OPEN_QUICK_MENU) { + if (!viewMainMenu) openMenu(); + } else { + if (viewMainMenu) + viewMainMenu->closeMenu(); + QuickMenu::openPage(pg); + } } +void ViewMain::onPressSYS() { doKeyShortcut(EVT_KEY_BREAK(KEY_SYS)); } +void ViewMain::onLongPressSYS() { doKeyShortcut(EVT_KEY_LONG(KEY_SYS)); } +void ViewMain::onPressMDL() { doKeyShortcut(EVT_KEY_BREAK(KEY_MODEL)); } +void ViewMain::onLongPressMDL() { doKeyShortcut(EVT_KEY_LONG(KEY_MODEL)); } +void ViewMain::onPressTELE() { doKeyShortcut(EVT_KEY_BREAK(KEY_TELE)); } +void ViewMain::onLongPressTELE() { doKeyShortcut(EVT_KEY_LONG(KEY_TELE)); } void ViewMain::onPressPGUP() { if (!widget_select) { diff --git a/radio/src/gui/colorlcd/mainview/view_main.h b/radio/src/gui/colorlcd/mainview/view_main.h index 6f7713d93..98aef440d 100644 --- a/radio/src/gui/colorlcd/mainview/view_main.h +++ b/radio/src/gui/colorlcd/mainview/view_main.h @@ -111,6 +111,7 @@ class ViewMain : public NavWindow static void ws_timer(lv_timer_t* t); #if defined(HARDWARE_KEYS) + void doKeyShortcut(event_t event); void onPressSYS() override; void onLongPressSYS() override; void onPressMDL() override; diff --git a/radio/src/gui/colorlcd/mainview/widgets_setup.cpp b/radio/src/gui/colorlcd/mainview/widgets_setup.cpp index 9facaf34a..c2a41dbc8 100644 --- a/radio/src/gui/colorlcd/mainview/widgets_setup.cpp +++ b/radio/src/gui/colorlcd/mainview/widgets_setup.cpp @@ -155,7 +155,7 @@ void SetupWidgetsPage::onClicked() void SetupWidgetsPage::onCancel() { deleteLater(); - (PageGroup::ScreenMenu())->setCurrentTab(customScreenIdx + ScreenSetupPage::FIRST_SCREEN_OFFSET); + QuickMenu::openPage((QMPage)(QM_UI_SCREEN1 + customScreenIdx)); } void SetupWidgetsPage::deleteLater(bool detach, bool trash) diff --git a/radio/src/gui/colorlcd/model/model_curves.h b/radio/src/gui/colorlcd/model/model_curves.h index 3b4080f7d..4bfcc17d5 100644 --- a/radio/src/gui/colorlcd/model/model_curves.h +++ b/radio/src/gui/colorlcd/model/model_curves.h @@ -31,8 +31,6 @@ class ModelCurvesPage : public PageGroupItem static void pushEditCurve(int index, std::function refreshView, mixsrc_t source); - bool isVisible() const override { return modelCurvesEnabled(); } - virtual void build(Window* window) override; static LAYOUT_ORIENTATION(PER_ROW, 3, 2) diff --git a/radio/src/gui/colorlcd/model/model_flightmodes.h b/radio/src/gui/colorlcd/model/model_flightmodes.h index e0022ee8c..84a9a7d48 100644 --- a/radio/src/gui/colorlcd/model/model_flightmodes.h +++ b/radio/src/gui/colorlcd/model/model_flightmodes.h @@ -29,8 +29,6 @@ class ModelFlightModesPage : public PageGroupItem public: ModelFlightModesPage(PageDef& pageDef); - bool isVisible() const override { return modelFMEnabled(); } - void build(Window* window) override; protected: diff --git a/radio/src/gui/colorlcd/model/model_gvars.h b/radio/src/gui/colorlcd/model/model_gvars.h index fb148c9da..fe0d43b20 100644 --- a/radio/src/gui/colorlcd/model/model_gvars.h +++ b/radio/src/gui/colorlcd/model/model_gvars.h @@ -29,8 +29,6 @@ class ModelGVarsPage : public PageGroupItem public: ModelGVarsPage(PageDef& pageDef); - bool isVisible() const override { return modelGVEnabled(); } - void cleanup() override; protected: diff --git a/radio/src/gui/colorlcd/model/model_logical_switches.h b/radio/src/gui/colorlcd/model/model_logical_switches.h index 9dee431c1..bd52b620d 100644 --- a/radio/src/gui/colorlcd/model/model_logical_switches.h +++ b/radio/src/gui/colorlcd/model/model_logical_switches.h @@ -29,8 +29,6 @@ class ModelLogicalSwitchesPage : public PageGroupItem public: ModelLogicalSwitchesPage(PageDef& pageDef); - bool isVisible() const override { return modelLSEnabled(); } - virtual void build(Window* window) override; protected: diff --git a/radio/src/gui/colorlcd/model/model_mixer_scripts.h b/radio/src/gui/colorlcd/model/model_mixer_scripts.h index 07ad1209b..62d81b545 100644 --- a/radio/src/gui/colorlcd/model/model_mixer_scripts.h +++ b/radio/src/gui/colorlcd/model/model_mixer_scripts.h @@ -29,8 +29,6 @@ class ModelMixerScriptsPage : public PageGroupItem public: ModelMixerScriptsPage(PageDef& pageDef); - bool isVisible() const override { return modelCustomScriptsEnabled(); } - virtual void build(Window* window) override { build(window, 0); } protected: diff --git a/radio/src/gui/colorlcd/model/model_select.cpp b/radio/src/gui/colorlcd/model/model_select.cpp index ef43f7a13..0866ff5cf 100644 --- a/radio/src/gui/colorlcd/model/model_select.cpp +++ b/radio/src/gui/colorlcd/model/model_select.cpp @@ -521,7 +521,7 @@ class ModelLayoutButton : public IconButton ModelLabelsWindow::ModelLabelsWindow() : Page(ICON_MODEL_SELECT, PAD_ZERO, true) { - QuickMenu::setCurrentPage(QuickMenu::MANAGE_MODELS); + QuickMenu::setCurrentPage(QM_MANAGE_MODELS); buildHead(header); buildBody(body); @@ -550,23 +550,22 @@ ModelLabelsWindow::ModelLabelsWindow() : Page(ICON_MODEL_SELECT, PAD_ZERO, true) void ModelLabelsWindow::onLongPressSYS() { onCancel(); - // Radio setup - PageGroup::ToolsMenu(); + Page::onLongPressSYS(); } void ModelLabelsWindow::onPressMDL() { onCancel(); - PageGroup::ModelMenu(); + Page::onPressMDL(); } void ModelLabelsWindow::onPressTELE() { onCancel(); - (PageGroup::ScreenMenu())->setCurrentTab(ViewMain::instance()->getCurrentMainView() + ScreenSetupPage::FIRST_SCREEN_OFFSET); + Page::onPressTELE(); } void ModelLabelsWindow::onLongPressTELE() { onCancel(); - new ChannelsViewMenu(); + Page::onLongPressTELE(); } void ModelLabelsWindow::onPressPG(bool isNext) { diff --git a/radio/src/gui/colorlcd/model/model_select.h b/radio/src/gui/colorlcd/model/model_select.h index 29a72e100..f55ef99be 100644 --- a/radio/src/gui/colorlcd/model/model_select.h +++ b/radio/src/gui/colorlcd/model/model_select.h @@ -76,6 +76,7 @@ class ModelLabelsWindow : public Page #if defined(HARDWARE_KEYS) void onLongPressSYS() override; void onPressMDL() override; + void onLongPressMDL() override {} void onPressTELE() override; void onLongPressTELE() override; void onPressPG(bool isNext); diff --git a/radio/src/gui/colorlcd/model/model_telemetry.h b/radio/src/gui/colorlcd/model/model_telemetry.h index 408774baa..2e5f2510f 100644 --- a/radio/src/gui/colorlcd/model/model_telemetry.h +++ b/radio/src/gui/colorlcd/model/model_telemetry.h @@ -29,8 +29,6 @@ class ModelTelemetryPage : public PageGroupItem public: ModelTelemetryPage(PageDef& pageDef); - bool isVisible() const override { return modelTelemetryEnabled(); } - void build(Window* window) override; static LAYOUT_SIZE_SCALED(NUM_EDIT_W, 100, 65) diff --git a/radio/src/gui/colorlcd/model/special_functions.h b/radio/src/gui/colorlcd/model/special_functions.h index 5702c5811..9a7720467 100644 --- a/radio/src/gui/colorlcd/model/special_functions.h +++ b/radio/src/gui/colorlcd/model/special_functions.h @@ -154,8 +154,6 @@ class SpecialFunctionsPage : public FunctionsPage public: SpecialFunctionsPage(PageDef& pageDef); - bool isVisible() const override { return modelSFEnabled(); } - protected: CustomFunctionData* customFunctionData(uint8_t index) const override; FunctionEditPage* editPage(uint8_t index) const override; @@ -171,8 +169,6 @@ class GlobalFunctionsPage : public FunctionsPage public: GlobalFunctionsPage(PageDef& pageDef); - bool isVisible() const override { return radioGFEnabled(); } - protected: CustomFunctionData* customFunctionData(uint8_t index) const override; FunctionEditPage* editPage(uint8_t index) const override; diff --git a/radio/src/gui/colorlcd/radio/radio_diaganas.cpp b/radio/src/gui/colorlcd/radio/radio_diaganas.cpp index 49d3c3498..7ff29c094 100644 --- a/radio/src/gui/colorlcd/radio/radio_diaganas.cpp +++ b/radio/src/gui/colorlcd/radio/radio_diaganas.cpp @@ -470,8 +470,8 @@ class AnaMinMaxViewWindow : public AnaViewWindow class AnaCalibratedViewPage : public PageGroupItem { public: - AnaCalibratedViewPage(QuickMenu::SubMenu subMenu) : - PageGroupItem(STR_ANADIAGS_CALIB, subMenu) + AnaCalibratedViewPage(QMPage qmPage) : + PageGroupItem(STR_ANADIAGS_CALIB, qmPage) { icon = ICON_STATS; } @@ -486,8 +486,8 @@ class AnaCalibratedViewPage : public PageGroupItem class AnaFilteredDevViewPage : public PageGroupItem { public: - AnaFilteredDevViewPage(QuickMenu::SubMenu subMenu) : - PageGroupItem(STR_ANADIAGS_FILTRAWDEV, subMenu) + AnaFilteredDevViewPage(QMPage qmPage) : + PageGroupItem(STR_ANADIAGS_FILTRAWDEV, qmPage) { icon = ICON_STATS; } @@ -502,8 +502,8 @@ class AnaFilteredDevViewPage : public PageGroupItem class AnaUnfilteredRawViewPage : public PageGroupItem { public: - AnaUnfilteredRawViewPage(QuickMenu::SubMenu subMenu) : - PageGroupItem(STR_ANADIAGS_UNFILTRAW, subMenu) + AnaUnfilteredRawViewPage(QMPage qmPage) : + PageGroupItem(STR_ANADIAGS_UNFILTRAW, qmPage) { icon = ICON_STATS; } @@ -518,8 +518,8 @@ class AnaUnfilteredRawViewPage : public PageGroupItem class AnaMinMaxViewPage : public PageGroupItem { public: - AnaMinMaxViewPage(QuickMenu::SubMenu subMenu) : - PageGroupItem(STR_ANADIAGS_MINMAX, subMenu) + AnaMinMaxViewPage(QMPage qmPage) : + PageGroupItem(STR_ANADIAGS_MINMAX, qmPage) { icon = ICON_STATS; } @@ -531,11 +531,11 @@ class AnaMinMaxViewPage : public PageGroupItem } }; -RadioAnalogsDiagsViewPageGroup::RadioAnalogsDiagsViewPageGroup(QuickMenu::SubMenu subMenu) : +RadioAnalogsDiagsViewPageGroup::RadioAnalogsDiagsViewPageGroup(QMPage qmPage) : TabsGroup(ICON_STATS, STR_ANALOGS_BTN) { - addTab(new AnaCalibratedViewPage(subMenu)); - addTab(new AnaFilteredDevViewPage(subMenu)); - addTab(new AnaUnfilteredRawViewPage(subMenu)); - addTab(new AnaMinMaxViewPage(subMenu)); + addTab(new AnaCalibratedViewPage(qmPage)); + addTab(new AnaFilteredDevViewPage(qmPage)); + addTab(new AnaUnfilteredRawViewPage(qmPage)); + addTab(new AnaMinMaxViewPage(qmPage)); } diff --git a/radio/src/gui/colorlcd/radio/radio_diaganas.h b/radio/src/gui/colorlcd/radio/radio_diaganas.h index 70e5d3196..701d2efcf 100644 --- a/radio/src/gui/colorlcd/radio/radio_diaganas.h +++ b/radio/src/gui/colorlcd/radio/radio_diaganas.h @@ -26,5 +26,5 @@ class RadioAnalogsDiagsViewPageGroup : public TabsGroup { public: - RadioAnalogsDiagsViewPageGroup(QuickMenu::SubMenu subMenu); + RadioAnalogsDiagsViewPageGroup(QMPage qmPage); }; diff --git a/radio/src/gui/colorlcd/radio/radio_hardware.cpp b/radio/src/gui/colorlcd/radio/radio_hardware.cpp index 2bcdcd1db..bf4f84131 100644 --- a/radio/src/gui/colorlcd/radio/radio_hardware.cpp +++ b/radio/src/gui/colorlcd/radio/radio_hardware.cpp @@ -198,7 +198,7 @@ void RadioHardwarePage::build(Window* window) // Debugs new SetupButtonGroup(window, {0, 0, LCD_W - padding * 2, 0}, STR_DEBUG, FS_BTN_COLS, PAD_ZERO, { - {STR_DEF(STR_ANALOGS_BTN), [=]() { new RadioAnalogsDiagsViewPageGroup(quickMenuId); }}, + {STR_DEF(STR_ANALOGS_BTN), [=]() { new RadioAnalogsDiagsViewPageGroup(qmPageId); }}, {STR_DEF(STR_KEYS_BTN), []() { new RadioKeyDiagsPage(); }}, #if defined(FUNCTION_SWITCHES) {STR_DEF(STR_FS_BTN), []() { new RadioCustSwitchesDiagsPage(); }}, diff --git a/radio/src/gui/colorlcd/radio/radio_setup.cpp b/radio/src/gui/colorlcd/radio/radio_setup.cpp index c0f644e20..ebedd552b 100644 --- a/radio/src/gui/colorlcd/radio/radio_setup.cpp +++ b/radio/src/gui/colorlcd/radio/radio_setup.cpp @@ -33,6 +33,8 @@ #include "storage/modelslist.h" #include "tasks/mixer_task.h" #include "slider.h" +#include "key_shortcuts.h" +#include "quick_menu_favorites.h" #define SET_DIRTY() storageDirty(EE_GENERAL) @@ -827,7 +829,7 @@ static SetupLineDef setupLines[] = { PageGroup* pg = (PageGroup*)Layer::getPageGroup(); coord_t y = pg->getScrollY(); pg->onCancel(); - PageGroup::RadioMenu(); + QuickMenu::openPage(QM_RADIO_SETUP); pg = (PageGroup*)Layer::getPageGroup(); pg->setScrollY(y); // Force QM rebuild for language change @@ -955,6 +957,15 @@ static SetupLineDef setupLines[] = { RadioSetupPage::RadioSetupPage(PageDef& pageDef) : PageGroupItem(pageDef, PAD_TINY) {} +static bool hasShortcutKeys() +{ +#if defined(USE_HATS_AS_KEYS) + return true; +#else + return keysGetSupported() & ((1 << KEY_MODEL) | (1 << KEY_SYS) | (1 << KEY_TELE)); +#endif +} + void RadioSetupPage::build(Window* window) { coord_t y = 0; @@ -980,6 +991,8 @@ 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(); }}, + {STR_DEF(STR_KEY_SHORTCUTS), []() { new QMKeyShortcutsPage(); }, nullptr, [=]() { return hasShortcutKeys(); }}, + {STR_DEF(STR_QUICK_MENU_FAVORITES), []() { new QMFavoritesPage(); }, nullptr}, }, BTN_H); y += w->height() + padding; diff --git a/radio/src/gui/colorlcd/radio/radio_theme.h b/radio/src/gui/colorlcd/radio/radio_theme.h index 084e74265..35ba5996f 100644 --- a/radio/src/gui/colorlcd/radio/radio_theme.h +++ b/radio/src/gui/colorlcd/radio/radio_theme.h @@ -39,8 +39,6 @@ class ThemeSetupPage : public PageGroupItem void build(Window *window) override; void checkEvents() override; - bool isVisible() const override { return radioThemesEnabled(); } - static LAYOUT_VAL_SCALED(COLOR_PREVIEW_SIZE, 18) static LAYOUT_ORIENTATION(LIST_SIZE, (LCD_W - PAD_MEDIUM * 2) / 2 - COLOR_PREVIEW_SIZE, LCD_H / 2 - LAYOUT_SCALE(38)); diff --git a/radio/src/gui/colorlcd/radio/radio_trainer.h b/radio/src/gui/colorlcd/radio/radio_trainer.h index 23257bd51..e5d7df45c 100644 --- a/radio/src/gui/colorlcd/radio/radio_trainer.h +++ b/radio/src/gui/colorlcd/radio/radio_trainer.h @@ -29,7 +29,5 @@ class RadioTrainerPage : public PageGroupItem public: RadioTrainerPage(PageDef& pageDef); - bool isVisible() const override { return radioTrainerEnabled(); } - void build(Window* window) override; }; diff --git a/radio/src/gui/colorlcd/setup_menus/key_shortcuts.cpp b/radio/src/gui/colorlcd/setup_menus/key_shortcuts.cpp new file mode 100644 index 000000000..659f18a4f --- /dev/null +++ b/radio/src/gui/colorlcd/setup_menus/key_shortcuts.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "key_shortcuts.h" +#include "edgetx.h" +#include "pagegroup.h" + +#define SET_DIRTY() storageDirty(EE_GENERAL) + +static bool hasKey(event_t event) +{ +#if defined(USE_HATS_AS_KEYS) + return true; +#else + EnumKeys key = (EnumKeys)EVT_KEY_MASK(event); + return (keysGetSupported() & (1 << key)); +#endif +} + +void QMKeyShortcutsPage::addKey(event_t event, std::vector qmPages, const char* nm) +{ + if (hasKey(event)) { + extern uint16_t keyMapping(uint16_t event); + event = keyMapping(event); + + setupLine(nm, [=](Window* parent, coord_t x, coord_t y) { + auto c = new Choice( + parent, {LCD_W / 4, y, LCD_W * 2 / 3, 0}, qmPages, QM_NONE, QM_TOOLS_DEBUG, + GET_DEFAULT(g_eeGeneral.getKeyShortcut(event)), + [=](int32_t newValue) { + g_eeGeneral.setKeyShortcut(event, (QMPage)newValue); + SET_DIRTY(); + }, STR_KEY_SHORTCUTS); + + c->setPopupWidth(LCD_W * 3 / 4); + c->setAvailableHandler( + [=](int newValue) { + if (newValue == QM_NONE) return true; + if (g_eeGeneral.hasKeyShortcut((QMPage)newValue)) + return false; + return newValue <= QM_UI_SCREEN1 || newValue > QM_UI_ADD_PG; } + ); + }); + } +} + +QMKeyShortcutsPage::QMKeyShortcutsPage(): + SubPage(ICON_RADIO, STR_MAIN_MENU_RADIO_SETTINGS, STR_KEY_SHORTCUTS, true) +{ + std::vector qmPages = QuickMenu::menuPageNames(false); + + setupLine(STR_SHORT_PRESS, nullptr); + addKey(EVT_KEY_BREAK(KEY_SYS), qmPages, "SYS"); + addKey(EVT_KEY_BREAK(KEY_MODEL), qmPages, "MDL"); + addKey(EVT_KEY_BREAK(KEY_TELE), qmPages, "TELE"); + + setupLine(STR_LONG_PRESS, nullptr); + addKey(EVT_KEY_LONG(KEY_SYS), qmPages, "SYS"); + addKey(EVT_KEY_LONG(KEY_MODEL), qmPages, "MDL"); + addKey(EVT_KEY_LONG(KEY_TELE), qmPages, "TELE"); + + new TextButton(body, {LV_PCT(10), y + PAD_LARGE, LV_PCT(80), 0}, STR_SF_RESET, + [=]() { + g_eeGeneral.defaultKeyShortcuts(); + SET_DIRTY(); + return 0; + }); + + enableRefresh(); +} diff --git a/radio/src/gui/colorlcd/setup_menus/key_shortcuts.h b/radio/src/gui/colorlcd/setup_menus/key_shortcuts.h new file mode 100644 index 000000000..9f7977362 --- /dev/null +++ b/radio/src/gui/colorlcd/setup_menus/key_shortcuts.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#pragma once + +#include "page.h" + +class QMKeyShortcutsPage : public SubPage +{ + public: + QMKeyShortcutsPage(); + + protected: + void addKey(event_t event, std::vector qmPages, const char* nm); +}; diff --git a/radio/src/gui/colorlcd/setup_menus/menu_model.cpp b/radio/src/gui/colorlcd/setup_menus/menu_model.cpp deleted file mode 100644 index c2636247c..000000000 --- a/radio/src/gui/colorlcd/setup_menus/menu_model.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * Based on code named - * opentx - https://github.com/opentx/opentx - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "edgetx.h" -#include "model_curves.h" -#include "model_flightmodes.h" -#include "model_gvars.h" -#include "model_heli.h" -#include "model_inputs.h" -#include "model_logical_switches.h" -#include "model_mixer_scripts.h" -#include "model_mixes.h" -#include "model_outputs.h" -#include "model_select.h" -#include "model_setup.h" -#include "model_telemetry.h" -#include "special_functions.h" -#include "view_text.h" - -PageDef modelMenuItems[] = { - { ICON_MODEL_SETUP, STR_DEF(STR_QM_GEN_SETTINGS), STR_DEF(STR_MAIN_MENU_SETTINGS), PAGE_CREATE, QuickMenu::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, QuickMenu::MODEL_FLIGHTMODES, [](PageDef& pageDef) { return new ModelFlightModesPage(pageDef); }, modelFMEnabled}, -#endif - { ICON_MODEL_INPUTS, STR_DEF(STR_QM_INPUTS), STR_DEF(STR_MENUINPUTS), PAGE_CREATE, QuickMenu::MODEL_INPUTS, [](PageDef& pageDef) { return new ModelInputsPage(pageDef); }}, - { ICON_MODEL_MIXER, STR_DEF(STR_QM_MIXES), STR_DEF(STR_MIXES), PAGE_CREATE, QuickMenu::MODEL_MIXES, [](PageDef& pageDef) { return new ModelMixesPage(pageDef); }}, - { ICON_MODEL_OUTPUTS, STR_DEF(STR_QM_OUTPUTS), STR_DEF(STR_MENULIMITS), PAGE_CREATE, QuickMenu::MODEL_OUTPUTS, [](PageDef& pageDef) { return new ModelOutputsPage(pageDef); }}, - { ICON_MODEL_CURVES, STR_DEF(STR_QM_CURVES), STR_DEF(STR_MENUCURVES), PAGE_CREATE, QuickMenu::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, QuickMenu::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, QuickMenu::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, QuickMenu::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, QuickMenu::MODEL_SCRIPTS, [](PageDef& pageDef) { return new ModelMixerScriptsPage(pageDef); }, modelCustomScriptsEnabled}, -#endif - { ICON_MODEL_TELEMETRY, STR_DEF(STR_QM_TELEM), STR_DEF(STR_MENUTELEMETRY), PAGE_CREATE, QuickMenu::MODEL_TELEMETRY, [](PageDef& pageDef) { return new ModelTelemetryPage(pageDef); }, modelTelemetryEnabled}, - { ICON_MODEL_NOTES, STR_DEF(STR_MAIN_MENU_MODEL_NOTES), STR_DEF(STR_MAIN_MENU_MODEL_NOTES), PAGE_CREATE, QuickMenu::MODEL_NOTES, [](PageDef& pageDef) { return new ModelNotesPage(pageDef); }, modelHasNotes}, - { EDGETX_ICONS_COUNT } -}; diff --git a/radio/src/gui/colorlcd/setup_menus/menu_radio.cpp b/radio/src/gui/colorlcd/setup_menus/menu_radio.cpp deleted file mode 100644 index 497c57c8f..000000000 --- a/radio/src/gui/colorlcd/setup_menus/menu_radio.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * Based on code named - * opentx - https://github.com/opentx/opentx - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "edgetx.h" -#include "radio_hardware.h" -#include "radio_setup.h" -#include "radio_trainer.h" -#include "radio_version.h" -#include "special_functions.h" - -PageDef radioMenuItems[] = { - { ICON_RADIO_SETUP, STR_DEF(STR_QM_GEN_SETTINGS), STR_DEF(STR_MAIN_MENU_SETTINGS), PAGE_CREATE, QuickMenu::RADIO_SETUP, [](PageDef& pageDef) { return new RadioSetupPage(pageDef); }}, - { ICON_RADIO_GLOBAL_FUNCTIONS, STR_DEF(STR_QM_GLOB_FUNC), STR_DEF(STR_MENUSPECIALFUNCS), PAGE_CREATE, QuickMenu::RADIO_GF, [](PageDef& pageDef) { return new GlobalFunctionsPage(pageDef); }, radioGFEnabled}, - { ICON_RADIO_TRAINER, STR_DEF(STR_QM_TRAINER), STR_DEF(STR_MENUTRAINER), PAGE_CREATE, QuickMenu::RADIO_TRAINER, [](PageDef& pageDef) { return new RadioTrainerPage(pageDef); }, radioTrainerEnabled}, - { ICON_RADIO_HARDWARE, STR_DEF(STR_QM_HARDWARE), STR_DEF(STR_HARDWARE), PAGE_CREATE, QuickMenu::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, QuickMenu::RADIO_VERSION, [](PageDef& pageDef) { return new RadioVersionPage(pageDef); }}, - { EDGETX_ICONS_COUNT } -}; diff --git a/radio/src/gui/colorlcd/setup_menus/menu_screen.cpp b/radio/src/gui/colorlcd/setup_menus/menu_screen.cpp deleted file mode 100644 index ee5468d5a..000000000 --- a/radio/src/gui/colorlcd/setup_menus/menu_screen.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * Based on code named - * opentx - https://github.com/opentx/opentx - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "edgetx.h" -#include "screen_setup.h" -#include "view_main.h" -#include "quick_menu.h" - -PageDef screensMenuItems[] = { - { ICON_RADIO_EDIT_THEME, STR_DEF(STR_QM_THEMES), STR_DEF(STR_MAIN_MENU_THEMES), PAGE_CREATE, QuickMenu::UI_THEMES, [](PageDef& pageDef) { return new ThemeSetupPage(pageDef); }, radioThemesEnabled}, - { ICON_THEME_SETUP, STR_DEF(STR_QM_TOP_BAR), STR_DEF(STR_USER_INTERFACE), PAGE_CREATE, QuickMenu::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, QuickMenu::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, QuickMenu::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, QuickMenu::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, QuickMenu::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, QuickMenu::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, QuickMenu::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, QuickMenu::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, QuickMenu::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, QuickMenu::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, QuickMenu::UI_SCREEN10, [](PageDef& pageDef) { return new ScreenSetupPage(9, pageDef); }, []() { return customScreens[9] != nullptr; }}, - { ICON_THEME_ADD_VIEW, STR_DEF(STR_QM_ADD_SCREEN), nullptr, PAGE_ACTION, QuickMenu::UI_ADD_PG, nullptr, []() { return customScreens[9] == nullptr; }, - [](QuickSubMenu* subMenu) { - 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)); - - subMenu->onPress(newIdx + ScreenSetupPage::FIRST_SCREEN_OFFSET); - - storageDirty(EE_MODEL); - } else { - TRACE("Add screen: factory is NULL"); - } - } - }, - { EDGETX_ICONS_COUNT } -}; diff --git a/radio/src/gui/colorlcd/setup_menus/menu_tools.cpp b/radio/src/gui/colorlcd/setup_menus/menu_tools.cpp deleted file mode 100644 index c0682a1f0..000000000 --- a/radio/src/gui/colorlcd/setup_menus/menu_tools.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * Based on code named - * opentx - https://github.com/opentx/opentx - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "edgetx.h" -#include "radio_sdmanager.h" -#include "radio_tools.h" -#include "view_statistics.h" -#include "view_logical_switches.h" -#include "view_channels.h" - -PageDef toolsMenuItems[] = { - { ICON_TOOLS_APPS, STR_DEF(STR_QM_APPS), STR_DEF(STR_MAIN_MENU_APPS), PAGE_CREATE, QuickMenu::TOOLS_APPS, [](PageDef& pageDef) { return new RadioToolsPage(pageDef); }}, - { ICON_RADIO_SD_MANAGER, STR_DEF(STR_QM_STORAGE), STR_DEF(STR_SD_CARD), PAGE_CREATE, QuickMenu::TOOLS_STORAGE, [](PageDef& pageDef) { return new RadioSdManagerPage(pageDef); }}, - { ICON_TOOLS_RESET, STR_DEF(STR_QM_RESET), nullptr, PAGE_ACTION, QuickMenu::TOOLS_RESET, nullptr, nullptr, - [](QuickSubMenu* subMenu) { - subMenu->onSelect(true); - 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_MONITOR, STR_DEF(STR_QM_CHAN_MON), nullptr, PAGE_ACTION, QuickMenu::TOOLS_CHAN_MON, nullptr, nullptr, - [](QuickSubMenu* subMenu) { - subMenu->onSelect(true); - new ChannelsViewMenu(); - } - }, - { ICON_MONITOR_LOGICAL_SWITCHES, STR_DEF(STR_QM_LS_MON), STR_DEF(STR_MONITOR_SWITCHES), PAGE_CREATE, QuickMenu::TOOLS_LS_MON, [](PageDef& pageDef) { return new LogicalSwitchesViewPage(pageDef); }}, - { ICON_STATS, STR_DEF(STR_QM_STATS), STR_DEF(STR_MAIN_MENU_STATISTICS), PAGE_CREATE, QuickMenu::TOOLS_STATS, [](PageDef& pageDef) { return new StatisticsViewPage(pageDef); }}, - { ICON_STATS_DEBUG, STR_DEF(STR_QM_DEBUG), STR_DEF(STR_DEBUG), PAGE_CREATE, QuickMenu::TOOLS_DEBUG, [](PageDef& pageDef) { return new DebugViewPage(pageDef); }}, - { EDGETX_ICONS_COUNT } -}; diff --git a/radio/src/gui/colorlcd/setup_menus/pagegroup.cpp b/radio/src/gui/colorlcd/setup_menus/pagegroup.cpp index d095d5fb4..6fdc2014d 100644 --- a/radio/src/gui/colorlcd/setup_menus/pagegroup.cpp +++ b/radio/src/gui/colorlcd/setup_menus/pagegroup.cpp @@ -63,14 +63,14 @@ PageGroupHeaderBase::PageGroupHeaderBase(Window* parent, coord_t height, EdgeTxI parentLabel = etx_label_create(lvobj); etx_txt_color(parentLabel, COLOR_THEME_PRIMARY2_INDEX); - lv_obj_set_pos(parentLabel, PageGroup::PAGE_TOP_BAR_H + PAD_LARGE, PageHeader::PAGE_TITLE_TOP); - lv_obj_set_size(parentLabel, LCD_W - PageGroup::PAGE_TOP_BAR_H * 4 - PAD_LARGE * 2, EdgeTxStyles::STD_FONT_HEIGHT); + 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_label_set_text(parentLabel, parentTitle); titleLabel = etx_label_create(lvobj); etx_txt_color(titleLabel, COLOR_THEME_PRIMARY2_INDEX); - lv_obj_set_pos(titleLabel, PageGroup::PAGE_TOP_BAR_H + PAD_LARGE, PageHeader::PAGE_TITLE_TOP + EdgeTxStyles::STD_FONT_HEIGHT); - lv_obj_set_size(titleLabel, LCD_W - PageGroup::PAGE_TOP_BAR_H * 4 - PAD_LARGE * 2, EdgeTxStyles::STD_FONT_HEIGHT); + 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); setTitle(""); } @@ -89,10 +89,10 @@ void PageGroupHeaderBase::addTab(PageGroupItem* page) pages.emplace_back(page); } -bool PageGroupHeaderBase::hasSubMenu(QuickMenu::SubMenu subMenu) +bool PageGroupHeaderBase::hasSubMenu(QMPage qmPage) { for (uint8_t i = 0; i < pages.size(); i += 1) { - if (pages[i]->subMenu() == subMenu) + if (pages[i]->pageId() == qmPage) return true; } return false; @@ -233,6 +233,8 @@ void PageGroupBase::setCurrentTab(unsigned index) header->setTitle(tab->getTitle().c_str()); header->setIcon(tab->getIcon()); + QuickMenu::setCurrentPage(tab->pageId(), icon); + lv_obj_enable_style_refresh(false); body->clear(); @@ -267,52 +269,26 @@ void PageGroupBase::setCurrentTab(unsigned index) } #if defined(HARDWARE_KEYS) -void PageGroupBase::onPressSYS() +void PageGroupBase::doKeyShortcut(event_t event) { - if (!quickMenu) openMenu(); -} - -void PageGroupBase::onLongPressSYS() -{ - if (icon == ICON_RADIO) { - setCurrentTab(0); + QMPage pg = g_eeGeneral.getKeyShortcut(event); + if (pg == QM_OPEN_QUICK_MENU) { + if (!quickMenu) openMenu(); } else { - onCancel(); - PageGroup::ToolsMenu(); - } -} - -void PageGroupBase::onPressMDL() -{ - if (icon == ICON_MODEL) { - setCurrentTab(0); - } else { - onCancel(); - PageGroup::ModelMenu(); - } -} - -void PageGroupBase::onLongPressMDL() -{ - onCancel(); - new ModelLabelsWindow(); -} - -void PageGroupBase::onPressTELE() -{ - if (icon != ICON_THEME) { - onCancel(); - (PageGroup::ScreenMenu())->setCurrentTab(ViewMain::instance()->getCurrentMainView() + ScreenSetupPage::FIRST_SCREEN_OFFSET); - } -} - -void PageGroupBase::onLongPressTELE() -{ - if (icon != ICON_MONITOR) { - onCancel(); - new ChannelsViewMenu(); + if (QuickMenu::pageIcon(pg) == icon) { + setCurrentTab(QuickMenu::pageIndex(pg)); + } else { + onCancel(); + QuickMenu::openPage(pg); + } } } +void PageGroupBase::onPressSYS() { doKeyShortcut(EVT_KEY_BREAK(KEY_SYS)); } +void PageGroupBase::onLongPressSYS() { doKeyShortcut(EVT_KEY_LONG(KEY_SYS)); } +void PageGroupBase::onPressMDL() { doKeyShortcut(EVT_KEY_BREAK(KEY_MODEL)); } +void PageGroupBase::onLongPressMDL() { doKeyShortcut(EVT_KEY_LONG(KEY_MODEL)); } +void PageGroupBase::onPressTELE() { doKeyShortcut(EVT_KEY_BREAK(KEY_TELE)); } +void PageGroupBase::onLongPressTELE() { doKeyShortcut(EVT_KEY_LONG(KEY_TELE)); } void PageGroupBase::onPressPGUP() { header->prevTab(); } void PageGroupBase::onPressPGDN() { header->nextTab(); } @@ -321,9 +297,9 @@ void PageGroupBase::onLongPressPGDN() { header->nextTab(); } void PageGroupBase::onLongPressRTN() { onCancel(); } #endif -bool PageGroupBase::hasSubMenu(QuickMenu::SubMenu subMenu) +bool PageGroupBase::hasSubMenu(QMPage qmPage) { - return header->hasSubMenu(subMenu); + return header->hasSubMenu(qmPage); } coord_t PageGroupBase::getScrollY() @@ -372,14 +348,9 @@ void PageGroup::openMenu() [=](bool close) { if (close) onCancel(); - }, this, currentTab->subMenu()); + }, this, currentTab->pageId()); } -PageGroup* PageGroup::ScreenMenu() { return new PageGroup(ICON_THEME, STR_MAIN_MENU_SCREEN_SETTINGS, screensMenuItems); } -PageGroup* PageGroup::RadioMenu() { return new PageGroup(ICON_RADIO, STR_MAIN_MENU_RADIO_SETTINGS, radioMenuItems); } -PageGroup* PageGroup::ToolsMenu() { return new PageGroup(ICON_RADIO_TOOLS, STR_QM_TOOLS, toolsMenuItems); } -PageGroup* PageGroup::ModelMenu() { return new PageGroup(ICON_MODEL, STR_MAIN_MENU_MODEL_SETTINGS, modelMenuItems); } - //----------------------------------------------------------------------------- class TabsGroupHeader : public PageGroupHeaderBase @@ -454,9 +425,9 @@ TabsGroup::TabsGroup(EdgeTxIcon icon, const char* parentLabel) : void TabsGroup::openMenu() { PageGroup* p = (PageGroup*)Layer::getPageGroup(); - QuickMenu::SubMenu subMenu = QuickMenu::NONE; + QMPage qmPage = QM_NONE; if (p) - subMenu = p->getCurrentTab()->subMenu(); + qmPage = p->getCurrentTab()->pageId(); quickMenu = QuickMenu::openQuickMenu([=]() { quickMenu = nullptr; }, [=](bool close) { onCancel(); @@ -467,7 +438,7 @@ void TabsGroup::openMenu() if (close) Layer::back()->onCancel(); } - }, p, subMenu); + }, p, qmPage); } void TabsGroup::hidePageButtons() diff --git a/radio/src/gui/colorlcd/setup_menus/pagegroup.h b/radio/src/gui/colorlcd/setup_menus/pagegroup.h index 0b6c4fe12..8da98514d 100644 --- a/radio/src/gui/colorlcd/setup_menus/pagegroup.h +++ b/radio/src/gui/colorlcd/setup_menus/pagegroup.h @@ -40,34 +40,49 @@ struct PageDef { STR_TYP qmTitle; STR_TYP title; PageDefAction pageAction; - QuickMenu::SubMenu subMenu; + QMPage qmPage; std::function create; std::function enabled; - std::function action; + std::function action; }; -extern PageDef modelMenuItems[]; -extern PageDef radioMenuItems[]; -extern PageDef screensMenuItems[]; -extern PageDef toolsMenuItems[]; +extern PageDef favoritesMenuItems[]; + +enum QMTopDefAction { + QM_SUBMENU, + QM_ACTION +}; + +struct QMTopDef { + EdgeTxIcon icon; + STR_TYP qmTitle; + STR_TYP title; + QMTopDefAction pageAction; + QMPage qmPage; + PageDef* subMenuItems; + std::function action; + std::function enabled; +}; + +extern QMTopDef qmTopItems[]; //----------------------------------------------------------------------------- class PageGroupItem { public: - PageGroupItem(const std::string& title, QuickMenu::SubMenu subMenu = QuickMenu::NONE) : - title(std::move(title)), icon(ICON_EDGETX), quickMenuId(subMenu), padding(PAD_SMALL) + PageGroupItem(std::string title, QMPage qmPage = QM_NONE) : + title(std::move(title)), icon(ICON_EDGETX), qmPageId(qmPage), padding(PAD_SMALL) {} PageGroupItem(PageDef& pageDef, PaddingSize padding = PAD_SMALL) : - title(STR_VAL(pageDef.title)), icon(pageDef.icon), quickMenuId(pageDef.subMenu), - padding(padding) + title(STR_VAL(pageDef.title)), icon(pageDef.icon), qmPageId(pageDef.qmPage), + padding(padding), enabled(std::move(pageDef.enabled)) {} virtual ~PageGroupItem() = default; - virtual bool isVisible() const { return true; } + bool isVisible() const { return enabled == nullptr || enabled(); } virtual void build(Window* window) = 0; @@ -84,13 +99,14 @@ class PageGroupItem virtual void update(uint8_t index) {} virtual void cleanup() {} - QuickMenu::SubMenu subMenu() const { return quickMenuId; } + QMPage pageId() const { return qmPageId; } protected: std::string title; EdgeTxIcon icon; - QuickMenu::SubMenu quickMenuId = QuickMenu::NONE; + QMPage qmPageId = QM_NONE; PaddingSize padding; + std::function enabled = nullptr; }; //----------------------------------------------------------------------------- @@ -118,7 +134,7 @@ class PageGroupHeaderBase : public Window } } - bool hasSubMenu(QuickMenu::SubMenu n); + bool hasSubMenu(QMPage n); PageGroupItem* pageTab(uint8_t idx) const { return pages[idx]; } bool isCurrent(uint8_t idx) const { return currentIndex == idx; } @@ -151,11 +167,13 @@ class PageGroupBase : public NavWindow void addTab(PageGroupItem* page); - bool hasSubMenu(QuickMenu::SubMenu n); + bool hasSubMenu(QMPage n); coord_t getScrollY(); void setScrollY(coord_t y); + EdgeTxIcon getIcon() const { return icon; } + protected: PageGroupHeaderBase* header = nullptr; Window* body = nullptr; @@ -170,6 +188,7 @@ class PageGroupBase : public NavWindow void deleteLater(bool detach = true, bool trash = true) override; #if defined(HARDWARE_KEYS) + void doKeyShortcut(event_t event); void onPressSYS() override; void onLongPressSYS() override; void onPressMDL() override; @@ -201,11 +220,6 @@ class PageGroup : public PageGroupBase bool isPageGroup() override { return true; } - static PageGroup* ScreenMenu(); - static PageGroup* RadioMenu(); - static PageGroup* ToolsMenu(); - static PageGroup* ModelMenu(); - static LAYOUT_VAL_SCALED(PAGE_TOP_BAR_H, 45) protected: diff --git a/radio/src/gui/colorlcd/setup_menus/quick_menu.cpp b/radio/src/gui/colorlcd/setup_menus/quick_menu.cpp index 1dd52f9f5..0e3cf79b6 100644 --- a/radio/src/gui/colorlcd/setup_menus/quick_menu.cpp +++ b/radio/src/gui/colorlcd/setup_menus/quick_menu.cpp @@ -32,151 +32,180 @@ //----------------------------------------------------------------------------- -ButtonBase* QuickSubMenu::addButton() +class QuickSubMenu { - menuButton = quickMenu->getTopMenu()->addButton(icon, title, - [=]() -> uint8_t { - activate(); - return 0; - }); + public: + QuickSubMenu(Window* parent, QuickMenu* quickMenu, + EdgeTxIcon icon, const char* title, const char* parentTitle, + PageDef* items): + parent(parent), quickMenu(quickMenu), + icon(icon), title(title), parentTitle(parentTitle), items(items) + {} - menuButton->setFocusHandler([=](bool focus) { - if (!quickMenu->deleted()) { - if (focus) { - if (!subMenu) buildSubMenu(); - quickMenu->getTopMenu()->setCurrent(menuButton); - } - if (subMenu) - subMenu->show(focus); - if (!focus && quickMenu->getTopMenu()) - quickMenu->getTopMenu()->setGroup(); - } - }); - - return menuButton; -} - -bool QuickSubMenu::isSubMenu(QuickMenu::SubMenu n) -{ - for (int i = 0; items[i].icon < EDGETX_ICONS_COUNT; i += 1) - if (items[i].subMenu == n) return true; - return false; -} - -bool QuickSubMenu::isSubMenu(ButtonBase* b) -{ - for (int i = 0; items[i].icon < EDGETX_ICONS_COUNT; i += 1) - if (menuButton == b) return true; - return false; -} - -int QuickSubMenu::getIndex(QuickMenu::SubMenu n) -{ - for (int i = 0; items[i].icon < EDGETX_ICONS_COUNT; i += 1) - if (items[i].subMenu == n) return i; - return -1; -} - -void QuickSubMenu::enableSubMenu() -{ - subMenu->setGroup(); - subMenu->setFocus(); - subMenu->setEnabled(); - subMenu->show(); - quickMenu->enableSubMenu(); -} - -void QuickSubMenu::setDisabled(bool all) -{ - if (subMenu) - subMenu->setDisabled(all); -} - -void QuickSubMenu::setCurrent(QuickMenu::SubMenu n) -{ - if (!subMenu) buildSubMenu(); - quickMenu->getTopMenu()->setCurrent(menuButton); - quickMenu->getTopMenu()->setDisabled(false); - subMenu->setCurrent(getIndex(n)); - enableSubMenu(); -} - -void QuickSubMenu::activate() -{ - if (!subMenu) buildSubMenu(); - quickMenu->getTopMenu()->setCurrent(menuButton); - quickMenu->getTopMenu()->setDisabled(false); - quickMenu->getTopMenu()->clearFocus(); - enableSubMenu(); -} - -void QuickSubMenu::doLayout() -{ - if (subMenu) - subMenu->doLayout(QuickMenu::QM_SUB_COLS); -} - -void QuickSubMenu::buildSubMenu() -{ - subMenu = new QuickMenuGroup(parent); - - for (int i = 0; items[i].icon < EDGETX_ICONS_COUNT; i += 1) { - subMenu->addButton(items[i].icon, STR_VAL(items[i].qmTitle), - std::bind(&QuickSubMenu::onPress, this, i), - [=]() { return items[i].enabled ? items[i].enabled() : true; }, - [=]() { QuickMenu::setCurrentPage(items[i].subMenu); }); + bool isSubMenu(QMPage n) + { + for (int i = 0; items[i].icon < EDGETX_ICONS_COUNT; i += 1) + if (items[i].qmPage == n) return true; + return false; } - doLayout(); - subMenu->hide(); - subMenu->setDisabled(true); -} + bool isSubMenu(QMPage n, EdgeTxIcon curIcon) + { + if ((icon != EDGETX_ICONS_COUNT) && (icon != curIcon)) return false; + return isSubMenu(n); + } -int QuickSubMenu::getPageNumber(int iconNumber) -{ - int pageNumber = 0; - for (int i = 0; i < iconNumber; i += 1) - if (items[i].pageAction == PAGE_CREATE) - pageNumber += 1; - return pageNumber; -} + bool isSubMenu(ButtonBase* b) + { + for (int i = 0; items[i].icon < EDGETX_ICONS_COUNT; i += 1) + if (menuButton == b) return true; + return false; + } -uint8_t QuickSubMenu::onPress(int n) -{ - if (items[n].pageAction == PAGE_CREATE) { - quickMenu->getTopMenu()->clearFocus(); - int pgIdx = getPageNumber(n); - if (quickMenu->getPageGroup() && quickMenu->getPageGroup()->hasSubMenu(items[n].subMenu)) { - quickMenu->onSelect(false); - quickMenu->getPageGroup()->setCurrentTab(pgIdx); - } else { - quickMenu->onSelect(true); - auto pg = new PageGroup(icon, parentTitle, items); - pg->setCurrentTab(pgIdx); - } - } else { + int getIndex(QMPage n) + { + for (int i = 0; items[i].icon < EDGETX_ICONS_COUNT; i += 1) + if (items[i].qmPage == n) return i; + return -1; + } + + ButtonBase* addButton() + { + menuButton = quickMenu->getTopMenu()->addButton(icon, title, + [=]() -> uint8_t { + activate(); + return 0; + }); + + menuButton->setFocusHandler([=](bool focus) { + if (!quickMenu->deleted()) { + if (focus) { + if (!subMenu) buildSubMenu(); + quickMenu->getTopMenu()->setCurrent(menuButton); + } + if (subMenu) + subMenu->show(focus); + if (!focus && quickMenu->getTopMenu()) + quickMenu->getTopMenu()->setGroup(); + } + }); + + return menuButton; + } + + void enableSubMenu() + { + subMenu->setGroup(); + subMenu->setFocus(); + subMenu->setEnabled(); + subMenu->show(); + quickMenu->enableSubMenu(); + } + + void setDisabled(bool all) + { + if (subMenu) + subMenu->setDisabled(all); + } + + void setCurrent(QMPage n) + { + if (!subMenu) buildSubMenu(); + quickMenu->getTopMenu()->setCurrent(menuButton); + quickMenu->getTopMenu()->setDisabled(false); + subMenu->setCurrent(getIndex(n)); + enableSubMenu(); + } + + void activate() + { + if (!subMenu) buildSubMenu(); quickMenu->getTopMenu()->setCurrent(menuButton); quickMenu->getTopMenu()->setDisabled(false); quickMenu->getTopMenu()->clearFocus(); enableSubMenu(); - items[n].action(this); } - return 0; -} -void QuickSubMenu::onSelect(bool close) -{ - quickMenu->onSelect(close); -} + void buildSubMenu() + { + subMenu = new QuickMenuGroup(parent); + + for (int i = 0; items[i].icon < EDGETX_ICONS_COUNT; i += 1) { + subMenu->addButton(items[i].icon, STR_VAL(items[i].qmTitle), + std::bind(&QuickSubMenu::onPress, this, i), + items[i].enabled, + [=]() { QuickMenu::setCurrentPage(items[i].qmPage, icon); }); + } + + doLayout(); + subMenu->hide(); + subMenu->setDisabled(true); + } + + uint8_t onPress(int n) + { + if (items[n].pageAction == PAGE_CREATE) { + quickMenu->getTopMenu()->clearFocus(); + int pgIdx = getPageNumber(n); + if (quickMenu->getPageGroup() && quickMenu->getPageGroup()->hasSubMenu(items[n].qmPage)) { + quickMenu->onSelect(false); + quickMenu->getPageGroup()->setCurrentTab(pgIdx); + } else { + quickMenu->onSelect(true); + auto pg = new PageGroup(icon, parentTitle, items); + pg->setCurrentTab(pgIdx); + } + } else { + quickMenu->getTopMenu()->setCurrent(menuButton); + quickMenu->getTopMenu()->setDisabled(false); + quickMenu->getTopMenu()->clearFocus(); + enableSubMenu(); + onSelect(true); + items[n].action(); + } + return 0; + } + + void onSelect(bool close) + { + quickMenu->onSelect(close); + } + + int getPageNumber(int iconNumber) + { + int pageNumber = 0; + for (int i = 0; i < iconNumber; i += 1) + if (items[i].pageAction == PAGE_CREATE) + pageNumber += 1; + return pageNumber; + } + + void doLayout() + { + if (subMenu) + subMenu->doLayout(QuickMenu::QM_SUB_COLS); + } + + protected: + Window* parent; + QuickMenu* quickMenu; + EdgeTxIcon icon; + const char* title; + const char* parentTitle; + PageDef* items; + QuickMenuGroup* subMenu = nullptr; + ButtonBase* menuButton = nullptr; +}; //----------------------------------------------------------------------------- QuickMenu* QuickMenu::instance = nullptr; -QuickMenu::SubMenu QuickMenu::curPage = QuickMenu::NONE; +QMPage QuickMenu::curPage = QM_NONE; +EdgeTxIcon QuickMenu::curIcon = EDGETX_ICONS_COUNT; QuickMenu* QuickMenu::openQuickMenu(std::function cancelHandler, std::function selectHandler, - PageGroupBase* pageGroup, SubMenu curPage) + PageGroupBase* pageGroup, QMPage curPage) { if (!instance) { instance = new QuickMenu(); @@ -188,6 +217,7 @@ QuickMenu* QuickMenu::openQuickMenu(std::function cancelHandler, void QuickMenu::shutdownQuickMenu() { if (instance) instance->deleteLater(); + instance = nullptr; } QuickMenu::QuickMenu() : @@ -218,32 +248,28 @@ QuickMenu::QuickMenu() : mainMenu = new QuickMenuGroup(box); - mainMenu->addButton(ICON_MODEL_SELECT, STR_QM_MANAGE_MODELS, - [=]() -> uint8_t { - onSelect(true); - new ModelLabelsWindow(); - return 0; - }); - box = new Window(this, {QM_SUB_X, QM_SUB_Y, QM_SUB_W, QM_SUB_H}); - QuickSubMenu* sub; + int f = 0; + for (int i = 0; i < MAX_QM_FAVORITES; i += 1) { + if (g_eeGeneral.qmFavorites[i].shortcut != QM_NONE) { + setupFavorite((QMPage)g_eeGeneral.qmFavorites[i].shortcut, f); + f += 1; + } + } + favoritesMenuItems[f].icon = EDGETX_ICONS_COUNT; - sub = new QuickSubMenu(box, this, ICON_MODEL, STR_QM_MODEL_SETUP, STR_MAIN_MENU_MODEL_SETTINGS, modelMenuItems); - sub->addButton(); - subMenus.emplace_back(sub); - - sub = new QuickSubMenu(box, this, ICON_RADIO, STR_QM_RADIO_SETUP, STR_MAIN_MENU_RADIO_SETTINGS, radioMenuItems); - sub->addButton(); - subMenus.emplace_back(sub); - - sub = new QuickSubMenu(box, this, ICON_THEME, STR_QM_UI_SETUP, STR_MAIN_MENU_SCREEN_SETTINGS, screensMenuItems); - sub->addButton(); - subMenus.emplace_back(sub); - - sub = new QuickSubMenu(box, this, ICON_RADIO_TOOLS, STR_QM_TOOLS, STR_QM_TOOLS, toolsMenuItems); - sub->addButton(); - subMenus.emplace_back(sub); + 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); + } 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); + } + } + } } void QuickMenu::deleteLater(bool detach, bool trash) @@ -257,7 +283,7 @@ void QuickMenu::deleteLater(bool detach, bool trash) void QuickMenu::openQM(std::function cancelHandler, std::function selectHandler, - PageGroupBase* newPageGroup, SubMenu newCurPage) + PageGroupBase* newPageGroup, QMPage newCurPage) { Layer::push(this); @@ -272,23 +298,182 @@ void QuickMenu::openQM(std::function cancelHandler, if (newPageGroup) { pageGroup = newPageGroup; curPage = newCurPage; + curIcon = pageGroup->getIcon(); mainMenu->setDisabled(false); mainMenu->clearFocus(); setFocus(curPage); } else { pageGroup = nullptr; - if (curPage >= QuickMenu::FIRST_SUB_MENU_ITEM) { + if (curPage != QM_MANAGE_MODELS && curPage != QM_NONE) { mainMenu->setDisabled(false); mainMenu->clearFocus(); setFocus(curPage); } else { - if (curPage == QuickMenu::MANAGE_MODELS) - mainMenu->setCurrent(0); + if (curPage == QM_MANAGE_MODELS) + mainMenu->setCurrent(favoritesMenuItems[0].icon == EDGETX_ICONS_COUNT ? 0 : 1); focusMainMenu(); } } } +void QuickMenu::selected() +{ + if (instance) + instance->onSelect(true); +} + +void QuickMenu::openPage(QMPage page) +{ + for (int i = 1; qmTopItems[i].icon != EDGETX_ICONS_COUNT; i += 1) { + if (qmTopItems[i].pageAction == QM_ACTION) { + if (qmTopItems[i].qmPage == page) { + qmTopItems[i].action(); + return; + } + } else { + PageDef* sub = qmTopItems[i].subMenuItems; + 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) { + sub[j].action(); + } else { + auto pg = new PageGroup(qmTopItems[i].icon, STR_VAL(qmTopItems[i].title), sub); + pg->setCurrentTab(k); + return; + } + } else if (sub[j].pageAction == PAGE_CREATE) { + k += 1; + } + } + } + } +} + +EdgeTxIcon QuickMenu::pageIcon(QMPage page) +{ + for (int i = 1; qmTopItems[i].icon != EDGETX_ICONS_COUNT; i += 1) { + if (qmTopItems[i].pageAction == QM_ACTION) { + if (qmTopItems[i].qmPage == page) { + return qmTopItems[i].icon; + } + } else { + PageDef* sub = qmTopItems[i].subMenuItems; + for (int j = 0; sub[j].icon != EDGETX_ICONS_COUNT; j += 1) { + if (sub[j].qmPage == page) { + return sub[j].icon; + } + } + } + } + return EDGETX_ICONS_COUNT; +} + +int QuickMenu::pageIndex(QMPage page) +{ + for (int i = 1; qmTopItems[i].icon != EDGETX_ICONS_COUNT; i += 1) { + if (qmTopItems[i].pageAction == QM_ACTION) { + if (qmTopItems[i].qmPage == page) { + return 0; + } + } else { + PageDef* sub = qmTopItems[i].subMenuItems; + for (int j = 0, k = 0; sub[j].icon != EDGETX_ICONS_COUNT; j += 1) { + if (sub[j].qmPage == page) { + if (sub[j].pageAction == PAGE_CREATE) + return k; + else + return 0; + } else if (sub[j].pageAction == PAGE_CREATE) { + k += 1; + } + } + } + } + return 0; +} + +static 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) + { + str.replace(pos, from.length(), to); + // easy to forget to add to.length() + pos = str.find(from, pos + to.length()); + } + return str; +} + +std::vector QuickMenu::menuPageNames(bool forFavorites) +{ + std::vector qmPages; + + qmPages.emplace_back(STR_NONE); + qmPages.emplace_back(STR_OPEN_QUICK_MENU); + + for (int i = 1; qmTopItems[i].icon != EDGETX_ICONS_COUNT; i += 1) { + if (qmTopItems[i].pageAction == QM_ACTION) { + qmPages.emplace_back(STR_VAL(qmTopItems[i].title)); + } else { + PageDef* sub = qmTopItems[i].subMenuItems; + for (int j = 0; sub[j].icon != EDGETX_ICONS_COUNT; j += 1) { + std::string s(STR_VAL(qmTopItems[i].title)); + s += " - "; + if (!forFavorites && sub[j].qmPage >= QM_UI_SCREEN1 && sub[j].qmPage <= QM_UI_SCREEN10) + s += STR_CURRENT_SCREEN; + else + s += STR_VAL(sub[j].title); + s = replaceAll(s, "\n", " "); + qmPages.emplace_back(s); + } + } + } + + return qmPages; +} + +void QuickMenu::setupFavorite(QMPage page, int f) +{ + PageDef& fav = favoritesMenuItems[f]; + + for (int i = 1; qmTopItems[i].icon != EDGETX_ICONS_COUNT; i += 1) { + if (qmTopItems[i].pageAction == QM_ACTION) { + if (qmTopItems[i].qmPage == page) { + fav.icon = qmTopItems[i].icon; + fav.qmTitle = qmTopItems[i].qmTitle; + fav.title = qmTopItems[i].title; + fav.pageAction = PAGE_ACTION; + fav.qmPage = qmTopItems[i].qmPage; + fav.create = nullptr; + fav.enabled = nullptr; + fav.action = qmTopItems[i].action; + return; + } + } else { + PageDef* sub = qmTopItems[i].subMenuItems; + for (int j = 0; sub[j].icon != EDGETX_ICONS_COUNT; j += 1) { + if (sub[j].qmPage == page) { + fav.icon = sub[j].icon; + fav.qmTitle = sub[j].qmTitle; + fav.title = sub[j].title; + fav.pageAction = sub[j].pageAction; + fav.qmPage = sub[j].qmPage; + fav.create = sub[j].create; + fav.enabled = sub[j].enabled; + fav.action = sub[j].action; + return; + } + } + } + } +} + +void QuickMenu::setCurrentPage(QMPage newPage, EdgeTxIcon newIcon) +{ + curPage = newPage; + curIcon = newIcon; +} + void QuickMenu::focusMainMenu() { inSubMenu = false; @@ -316,16 +501,16 @@ void QuickMenu::onCancel() { if (inSubMenu) { focusMainMenu(); - curPage = QuickMenu::NONE; + curPage = QM_NONE; } else { closeMenu(); } } -void QuickMenu::setFocus(SubMenu selection) +void QuickMenu::setFocus(QMPage selection) { for(auto sub : subMenus) { - if (sub->isSubMenu(selection)) { + if (sub->isSubMenu(selection, curIcon)) { sub->setCurrent(selection); return; } @@ -338,12 +523,22 @@ void QuickMenu::enableSubMenu() } #if defined(HARDWARE_KEYS) -void QuickMenu::onPressSYS() { closeMenu(); } -void QuickMenu::onLongPressSYS() { subMenus[3]->onPress(0); } -void QuickMenu::onPressMDL() { subMenus[0]->onPress(0); } -void QuickMenu::onLongPressMDL() { onSelect(true); new ModelLabelsWindow(); } -void QuickMenu::onPressTELE() { subMenus[2]->onPress(ScreenSetupPage::FIRST_SCREEN_OFFSET); } -void QuickMenu::onLongPressTELE() { onSelect(true); new ChannelsViewMenu(); } +void QuickMenu::doKeyShortcut(event_t event) +{ + QMPage pg = g_eeGeneral.getKeyShortcut(event); + if (pg == QM_OPEN_QUICK_MENU) { + closeMenu(); + } else { + onSelect(true); + QuickMenu::openPage(pg); + } +} +void QuickMenu::onPressSYS() { doKeyShortcut(EVT_KEY_BREAK(KEY_SYS)); } +void QuickMenu::onLongPressSYS() { doKeyShortcut(EVT_KEY_LONG(KEY_SYS)); } +void QuickMenu::onPressMDL() { doKeyShortcut(EVT_KEY_BREAK(KEY_MODEL)); } +void QuickMenu::onLongPressMDL() { doKeyShortcut(EVT_KEY_LONG(KEY_MODEL)); } +void QuickMenu::onPressTELE() { doKeyShortcut(EVT_KEY_BREAK(KEY_TELE)); } +void QuickMenu::onLongPressTELE() { doKeyShortcut(EVT_KEY_LONG(KEY_TELE)); } void QuickMenu::onLongPressRTN() { closeMenu(); } void QuickMenu::afterPG() @@ -357,7 +552,7 @@ void QuickMenu::afterPG() } } focusMainMenu(); - curPage = QuickMenu::NONE; + 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 86e33fb49..e73af19bd 100644 --- a/radio/src/gui/colorlcd/setup_menus/quick_menu.h +++ b/radio/src/gui/colorlcd/setup_menus/quick_menu.h @@ -25,6 +25,7 @@ #include "bitmaps.h" #include #include "quick_menu_group.h" +#include "quick_menu_def.h" class PageGroup; class PageGroupBase; @@ -42,76 +43,36 @@ struct PageDef; class QuickMenu : public NavWindow { public: - enum SubMenu { - NONE = 0, - MANAGE_MODELS, - FIRST_SUB_MENU_ITEM, - // Model menu - MODEL_SETUP = FIRST_SUB_MENU_ITEM, - MODEL_HELI, - MODEL_FLIGHTMODES, - MODEL_INPUTS, - MODEL_MIXES, - MODEL_OUTPUTS, - MODEL_CURVES, - MODEL_GVARS, - MODEL_LS, - MODEL_SF, - MODEL_SCRIPTS, - MODEL_TELEMETRY, - MODEL_NOTES, - // Radio menu - RADIO_SETUP, - RADIO_GF, - RADIO_TRAINER, - RADIO_HARDWARE, - RADIO_VERSION, - // UI menu - UI_THEMES, - UI_SETUP, - UI_SCREEN1, - UI_SCREEN2, - UI_SCREEN3, - UI_SCREEN4, - UI_SCREEN5, - UI_SCREEN6, - UI_SCREEN7, - UI_SCREEN8, - UI_SCREEN9, - UI_SCREEN10, - UI_ADD_PG, - // Tools menu - TOOLS_APPS, - TOOLS_STORAGE, - TOOLS_RESET, - TOOLS_CHAN_MON, - TOOLS_LS_MON, - TOOLS_STATS, - TOOLS_DEBUG, - }; QuickMenu(); - static QuickMenu* openQuickMenu(std::function cancelHandler, - std::function selectHandler = nullptr, - PageGroupBase* pageGroup = nullptr, SubMenu curPage = NONE); - static void shutdownQuickMenu(); - void onCancel() override; void onSelect(bool close); void closeMenu(); - void setFocus(SubMenu selection); + void setFocus(QMPage selection); void enableSubMenu(); - SubMenu currentPage() const { return curPage; } - static void setCurrentPage(SubMenu newPage) { curPage = newPage; } + static void setCurrentPage(QMPage newPage, EdgeTxIcon newIcon = EDGETX_ICONS_COUNT); PageGroupBase* getPageGroup() const { return pageGroup; } QuickMenuGroup* getTopMenu() const { return mainMenu; } + static QuickMenu* openQuickMenu(std::function cancelHandler, + std::function selectHandler = nullptr, + PageGroupBase* pageGroup = nullptr, QMPage curPage = QM_NONE); + + static void shutdownQuickMenu(); + static void selected(); + static void openPage(QMPage page); + 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); void onPressSYS() override; void onLongPressSYS() override; void onPressMDL() override; @@ -147,49 +108,14 @@ class QuickMenu : public NavWindow QuickMenuGroup* mainMenu = nullptr; std::vector subMenus; PageGroupBase* pageGroup = nullptr; - static SubMenu curPage; + static QMPage curPage; + static EdgeTxIcon curIcon; void openQM(std::function cancelHandler, std::function selectHandler, - PageGroupBase* pageGroup, SubMenu curPage); + PageGroupBase* pageGroup, QMPage curPage); void focusMainMenu(); void deleteLater(bool detach = true, bool trash = true) override; }; - -class QuickSubMenu -{ - public: - QuickSubMenu(Window* parent, QuickMenu* quickMenu, - EdgeTxIcon icon, const char* title, const char* parentTitle, - PageDef* items): - parent(parent), quickMenu(quickMenu), - icon(icon), title(title), parentTitle(parentTitle), items(items) - {} - - bool isSubMenu(QuickMenu::SubMenu n); - bool isSubMenu(ButtonBase* b); - int getIndex(QuickMenu::SubMenu n); - - ButtonBase* addButton(); - void enableSubMenu(); - void setDisabled(bool all); - void setCurrent(QuickMenu::SubMenu n); - void activate(); - void buildSubMenu(); - uint8_t onPress(int n); - void onSelect(bool close); - int getPageNumber(int iconNumber); - void doLayout(); - - protected: - Window* parent; - QuickMenu* quickMenu; - EdgeTxIcon icon; - const char* title; - const char* parentTitle; - PageDef* items; - QuickMenuGroup* subMenu = nullptr; - ButtonBase* menuButton = nullptr; -}; diff --git a/radio/src/gui/colorlcd/setup_menus/quick_menu_data.cpp b/radio/src/gui/colorlcd/setup_menus/quick_menu_data.cpp new file mode 100644 index 000000000..632b0d2e4 --- /dev/null +++ b/radio/src/gui/colorlcd/setup_menus/quick_menu_data.cpp @@ -0,0 +1,179 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "edgetx.h" +#include "pagegroup.h" +#include "model_curves.h" +#include "model_flightmodes.h" +#include "model_gvars.h" +#include "model_heli.h" +#include "model_inputs.h" +#include "model_logical_switches.h" +#include "model_mixer_scripts.h" +#include "model_mixes.h" +#include "model_outputs.h" +#include "model_select.h" +#include "model_setup.h" +#include "model_telemetry.h" +#include "special_functions.h" +#include "view_text.h" +#include "radio_hardware.h" +#include "radio_setup.h" +#include "radio_trainer.h" +#include "radio_version.h" +#include "screen_setup.h" +#include "view_main.h" +#include "radio_sdmanager.h" +#include "radio_tools.h" +#include "view_statistics.h" +#include "view_logical_switches.h" +#include "view_channels.h" + +PageDef favoritesMenuItems[] = { + { EDGETX_ICONS_COUNT, nullptr, nullptr, PAGE_CREATE, QM_NONE, nullptr}, + { EDGETX_ICONS_COUNT, nullptr, nullptr, PAGE_CREATE, QM_NONE, nullptr}, + { EDGETX_ICONS_COUNT, nullptr, nullptr, PAGE_CREATE, QM_NONE, nullptr}, + { EDGETX_ICONS_COUNT, nullptr, nullptr, PAGE_CREATE, QM_NONE, nullptr}, + { EDGETX_ICONS_COUNT, nullptr, nullptr, PAGE_CREATE, QM_NONE, nullptr}, + { EDGETX_ICONS_COUNT, nullptr, nullptr, PAGE_CREATE, QM_NONE, nullptr}, + { EDGETX_ICONS_COUNT, nullptr, nullptr, PAGE_CREATE, QM_NONE, nullptr}, + { EDGETX_ICONS_COUNT, nullptr, nullptr, PAGE_CREATE, QM_NONE, nullptr}, + { EDGETX_ICONS_COUNT, nullptr, nullptr, PAGE_CREATE, QM_NONE, nullptr}, + { EDGETX_ICONS_COUNT, nullptr, nullptr, PAGE_CREATE, QM_NONE, nullptr}, + { EDGETX_ICONS_COUNT, nullptr, nullptr, PAGE_CREATE, QM_NONE, nullptr}, + { EDGETX_ICONS_COUNT, nullptr, nullptr, PAGE_CREATE, QM_NONE, nullptr}, + { EDGETX_ICONS_COUNT } +}; + +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}, + { ICON_MODEL_NOTES, STR_DEF(STR_MAIN_MENU_MODEL_NOTES), STR_DEF(STR_MAIN_MENU_MODEL_NOTES), PAGE_CREATE, QM_MODEL_NOTES, [](PageDef& pageDef) { return new ModelNotesPage(pageDef); }, modelHasNotes}, + { EDGETX_ICONS_COUNT } +}; + +PageDef radioMenuItems[] = { + { 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_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_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_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_ACTION, QM_UI_ADD_PG, nullptr, []() { return customScreens[9] == nullptr; }, + []() { + 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)); + + QuickMenu::openPage((QMPage)(QM_UI_SCREEN1 + newIdx)); + + storageDirty(EE_MODEL); + } else { + TRACE("Add screen: factory is NULL"); + } + } + }, + { EDGETX_ICONS_COUNT } +}; + +PageDef toolsMenuItems[] = { + { 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_TOOLS_RESET, STR_DEF(STR_QM_RESET), STR_DEF(STR_QM_RESET), PAGE_ACTION, QM_TOOLS_RESET, nullptr, nullptr, + []() { + 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_MONITOR, STR_DEF(STR_QM_CHAN_MON), STR_DEF(STR_QM_CHAN_MON), PAGE_ACTION, QM_TOOLS_CHAN_MON, nullptr, nullptr, + []() { + new ChannelsViewMenu(); + } + }, + { ICON_MONITOR_LOGICAL_SWITCHES, STR_DEF(STR_QM_LS_MON), STR_DEF(STR_MONITOR_SWITCHES), PAGE_CREATE, QM_TOOLS_LS_MON, [](PageDef& pageDef) { return new LogicalSwitchesViewPage(pageDef); }}, + { 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_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, 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 } +}; diff --git a/radio/src/gui/colorlcd/setup_menus/quick_menu_def.h b/radio/src/gui/colorlcd/setup_menus/quick_menu_def.h new file mode 100644 index 000000000..0335519e3 --- /dev/null +++ b/radio/src/gui/colorlcd/setup_menus/quick_menu_def.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#pragma once + +enum QMPage { + QM_NONE = 0, + QM_OPEN_QUICK_MENU, + QM_MANAGE_MODELS, + // Model menu + QM_MODEL_SETUP, + QM_MODEL_FLIGHTMODES, + QM_MODEL_INPUTS, + QM_MODEL_MIXES, + QM_MODEL_OUTPUTS, + QM_MODEL_CURVES, + QM_MODEL_GVARS, + QM_MODEL_LS, + QM_MODEL_SF, + QM_MODEL_SCRIPTS, + QM_MODEL_TELEMETRY, + QM_MODEL_NOTES, + // Radio menu + QM_RADIO_SETUP, + QM_RADIO_GF, + QM_RADIO_TRAINER, + QM_RADIO_HARDWARE, + QM_RADIO_VERSION, + // UI menu + QM_UI_THEMES, + QM_UI_SETUP, + QM_UI_SCREEN1, + QM_UI_SCREEN2, + QM_UI_SCREEN3, + QM_UI_SCREEN4, + QM_UI_SCREEN5, + QM_UI_SCREEN6, + QM_UI_SCREEN7, + QM_UI_SCREEN8, + QM_UI_SCREEN9, + QM_UI_SCREEN10, + QM_UI_ADD_PG, + // Tools menu + QM_TOOLS_APPS, + QM_TOOLS_STORAGE, + QM_TOOLS_RESET, + QM_TOOLS_CHAN_MON, + QM_TOOLS_LS_MON, + QM_TOOLS_STATS, + QM_TOOLS_DEBUG, +}; diff --git a/radio/src/gui/colorlcd/setup_menus/quick_menu_favorites.cpp b/radio/src/gui/colorlcd/setup_menus/quick_menu_favorites.cpp new file mode 100644 index 000000000..5a39dffd5 --- /dev/null +++ b/radio/src/gui/colorlcd/setup_menus/quick_menu_favorites.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "quick_menu_favorites.h" +#include "edgetx.h" +#include "pagegroup.h" + +#define SET_DIRTY() storageDirty(EE_GENERAL) + +QMFavoritesPage::QMFavoritesPage(): + SubPage(ICON_RADIO, STR_MAIN_MENU_RADIO_SETTINGS, STR_QUICK_MENU_FAVORITES, true) +{ + std::vector qmPages = QuickMenu::menuPageNames(true); + + for (int i = 0; i < MAX_QM_FAVORITES; i += 1) { + char nm[50]; + strAppendUnsigned(strAppend(strAppend(nm, "#"), " "), i + 1); + setupLine(nm, [=](Window* parent, coord_t x, coord_t y) { + auto c = new Choice( + parent, {LCD_W / 4, y, LCD_W * 2 / 3, 0}, qmPages, QM_NONE, QM_TOOLS_DEBUG, + GET_DEFAULT(g_eeGeneral.qmFavorites[i].shortcut), + [=](int32_t pg) { + g_eeGeneral.qmFavorites[i].shortcut = (QMPage)pg; + changed = true; + SET_DIRTY(); + }, STR_QUICK_MENU_FAVORITES); + + c->setPopupWidth(LCD_W * 3 / 4); + c->setAvailableHandler( + [=](int pg) { + if (pg == QM_NONE) return true; + for (int i = 0; i < MAX_QM_FAVORITES; i += 1) + if (g_eeGeneral.qmFavorites[i].shortcut == (QMPage)pg) + return false; + return pg != QM_OPEN_QUICK_MENU; } + ); + }); + } + + enableRefresh(); +} + +void QMFavoritesPage::onCancel() +{ + if (changed) { + // Delete quick menu, and close parent page group (in case it is Favorites group) + QuickMenu::shutdownQuickMenu(); + QuickMenu::setCurrentPage(QM_NONE); + Layer::pop(this); + Layer::back()->onCancel(); + } + + SubPage::onCancel(); +} diff --git a/radio/src/gui/colorlcd/setup_menus/quick_menu_favorites.h b/radio/src/gui/colorlcd/setup_menus/quick_menu_favorites.h new file mode 100644 index 000000000..cb1280a66 --- /dev/null +++ b/radio/src/gui/colorlcd/setup_menus/quick_menu_favorites.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#pragma once + +#include "page.h" + +class QMFavoritesPage : public SubPage +{ + public: + QMFavoritesPage(); + + protected: + bool changed = false; + + void addKey(event_t event, std::vector qmPages, const char* nm); + + void onCancel() override; +}; 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 e53e9f1b7..4bf9d84d4 100644 --- a/radio/src/gui/colorlcd/setup_menus/quick_menu_group.cpp +++ b/radio/src/gui/colorlcd/setup_menus/quick_menu_group.cpp @@ -138,12 +138,12 @@ QuickMenuGroup::QuickMenuGroup(Window* parent) : } ButtonBase* QuickMenuGroup::addButton(EdgeTxIcon icon, const char* title, - std::function pressHandler, + std::function pressHandler, std::function visibleHandler, std::function focusHandler) { - ButtonBase* b = new QuickMenuButton(this, icon, title, pressHandler, visibleHandler); - b->setLongPressHandler(pressHandler); + ButtonBase* b = new QuickMenuButton(this, icon, title, [=]() { pressHandler(); return 0; }, visibleHandler); + b->setLongPressHandler([=]() { pressHandler(); return 0; }); btns.push_back(b); if (group) lv_group_add_obj(group, b->getLvObj()); b->setFocusHandler([=](bool focus) { diff --git a/radio/src/gui/colorlcd/setup_menus/quick_menu_group.h b/radio/src/gui/colorlcd/setup_menus/quick_menu_group.h index cf8108cbe..752a50d49 100644 --- a/radio/src/gui/colorlcd/setup_menus/quick_menu_group.h +++ b/radio/src/gui/colorlcd/setup_menus/quick_menu_group.h @@ -38,7 +38,7 @@ class QuickMenuGroup : public Window // Add a new button to the carousel ButtonBase* addButton(EdgeTxIcon icon, const char* title, - std::function pressHandler, + std::function pressHandler, std::function visibleHandler = nullptr, std::function focusHandler = nullptr); diff --git a/radio/src/storage/sdcard_yaml.cpp b/radio/src/storage/sdcard_yaml.cpp index 8164989af..aad69a003 100644 --- a/radio/src/storage/sdcard_yaml.cpp +++ b/radio/src/storage/sdcard_yaml.cpp @@ -182,6 +182,9 @@ const char * loadRadioSettings() adcCalibDefaults(); generalDefaultSwitches(); +#if defined(COLORLCD) + g_eeGeneral.defaultKeyShortcuts(); +#endif const char* error = loadRadioSettingsYaml(true); if (!error) { diff --git a/radio/src/storage/yaml/yaml_datastructs_f16.cpp b/radio/src/storage/yaml/yaml_datastructs_f16.cpp index 937147c7e..3d6ee52e4 100644 --- a/radio/src/storage/yaml/yaml_datastructs_f16.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_f16.cpp @@ -101,6 +101,49 @@ const struct YamlIdStr enum_SwitchConfig[] = { { SWITCH_3pos, "3pos" }, { 0, NULL } }; +const struct YamlIdStr enum_QMPage[] = { + { QM_NONE, "NONE" }, + { QM_OPEN_QUICK_MENU, "OPEN_QUICK_MENU" }, + { QM_MANAGE_MODELS, "MANAGE_MODELS" }, + { QM_MODEL_SETUP, "MODEL_SETUP" }, + { QM_MODEL_FLIGHTMODES, "MODEL_FLIGHTMODES" }, + { QM_MODEL_INPUTS, "MODEL_INPUTS" }, + { QM_MODEL_MIXES, "MODEL_MIXES" }, + { QM_MODEL_OUTPUTS, "MODEL_OUTPUTS" }, + { QM_MODEL_CURVES, "MODEL_CURVES" }, + { QM_MODEL_GVARS, "MODEL_GVARS" }, + { QM_MODEL_LS, "MODEL_LS" }, + { QM_MODEL_SF, "MODEL_SF" }, + { QM_MODEL_SCRIPTS, "MODEL_SCRIPTS" }, + { QM_MODEL_TELEMETRY, "MODEL_TELEMETRY" }, + { QM_MODEL_NOTES, "MODEL_NOTES" }, + { QM_RADIO_SETUP, "RADIO_SETUP" }, + { QM_RADIO_GF, "RADIO_GF" }, + { QM_RADIO_TRAINER, "RADIO_TRAINER" }, + { QM_RADIO_HARDWARE, "RADIO_HARDWARE" }, + { QM_RADIO_VERSION, "RADIO_VERSION" }, + { QM_UI_THEMES, "UI_THEMES" }, + { QM_UI_SETUP, "UI_SETUP" }, + { QM_UI_SCREEN1, "UI_SCREEN1" }, + { QM_UI_SCREEN2, "UI_SCREEN2" }, + { QM_UI_SCREEN3, "UI_SCREEN3" }, + { QM_UI_SCREEN4, "UI_SCREEN4" }, + { QM_UI_SCREEN5, "UI_SCREEN5" }, + { QM_UI_SCREEN6, "UI_SCREEN6" }, + { QM_UI_SCREEN7, "UI_SCREEN7" }, + { QM_UI_SCREEN8, "UI_SCREEN8" }, + { QM_UI_SCREEN9, "UI_SCREEN9" }, + { QM_UI_SCREEN10, "UI_SCREEN10" }, + { QM_UI_ADD_PG, "UI_ADD_PG" }, + { QM_TOOLS_APPS, "TOOLS_APPS" }, + { QM_TOOLS_STORAGE, "TOOLS_STORAGE" }, + { QM_TOOLS_RESET, "TOOLS_RESET" }, + { QM_TOOLS_CHAN_MON, "TOOLS_CHAN_MON" }, + { QM_TOOLS_LS_MON, "TOOLS_LS_MON" }, + { QM_TOOLS_STATS, "TOOLS_STATS" }, + { QM_TOOLS_DEBUG, "TOOLS_DEBUG" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -290,6 +333,11 @@ static const struct YamlNode struct_switchDef[] = { YAML_PADDING( 5 ), YAML_END }; +static const struct YamlNode struct_QuickMenuPage[] = { + YAML_IDX, + YAML_ENUM("shortcut", 8, enum_QMPage, NULL), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -399,6 +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_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 0deaa5741..8db206445 100644 --- a/radio/src/storage/yaml/yaml_datastructs_nb4p.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_nb4p.cpp @@ -100,6 +100,49 @@ const struct YamlIdStr enum_SwitchConfig[] = { { SWITCH_3pos, "3pos" }, { 0, NULL } }; +const struct YamlIdStr enum_QMPage[] = { + { QM_NONE, "NONE" }, + { QM_OPEN_QUICK_MENU, "OPEN_QUICK_MENU" }, + { QM_MANAGE_MODELS, "MANAGE_MODELS" }, + { QM_MODEL_SETUP, "MODEL_SETUP" }, + { QM_MODEL_FLIGHTMODES, "MODEL_FLIGHTMODES" }, + { QM_MODEL_INPUTS, "MODEL_INPUTS" }, + { QM_MODEL_MIXES, "MODEL_MIXES" }, + { QM_MODEL_OUTPUTS, "MODEL_OUTPUTS" }, + { QM_MODEL_CURVES, "MODEL_CURVES" }, + { QM_MODEL_GVARS, "MODEL_GVARS" }, + { QM_MODEL_LS, "MODEL_LS" }, + { QM_MODEL_SF, "MODEL_SF" }, + { QM_MODEL_SCRIPTS, "MODEL_SCRIPTS" }, + { QM_MODEL_TELEMETRY, "MODEL_TELEMETRY" }, + { QM_MODEL_NOTES, "MODEL_NOTES" }, + { QM_RADIO_SETUP, "RADIO_SETUP" }, + { QM_RADIO_GF, "RADIO_GF" }, + { QM_RADIO_TRAINER, "RADIO_TRAINER" }, + { QM_RADIO_HARDWARE, "RADIO_HARDWARE" }, + { QM_RADIO_VERSION, "RADIO_VERSION" }, + { QM_UI_THEMES, "UI_THEMES" }, + { QM_UI_SETUP, "UI_SETUP" }, + { QM_UI_SCREEN1, "UI_SCREEN1" }, + { QM_UI_SCREEN2, "UI_SCREEN2" }, + { QM_UI_SCREEN3, "UI_SCREEN3" }, + { QM_UI_SCREEN4, "UI_SCREEN4" }, + { QM_UI_SCREEN5, "UI_SCREEN5" }, + { QM_UI_SCREEN6, "UI_SCREEN6" }, + { QM_UI_SCREEN7, "UI_SCREEN7" }, + { QM_UI_SCREEN8, "UI_SCREEN8" }, + { QM_UI_SCREEN9, "UI_SCREEN9" }, + { QM_UI_SCREEN10, "UI_SCREEN10" }, + { QM_UI_ADD_PG, "UI_ADD_PG" }, + { QM_TOOLS_APPS, "TOOLS_APPS" }, + { QM_TOOLS_STORAGE, "TOOLS_STORAGE" }, + { QM_TOOLS_RESET, "TOOLS_RESET" }, + { QM_TOOLS_CHAN_MON, "TOOLS_CHAN_MON" }, + { QM_TOOLS_LS_MON, "TOOLS_LS_MON" }, + { QM_TOOLS_STATS, "TOOLS_STATS" }, + { QM_TOOLS_DEBUG, "TOOLS_DEBUG" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -281,6 +324,11 @@ static const struct YamlNode struct_switchDef[] = { YAML_PADDING( 5 ), YAML_END }; +static const struct YamlNode struct_QuickMenuPage[] = { + YAML_IDX, + YAML_ENUM("shortcut", 8, enum_QMPage, NULL), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -390,6 +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_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 ff4a68f81..20a04c459 100644 --- a/radio/src/storage/yaml/yaml_datastructs_nv14.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_nv14.cpp @@ -107,6 +107,49 @@ const struct YamlIdStr enum_SwitchConfig[] = { { SWITCH_3pos, "3pos" }, { 0, NULL } }; +const struct YamlIdStr enum_QMPage[] = { + { QM_NONE, "NONE" }, + { QM_OPEN_QUICK_MENU, "OPEN_QUICK_MENU" }, + { QM_MANAGE_MODELS, "MANAGE_MODELS" }, + { QM_MODEL_SETUP, "MODEL_SETUP" }, + { QM_MODEL_FLIGHTMODES, "MODEL_FLIGHTMODES" }, + { QM_MODEL_INPUTS, "MODEL_INPUTS" }, + { QM_MODEL_MIXES, "MODEL_MIXES" }, + { QM_MODEL_OUTPUTS, "MODEL_OUTPUTS" }, + { QM_MODEL_CURVES, "MODEL_CURVES" }, + { QM_MODEL_GVARS, "MODEL_GVARS" }, + { QM_MODEL_LS, "MODEL_LS" }, + { QM_MODEL_SF, "MODEL_SF" }, + { QM_MODEL_SCRIPTS, "MODEL_SCRIPTS" }, + { QM_MODEL_TELEMETRY, "MODEL_TELEMETRY" }, + { QM_MODEL_NOTES, "MODEL_NOTES" }, + { QM_RADIO_SETUP, "RADIO_SETUP" }, + { QM_RADIO_GF, "RADIO_GF" }, + { QM_RADIO_TRAINER, "RADIO_TRAINER" }, + { QM_RADIO_HARDWARE, "RADIO_HARDWARE" }, + { QM_RADIO_VERSION, "RADIO_VERSION" }, + { QM_UI_THEMES, "UI_THEMES" }, + { QM_UI_SETUP, "UI_SETUP" }, + { QM_UI_SCREEN1, "UI_SCREEN1" }, + { QM_UI_SCREEN2, "UI_SCREEN2" }, + { QM_UI_SCREEN3, "UI_SCREEN3" }, + { QM_UI_SCREEN4, "UI_SCREEN4" }, + { QM_UI_SCREEN5, "UI_SCREEN5" }, + { QM_UI_SCREEN6, "UI_SCREEN6" }, + { QM_UI_SCREEN7, "UI_SCREEN7" }, + { QM_UI_SCREEN8, "UI_SCREEN8" }, + { QM_UI_SCREEN9, "UI_SCREEN9" }, + { QM_UI_SCREEN10, "UI_SCREEN10" }, + { QM_UI_ADD_PG, "UI_ADD_PG" }, + { QM_TOOLS_APPS, "TOOLS_APPS" }, + { QM_TOOLS_STORAGE, "TOOLS_STORAGE" }, + { QM_TOOLS_RESET, "TOOLS_RESET" }, + { QM_TOOLS_CHAN_MON, "TOOLS_CHAN_MON" }, + { QM_TOOLS_LS_MON, "TOOLS_LS_MON" }, + { QM_TOOLS_STATS, "TOOLS_STATS" }, + { QM_TOOLS_DEBUG, "TOOLS_DEBUG" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -288,6 +331,11 @@ static const struct YamlNode struct_switchDef[] = { YAML_PADDING( 5 ), YAML_END }; +static const struct YamlNode struct_QuickMenuPage[] = { + YAML_IDX, + YAML_ENUM("shortcut", 8, enum_QMPage, NULL), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -397,6 +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_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 d7b714cc0..5f3392a05 100644 --- a/radio/src/storage/yaml/yaml_datastructs_pa01.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_pa01.cpp @@ -113,6 +113,49 @@ const struct YamlIdStr enum_booleanEnum[] = { { BOOL_ON, "ON" }, { 0, NULL } }; +const struct YamlIdStr enum_QMPage[] = { + { QM_NONE, "NONE" }, + { QM_OPEN_QUICK_MENU, "OPEN_QUICK_MENU" }, + { QM_MANAGE_MODELS, "MANAGE_MODELS" }, + { QM_MODEL_SETUP, "MODEL_SETUP" }, + { QM_MODEL_FLIGHTMODES, "MODEL_FLIGHTMODES" }, + { QM_MODEL_INPUTS, "MODEL_INPUTS" }, + { QM_MODEL_MIXES, "MODEL_MIXES" }, + { QM_MODEL_OUTPUTS, "MODEL_OUTPUTS" }, + { QM_MODEL_CURVES, "MODEL_CURVES" }, + { QM_MODEL_GVARS, "MODEL_GVARS" }, + { QM_MODEL_LS, "MODEL_LS" }, + { QM_MODEL_SF, "MODEL_SF" }, + { QM_MODEL_SCRIPTS, "MODEL_SCRIPTS" }, + { QM_MODEL_TELEMETRY, "MODEL_TELEMETRY" }, + { QM_MODEL_NOTES, "MODEL_NOTES" }, + { QM_RADIO_SETUP, "RADIO_SETUP" }, + { QM_RADIO_GF, "RADIO_GF" }, + { QM_RADIO_TRAINER, "RADIO_TRAINER" }, + { QM_RADIO_HARDWARE, "RADIO_HARDWARE" }, + { QM_RADIO_VERSION, "RADIO_VERSION" }, + { QM_UI_THEMES, "UI_THEMES" }, + { QM_UI_SETUP, "UI_SETUP" }, + { QM_UI_SCREEN1, "UI_SCREEN1" }, + { QM_UI_SCREEN2, "UI_SCREEN2" }, + { QM_UI_SCREEN3, "UI_SCREEN3" }, + { QM_UI_SCREEN4, "UI_SCREEN4" }, + { QM_UI_SCREEN5, "UI_SCREEN5" }, + { QM_UI_SCREEN6, "UI_SCREEN6" }, + { QM_UI_SCREEN7, "UI_SCREEN7" }, + { QM_UI_SCREEN8, "UI_SCREEN8" }, + { QM_UI_SCREEN9, "UI_SCREEN9" }, + { QM_UI_SCREEN10, "UI_SCREEN10" }, + { QM_UI_ADD_PG, "UI_ADD_PG" }, + { QM_TOOLS_APPS, "TOOLS_APPS" }, + { QM_TOOLS_STORAGE, "TOOLS_STORAGE" }, + { QM_TOOLS_RESET, "TOOLS_RESET" }, + { QM_TOOLS_CHAN_MON, "TOOLS_CHAN_MON" }, + { QM_TOOLS_LS_MON, "TOOLS_LS_MON" }, + { QM_TOOLS_STATS, "TOOLS_STATS" }, + { QM_TOOLS_DEBUG, "TOOLS_DEBUG" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -313,6 +356,11 @@ static const struct YamlNode struct_switchDef[] = { YAML_STRUCT("offColor", 24, struct_RGBLedColor, switch_is_cfs), YAML_END }; +static const struct YamlNode struct_QuickMenuPage[] = { + YAML_IDX, + YAML_ENUM("shortcut", 8, enum_QMPage, NULL), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -422,6 +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_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 39d396402..6c3bb5fc7 100644 --- a/radio/src/storage/yaml/yaml_datastructs_pl18.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_pl18.cpp @@ -107,6 +107,49 @@ const struct YamlIdStr enum_SwitchConfig[] = { { SWITCH_3pos, "3pos" }, { 0, NULL } }; +const struct YamlIdStr enum_QMPage[] = { + { QM_NONE, "NONE" }, + { QM_OPEN_QUICK_MENU, "OPEN_QUICK_MENU" }, + { QM_MANAGE_MODELS, "MANAGE_MODELS" }, + { QM_MODEL_SETUP, "MODEL_SETUP" }, + { QM_MODEL_FLIGHTMODES, "MODEL_FLIGHTMODES" }, + { QM_MODEL_INPUTS, "MODEL_INPUTS" }, + { QM_MODEL_MIXES, "MODEL_MIXES" }, + { QM_MODEL_OUTPUTS, "MODEL_OUTPUTS" }, + { QM_MODEL_CURVES, "MODEL_CURVES" }, + { QM_MODEL_GVARS, "MODEL_GVARS" }, + { QM_MODEL_LS, "MODEL_LS" }, + { QM_MODEL_SF, "MODEL_SF" }, + { QM_MODEL_SCRIPTS, "MODEL_SCRIPTS" }, + { QM_MODEL_TELEMETRY, "MODEL_TELEMETRY" }, + { QM_MODEL_NOTES, "MODEL_NOTES" }, + { QM_RADIO_SETUP, "RADIO_SETUP" }, + { QM_RADIO_GF, "RADIO_GF" }, + { QM_RADIO_TRAINER, "RADIO_TRAINER" }, + { QM_RADIO_HARDWARE, "RADIO_HARDWARE" }, + { QM_RADIO_VERSION, "RADIO_VERSION" }, + { QM_UI_THEMES, "UI_THEMES" }, + { QM_UI_SETUP, "UI_SETUP" }, + { QM_UI_SCREEN1, "UI_SCREEN1" }, + { QM_UI_SCREEN2, "UI_SCREEN2" }, + { QM_UI_SCREEN3, "UI_SCREEN3" }, + { QM_UI_SCREEN4, "UI_SCREEN4" }, + { QM_UI_SCREEN5, "UI_SCREEN5" }, + { QM_UI_SCREEN6, "UI_SCREEN6" }, + { QM_UI_SCREEN7, "UI_SCREEN7" }, + { QM_UI_SCREEN8, "UI_SCREEN8" }, + { QM_UI_SCREEN9, "UI_SCREEN9" }, + { QM_UI_SCREEN10, "UI_SCREEN10" }, + { QM_UI_ADD_PG, "UI_ADD_PG" }, + { QM_TOOLS_APPS, "TOOLS_APPS" }, + { QM_TOOLS_STORAGE, "TOOLS_STORAGE" }, + { QM_TOOLS_RESET, "TOOLS_RESET" }, + { QM_TOOLS_CHAN_MON, "TOOLS_CHAN_MON" }, + { QM_TOOLS_LS_MON, "TOOLS_LS_MON" }, + { QM_TOOLS_STATS, "TOOLS_STATS" }, + { QM_TOOLS_DEBUG, "TOOLS_DEBUG" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -288,6 +331,11 @@ static const struct YamlNode struct_switchDef[] = { YAML_PADDING( 5 ), YAML_END }; +static const struct YamlNode struct_QuickMenuPage[] = { + YAML_IDX, + YAML_ENUM("shortcut", 8, enum_QMPage, NULL), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -397,6 +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_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 bc688af69..8dfd18c66 100644 --- a/radio/src/storage/yaml/yaml_datastructs_pl18u.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_pl18u.cpp @@ -100,6 +100,49 @@ const struct YamlIdStr enum_SwitchConfig[] = { { SWITCH_3pos, "3pos" }, { 0, NULL } }; +const struct YamlIdStr enum_QMPage[] = { + { QM_NONE, "NONE" }, + { QM_OPEN_QUICK_MENU, "OPEN_QUICK_MENU" }, + { QM_MANAGE_MODELS, "MANAGE_MODELS" }, + { QM_MODEL_SETUP, "MODEL_SETUP" }, + { QM_MODEL_FLIGHTMODES, "MODEL_FLIGHTMODES" }, + { QM_MODEL_INPUTS, "MODEL_INPUTS" }, + { QM_MODEL_MIXES, "MODEL_MIXES" }, + { QM_MODEL_OUTPUTS, "MODEL_OUTPUTS" }, + { QM_MODEL_CURVES, "MODEL_CURVES" }, + { QM_MODEL_GVARS, "MODEL_GVARS" }, + { QM_MODEL_LS, "MODEL_LS" }, + { QM_MODEL_SF, "MODEL_SF" }, + { QM_MODEL_SCRIPTS, "MODEL_SCRIPTS" }, + { QM_MODEL_TELEMETRY, "MODEL_TELEMETRY" }, + { QM_MODEL_NOTES, "MODEL_NOTES" }, + { QM_RADIO_SETUP, "RADIO_SETUP" }, + { QM_RADIO_GF, "RADIO_GF" }, + { QM_RADIO_TRAINER, "RADIO_TRAINER" }, + { QM_RADIO_HARDWARE, "RADIO_HARDWARE" }, + { QM_RADIO_VERSION, "RADIO_VERSION" }, + { QM_UI_THEMES, "UI_THEMES" }, + { QM_UI_SETUP, "UI_SETUP" }, + { QM_UI_SCREEN1, "UI_SCREEN1" }, + { QM_UI_SCREEN2, "UI_SCREEN2" }, + { QM_UI_SCREEN3, "UI_SCREEN3" }, + { QM_UI_SCREEN4, "UI_SCREEN4" }, + { QM_UI_SCREEN5, "UI_SCREEN5" }, + { QM_UI_SCREEN6, "UI_SCREEN6" }, + { QM_UI_SCREEN7, "UI_SCREEN7" }, + { QM_UI_SCREEN8, "UI_SCREEN8" }, + { QM_UI_SCREEN9, "UI_SCREEN9" }, + { QM_UI_SCREEN10, "UI_SCREEN10" }, + { QM_UI_ADD_PG, "UI_ADD_PG" }, + { QM_TOOLS_APPS, "TOOLS_APPS" }, + { QM_TOOLS_STORAGE, "TOOLS_STORAGE" }, + { QM_TOOLS_RESET, "TOOLS_RESET" }, + { QM_TOOLS_CHAN_MON, "TOOLS_CHAN_MON" }, + { QM_TOOLS_LS_MON, "TOOLS_LS_MON" }, + { QM_TOOLS_STATS, "TOOLS_STATS" }, + { QM_TOOLS_DEBUG, "TOOLS_DEBUG" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -281,6 +324,11 @@ static const struct YamlNode struct_switchDef[] = { YAML_PADDING( 5 ), YAML_END }; +static const struct YamlNode struct_QuickMenuPage[] = { + YAML_IDX, + YAML_ENUM("shortcut", 8, enum_QMPage, NULL), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -390,6 +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_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 a0a99fe95..a59adaa6a 100644 --- a/radio/src/storage/yaml/yaml_datastructs_st16.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_st16.cpp @@ -113,6 +113,49 @@ const struct YamlIdStr enum_booleanEnum[] = { { BOOL_ON, "ON" }, { 0, NULL } }; +const struct YamlIdStr enum_QMPage[] = { + { QM_NONE, "NONE" }, + { QM_OPEN_QUICK_MENU, "OPEN_QUICK_MENU" }, + { QM_MANAGE_MODELS, "MANAGE_MODELS" }, + { QM_MODEL_SETUP, "MODEL_SETUP" }, + { QM_MODEL_FLIGHTMODES, "MODEL_FLIGHTMODES" }, + { QM_MODEL_INPUTS, "MODEL_INPUTS" }, + { QM_MODEL_MIXES, "MODEL_MIXES" }, + { QM_MODEL_OUTPUTS, "MODEL_OUTPUTS" }, + { QM_MODEL_CURVES, "MODEL_CURVES" }, + { QM_MODEL_GVARS, "MODEL_GVARS" }, + { QM_MODEL_LS, "MODEL_LS" }, + { QM_MODEL_SF, "MODEL_SF" }, + { QM_MODEL_SCRIPTS, "MODEL_SCRIPTS" }, + { QM_MODEL_TELEMETRY, "MODEL_TELEMETRY" }, + { QM_MODEL_NOTES, "MODEL_NOTES" }, + { QM_RADIO_SETUP, "RADIO_SETUP" }, + { QM_RADIO_GF, "RADIO_GF" }, + { QM_RADIO_TRAINER, "RADIO_TRAINER" }, + { QM_RADIO_HARDWARE, "RADIO_HARDWARE" }, + { QM_RADIO_VERSION, "RADIO_VERSION" }, + { QM_UI_THEMES, "UI_THEMES" }, + { QM_UI_SETUP, "UI_SETUP" }, + { QM_UI_SCREEN1, "UI_SCREEN1" }, + { QM_UI_SCREEN2, "UI_SCREEN2" }, + { QM_UI_SCREEN3, "UI_SCREEN3" }, + { QM_UI_SCREEN4, "UI_SCREEN4" }, + { QM_UI_SCREEN5, "UI_SCREEN5" }, + { QM_UI_SCREEN6, "UI_SCREEN6" }, + { QM_UI_SCREEN7, "UI_SCREEN7" }, + { QM_UI_SCREEN8, "UI_SCREEN8" }, + { QM_UI_SCREEN9, "UI_SCREEN9" }, + { QM_UI_SCREEN10, "UI_SCREEN10" }, + { QM_UI_ADD_PG, "UI_ADD_PG" }, + { QM_TOOLS_APPS, "TOOLS_APPS" }, + { QM_TOOLS_STORAGE, "TOOLS_STORAGE" }, + { QM_TOOLS_RESET, "TOOLS_RESET" }, + { QM_TOOLS_CHAN_MON, "TOOLS_CHAN_MON" }, + { QM_TOOLS_LS_MON, "TOOLS_LS_MON" }, + { QM_TOOLS_STATS, "TOOLS_STATS" }, + { QM_TOOLS_DEBUG, "TOOLS_DEBUG" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -313,6 +356,11 @@ static const struct YamlNode struct_switchDef[] = { YAML_STRUCT("offColor", 24, struct_RGBLedColor, switch_is_cfs), YAML_END }; +static const struct YamlNode struct_QuickMenuPage[] = { + YAML_IDX, + YAML_ENUM("shortcut", 8, enum_QMPage, NULL), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -422,6 +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_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 a5a39ad88..bab90cd29 100644 --- a/radio/src/storage/yaml/yaml_datastructs_t15.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_t15.cpp @@ -108,6 +108,49 @@ const struct YamlIdStr enum_fsStartPositionType[] = { { FS_START_PREVIOUS, "START_PREVIOUS" }, { 0, NULL } }; +const struct YamlIdStr enum_QMPage[] = { + { QM_NONE, "NONE" }, + { QM_OPEN_QUICK_MENU, "OPEN_QUICK_MENU" }, + { QM_MANAGE_MODELS, "MANAGE_MODELS" }, + { QM_MODEL_SETUP, "MODEL_SETUP" }, + { QM_MODEL_FLIGHTMODES, "MODEL_FLIGHTMODES" }, + { QM_MODEL_INPUTS, "MODEL_INPUTS" }, + { QM_MODEL_MIXES, "MODEL_MIXES" }, + { QM_MODEL_OUTPUTS, "MODEL_OUTPUTS" }, + { QM_MODEL_CURVES, "MODEL_CURVES" }, + { QM_MODEL_GVARS, "MODEL_GVARS" }, + { QM_MODEL_LS, "MODEL_LS" }, + { QM_MODEL_SF, "MODEL_SF" }, + { QM_MODEL_SCRIPTS, "MODEL_SCRIPTS" }, + { QM_MODEL_TELEMETRY, "MODEL_TELEMETRY" }, + { QM_MODEL_NOTES, "MODEL_NOTES" }, + { QM_RADIO_SETUP, "RADIO_SETUP" }, + { QM_RADIO_GF, "RADIO_GF" }, + { QM_RADIO_TRAINER, "RADIO_TRAINER" }, + { QM_RADIO_HARDWARE, "RADIO_HARDWARE" }, + { QM_RADIO_VERSION, "RADIO_VERSION" }, + { QM_UI_THEMES, "UI_THEMES" }, + { QM_UI_SETUP, "UI_SETUP" }, + { QM_UI_SCREEN1, "UI_SCREEN1" }, + { QM_UI_SCREEN2, "UI_SCREEN2" }, + { QM_UI_SCREEN3, "UI_SCREEN3" }, + { QM_UI_SCREEN4, "UI_SCREEN4" }, + { QM_UI_SCREEN5, "UI_SCREEN5" }, + { QM_UI_SCREEN6, "UI_SCREEN6" }, + { QM_UI_SCREEN7, "UI_SCREEN7" }, + { QM_UI_SCREEN8, "UI_SCREEN8" }, + { QM_UI_SCREEN9, "UI_SCREEN9" }, + { QM_UI_SCREEN10, "UI_SCREEN10" }, + { QM_UI_ADD_PG, "UI_ADD_PG" }, + { QM_TOOLS_APPS, "TOOLS_APPS" }, + { QM_TOOLS_STORAGE, "TOOLS_STORAGE" }, + { QM_TOOLS_RESET, "TOOLS_RESET" }, + { QM_TOOLS_CHAN_MON, "TOOLS_CHAN_MON" }, + { QM_TOOLS_LS_MON, "TOOLS_LS_MON" }, + { QM_TOOLS_STATS, "TOOLS_STATS" }, + { QM_TOOLS_DEBUG, "TOOLS_DEBUG" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -298,6 +341,11 @@ static const struct YamlNode struct_switchDef[] = { YAML_PADDING( 3 ), YAML_END }; +static const struct YamlNode struct_QuickMenuPage[] = { + YAML_IDX, + YAML_ENUM("shortcut", 8, enum_QMPage, NULL), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -407,6 +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_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 a0a99fe95..a59adaa6a 100644 --- a/radio/src/storage/yaml/yaml_datastructs_t15pro.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_t15pro.cpp @@ -113,6 +113,49 @@ const struct YamlIdStr enum_booleanEnum[] = { { BOOL_ON, "ON" }, { 0, NULL } }; +const struct YamlIdStr enum_QMPage[] = { + { QM_NONE, "NONE" }, + { QM_OPEN_QUICK_MENU, "OPEN_QUICK_MENU" }, + { QM_MANAGE_MODELS, "MANAGE_MODELS" }, + { QM_MODEL_SETUP, "MODEL_SETUP" }, + { QM_MODEL_FLIGHTMODES, "MODEL_FLIGHTMODES" }, + { QM_MODEL_INPUTS, "MODEL_INPUTS" }, + { QM_MODEL_MIXES, "MODEL_MIXES" }, + { QM_MODEL_OUTPUTS, "MODEL_OUTPUTS" }, + { QM_MODEL_CURVES, "MODEL_CURVES" }, + { QM_MODEL_GVARS, "MODEL_GVARS" }, + { QM_MODEL_LS, "MODEL_LS" }, + { QM_MODEL_SF, "MODEL_SF" }, + { QM_MODEL_SCRIPTS, "MODEL_SCRIPTS" }, + { QM_MODEL_TELEMETRY, "MODEL_TELEMETRY" }, + { QM_MODEL_NOTES, "MODEL_NOTES" }, + { QM_RADIO_SETUP, "RADIO_SETUP" }, + { QM_RADIO_GF, "RADIO_GF" }, + { QM_RADIO_TRAINER, "RADIO_TRAINER" }, + { QM_RADIO_HARDWARE, "RADIO_HARDWARE" }, + { QM_RADIO_VERSION, "RADIO_VERSION" }, + { QM_UI_THEMES, "UI_THEMES" }, + { QM_UI_SETUP, "UI_SETUP" }, + { QM_UI_SCREEN1, "UI_SCREEN1" }, + { QM_UI_SCREEN2, "UI_SCREEN2" }, + { QM_UI_SCREEN3, "UI_SCREEN3" }, + { QM_UI_SCREEN4, "UI_SCREEN4" }, + { QM_UI_SCREEN5, "UI_SCREEN5" }, + { QM_UI_SCREEN6, "UI_SCREEN6" }, + { QM_UI_SCREEN7, "UI_SCREEN7" }, + { QM_UI_SCREEN8, "UI_SCREEN8" }, + { QM_UI_SCREEN9, "UI_SCREEN9" }, + { QM_UI_SCREEN10, "UI_SCREEN10" }, + { QM_UI_ADD_PG, "UI_ADD_PG" }, + { QM_TOOLS_APPS, "TOOLS_APPS" }, + { QM_TOOLS_STORAGE, "TOOLS_STORAGE" }, + { QM_TOOLS_RESET, "TOOLS_RESET" }, + { QM_TOOLS_CHAN_MON, "TOOLS_CHAN_MON" }, + { QM_TOOLS_LS_MON, "TOOLS_LS_MON" }, + { QM_TOOLS_STATS, "TOOLS_STATS" }, + { QM_TOOLS_DEBUG, "TOOLS_DEBUG" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -313,6 +356,11 @@ static const struct YamlNode struct_switchDef[] = { YAML_STRUCT("offColor", 24, struct_RGBLedColor, switch_is_cfs), YAML_END }; +static const struct YamlNode struct_QuickMenuPage[] = { + YAML_IDX, + YAML_ENUM("shortcut", 8, enum_QMPage, NULL), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -422,6 +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_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 a0a99fe95..a59adaa6a 100644 --- a/radio/src/storage/yaml/yaml_datastructs_tx15.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_tx15.cpp @@ -113,6 +113,49 @@ const struct YamlIdStr enum_booleanEnum[] = { { BOOL_ON, "ON" }, { 0, NULL } }; +const struct YamlIdStr enum_QMPage[] = { + { QM_NONE, "NONE" }, + { QM_OPEN_QUICK_MENU, "OPEN_QUICK_MENU" }, + { QM_MANAGE_MODELS, "MANAGE_MODELS" }, + { QM_MODEL_SETUP, "MODEL_SETUP" }, + { QM_MODEL_FLIGHTMODES, "MODEL_FLIGHTMODES" }, + { QM_MODEL_INPUTS, "MODEL_INPUTS" }, + { QM_MODEL_MIXES, "MODEL_MIXES" }, + { QM_MODEL_OUTPUTS, "MODEL_OUTPUTS" }, + { QM_MODEL_CURVES, "MODEL_CURVES" }, + { QM_MODEL_GVARS, "MODEL_GVARS" }, + { QM_MODEL_LS, "MODEL_LS" }, + { QM_MODEL_SF, "MODEL_SF" }, + { QM_MODEL_SCRIPTS, "MODEL_SCRIPTS" }, + { QM_MODEL_TELEMETRY, "MODEL_TELEMETRY" }, + { QM_MODEL_NOTES, "MODEL_NOTES" }, + { QM_RADIO_SETUP, "RADIO_SETUP" }, + { QM_RADIO_GF, "RADIO_GF" }, + { QM_RADIO_TRAINER, "RADIO_TRAINER" }, + { QM_RADIO_HARDWARE, "RADIO_HARDWARE" }, + { QM_RADIO_VERSION, "RADIO_VERSION" }, + { QM_UI_THEMES, "UI_THEMES" }, + { QM_UI_SETUP, "UI_SETUP" }, + { QM_UI_SCREEN1, "UI_SCREEN1" }, + { QM_UI_SCREEN2, "UI_SCREEN2" }, + { QM_UI_SCREEN3, "UI_SCREEN3" }, + { QM_UI_SCREEN4, "UI_SCREEN4" }, + { QM_UI_SCREEN5, "UI_SCREEN5" }, + { QM_UI_SCREEN6, "UI_SCREEN6" }, + { QM_UI_SCREEN7, "UI_SCREEN7" }, + { QM_UI_SCREEN8, "UI_SCREEN8" }, + { QM_UI_SCREEN9, "UI_SCREEN9" }, + { QM_UI_SCREEN10, "UI_SCREEN10" }, + { QM_UI_ADD_PG, "UI_ADD_PG" }, + { QM_TOOLS_APPS, "TOOLS_APPS" }, + { QM_TOOLS_STORAGE, "TOOLS_STORAGE" }, + { QM_TOOLS_RESET, "TOOLS_RESET" }, + { QM_TOOLS_CHAN_MON, "TOOLS_CHAN_MON" }, + { QM_TOOLS_LS_MON, "TOOLS_LS_MON" }, + { QM_TOOLS_STATS, "TOOLS_STATS" }, + { QM_TOOLS_DEBUG, "TOOLS_DEBUG" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -313,6 +356,11 @@ static const struct YamlNode struct_switchDef[] = { YAML_STRUCT("offColor", 24, struct_RGBLedColor, switch_is_cfs), YAML_END }; +static const struct YamlNode struct_QuickMenuPage[] = { + YAML_IDX, + YAML_ENUM("shortcut", 8, enum_QMPage, NULL), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -422,6 +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_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 c37be430a..2a219413e 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x10.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x10.cpp @@ -100,6 +100,49 @@ const struct YamlIdStr enum_SwitchConfig[] = { { SWITCH_3pos, "3pos" }, { 0, NULL } }; +const struct YamlIdStr enum_QMPage[] = { + { QM_NONE, "NONE" }, + { QM_OPEN_QUICK_MENU, "OPEN_QUICK_MENU" }, + { QM_MANAGE_MODELS, "MANAGE_MODELS" }, + { QM_MODEL_SETUP, "MODEL_SETUP" }, + { QM_MODEL_FLIGHTMODES, "MODEL_FLIGHTMODES" }, + { QM_MODEL_INPUTS, "MODEL_INPUTS" }, + { QM_MODEL_MIXES, "MODEL_MIXES" }, + { QM_MODEL_OUTPUTS, "MODEL_OUTPUTS" }, + { QM_MODEL_CURVES, "MODEL_CURVES" }, + { QM_MODEL_GVARS, "MODEL_GVARS" }, + { QM_MODEL_LS, "MODEL_LS" }, + { QM_MODEL_SF, "MODEL_SF" }, + { QM_MODEL_SCRIPTS, "MODEL_SCRIPTS" }, + { QM_MODEL_TELEMETRY, "MODEL_TELEMETRY" }, + { QM_MODEL_NOTES, "MODEL_NOTES" }, + { QM_RADIO_SETUP, "RADIO_SETUP" }, + { QM_RADIO_GF, "RADIO_GF" }, + { QM_RADIO_TRAINER, "RADIO_TRAINER" }, + { QM_RADIO_HARDWARE, "RADIO_HARDWARE" }, + { QM_RADIO_VERSION, "RADIO_VERSION" }, + { QM_UI_THEMES, "UI_THEMES" }, + { QM_UI_SETUP, "UI_SETUP" }, + { QM_UI_SCREEN1, "UI_SCREEN1" }, + { QM_UI_SCREEN2, "UI_SCREEN2" }, + { QM_UI_SCREEN3, "UI_SCREEN3" }, + { QM_UI_SCREEN4, "UI_SCREEN4" }, + { QM_UI_SCREEN5, "UI_SCREEN5" }, + { QM_UI_SCREEN6, "UI_SCREEN6" }, + { QM_UI_SCREEN7, "UI_SCREEN7" }, + { QM_UI_SCREEN8, "UI_SCREEN8" }, + { QM_UI_SCREEN9, "UI_SCREEN9" }, + { QM_UI_SCREEN10, "UI_SCREEN10" }, + { QM_UI_ADD_PG, "UI_ADD_PG" }, + { QM_TOOLS_APPS, "TOOLS_APPS" }, + { QM_TOOLS_STORAGE, "TOOLS_STORAGE" }, + { QM_TOOLS_RESET, "TOOLS_RESET" }, + { QM_TOOLS_CHAN_MON, "TOOLS_CHAN_MON" }, + { QM_TOOLS_LS_MON, "TOOLS_LS_MON" }, + { QM_TOOLS_STATS, "TOOLS_STATS" }, + { QM_TOOLS_DEBUG, "TOOLS_DEBUG" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -289,6 +332,11 @@ static const struct YamlNode struct_switchDef[] = { YAML_PADDING( 5 ), YAML_END }; +static const struct YamlNode struct_QuickMenuPage[] = { + YAML_IDX, + YAML_ENUM("shortcut", 8, enum_QMPage, NULL), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -398,6 +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_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/translations/i18n/cn.h b/radio/src/translations/i18n/cn.h index 05ca063fa..8931d8dfa 100644 --- a/radio/src/translations/i18n/cn.h +++ b/radio/src/translations/i18n/cn.h @@ -35,7 +35,8 @@ #define TR_QM_RADIO_SETUP "系统\n设置" #define TR_QM_UI_SETUP "界面\n设置" #define TR_QM_TOOLS "工具\nAPP" -#define TR_QM_GEN_SETTINGS "常规\n设置" +#define TR_QM_MODEL_SETTINGS "Model\nSettings" +#define TR_QM_RADIO_SETTINGS "Radio\nSettings" #define TR_QM_FLIGHT_MODES TR_SFC_AIR("驾驶\n模式", "飞行\n模式") #define TR_QM_INPUTS "输入" #define TR_QM_MIXES "混控" @@ -70,7 +71,8 @@ #define TR_QM_LS_MON "逻辑开关\n监视器" #define TR_QM_STATS "统计" #define TR_QM_DEBUG "Debug" -#define TR_MAIN_MENU_SETTINGS "常规设置" +#define TR_MAIN_MODEL_SETTINGS "Model Settings" +#define TR_MAIN_RADIO_SETTINGS "Radio Settings" #define TR_MAIN_MENU_MANAGE_MODELS "模型管理" #define TR_MAIN_MENU_MODEL_NOTES "模型说明" #define TR_MAIN_MENU_CHANNEL_MONITOR "通道监视器" @@ -1403,3 +1405,10 @@ #define TR_WIDGET_SIZE "小部件尺寸" #define TR_DEL_DIR_NOT_EMPTY "删除文件夹必须为空 !" + +#define TR_KEY_SHORTCUTS "Key Shortcuts" +#define TR_CURRENT_SCREEN "Current Screen" +#define TR_SHORT_PRESS "Short Press" +#define TR_LONG_PRESS "Long Press" +#define TR_OPEN_QUICK_MENU "Open Quick Menu" +#define TR_QUICK_MENU_FAVORITES "Quick Menu Favorites" diff --git a/radio/src/translations/i18n/cz.h b/radio/src/translations/i18n/cz.h index 06639a4f2..41ebcdfa2 100644 --- a/radio/src/translations/i18n/cz.h +++ b/radio/src/translations/i18n/cz.h @@ -37,7 +37,8 @@ #define TR_QM_RADIO_SETUP "Radio\nSetup" #define TR_QM_UI_SETUP "UI\nSetup" #define TR_QM_TOOLS "Tools" -#define TR_QM_GEN_SETTINGS "General\nSettings" +#define TR_QM_MODEL_SETTINGS "Model\nSettings" +#define TR_QM_RADIO_SETTINGS "Radio\nSettings" #define TR_QM_FLIGHT_MODES TR_SFC_AIR("Drive\nModes", "Flight\nModes") #define TR_QM_INPUTS "Inputs" #define TR_QM_MIXES "Mixes" @@ -72,7 +73,8 @@ #define TR_QM_LS_MON "LS\nMonitor" #define TR_QM_STATS "Statistics" #define TR_QM_DEBUG "Debug" -#define TR_MAIN_MENU_SETTINGS "General Settings" +#define TR_MAIN_MODEL_SETTINGS "Model Settings" +#define TR_MAIN_RADIO_SETTINGS "Radio Settings" #define TR_MAIN_MENU_MANAGE_MODELS "Správa modelů" #define TR_MAIN_MENU_MODEL_NOTES "Poznámky modelu" #define TR_MAIN_MENU_CHANNEL_MONITOR "Monitor kanálů" @@ -1403,3 +1405,10 @@ #define TR_WIDGET_SIZE "Velikost widgetu" #define TR_DEL_DIR_NOT_EMPTY "Directory must be empty before deletion" + +#define TR_KEY_SHORTCUTS "Key Shortcuts" +#define TR_CURRENT_SCREEN "Current Screen" +#define TR_SHORT_PRESS "Short Press" +#define TR_LONG_PRESS "Long Press" +#define TR_OPEN_QUICK_MENU "Open Quick Menu" +#define TR_QUICK_MENU_FAVORITES "Quick Menu Favorites" diff --git a/radio/src/translations/i18n/da.h b/radio/src/translations/i18n/da.h index ab27f1483..0e3ecc747 100644 --- a/radio/src/translations/i18n/da.h +++ b/radio/src/translations/i18n/da.h @@ -36,7 +36,8 @@ #define TR_QM_RADIO_SETUP "Radio\nSetup" #define TR_QM_UI_SETUP "UI\nSetup" #define TR_QM_TOOLS "Tools" -#define TR_QM_GEN_SETTINGS "General\nSettings" +#define TR_QM_MODEL_SETTINGS "Model\nSettings" +#define TR_QM_RADIO_SETTINGS "Radio\nSettings" #define TR_QM_FLIGHT_MODES TR_SFC_AIR("Drive\nModes", "Flight\nModes") #define TR_QM_INPUTS "Inputs" #define TR_QM_MIXES "Mixes" @@ -71,7 +72,8 @@ #define TR_QM_LS_MON "LS\nMonitor" #define TR_QM_STATS "Statistics" #define TR_QM_DEBUG "Debug" -#define TR_MAIN_MENU_SETTINGS "General Settings" +#define TR_MAIN_MODEL_SETTINGS "Model Settings" +#define TR_MAIN_RADIO_SETTINGS "Radio Settings" #define TR_MAIN_MENU_MANAGE_MODELS "Vælg Model" #define TR_MAIN_MENU_MODEL_NOTES "Model Noter" #define TR_MAIN_MENU_CHANNEL_MONITOR "Kanal Monitor" @@ -1413,3 +1415,10 @@ #define TR_WIDGET_SIZE "Widget størrelse" #define TR_DEL_DIR_NOT_EMPTY "Katalog skal være tomt, før det kan slettes" + +#define TR_KEY_SHORTCUTS "Key Shortcuts" +#define TR_CURRENT_SCREEN "Current Screen" +#define TR_SHORT_PRESS "Short Press" +#define TR_LONG_PRESS "Long Press" +#define TR_OPEN_QUICK_MENU "Open Quick Menu" +#define TR_QUICK_MENU_FAVORITES "Quick Menu Favorites" diff --git a/radio/src/translations/i18n/de.h b/radio/src/translations/i18n/de.h index 82ef9e4bc..ccd1ee62f 100644 --- a/radio/src/translations/i18n/de.h +++ b/radio/src/translations/i18n/de.h @@ -38,7 +38,8 @@ #define TR_QM_RADIO_SETUP "Radio\nSetup" #define TR_QM_UI_SETUP "UI\nSetup" #define TR_QM_TOOLS "Tools" -#define TR_QM_GEN_SETTINGS "General\nSettings" +#define TR_QM_MODEL_SETTINGS "Model\nSettings" +#define TR_QM_RADIO_SETTINGS "Radio\nSettings" #define TR_QM_FLIGHT_MODES TR_SFC_AIR("Drive\nModes", "Flight\nModes") #define TR_QM_INPUTS "Inputs" #define TR_QM_MIXES "Mixes" @@ -73,7 +74,8 @@ #define TR_QM_LS_MON "LS\nMonitor" #define TR_QM_STATS "Statistics" #define TR_QM_DEBUG "Debug" -#define TR_MAIN_MENU_SETTINGS "General Settings" +#define TR_MAIN_MODEL_SETTINGS "Model Settings" +#define TR_MAIN_RADIO_SETTINGS "Radio Settings" #define TR_MAIN_MENU_MANAGE_MODELS "Modell Manager" #define TR_MAIN_MENU_MODEL_NOTES "Modell Notizen" #define TR_MAIN_MENU_CHANNEL_MONITOR "Kanal Monitor" @@ -1402,3 +1404,10 @@ #define TR_WIDGET_SIZE "Widget Größe" #define TR_DEL_DIR_NOT_EMPTY "Directory must be empty before deletion" + +#define TR_KEY_SHORTCUTS "Key Shortcuts" +#define TR_CURRENT_SCREEN "Current Screen" +#define TR_SHORT_PRESS "Short Press" +#define TR_LONG_PRESS "Long Press" +#define TR_OPEN_QUICK_MENU "Open Quick Menu" +#define TR_QUICK_MENU_FAVORITES "Quick Menu Favorites" diff --git a/radio/src/translations/i18n/en.h b/radio/src/translations/i18n/en.h index 11272a143..fb9e8c096 100644 --- a/radio/src/translations/i18n/en.h +++ b/radio/src/translations/i18n/en.h @@ -35,7 +35,8 @@ #define TR_QM_RADIO_SETUP "Radio\nSetup" #define TR_QM_UI_SETUP "UI\nSetup" #define TR_QM_TOOLS "Tools" -#define TR_QM_GEN_SETTINGS "General\nSettings" +#define TR_QM_MODEL_SETTINGS "Model\nSettings" +#define TR_QM_RADIO_SETTINGS "Radio\nSettings" #define TR_QM_FLIGHT_MODES TR_SFC_AIR("Drive\nModes", "Flight\nModes") #define TR_QM_INPUTS "Inputs" #define TR_QM_MIXES "Mixes" @@ -70,7 +71,8 @@ #define TR_QM_LS_MON "LS\nMonitor" #define TR_QM_STATS "Statistics" #define TR_QM_DEBUG "Debug" -#define TR_MAIN_MENU_SETTINGS "General Settings" +#define TR_MAIN_MODEL_SETTINGS "Model Settings" +#define TR_MAIN_RADIO_SETTINGS "Radio Settings" #define TR_MAIN_MENU_MANAGE_MODELS "Manage Models" #define TR_MAIN_MENU_MODEL_NOTES "Model Notes" #define TR_MAIN_MENU_CHANNEL_MONITOR "Channel Monitor" @@ -1400,3 +1402,10 @@ #define TR_WIDGET_SIZE "Widget size" #define TR_DEL_DIR_NOT_EMPTY "Directory must be empty before deletion" + +#define TR_KEY_SHORTCUTS "Key Shortcuts" +#define TR_CURRENT_SCREEN "Current Screen" +#define TR_SHORT_PRESS "Short Press" +#define TR_LONG_PRESS "Long Press" +#define TR_OPEN_QUICK_MENU "Open Quick Menu" +#define TR_QUICK_MENU_FAVORITES "Quick Menu Favorites" diff --git a/radio/src/translations/i18n/es.h b/radio/src/translations/i18n/es.h index 447a2e9da..405a8f340 100644 --- a/radio/src/translations/i18n/es.h +++ b/radio/src/translations/i18n/es.h @@ -36,7 +36,8 @@ #define TR_QM_RADIO_SETUP "Radio\nSetup" #define TR_QM_UI_SETUP "UI\nSetup" #define TR_QM_TOOLS "Tools" -#define TR_QM_GEN_SETTINGS "General\nSettings" +#define TR_QM_MODEL_SETTINGS "Model\nSettings" +#define TR_QM_RADIO_SETTINGS "Radio\nSettings" #define TR_QM_FLIGHT_MODES TR_SFC_AIR("Drive\nModes", "Flight\nModes") #define TR_QM_INPUTS "Inputs" #define TR_QM_MIXES "Mixes" @@ -71,7 +72,8 @@ #define TR_QM_LS_MON "LS\nMonitor" #define TR_QM_STATS "Statistics" #define TR_QM_DEBUG "Debug" -#define TR_MAIN_MENU_SETTINGS "General Settings" +#define TR_MAIN_MODEL_SETTINGS "Model Settings" +#define TR_MAIN_RADIO_SETTINGS "Radio Settings" #define TR_MAIN_MENU_MANAGE_MODELS "Model Manager" #define TR_MAIN_MENU_MODEL_NOTES "Model Notes" #define TR_MAIN_MENU_CHANNEL_MONITOR "Channel Monitor" @@ -1403,3 +1405,10 @@ #define TR_WIDGET_SIZE "Widget size" #define TR_DEL_DIR_NOT_EMPTY "Directory must be empty before deletion" + +#define TR_KEY_SHORTCUTS "Key Shortcuts" +#define TR_CURRENT_SCREEN "Current Screen" +#define TR_SHORT_PRESS "Short Press" +#define TR_LONG_PRESS "Long Press" +#define TR_OPEN_QUICK_MENU "Open Quick Menu" +#define TR_QUICK_MENU_FAVORITES "Quick Menu Favorites" diff --git a/radio/src/translations/i18n/fi.h b/radio/src/translations/i18n/fi.h index f80deb663..ff7e98fdb 100644 --- a/radio/src/translations/i18n/fi.h +++ b/radio/src/translations/i18n/fi.h @@ -37,7 +37,8 @@ #define TR_QM_RADIO_SETUP "Radio\nSetup" #define TR_QM_UI_SETUP "UI\nSetup" #define TR_QM_TOOLS "Tools" -#define TR_QM_GEN_SETTINGS "General\nSettings" +#define TR_QM_MODEL_SETTINGS "Model\nSettings" +#define TR_QM_RADIO_SETTINGS "Radio\nSettings" #define TR_QM_FLIGHT_MODES TR_SFC_AIR("Drive\nModes", "Flight\nModes") #define TR_QM_INPUTS "Inputs" #define TR_QM_MIXES "Mixes" @@ -72,7 +73,8 @@ #define TR_QM_LS_MON "LS\nMonitor" #define TR_QM_STATS "Statistics" #define TR_QM_DEBUG "Debug" -#define TR_MAIN_MENU_SETTINGS "General Settings" +#define TR_MAIN_MODEL_SETTINGS "Model Settings" +#define TR_MAIN_RADIO_SETTINGS "Radio Settings" #define TR_MAIN_MENU_MANAGE_MODELS "Model Manager" #define TR_MAIN_MENU_MODEL_NOTES "Model Notes" #define TR_MAIN_MENU_CHANNEL_MONITOR "Channel Monitor" @@ -1406,3 +1408,10 @@ #define TR_WIDGET_SIZE "Widget size" #define TR_DEL_DIR_NOT_EMPTY "Directory must be empty before deletion" + +#define TR_KEY_SHORTCUTS "Key Shortcuts" +#define TR_CURRENT_SCREEN "Current Screen" +#define TR_SHORT_PRESS "Short Press" +#define TR_LONG_PRESS "Long Press" +#define TR_OPEN_QUICK_MENU "Open Quick Menu" +#define TR_QUICK_MENU_FAVORITES "Quick Menu Favorites" diff --git a/radio/src/translations/i18n/fr.h b/radio/src/translations/i18n/fr.h index 20ad77c06..4509dea7b 100644 --- a/radio/src/translations/i18n/fr.h +++ b/radio/src/translations/i18n/fr.h @@ -36,7 +36,8 @@ #define TR_QM_RADIO_SETUP "Radio\nSetup" #define TR_QM_UI_SETUP "UI\nSetup" #define TR_QM_TOOLS "Tools" -#define TR_QM_GEN_SETTINGS "General\nSettings" +#define TR_QM_MODEL_SETTINGS "Model\nSettings" +#define TR_QM_RADIO_SETTINGS "Radio\nSettings" #define TR_QM_FLIGHT_MODES TR_SFC_AIR("Drive\nModes", "Flight\nModes") #define TR_QM_INPUTS "Inputs" #define TR_QM_MIXES "Mixes" @@ -71,7 +72,8 @@ #define TR_QM_LS_MON "LS\nMonitor" #define TR_QM_STATS "Statistics" #define TR_QM_DEBUG "Debug" -#define TR_MAIN_MENU_SETTINGS "General Settings" +#define TR_MAIN_MODEL_SETTINGS "Model Settings" +#define TR_MAIN_RADIO_SETTINGS "Radio Settings" #define TR_MAIN_MENU_MANAGE_MODELS "Gestion Modèles" #define TR_MAIN_MENU_MODEL_NOTES "Notes Modèles" #define TR_MAIN_MENU_CHANNEL_MONITOR "Moniteur Voies" @@ -1408,3 +1410,10 @@ #define TR_WIDGET_SIZE "Taille Widget" #define TR_DEL_DIR_NOT_EMPTY "Directory must be empty before deletion" + +#define TR_KEY_SHORTCUTS "Key Shortcuts" +#define TR_CURRENT_SCREEN "Current Screen" +#define TR_SHORT_PRESS "Short Press" +#define TR_LONG_PRESS "Long Press" +#define TR_OPEN_QUICK_MENU "Open Quick Menu" +#define TR_QUICK_MENU_FAVORITES "Quick Menu Favorites" diff --git a/radio/src/translations/i18n/he.h b/radio/src/translations/i18n/he.h index 365fcea88..8d7c83127 100644 --- a/radio/src/translations/i18n/he.h +++ b/radio/src/translations/i18n/he.h @@ -38,7 +38,8 @@ #define TR_QM_RADIO_SETUP "Radio\nSetup" #define TR_QM_UI_SETUP "UI\nSetup" #define TR_QM_TOOLS "Tools" -#define TR_QM_GEN_SETTINGS "General\nSettings" +#define TR_QM_MODEL_SETTINGS "Model\nSettings" +#define TR_QM_RADIO_SETTINGS "Radio\nSettings" #define TR_QM_FLIGHT_MODES TR_SFC_AIR("Drive\nModes", "Flight\nModes") #define TR_QM_INPUTS "Inputs" #define TR_QM_MIXES "Mixes" @@ -73,7 +74,8 @@ #define TR_QM_LS_MON "LS\nMonitor" #define TR_QM_STATS "Statistics" #define TR_QM_DEBUG "Debug" -#define TR_MAIN_MENU_SETTINGS "הגדרות כלליות" +#define TR_MAIN_MODEL_SETTINGS "Model Settings" +#define TR_MAIN_RADIO_SETTINGS "Radio Settings" #define TR_MAIN_MENU_MANAGE_MODELS "ניהול מודלים" #define TR_MAIN_MENU_MODEL_NOTES "Model Notes" #define TR_MAIN_MENU_CHANNEL_MONITOR "מצגי ערוצים" @@ -1402,3 +1404,10 @@ #define TR_WIDGET_SIZE "Widget size" #define TR_DEL_DIR_NOT_EMPTY "Directory must be empty before deletion" + +#define TR_KEY_SHORTCUTS "Key Shortcuts" +#define TR_CURRENT_SCREEN "Current Screen" +#define TR_SHORT_PRESS "Short Press" +#define TR_LONG_PRESS "Long Press" +#define TR_OPEN_QUICK_MENU "Open Quick Menu" +#define TR_QUICK_MENU_FAVORITES "Quick Menu Favorites" diff --git a/radio/src/translations/i18n/it.h b/radio/src/translations/i18n/it.h index 571519bd7..a51e2a7e9 100644 --- a/radio/src/translations/i18n/it.h +++ b/radio/src/translations/i18n/it.h @@ -35,7 +35,8 @@ #define TR_QM_RADIO_SETUP "Radio\nSetup" #define TR_QM_UI_SETUP "UI\nSetup" #define TR_QM_TOOLS "Tools" -#define TR_QM_GEN_SETTINGS "General\nSettings" +#define TR_QM_MODEL_SETTINGS "Model\nSettings" +#define TR_QM_RADIO_SETTINGS "Radio\nSettings" #define TR_QM_FLIGHT_MODES TR_SFC_AIR("Drive\nModes", "Flight\nModes") #define TR_QM_INPUTS "Inputs" #define TR_QM_MIXES "Mixes" @@ -70,7 +71,8 @@ #define TR_QM_LS_MON "LS\nMonitor" #define TR_QM_STATS "Statistics" #define TR_QM_DEBUG "Debug" -#define TR_MAIN_MENU_SETTINGS "General Settings" +#define TR_MAIN_MODEL_SETTINGS "Model Settings" +#define TR_MAIN_RADIO_SETTINGS "Radio Settings" #define TR_MAIN_MENU_MANAGE_MODELS "Gestione Modelli" #define TR_MAIN_MENU_MODEL_NOTES "Note Modello" #define TR_MAIN_MENU_CHANNEL_MONITOR "Monitor Canali" @@ -1405,3 +1407,10 @@ * Update V2.11.x by: Marco Robustini * Fix V2.11.3 by: MatCron on 4/7/2025 */ + +#define TR_KEY_SHORTCUTS "Key Shortcuts" +#define TR_CURRENT_SCREEN "Current Screen" +#define TR_SHORT_PRESS "Short Press" +#define TR_LONG_PRESS "Long Press" +#define TR_OPEN_QUICK_MENU "Open Quick Menu" +#define TR_QUICK_MENU_FAVORITES "Quick Menu Favorites" diff --git a/radio/src/translations/i18n/jp.h b/radio/src/translations/i18n/jp.h index 04a458fac..e70fac579 100644 --- a/radio/src/translations/i18n/jp.h +++ b/radio/src/translations/i18n/jp.h @@ -35,7 +35,8 @@ #define TR_QM_RADIO_SETUP "Radio\nSetup" #define TR_QM_UI_SETUP "UI\nSetup" #define TR_QM_TOOLS "Tools" -#define TR_QM_GEN_SETTINGS "General\nSettings" +#define TR_QM_MODEL_SETTINGS "Model\nSettings" +#define TR_QM_RADIO_SETTINGS "Radio\nSettings" #define TR_QM_FLIGHT_MODES TR_SFC_AIR("Drive\nModes", "Flight\nModes") #define TR_QM_INPUTS "Inputs" #define TR_QM_MIXES "Mixes" @@ -70,7 +71,8 @@ #define TR_QM_LS_MON "LS\nMonitor" #define TR_QM_STATS "Statistics" #define TR_QM_DEBUG "Debug" -#define TR_MAIN_MENU_SETTINGS "General Settings" +#define TR_MAIN_MODEL_SETTINGS "Model Settings" +#define TR_MAIN_RADIO_SETTINGS "Radio Settings" #define TR_MAIN_MENU_MANAGE_MODELS "モデル 管理" #define TR_MAIN_MENU_MODEL_NOTES "モデル ノート" #define TR_MAIN_MENU_CHANNEL_MONITOR "Channel モニター" @@ -1398,3 +1400,10 @@ #define TR_WIDGET_SIZE "ウィジェットサイズ" #define TR_DEL_DIR_NOT_EMPTY "Directory must be empty before deletion" + +#define TR_KEY_SHORTCUTS "Key Shortcuts" +#define TR_CURRENT_SCREEN "Current Screen" +#define TR_SHORT_PRESS "Short Press" +#define TR_LONG_PRESS "Long Press" +#define TR_OPEN_QUICK_MENU "Open Quick Menu" +#define TR_QUICK_MENU_FAVORITES "Quick Menu Favorites" diff --git a/radio/src/translations/i18n/ko.h b/radio/src/translations/i18n/ko.h index b116a9dfe..00f3771cc 100644 --- a/radio/src/translations/i18n/ko.h +++ b/radio/src/translations/i18n/ko.h @@ -35,7 +35,8 @@ #define TR_QM_RADIO_SETUP "Radio\nSetup" #define TR_QM_UI_SETUP "UI\nSetup" #define TR_QM_TOOLS "Tools" -#define TR_QM_GEN_SETTINGS "General\nSettings" +#define TR_QM_MODEL_SETTINGS "Model\nSettings" +#define TR_QM_RADIO_SETTINGS "Radio\nSettings" #define TR_QM_FLIGHT_MODES TR_SFC_AIR("Drive\nModes", "Flight\nModes") #define TR_QM_INPUTS "Inputs" #define TR_QM_MIXES "Mixes" @@ -70,7 +71,8 @@ #define TR_QM_LS_MON "LS\nMonitor" #define TR_QM_STATS "Statistics" #define TR_QM_DEBUG "Debug" -#define TR_MAIN_MENU_SETTINGS "General Settings" +#define TR_MAIN_MODEL_SETTINGS "Model Settings" +#define TR_MAIN_RADIO_SETTINGS "Radio Settings" #define TR_MAIN_MENU_MANAGE_MODELS "모델\n관리" #define TR_MAIN_MENU_MODEL_NOTES "모델\n노트" #define TR_MAIN_MENU_CHANNEL_MONITOR "채널\n모니터" @@ -1434,3 +1436,10 @@ #define TR_HIGH_BATT_COLOR "배터리 충전 색상" #define TR_WIDGET_SIZE "위젯 크기" #define TR_DEL_DIR_NOT_EMPTY "폴더를 삭제하려면 먼저 비워야 합니다" + +#define TR_KEY_SHORTCUTS "Key Shortcuts" +#define TR_CURRENT_SCREEN "Current Screen" +#define TR_SHORT_PRESS "Short Press" +#define TR_LONG_PRESS "Long Press" +#define TR_OPEN_QUICK_MENU "Open Quick Menu" +#define TR_QUICK_MENU_FAVORITES "Quick Menu Favorites" diff --git a/radio/src/translations/i18n/nl.h b/radio/src/translations/i18n/nl.h index 8be740233..ecce46a00 100644 --- a/radio/src/translations/i18n/nl.h +++ b/radio/src/translations/i18n/nl.h @@ -37,7 +37,8 @@ #define TR_QM_RADIO_SETUP "Radio\nSetup" #define TR_QM_UI_SETUP "UI\nSetup" #define TR_QM_TOOLS "Tools" -#define TR_QM_GEN_SETTINGS "General\nSettings" +#define TR_QM_MODEL_SETTINGS "Model\nSettings" +#define TR_QM_RADIO_SETTINGS "Radio\nSettings" #define TR_QM_FLIGHT_MODES TR_SFC_AIR("Drive\nModes", "Flight\nModes") #define TR_QM_INPUTS "Inputs" #define TR_QM_MIXES "Mixes" @@ -72,7 +73,8 @@ #define TR_QM_LS_MON "LS\nMonitor" #define TR_QM_STATS "Statistics" #define TR_QM_DEBUG "Debug" -#define TR_MAIN_MENU_SETTINGS "General Settings" +#define TR_MAIN_MODEL_SETTINGS "Model Settings" +#define TR_MAIN_RADIO_SETTINGS "Radio Settings" #define TR_MAIN_MENU_MANAGE_MODELS "Model Manager" #define TR_MAIN_MENU_MODEL_NOTES "Model Notes" #define TR_MAIN_MENU_CHANNEL_MONITOR "Channel Monitor" @@ -1404,3 +1406,10 @@ #define TR_WIDGET_SIZE "Widget size" #define TR_DEL_DIR_NOT_EMPTY "Directory must be empty before deletion" + +#define TR_KEY_SHORTCUTS "Key Shortcuts" +#define TR_CURRENT_SCREEN "Current Screen" +#define TR_SHORT_PRESS "Short Press" +#define TR_LONG_PRESS "Long Press" +#define TR_OPEN_QUICK_MENU "Open Quick Menu" +#define TR_QUICK_MENU_FAVORITES "Quick Menu Favorites" diff --git a/radio/src/translations/i18n/pl.h b/radio/src/translations/i18n/pl.h index f01132666..725c9990f 100644 --- a/radio/src/translations/i18n/pl.h +++ b/radio/src/translations/i18n/pl.h @@ -37,7 +37,8 @@ #define TR_QM_RADIO_SETUP "Radio\nSetup" #define TR_QM_UI_SETUP "UI\nSetup" #define TR_QM_TOOLS "Tools" -#define TR_QM_GEN_SETTINGS "General\nSettings" +#define TR_QM_MODEL_SETTINGS "Model\nSettings" +#define TR_QM_RADIO_SETTINGS "Radio\nSettings" #define TR_QM_FLIGHT_MODES TR_SFC_AIR("Drive\nModes", "Flight\nModes") #define TR_QM_INPUTS "Inputs" #define TR_QM_MIXES "Mixes" @@ -72,7 +73,8 @@ #define TR_QM_LS_MON "LS\nMonitor" #define TR_QM_STATS "Statistics" #define TR_QM_DEBUG "Debug" -#define TR_MAIN_MENU_SETTINGS "General Settings" +#define TR_MAIN_MODEL_SETTINGS "Model Settings" +#define TR_MAIN_RADIO_SETTINGS "Radio Settings" #define TR_MAIN_MENU_MANAGE_MODELS "Menadżer modeli" #define TR_MAIN_MENU_MODEL_NOTES "Notatki modelu" #define TR_MAIN_MENU_CHANNEL_MONITOR "Monitor kanałów" @@ -1399,3 +1401,10 @@ #define TR_WIDGET_SIZE "Rozmiar widżetu" #define TR_DEL_DIR_NOT_EMPTY "Directory must be empty before deletion" + +#define TR_KEY_SHORTCUTS "Key Shortcuts" +#define TR_CURRENT_SCREEN "Current Screen" +#define TR_SHORT_PRESS "Short Press" +#define TR_LONG_PRESS "Long Press" +#define TR_OPEN_QUICK_MENU "Open Quick Menu" +#define TR_QUICK_MENU_FAVORITES "Quick Menu Favorites" diff --git a/radio/src/translations/i18n/pt.h b/radio/src/translations/i18n/pt.h index 88ea4a8a3..bc969e951 100644 --- a/radio/src/translations/i18n/pt.h +++ b/radio/src/translations/i18n/pt.h @@ -38,7 +38,8 @@ #define TR_QM_RADIO_SETUP "Radio\nSetup" #define TR_QM_UI_SETUP "UI\nSetup" #define TR_QM_TOOLS "Tools" -#define TR_QM_GEN_SETTINGS "General\nSettings" +#define TR_QM_MODEL_SETTINGS "Model\nSettings" +#define TR_QM_RADIO_SETTINGS "Radio\nSettings" #define TR_QM_FLIGHT_MODES TR_SFC_AIR("Drive\nModes", "Flight\nModes") #define TR_QM_INPUTS "Inputs" #define TR_QM_MIXES "Mixes" @@ -73,7 +74,8 @@ #define TR_QM_LS_MON "LS\nMonitor" #define TR_QM_STATS "Statistics" #define TR_QM_DEBUG "Debug" -#define TR_MAIN_MENU_SETTINGS "General Settings" +#define TR_MAIN_MODEL_SETTINGS "Model Settings" +#define TR_MAIN_RADIO_SETTINGS "Radio Settings" #define TR_MAIN_MENU_MANAGE_MODELS "Gerenciar Modelos" #define TR_MAIN_MENU_MODEL_NOTES "Notas Modelo" #define TR_MAIN_MENU_CHANNEL_MONITOR "Monitor Canais" @@ -1401,3 +1403,10 @@ #define TR_WIDGET_SIZE "Tamanho do widget" #define TR_DEL_DIR_NOT_EMPTY "Directory must be empty before deletion" + +#define TR_KEY_SHORTCUTS "Key Shortcuts" +#define TR_CURRENT_SCREEN "Current Screen" +#define TR_SHORT_PRESS "Short Press" +#define TR_LONG_PRESS "Long Press" +#define TR_OPEN_QUICK_MENU "Open Quick Menu" +#define TR_QUICK_MENU_FAVORITES "Quick Menu Favorites" diff --git a/radio/src/translations/i18n/ru.h b/radio/src/translations/i18n/ru.h index 32691d89d..388102581 100644 --- a/radio/src/translations/i18n/ru.h +++ b/radio/src/translations/i18n/ru.h @@ -38,7 +38,8 @@ #define TR_QM_RADIO_SETUP "Radio\nSetup" #define TR_QM_UI_SETUP "UI\nSetup" #define TR_QM_TOOLS "Tools" -#define TR_QM_GEN_SETTINGS "General\nSettings" +#define TR_QM_MODEL_SETTINGS "Model\nSettings" +#define TR_QM_RADIO_SETTINGS "Radio\nSettings" #define TR_QM_FLIGHT_MODES TR_SFC_AIR("Drive\nModes", "Flight\nModes") #define TR_QM_INPUTS "Inputs" #define TR_QM_MIXES "Mixes" @@ -73,7 +74,8 @@ #define TR_QM_LS_MON "LS\nMonitor" #define TR_QM_STATS "Statistics" #define TR_QM_DEBUG "Debug" -#define TR_MAIN_MENU_SETTINGS "General Settings" +#define TR_MAIN_MODEL_SETTINGS "Model Settings" +#define TR_MAIN_RADIO_SETTINGS "Radio Settings" #define TR_MAIN_MENU_MANAGE_MODELS "Меню Моделей" #define TR_MAIN_MENU_MODEL_NOTES "Заметки Модели" #define TR_MAIN_MENU_CHANNEL_MONITOR "Монитор Каналов" @@ -1401,3 +1403,10 @@ #define TR_WIDGET_SIZE "Размер виджета" #define TR_DEL_DIR_NOT_EMPTY "Перед удал каталог должен быть пустым" + +#define TR_KEY_SHORTCUTS "Key Shortcuts" +#define TR_CURRENT_SCREEN "Current Screen" +#define TR_SHORT_PRESS "Short Press" +#define TR_LONG_PRESS "Long Press" +#define TR_OPEN_QUICK_MENU "Open Quick Menu" +#define TR_QUICK_MENU_FAVORITES "Quick Menu Favorites" diff --git a/radio/src/translations/i18n/se.h b/radio/src/translations/i18n/se.h index 1ae2ec4b5..c9a7ad38a 100644 --- a/radio/src/translations/i18n/se.h +++ b/radio/src/translations/i18n/se.h @@ -38,7 +38,8 @@ #define TR_QM_RADIO_SETUP "Radio\nSetup" #define TR_QM_UI_SETUP "UI\nSetup" #define TR_QM_TOOLS "Tools" -#define TR_QM_GEN_SETTINGS "General\nSettings" +#define TR_QM_MODEL_SETTINGS "Model\nSettings" +#define TR_QM_RADIO_SETTINGS "Radio\nSettings" #define TR_QM_FLIGHT_MODES TR_SFC_AIR("Drive\nModes", "Flight\nModes") #define TR_QM_INPUTS "Inputs" #define TR_QM_MIXES "Mixes" @@ -73,7 +74,8 @@ #define TR_QM_LS_MON "LS\nMonitor" #define TR_QM_STATS "Statistics" #define TR_QM_DEBUG "Debug" -#define TR_MAIN_MENU_SETTINGS "General Settings" +#define TR_MAIN_MODEL_SETTINGS "Model Settings" +#define TR_MAIN_RADIO_SETTINGS "Radio Settings" #define TR_MAIN_MENU_MANAGE_MODELS "Hantera modell" #define TR_MAIN_MENU_MODEL_NOTES "Modell- anteckn." #define TR_MAIN_MENU_CHANNEL_MONITOR "Kanal- monitor" @@ -1416,3 +1418,10 @@ #define TR_WIDGET_SIZE "Widgetstorlek" #define TR_DEL_DIR_NOT_EMPTY "Katalog måste var tom innan radering" + +#define TR_KEY_SHORTCUTS "Key Shortcuts" +#define TR_CURRENT_SCREEN "Current Screen" +#define TR_SHORT_PRESS "Short Press" +#define TR_LONG_PRESS "Long Press" +#define TR_OPEN_QUICK_MENU "Open Quick Menu" +#define TR_QUICK_MENU_FAVORITES "Quick Menu Favorites" diff --git a/radio/src/translations/i18n/tw.h b/radio/src/translations/i18n/tw.h index b6ce992ef..9ab9c1995 100644 --- a/radio/src/translations/i18n/tw.h +++ b/radio/src/translations/i18n/tw.h @@ -30,47 +30,49 @@ */ // Main menu -#define TR_QM_MANAGE_MODELS "Manage\nModels" -#define TR_QM_MODEL_SETUP "Model\nSetup" -#define TR_QM_RADIO_SETUP "Radio\nSetup" -#define TR_QM_UI_SETUP "UI\nSetup" -#define TR_QM_TOOLS "Tools" -#define TR_QM_GEN_SETTINGS "General\nSettings" -#define TR_QM_FLIGHT_MODES TR_SFC_AIR("Drive\nModes", "Flight\nModes") -#define TR_QM_INPUTS "Inputs" -#define TR_QM_MIXES "Mixes" -#define TR_QM_OUTPUTS "Outputs" -#define TR_QM_CURVES "Curves" -#define TR_QM_GLOBAL_VARS "Global\nVariables" -#define TR_QM_LOGICAL_SW "Logical\nSwitches" -#define TR_QM_SPEC_FUNC "Special\nFunctions" -#define TR_QM_CUSTOM_LUA "Custom\nScripts" -#define TR_QM_TELEM "Telemetry" -#define TR_QM_GLOB_FUNC "Global\nFunctions" -#define TR_QM_TRAINER "Trainer" -#define TR_QM_HARDWARE "Hardware" -#define TR_QM_ABOUT "About\nEdgeTX" -#define TR_QM_THEMES "Themes" -#define TR_QM_TOP_BAR "Top Bar" -#define TR_QM_SCREEN_1 "Screen 1" -#define TR_QM_SCREEN_2 "Screen 2" -#define TR_QM_SCREEN_3 "Screen 3" -#define TR_QM_SCREEN_4 "Screen 4" -#define TR_QM_SCREEN_5 "Screen 5" -#define TR_QM_SCREEN_6 "Screen 6" -#define TR_QM_SCREEN_7 "Screen 7" -#define TR_QM_SCREEN_8 "Screen 8" -#define TR_QM_SCREEN_9 "Screen 9" -#define TR_QM_SCREEN_10 "Screen 10" -#define TR_QM_ADD_SCREEN "Add\nScreen" -#define TR_QM_APPS "Apps" -#define TR_QM_STORAGE "Storage" -#define TR_QM_RESET TR_SFC_AIR("Drive\nReset", "Flight\nReset") -#define TR_QM_CHAN_MON "Channel\nMonitor" -#define TR_QM_LS_MON "LS\nMonitor" -#define TR_QM_STATS "Statistics" +#define TR_QM_MANAGE_MODELS "模型\n管理" +#define TR_QM_MODEL_SETUP "模型\n設置" +#define TR_QM_RADIO_SETUP "系統\n設置" +#define TR_QM_UI_SETUP "UI\n設置" +#define TR_QM_TOOLS "工具\nAPP" +#define TR_QM_MODEL_SETTINGS "Model\nSettings" +#define TR_QM_RADIO_SETTINGS "Radio\nSettings" +#define TR_QM_FLIGHT_MODES TR_SFC_AIR("駕駛\n模式", "飛行\n模式") +#define TR_QM_INPUTS "輸入" +#define TR_QM_MIXES "混控" +#define TR_QM_OUTPUTS "輸出" +#define TR_QM_CURVES "曲線" +#define TR_QM_GLOBAL_VARS "全局\n變量" +#define TR_QM_LOGICAL_SW "邏輯\n開關" +#define TR_QM_SPEC_FUNC "特殊\n功能" +#define TR_QM_CUSTOM_LUA "自定義\nLUA腳本" +#define TR_QM_TELEM "遙測/回傳" +#define TR_QM_GLOB_FUNC "全局\n功能" +#define TR_QM_TRAINER "教練" +#define TR_QM_HARDWARE "硬件" +#define TR_QM_ABOUT "關於\nEdgeTX" +#define TR_QM_THEMES "主題" +#define TR_QM_TOP_BAR "頂欄" +#define TR_QM_SCREEN_1 "屏幕 1" +#define TR_QM_SCREEN_2 "屏幕 2" +#define TR_QM_SCREEN_3 "屏幕 3" +#define TR_QM_SCREEN_4 "屏幕 4" +#define TR_QM_SCREEN_5 "屏幕 5" +#define TR_QM_SCREEN_6 "屏幕 6" +#define TR_QM_SCREEN_7 "屏幕 7" +#define TR_QM_SCREEN_8 "屏幕 8" +#define TR_QM_SCREEN_9 "屏幕 9" +#define TR_QM_SCREEN_10 "屏幕 10" +#define TR_QM_ADD_SCREEN "添加\n屏幕" +#define TR_QM_APPS "APP\nLUA腳本" +#define TR_QM_STORAGE "存儲器" +#define TR_QM_RESET TR_SFC_AIR("復位", "復位") +#define TR_QM_CHAN_MON "通道\n查看器" +#define TR_QM_LS_MON "邏輯開關\n查看器" +#define TR_QM_STATS "統計" #define TR_QM_DEBUG "Debug" -#define TR_MAIN_MENU_SETTINGS "General Settings" +#define TR_MAIN_MODEL_SETTINGS "Model Settings" +#define TR_MAIN_RADIO_SETTINGS "Radio Settings" #define TR_MAIN_MENU_MANAGE_MODELS "模型管理" #define TR_MAIN_MENU_MODEL_NOTES "模型說明" #define TR_MAIN_MENU_CHANNEL_MONITOR "通道查看" @@ -1401,3 +1403,10 @@ #define TR_WIDGET_SIZE "小部件尺寸" #define TR_DEL_DIR_NOT_EMPTY "刪除檔案夾必須爲空 !" + +#define TR_KEY_SHORTCUTS "Key Shortcuts" +#define TR_CURRENT_SCREEN "Current Screen" +#define TR_SHORT_PRESS "Short Press" +#define TR_LONG_PRESS "Long Press" +#define TR_OPEN_QUICK_MENU "Open Quick Menu" +#define TR_QUICK_MENU_FAVORITES "Quick Menu Favorites" diff --git a/radio/src/translations/i18n/ua.h b/radio/src/translations/i18n/ua.h index 5e4f6368d..15211d8e0 100644 --- a/radio/src/translations/i18n/ua.h +++ b/radio/src/translations/i18n/ua.h @@ -37,7 +37,8 @@ #define TR_QM_RADIO_SETUP "Radio\nSetup" #define TR_QM_UI_SETUP "UI\nSetup" #define TR_QM_TOOLS "Tools" -#define TR_QM_GEN_SETTINGS "General\nSettings" +#define TR_QM_MODEL_SETTINGS "Model\nSettings" +#define TR_QM_RADIO_SETTINGS "Radio\nSettings" #define TR_QM_FLIGHT_MODES TR_SFC_AIR("Drive\nModes", "Flight\nModes") #define TR_QM_INPUTS "Inputs" #define TR_QM_MIXES "Mixes" @@ -72,7 +73,8 @@ #define TR_QM_LS_MON "LS\nMonitor" #define TR_QM_STATS "Statistics" #define TR_QM_DEBUG "Debug" -#define TR_MAIN_MENU_SETTINGS "General Settings" +#define TR_MAIN_MODEL_SETTINGS "Model Settings" +#define TR_MAIN_RADIO_SETTINGS "Radio Settings" #define TR_MAIN_MENU_MANAGE_MODELS "Керувати Моделями" #define TR_MAIN_MENU_MODEL_NOTES "Моделі Нотатки" #define TR_MAIN_MENU_CHANNEL_MONITOR "Канал Монітор" @@ -1400,3 +1402,10 @@ #define TR_WIDGET_SIZE "Розмір віджета" #define TR_DEL_DIR_NOT_EMPTY "Directory must be empty before deletion" + +#define TR_KEY_SHORTCUTS "Key Shortcuts" +#define TR_CURRENT_SCREEN "Current Screen" +#define TR_SHORT_PRESS "Short Press" +#define TR_LONG_PRESS "Long Press" +#define TR_OPEN_QUICK_MENU "Open Quick Menu" +#define TR_QUICK_MENU_FAVORITES "Quick Menu Favorites" diff --git a/radio/src/translations/sim_string_list.h b/radio/src/translations/sim_string_list.h index 23b4e4439..cee761249 100644 --- a/radio/src/translations/sim_string_list.h +++ b/radio/src/translations/sim_string_list.h @@ -108,9 +108,10 @@ #define STR_MAIN_MENU_MODEL_SETTINGS currentLangStrings->STR_MAIN_MENU_MODEL_SETTINGS #define STR_MAIN_MENU_RADIO_SETTINGS currentLangStrings->STR_MAIN_MENU_RADIO_SETTINGS #define STR_MAIN_MENU_SCREEN_SETTINGS currentLangStrings->STR_MAIN_MENU_SCREEN_SETTINGS -#define STR_MAIN_MENU_SETTINGS currentLangStrings->STR_MAIN_MENU_SETTINGS #define STR_MAIN_MENU_STATISTICS currentLangStrings->STR_MAIN_MENU_STATISTICS #define STR_MAIN_MENU_THEMES currentLangStrings->STR_MAIN_MENU_THEMES +#define STR_MAIN_MODEL_SETTINGS currentLangStrings->STR_MAIN_MODEL_SETTINGS +#define STR_MAIN_RADIO_SETTINGS currentLangStrings->STR_MAIN_RADIO_SETTINGS #define STR_MANAGE_MODELS currentLangStrings->STR_MANAGE_MODELS #define STR_MEM_USED_EXTRA currentLangStrings->STR_MEM_USED_EXTRA #define STR_MEM_USED_SCRIPT currentLangStrings->STR_MEM_USED_SCRIPT @@ -192,7 +193,6 @@ #define STR_QM_CUSTOM_LUA currentLangStrings->STR_QM_CUSTOM_LUA #define STR_QM_DEBUG currentLangStrings->STR_QM_DEBUG #define STR_QM_FLIGHT_MODES currentLangStrings->STR_QM_FLIGHT_MODES -#define STR_QM_GEN_SETTINGS currentLangStrings->STR_QM_GEN_SETTINGS #define STR_QM_GLOB_FUNC currentLangStrings->STR_QM_GLOB_FUNC #define STR_QM_GLOBAL_VARS currentLangStrings->STR_QM_GLOBAL_VARS #define STR_QM_HARDWARE currentLangStrings->STR_QM_HARDWARE @@ -201,8 +201,10 @@ #define STR_QM_LS_MON currentLangStrings->STR_QM_LS_MON #define STR_QM_MANAGE_MODELS currentLangStrings->STR_QM_MANAGE_MODELS #define STR_QM_MIXES currentLangStrings->STR_QM_MIXES +#define STR_QM_MODEL_SETTINGS currentLangStrings->STR_QM_MODEL_SETTINGS #define STR_QM_MODEL_SETUP currentLangStrings->STR_QM_MODEL_SETUP #define STR_QM_OUTPUTS currentLangStrings->STR_QM_OUTPUTS +#define STR_QM_RADIO_SETTINGS currentLangStrings->STR_QM_RADIO_SETTINGS #define STR_QM_RADIO_SETUP currentLangStrings->STR_QM_RADIO_SETUP #define STR_QM_RESET currentLangStrings->STR_QM_RESET #define STR_QM_SCREEN_1 currentLangStrings->STR_QM_SCREEN_1 @@ -224,6 +226,19 @@ #define STR_QM_TOP_BAR currentLangStrings->STR_QM_TOP_BAR #define STR_QM_TRAINER currentLangStrings->STR_QM_TRAINER #define STR_QM_UI_SETUP currentLangStrings->STR_QM_UI_SETUP +#define STR_QUICK_MENU_FAVORITES currentLangStrings->STR_QUICK_MENU_FAVORITES +#define STR_CURRENT_SCREEN currentLangStrings->STR_CURRENT_SCREEN +#define STR_MAIN_MENU_APPS currentLangStrings->STR_MAIN_MENU_APPS +#define STR_MAIN_VIEW_1 currentLangStrings->STR_MAIN_VIEW_1 +#define STR_MAIN_VIEW_10 currentLangStrings->STR_MAIN_VIEW_10 +#define STR_MAIN_VIEW_2 currentLangStrings->STR_MAIN_VIEW_2 +#define STR_MAIN_VIEW_3 currentLangStrings->STR_MAIN_VIEW_3 +#define STR_MAIN_VIEW_4 currentLangStrings->STR_MAIN_VIEW_4 +#define STR_MAIN_VIEW_5 currentLangStrings->STR_MAIN_VIEW_5 +#define STR_MAIN_VIEW_6 currentLangStrings->STR_MAIN_VIEW_6 +#define STR_MAIN_VIEW_7 currentLangStrings->STR_MAIN_VIEW_7 +#define STR_MAIN_VIEW_8 currentLangStrings->STR_MAIN_VIEW_8 +#define STR_MAIN_VIEW_9 currentLangStrings->STR_MAIN_VIEW_9 // Main Menu #else // !COLORLCD @@ -587,6 +602,7 @@ #define STR_JITTER_FILTER currentLangStrings->STR_JITTER_FILTER #define STR_KEYS_BTN currentLangStrings->STR_KEYS_BTN #define STR_KEYSTUCK currentLangStrings->STR_KEYSTUCK +#define STR_KEY_SHORTCUTS currentLangStrings->STR_KEY_SHORTCUTS #define STR_LCD currentLangStrings->STR_LCD #define STR_LENGTH currentLangStrings->STR_LENGTH #define STR_LIMITS_HEADERS_DIRECTION currentLangStrings->STR_LIMITS_HEADERS_DIRECTION @@ -595,19 +611,9 @@ #define STR_LIMITS_HEADERS_SUBTRIMMODE currentLangStrings->STR_LIMITS_HEADERS_SUBTRIMMODE #define STR_LOADINGMODEL currentLangStrings->STR_LOADINGMODEL #define STR_LOGS currentLangStrings->STR_LOGS +#define STR_LONG_PRESS currentLangStrings->STR_LONG_PRESS #define STR_LOWALARM currentLangStrings->STR_LOWALARM #define STR_LUA_SCRIPTS_LABEL currentLangStrings->STR_LUA_SCRIPTS_LABEL -#define STR_MAIN_MENU_APPS currentLangStrings->STR_MAIN_MENU_APPS -#define STR_MAIN_VIEW_1 currentLangStrings->STR_MAIN_VIEW_1 -#define STR_MAIN_VIEW_10 currentLangStrings->STR_MAIN_VIEW_10 -#define STR_MAIN_VIEW_2 currentLangStrings->STR_MAIN_VIEW_2 -#define STR_MAIN_VIEW_3 currentLangStrings->STR_MAIN_VIEW_3 -#define STR_MAIN_VIEW_4 currentLangStrings->STR_MAIN_VIEW_4 -#define STR_MAIN_VIEW_5 currentLangStrings->STR_MAIN_VIEW_5 -#define STR_MAIN_VIEW_6 currentLangStrings->STR_MAIN_VIEW_6 -#define STR_MAIN_VIEW_7 currentLangStrings->STR_MAIN_VIEW_7 -#define STR_MAIN_VIEW_8 currentLangStrings->STR_MAIN_VIEW_8 -#define STR_MAIN_VIEW_9 currentLangStrings->STR_MAIN_VIEW_9 #define STR_MAX currentLangStrings->STR_MAX #define STR_MAXBAUDRATE currentLangStrings->STR_MAXBAUDRATE #define STR_MEMORYWARNING currentLangStrings->STR_MEMORYWARNING @@ -767,6 +773,7 @@ #define STR_OFFSET currentLangStrings->STR_OFFSET #define STR_OK currentLangStrings->STR_OK #define STR_ONLYPOSITIVE currentLangStrings->STR_ONLYPOSITIVE +#define STR_OPEN_QUICK_MENU currentLangStrings->STR_OPEN_QUICK_MENU #define STR_OPTIONS currentLangStrings->STR_OPTIONS #define STR_OTA_UPDATE_ERROR currentLangStrings->STR_OTA_UPDATE_ERROR #define STR_OTA_UPDATE currentLangStrings->STR_OTA_UPDATE @@ -912,6 +919,7 @@ #define STR_SF_VOLUME currentLangStrings->STR_SF_VOLUME #define STR_SF currentLangStrings->STR_SF #define STR_SHARE currentLangStrings->STR_SHARE +#define STR_SHORT_PRESS currentLangStrings->STR_SHORT_PRESS #define STR_SHOW_INSTANCE_ID currentLangStrings->STR_SHOW_INSTANCE_ID #define STR_SIDE currentLangStrings->STR_SIDE #define STR_SIGNAL_OUTPUT currentLangStrings->STR_SIGNAL_OUTPUT diff --git a/radio/src/translations/string_list.h b/radio/src/translations/string_list.h index 42c5522e3..147e964dc 100644 --- a/radio/src/translations/string_list.h +++ b/radio/src/translations/string_list.h @@ -107,9 +107,10 @@ STR(MAIN_MENU_MODEL_NOTES) STR(MAIN_MENU_MODEL_SETTINGS) STR(MAIN_MENU_RADIO_SETTINGS) STR(MAIN_MENU_SCREEN_SETTINGS) -STR(MAIN_MENU_SETTINGS) STR(MAIN_MENU_STATISTICS) STR(MAIN_MENU_THEMES) +STR(MAIN_MODEL_SETTINGS) +STR(MAIN_RADIO_SETTINGS) STR(MANAGE_MODELS) STR(MEM_USED_EXTRA) STR(MEM_USED_SCRIPT) @@ -191,7 +192,6 @@ STR(QM_CURVES) STR(QM_CUSTOM_LUA) STR(QM_DEBUG) STR(QM_FLIGHT_MODES) -STR(QM_GEN_SETTINGS) STR(QM_GLOB_FUNC) STR(QM_GLOBAL_VARS) STR(QM_HARDWARE) @@ -200,8 +200,10 @@ STR(QM_LOGICAL_SW) STR(QM_LS_MON) STR(QM_MANAGE_MODELS) STR(QM_MIXES) +STR(QM_MODEL_SETTINGS) STR(QM_MODEL_SETUP) STR(QM_OUTPUTS) +STR(QM_RADIO_SETTINGS) STR(QM_RADIO_SETUP) STR(QM_RESET) STR(QM_SCREEN_1) @@ -223,6 +225,19 @@ STR(QM_TOOLS) STR(QM_TOP_BAR) STR(QM_TRAINER) STR(QM_UI_SETUP) +STR(QUICK_MENU_FAVORITES) +STR(CURRENT_SCREEN) +STR(MAIN_MENU_APPS) +STR(MAIN_VIEW_1) +STR(MAIN_VIEW_10) +STR(MAIN_VIEW_2) +STR(MAIN_VIEW_3) +STR(MAIN_VIEW_4) +STR(MAIN_VIEW_5) +STR(MAIN_VIEW_6) +STR(MAIN_VIEW_7) +STR(MAIN_VIEW_8) +STR(MAIN_VIEW_9) // Main Menu #else // !COLORLCD @@ -586,6 +601,7 @@ STR(JACK_MODE) STR(JITTER_FILTER) STR(KEYS_BTN) STR(KEYSTUCK) +STR(KEY_SHORTCUTS) STR(LCD) STR(LENGTH) STR(LIMITS_HEADERS_DIRECTION) @@ -594,19 +610,9 @@ STR(LIMITS_HEADERS_SUBTRIM) STR(LIMITS_HEADERS_SUBTRIMMODE) STR(LOADINGMODEL) STR(LOGS) +STR(LONG_PRESS) STR(LOWALARM) STR(LUA_SCRIPTS_LABEL) -STR(MAIN_MENU_APPS) -STR(MAIN_VIEW_1) -STR(MAIN_VIEW_10) -STR(MAIN_VIEW_2) -STR(MAIN_VIEW_3) -STR(MAIN_VIEW_4) -STR(MAIN_VIEW_5) -STR(MAIN_VIEW_6) -STR(MAIN_VIEW_7) -STR(MAIN_VIEW_8) -STR(MAIN_VIEW_9) STR(MAX) STR(MAXBAUDRATE) STR(MEMORYWARNING) @@ -766,6 +772,7 @@ STR(OFF) STR(OFFSET) STR(OK) STR(ONLYPOSITIVE) +STR(OPEN_QUICK_MENU) STR(OPTIONS) STR(OTA_UPDATE_ERROR) STR(OTA_UPDATE) @@ -911,6 +918,7 @@ STR(SF_VARIO) STR(SF_VOLUME) STR(SF) STR(SHARE) +STR(SHORT_PRESS) STR(SHOW_INSTANCE_ID) STR(SIDE) STR(SIGNAL_OUTPUT)