From a48ca7a9ee4c6feaa960067fa8aab74e154ff3be Mon Sep 17 00:00:00 2001 From: philmoz Date: Tue, 26 Sep 2023 17:35:00 +1000 Subject: [PATCH] Allow SYS and MDL key navigation from within radio and model menus. --- radio/src/gui/colorlcd/menu_model.cpp | 55 +++---- radio/src/gui/colorlcd/menu_model.h | 40 +++-- radio/src/gui/colorlcd/menu_radio.cpp | 53 ++++--- radio/src/gui/colorlcd/menu_radio.h | 27 ++-- radio/src/gui/colorlcd/model_select.cpp | 178 ++++++++++++----------- radio/src/gui/colorlcd/model_select.h | 8 +- radio/src/gui/colorlcd/tabsgroup.cpp | 102 ++++++------- radio/src/gui/colorlcd/view_channels.cpp | 99 +++++++++---- radio/src/gui/colorlcd/view_channels.h | 9 +- radio/src/gui/colorlcd/view_main.cpp | 10 +- 10 files changed, 320 insertions(+), 261 deletions(-) diff --git a/radio/src/gui/colorlcd/menu_model.cpp b/radio/src/gui/colorlcd/menu_model.cpp index e2227f6d082..c855d75f750 100644 --- a/radio/src/gui/colorlcd/menu_model.cpp +++ b/radio/src/gui/colorlcd/menu_model.cpp @@ -21,8 +21,7 @@ #include "menu_model.h" -#include "translations.h" -#include "view_channels.h" +#include "menu_radio.h" #include "model_curves.h" #include "model_flightmodes.h" #include "model_gvars.h" @@ -32,16 +31,15 @@ #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 "opentx.h" #include "special_functions.h" +#include "translations.h" +#include "view_channels.h" -ModelMenu::ModelMenu(): - TabsGroup(ICON_MODEL) -{ - build(); -} +ModelMenu::ModelMenu() : TabsGroup(ICON_MODEL) { build(); } void ModelMenu::build() { @@ -56,32 +54,24 @@ void ModelMenu::build() addTab(new ModelSetupPage()); #if defined(HELI) - if (_modelHeliEnabled) - addTab(new ModelHeliPage()); + if (_modelHeliEnabled) addTab(new ModelHeliPage()); #endif #if defined(FLIGHT_MODES) - if (_modelFMEnabled) - addTab(new ModelFlightModesPage()); + if (_modelFMEnabled) addTab(new ModelFlightModesPage()); #endif addTab(new ModelInputsPage()); addTab(new ModelMixesPage()); addTab(new ModelOutputsPage()); - if (_modelCurvesEnabled) - addTab(new ModelCurvesPage()); + if (_modelCurvesEnabled) addTab(new ModelCurvesPage()); #if defined(GVARS) - if (_modelGVEnabled) - addTab(new ModelGVarsPage()); + if (_modelGVEnabled) addTab(new ModelGVarsPage()); #endif - if (_modelLSEnabled) - addTab(new ModelLogicalSwitchesPage()); - if (_modelSFEnabled) - addTab(new SpecialFunctionsPage(g_model.customFn)); + if (_modelLSEnabled) addTab(new ModelLogicalSwitchesPage()); + if (_modelSFEnabled) addTab(new SpecialFunctionsPage(g_model.customFn)); #if defined(LUA_MODEL_SCRIPTS) - if (_modelCustomScriptsEnabled) - addTab(new ModelMixerScriptsPage()); + if (_modelCustomScriptsEnabled) addTab(new ModelMixerScriptsPage()); #endif - if (_modelTelemetryEnabled) - addTab(new ModelTelemetryPage()); + if (_modelTelemetryEnabled) addTab(new ModelTelemetryPage()); #if defined(PCBNV14) || defined(PCBPL18) addGoToMonitorsButton(); @@ -109,9 +99,21 @@ void ModelMenu::checkEvents() void ModelMenu::onEvent(event_t event) { #if defined(HARDWARE_KEYS) - if (event == EVT_KEY_FIRST(KEY_MODEL)) { + if (event == EVT_KEY_BREAK(KEY_MODEL)) { killEvents(event); - new ChannelsViewMenu(); + new ChannelsViewMenu(this); + } else if (event == EVT_KEY_LONG(KEY_MODEL)) { + killEvents(KEY_MODEL); + onCancel(); + new ModelLabelsWindow(); + } else if (event == EVT_KEY_BREAK(KEY_SYS)) { + onCancel(); + new RadioMenu(); + } else if (event == EVT_KEY_LONG(KEY_SYS)) { + onCancel(); + killEvents(KEY_SYS); + // Radio setup + (new RadioMenu())->setCurrentTab(2); } else { TabsGroup::onEvent(event); } @@ -122,7 +124,8 @@ void ModelMenu::onEvent(event_t event) void ModelMenu::addGoToMonitorsButton() { new TextButton( - &header, {LCD_W / 2 + 6, MENU_TITLE_TOP + 1, LCD_W / 2 - 8, MENU_TITLE_HEIGHT - 2}, + &header, + {LCD_W / 2 + 6, MENU_TITLE_TOP + 1, LCD_W / 2 - 8, MENU_TITLE_HEIGHT - 2}, STR_OPEN_CHANNEL_MONITORS, [=]() { pushEvent(EVT_KEY_FIRST(KEY_MODEL)); return 0; diff --git a/radio/src/gui/colorlcd/menu_model.h b/radio/src/gui/colorlcd/menu_model.h index e1ba47a76a7..ed17ade3ea7 100644 --- a/radio/src/gui/colorlcd/menu_model.h +++ b/radio/src/gui/colorlcd/menu_model.h @@ -19,37 +19,33 @@ * GNU General Public License for more details. */ -#ifndef _MENU_MODEL_H_ -#define _MENU_MODEL_H_ +#pragma once #include "tabsgroup.h" class ModelMenu : public TabsGroup { - public: - ModelMenu(); - - void onEvent(event_t event) override; + public: + ModelMenu(); #if defined(DEBUG_WINDOWS) - std::string getName() const override { return "ModelMenu"; } + std::string getName() const override { return "ModelMenu"; } #endif - protected: + protected: #if defined(PCBNV14) || defined(PCBPL18) - void addGoToMonitorsButton(void); + void addGoToMonitorsButton(void); #endif - bool _modelHeliEnabled = true; - bool _modelFMEnabled = true; - bool _modelCurvesEnabled = true; - bool _modelGVEnabled = true; - bool _modelLSEnabled = true; - bool _modelSFEnabled = true; - bool _modelCustomScriptsEnabled = true; - bool _modelTelemetryEnabled = true; - - void build(); - void checkEvents() override; + bool _modelHeliEnabled = true; + bool _modelFMEnabled = true; + bool _modelCurvesEnabled = true; + bool _modelGVEnabled = true; + bool _modelLSEnabled = true; + bool _modelSFEnabled = true; + bool _modelCustomScriptsEnabled = true; + bool _modelTelemetryEnabled = true; + + void build(); + void checkEvents() override; + void onEvent(event_t event) override; }; - -#endif // _MENU_MODEL_H_ diff --git a/radio/src/gui/colorlcd/menu_radio.cpp b/radio/src/gui/colorlcd/menu_radio.cpp index 2197da51a8a..96eca8c6d8b 100644 --- a/radio/src/gui/colorlcd/menu_radio.cpp +++ b/radio/src/gui/colorlcd/menu_radio.cpp @@ -19,29 +19,25 @@ * GNU General Public License for more details. */ -#include "opentx.h" #include "menu_radio.h" -#include "radio_setup.h" + +#include "menu_model.h" +#include "model_select.h" +#include "myeeprom.h" +#include "opentx.h" +#include "radio_calibration.h" +#include "radio_hardware.h" #include "radio_sdmanager.h" +#include "radio_setup.h" +#include "radio_theme.h" #include "radio_tools.h" -#include "special_functions.h" -#include "radio_calibration.h" #include "radio_trainer.h" #include "radio_version.h" -#include "radio_hardware.h" -#include "radio_theme.h" -#include "myeeprom.h" +#include "special_functions.h" -RadioMenu::RadioMenu(): - TabsGroup(ICON_RADIO) -{ - build(); -} +RadioMenu::RadioMenu() : TabsGroup(ICON_RADIO) { build(); } -RadioMenu::~RadioMenu() -{ - storageCheck(true); -} +RadioMenu::~RadioMenu() { storageCheck(true); } void RadioMenu::build() { @@ -52,12 +48,9 @@ void RadioMenu::build() addTab(new RadioToolsPage()); addTab(new RadioSdManagerPage()); addTab(new RadioSetupPage()); - if (_radioThemesEnabled) - addTab(new ThemeSetupPage()); - if (_radioGFEnabled) - addTab(new SpecialFunctionsPage(g_eeGeneral.customFn)); - if (_radioTrainerEnabled) - addTab(new RadioTrainerPage()); + if (_radioThemesEnabled) addTab(new ThemeSetupPage()); + if (_radioGFEnabled) addTab(new SpecialFunctionsPage(g_eeGeneral.customFn)); + if (_radioTrainerEnabled) addTab(new RadioTrainerPage()); addTab(new RadioHardwarePage()); addTab(new RadioVersionPage()); } @@ -76,3 +69,19 @@ void RadioMenu::checkEvents() setCurrentTab(2); } } + +void RadioMenu::onEvent(event_t event) +{ +#if defined(HARDWARE_KEYS) + if (event == EVT_KEY_BREAK(KEY_MODEL)) { + onCancel(); + new ModelMenu(); + } else if (event == EVT_KEY_LONG(KEY_MODEL)) { + onCancel(); + killEvents(KEY_MODEL); + new ModelLabelsWindow(); + } else { + TabsGroup::onEvent(event); + } +#endif +} diff --git a/radio/src/gui/colorlcd/menu_radio.h b/radio/src/gui/colorlcd/menu_radio.h index 578f18031bc..8ad8a1eeef7 100644 --- a/radio/src/gui/colorlcd/menu_radio.h +++ b/radio/src/gui/colorlcd/menu_radio.h @@ -19,23 +19,22 @@ * GNU General Public License for more details. */ -#ifndef _MENU_RADIO_H_ -#define _MENU_RADIO_H_ +#pragma once #include "tabsgroup.h" -class RadioMenu: public TabsGroup { - public: - RadioMenu(); - ~RadioMenu(); +class RadioMenu : public TabsGroup +{ + public: + RadioMenu(); + ~RadioMenu(); - protected: - bool _radioThemesEnabled = true; - bool _radioGFEnabled = true; - bool _radioTrainerEnabled = true; + protected: + bool _radioThemesEnabled = true; + bool _radioGFEnabled = true; + bool _radioTrainerEnabled = true; - void build(); - void checkEvents() override; + void build(); + void checkEvents() override; + void onEvent(event_t event) override; }; - -#endif // _MENU_RADIO_H_ diff --git a/radio/src/gui/colorlcd/model_select.cpp b/radio/src/gui/colorlcd/model_select.cpp index bad8f4166d9..35a17176839 100644 --- a/radio/src/gui/colorlcd/model_select.cpp +++ b/radio/src/gui/colorlcd/model_select.cpp @@ -27,6 +27,8 @@ #include "libopenui.h" #include "listbox.h" +#include "menu_model.h" +#include "menu_radio.h" #include "model_templates.h" #include "opentx.h" #include "standalone_lua.h" @@ -60,14 +62,13 @@ constexpr coord_t MODEL_SELECT_CELL_HEIGHT = 92; constexpr int BUTTONS_HEIGHT = 30; constexpr int MODEL_CELLS_PER_LINE = 2; -#if LCD_W > LCD_H // Landscape +#if LCD_W > LCD_H // Landscape constexpr int LABELS_WIDTH = 132; constexpr int LAY_MARGIN = 5; constexpr coord_t MODEL_SELECT_CELL_WIDTH = - (LCD_W - LABELS_WIDTH - - (MODEL_CELLS_PER_LINE + 1) * MODEL_CELL_PADDING) / + (LCD_W - LABELS_WIDTH - (MODEL_CELLS_PER_LINE + 1) * MODEL_CELL_PADDING) / MODEL_CELLS_PER_LINE; -#else // Portrait +#else // Portrait constexpr int LAY_MARGIN = 8; constexpr int LABELS_HEIGHT = 140; constexpr coord_t MODEL_SELECT_CELL_WIDTH = @@ -85,7 +86,8 @@ class ToolbarButton : public Button lv_obj_set_style_border_width(lvobj, lv_dpx(2), 0); lv_obj_set_style_border_opa(lvobj, LV_OPA_TRANSP, 0); - lv_obj_set_style_border_color(lvobj, makeLvColor(COLOR_THEME_FOCUS), LV_STATE_FOCUSED); + lv_obj_set_style_border_color(lvobj, makeLvColor(COLOR_THEME_FOCUS), + LV_STATE_FOCUSED); lv_obj_set_style_border_opa(lvobj, LV_OPA_100, LV_STATE_FOCUSED); } @@ -159,7 +161,7 @@ class ButtonHolder : public FormWindow btn->padAll(lv_dpx(4)); lv_obj_align(btn->getLvObj(), LV_ALIGN_RIGHT_MID, 0, 0); - switch(modelslabels.sortOrder()) { + switch (modelslabels.sortOrder()) { case NAME_ASC: _buttons[0].button->setSelected(true); break; @@ -187,8 +189,7 @@ class ButtonHolder : public FormWindow _pressHandler = std::move(pressHandler); } - inline void setNewLabelHandler( - std::function newLabelHandler) + inline void setNewLabelHandler(std::function newLabelHandler) { _newLabelHandler = std::move(newLabelHandler); } @@ -196,7 +197,7 @@ class ButtonHolder : public FormWindow void addButton(const uint8_t *state1Bm, const uint8_t *state2Bm) { int buttonNumber = _buttons.size(); - auto tb = new ToolbarButton ( + auto tb = new ToolbarButton( this, {buttonNumber * (height() + 4), 0, height(), height()}, state1Bm); tb->setPressHandler([=]() { bool isSelected = tb->getSelected(); @@ -240,7 +241,8 @@ class ButtonHolder : public FormWindow class ModelButton : public Button { public: - ModelButton(FormWindow *parent, const rect_t &rect, ModelCell *modelCell, std::function setSelected) : + ModelButton(FormWindow *parent, const rect_t &rect, ModelCell *modelCell, + std::function setSelected) : Button(parent, rect), modelCell(modelCell) { m_setSelected = std::move(setSelected); @@ -319,7 +321,8 @@ class ModelButton : public Button const char *modelFilename() { return modelCell->modelFilename; } ModelCell *getModelCell() const { return modelCell; } - void setFocused() { + void setFocused() + { if (!lv_obj_has_state(lvobj, LV_STATE_FOCUSED)) { lv_group_focus_obj(lvobj); } @@ -331,7 +334,8 @@ class ModelButton : public Button BitmapBuffer *buffer = nullptr; std::function m_setSelected = nullptr; - void onClicked() override { + void onClicked() override + { setFocused(); Button::onClicked(); } @@ -382,7 +386,8 @@ void ModelsPageBody::selectModel(ModelCell *model) while (!TELEMETRY_STREAMING()) { if (getTicks() - startTime > TELEMETRY_CHECK_DELAY10ms) break; } - return !TELEMETRY_STREAMING() || g_eeGeneral.disableRssiPoweroffAlarm; + return !TELEMETRY_STREAMING() || + g_eeGeneral.disableRssiPoweroffAlarm; })) { return; // stop if connected but not confirmed } @@ -476,7 +481,7 @@ void ModelsPageBody::saveAsTemplate(ModelCell *model) }); } -void ModelsPageBody::editLabels(ModelCell* model) +void ModelsPageBody::editLabels(ModelCell *model) { auto labels = modelslabels.getLabels(); @@ -512,12 +517,13 @@ void ModelsPageBody::openMenu() { Menu *menu = new Menu(this); menu->setTitle(focusedModel->modelName); - if (g_eeGeneral.modelQuickSelect || focusedModel != modelslist.getCurrentModel()) { + if (g_eeGeneral.modelQuickSelect || + focusedModel != modelslist.getCurrentModel()) { menu->addLine(STR_SELECT_MODEL, [=]() { selectModel(focusedModel); }); } menu->addLine(STR_DUPLICATE_MODEL, [=]() { duplicateModel(focusedModel); }); menu->addLine(STR_LABEL_MODEL, [=]() { editLabels(focusedModel); }); - menu->addLine(STR_SAVE_TEMPLATE, [=]() { saveAsTemplate(focusedModel);}); + menu->addLine(STR_SAVE_TEMPLATE, [=]() { saveAsTemplate(focusedModel); }); if (focusedModel != modelslist.getCurrentModel()) { menu->addLine(STR_DELETE_MODEL, [=]() { deleteModel(focusedModel); }); } @@ -539,20 +545,16 @@ void ModelsPageBody::update() // current active model // previously selected model // first model in the list - ModelButton* firstButton = nullptr; - ModelButton* focusedButton = nullptr; + ModelButton *firstButton = nullptr; + ModelButton *focusedButton = nullptr; for (auto &model : models) { - auto button = new ModelButton(this, rect_t{}, model, [=]() { - focusedModel = model; - }); + auto button = + new ModelButton(this, rect_t{}, model, [=]() { focusedModel = model; }); - if (!firstButton) - firstButton = button; - if (model == modelslist.getCurrentModel()) - focusedButton = button; - if (model == focusedModel && !focusedButton) - focusedButton = button; + if (!firstButton) firstButton = button; + if (model == modelslist.getCurrentModel()) focusedButton = button; + if (model == focusedModel && !focusedButton) focusedButton = button; // Press Handler for Models button->setPressHandler([=]() -> uint8_t { @@ -576,8 +578,7 @@ void ModelsPageBody::update() }); } - if (!focusedButton) - focusedButton = firstButton; + if (!focusedButton) focusedButton = firstButton; if (focusedButton) { focusedButton->setFocused(); @@ -612,21 +613,17 @@ class LabelDialog : public Dialog auto box_obj = box->getLvObj(); lv_obj_set_style_flex_main_place(box_obj, LV_FLEX_ALIGN_SPACE_EVENLY, 0); - auto btn = new TextButton( - box, rect_t{}, STR_SAVE, - [=]() { - if (saveHandler != nullptr) saveHandler(label); - deleteLater(); - return 0; - }); + auto btn = new TextButton(box, rect_t{}, STR_SAVE, [=]() { + if (saveHandler != nullptr) saveHandler(label); + deleteLater(); + return 0; + }); btn->setWidth(LV_DPI_DEF); - btn = new TextButton( - box, rect_t{}, STR_CANCEL, - [=]() { - deleteLater(); - return 0; - }); + btn = new TextButton(box, rect_t{}, STR_CANCEL, [=]() { + deleteLater(); + return 0; + }); btn->setWidth(LV_DPI_DEF); content->setWidth(LCD_W * 0.8); @@ -670,8 +667,7 @@ void ModelLabelsWindow::onEvent(event_t event) if (event == EVT_KEY_BREAK(KEY_PAGEUP) || event == EVT_KEY_BREAK(KEY_PAGEDN)) { #else - if (event == EVT_KEY_LONG(KEY_PAGEDN) || - event == EVT_KEY_BREAK(KEY_PAGEDN)) { + if (event == EVT_KEY_LONG(KEY_PAGEDN) || event == EVT_KEY_BREAK(KEY_PAGEDN)) { #endif std::set curSel = lblselector->getSelection(); std::set sellist; @@ -679,22 +675,31 @@ void ModelLabelsWindow::onEvent(event_t event) int rowcount = lblselector->getRowCount(); if (event == EVT_KEY_BREAK(KEY_PAGEDN)) { - if(curSel.size()) - select = (*curSel.rbegin() + 1) % rowcount; + if (curSel.size()) select = (*curSel.rbegin() + 1) % rowcount; } else { killEvents(event); - if(curSel.size()) { + if (curSel.size()) { select = (int)*curSel.begin() - 1; - if(select < 0) - select += rowcount; + if (select < 0) select += rowcount; } else { select = rowcount - 1; } } sellist.insert(select); - lblselector->setSelected(sellist); // Check the items - lblselector->setSelected(select); // Causes the list to scroll - updateFilteredLabels(sellist); // Update the models + lblselector->setSelected(sellist); // Check the items + lblselector->setSelected(select); // Causes the list to scroll + updateFilteredLabels(sellist); // Update the models + } else if (event == EVT_KEY_BREAK(KEY_MODEL)) { + onCancel(); + new ModelMenu(); + } else if (event == EVT_KEY_BREAK(KEY_SYS)) { + onCancel(); + new RadioMenu(); + } else if (event == EVT_KEY_LONG(KEY_SYS)) { + onCancel(); + killEvents(KEY_SYS); + // Radio setup + (new RadioMenu())->setCurrentTab(2); } else { Page::onEvent(event); } @@ -708,8 +713,8 @@ void ModelLabelsWindow::newModel() storageCheck(true); new SelectTemplateFolder([=](std::string folder, std::string name) { - // Create a new blank ModelCell and activate it first, createmodel() will modify - // the model in memory. + // Create a new blank ModelCell and activate it first, createmodel() will + // modify the model in memory. auto newCell = modelslist.addModel("", false); modelslist.setCurrentModel(newCell); @@ -721,9 +726,9 @@ void ModelLabelsWindow::newModel() if (w) w->onCancel(); // Check for not 'Blank Model' - if (name.size() > 0) - { - static constexpr size_t LEN_BUFFER = sizeof(TEMPLATES_PATH) + 2 * TEXT_FILENAME_MAXLEN + 1; + if (name.size() > 0) { + static constexpr size_t LEN_BUFFER = + sizeof(TEMPLATES_PATH) + 2 * TEXT_FILENAME_MAXLEN + 1; char path[LEN_BUFFER + 1]; snprintf(path, LEN_BUFFER, "%s/%s", TEMPLATES_PATH, folder.c_str()); @@ -739,7 +744,7 @@ void ModelLabelsWindow::newModel() #if defined(LUA) // If there is a wizard Lua script, fire it up int len = strlen(path); - snprintf(path+len, LEN_BUFFER-len, "/%s%s", name.c_str(), SCRIPT_EXT); + snprintf(path + len, LEN_BUFFER - len, "/%s%s", name.c_str(), SCRIPT_EXT); if (f_stat(path, 0) == FR_OK) { luaExec(path); StandaloneLuaWindow::instance()->attach(); @@ -784,11 +789,14 @@ void ModelLabelsWindow::buildHead(PageHeader *hdr) } #if LCD_W > LCD_H -static const lv_coord_t col_dsc[] = {LABELS_WIDTH, LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST}; -static const lv_coord_t row_dsc[] = {LV_GRID_FR(1), BUTTONS_HEIGHT, LV_GRID_TEMPLATE_LAST}; +static const lv_coord_t col_dsc[] = {LABELS_WIDTH, LV_GRID_FR(1), + LV_GRID_TEMPLATE_LAST}; +static const lv_coord_t row_dsc[] = {LV_GRID_FR(1), BUTTONS_HEIGHT, + LV_GRID_TEMPLATE_LAST}; #else static const lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST}; -static const lv_coord_t row_dsc[] = {LV_GRID_FR(1), LABELS_HEIGHT, BUTTONS_HEIGHT, LV_GRID_TEMPLATE_LAST}; +static const lv_coord_t row_dsc[] = {LV_GRID_FR(1), LABELS_HEIGHT, + BUTTONS_HEIGHT, LV_GRID_TEMPLATE_LAST}; #endif void ModelLabelsWindow::buildBody(FormWindow *window) @@ -817,39 +825,45 @@ void ModelLabelsWindow::buildBody(FormWindow *window) #if LCD_W > LCD_H // Labels top left - lv_obj_set_grid_cell(lbl_obj, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_STRETCH, 0, 1); + lv_obj_set_grid_cell(lbl_obj, LV_GRID_ALIGN_STRETCH, 0, 1, + LV_GRID_ALIGN_STRETCH, 0, 1); // Buttons bottom left - lv_obj_set_grid_cell(mdl_obj, LV_GRID_ALIGN_STRETCH, 1, 1, LV_GRID_ALIGN_STRETCH, 0, 2); + lv_obj_set_grid_cell(mdl_obj, LV_GRID_ALIGN_STRETCH, 1, 1, + LV_GRID_ALIGN_STRETCH, 0, 2); lv_obj_set_width(mdl_obj, lv_pct(100)); window->padRight(0); // Models right - lv_obj_set_grid_cell(buth_obj, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_STRETCH, 1, 1); + lv_obj_set_grid_cell(buth_obj, LV_GRID_ALIGN_STRETCH, 0, 1, + LV_GRID_ALIGN_STRETCH, 1, 1); #else // Models top - lv_obj_set_grid_cell(mdl_obj, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_STRETCH, 0, 1); + lv_obj_set_grid_cell(mdl_obj, LV_GRID_ALIGN_STRETCH, 0, 1, + LV_GRID_ALIGN_STRETCH, 0, 1); lv_obj_set_width(mdl_obj, lv_pct(100)); // Labels middle - lv_obj_set_grid_cell(lbl_obj, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_STRETCH, 1, 1); + lv_obj_set_grid_cell(lbl_obj, LV_GRID_ALIGN_STRETCH, 0, 1, + LV_GRID_ALIGN_STRETCH, 1, 1); // Buttons bottom - lv_obj_set_grid_cell(buth_obj, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_STRETCH, 2, 1); + lv_obj_set_grid_cell(buth_obj, LV_GRID_ALIGN_STRETCH, 0, 1, + LV_GRID_ALIGN_STRETCH, 2, 1); #endif lv_obj_update_layout(mdl_obj); lblselector->setColumnWidth(0, lv_obj_get_content_width(lbl_obj)); btnh->setPressHandler([=](int index, ButtonHolder::ButtonInfo *button) { - if (index == 0) { // alpha - sort = button->sortState == 0 ? NAME_ASC : NAME_DES; - } else { - sort = button->sortState == 0 ? DATE_ASC : DATE_DES; - } - // Update the list asynchronously - mdlselector->setSortOrder(sort); - }); + if (index == 0) { // alpha + sort = button->sortState == 0 ? NAME_ASC : NAME_DES; + } else { + sort = button->sortState == 0 ? DATE_ASC : DATE_DES; + } + // Update the list asynchronously + mdlselector->setSortOrder(sort); + }); lblselector->setMultiSelect(true); lblselector->setSelected(modelslabels.filteredLabels()); @@ -894,15 +908,15 @@ void ModelLabelsWindow::buildBody(FormWindow *window) strncpy(tmpLabel, oldLabel.c_str(), LABEL_LENGTH); tmpLabel[LABEL_LENGTH] = '\0'; new LabelDialog(this, tmpLabel, [=](std::string newLabel) { - if(newLabel.size() > 0) { + if (newLabel.size() > 0) { auto rndialog = new ProgressDialog(this, STR_RENAME_LABEL, [=]() {}); modelslabels.renameLabel( oldLabel, newLabel, [=](const char *name, int percentage) { - rndialog->setTitle(std::string(STR_RENAME_LABEL) + " " + name); + rndialog->setTitle(std::string(STR_RENAME_LABEL) + " " + + name); rndialog->updateProgress(percentage); - if (percentage >= 100) - rndialog->closeDialog(); + if (percentage >= 100) rndialog->closeDialog(); }); auto labels = getLabels(); lblselector->setNames(labels); @@ -919,10 +933,10 @@ void ModelLabelsWindow::buildBody(FormWindow *window) new ProgressDialog(this, STR_DELETE_LABEL, [=]() {}); modelslabels.removeLabel( labelToDelete, [=](const char *name, int percentage) { - deldialog->setTitle(std::string(STR_RENAME_LABEL) + " " + name); + deldialog->setTitle(std::string(STR_RENAME_LABEL) + " " + + name); deldialog->updateProgress(percentage); - if (percentage >= 100) - deldialog->closeDialog(); + if (percentage >= 100) deldialog->closeDialog(); }); auto labels = getLabels(); std::set newset; diff --git a/radio/src/gui/colorlcd/model_select.h b/radio/src/gui/colorlcd/model_select.h index 8702c5dcdd9..23d60301855 100644 --- a/radio/src/gui/colorlcd/model_select.h +++ b/radio/src/gui/colorlcd/model_select.h @@ -66,10 +66,10 @@ class ModelsPageBody : public FormWindow std::function refreshLabels = nullptr; void openMenu(); - void selectModel(ModelCell* model); - void duplicateModel(ModelCell* model); - void deleteModel(ModelCell* model); - void editLabels(ModelCell* model); + void selectModel(ModelCell *model); + void duplicateModel(ModelCell *model); + void deleteModel(ModelCell *model); + void editLabels(ModelCell *model); void saveAsTemplate(ModelCell *model); }; diff --git a/radio/src/gui/colorlcd/tabsgroup.cpp b/radio/src/gui/colorlcd/tabsgroup.cpp index 4e87c61a5a4..0163e5efc33 100644 --- a/radio/src/gui/colorlcd/tabsgroup.cpp +++ b/radio/src/gui/colorlcd/tabsgroup.cpp @@ -22,18 +22,18 @@ #include "tabsgroup.h" #include "mainwindow.h" -#include "view_main.h" #include "static.h" #include "theme.h" +#include "view_main.h" #if defined(HARDWARE_TOUCH) #include "keyboard_base.h" #endif -#include "opentx.h" // TODO for constants... - #include +#include "opentx.h" // TODO for constants... + TabCarouselButton::TabCarouselButton(Window* parent, const rect_t& rect, std::vector& tabs, uint8_t index, std::function pressHandler, @@ -44,7 +44,7 @@ TabCarouselButton::TabCarouselButton(Window* parent, const rect_t& rect, { } -void TabCarouselButton::paint(BitmapBuffer * dc) +void TabCarouselButton::paint(BitmapBuffer* dc) { EdgeTxTheme::instance()->drawMenuIcon(dc, tabs[index]->getIcon(), checked()); } @@ -52,7 +52,7 @@ void TabCarouselButton::paint(BitmapBuffer * dc) void TabCarouselButton::check(bool checked) { Button::check(checked); - if(checked) { + if (checked) { lv_obj_move_foreground(lvobj); } } @@ -67,8 +67,7 @@ TabsGroupHeader::TabsGroupHeader(TabsGroup* parent, uint8_t icon) : parent->deleteLater(); return 1; }, - NO_FOCUS, - 0, window_create), + NO_FOCUS, 0, window_create), #endif icon(icon), carousel(this, parent) @@ -83,36 +82,36 @@ void TabsGroupHeader::paint(BitmapBuffer* dc) TabsCarousel::TabsCarousel(Window* parent, TabsGroup* menu) : Window(parent, - {MENU_HEADER_BUTTONS_LEFT, 0, DATETIME_SEPARATOR_X - MENU_HEADER_BUTTONS_LEFT, + {MENU_HEADER_BUTTONS_LEFT, 0, + DATETIME_SEPARATOR_X - MENU_HEADER_BUTTONS_LEFT, MENU_HEADER_HEIGHT + 10}, - NO_FOCUS | TRANSPARENT ), + NO_FOCUS | TRANSPARENT), menu(menu) { } void TabsCarousel::update() { - while(buttons.size() < menu->tabs.size()) - { + while (buttons.size() < menu->tabs.size()) { int index = buttons.size(); - rect_t btnCoords = {(int)(index * (MENU_HEADER_BUTTON_WIDTH + 1)), 0, (int)(MENU_HEADER_BUTTON_WIDTH + 3), int(MENU_TITLE_TOP + 5)}; - buttons.emplace_back(new TabCarouselButton(this, btnCoords, menu->tabs, index, - [&, index](){ - menu->setCurrentTab(index); - setCurrentIndex(index); - - for(auto &b: buttons) - b->check(false); - - buttons[index]->check(true); - return true; - } - , TRANSPARENT | NO_FOCUS)); - if(index == 0) - buttons[index]->check(true); + rect_t btnCoords = {(int)(index * (MENU_HEADER_BUTTON_WIDTH + 1)), 0, + (int)(MENU_HEADER_BUTTON_WIDTH + 3), + int(MENU_TITLE_TOP + 5)}; + buttons.emplace_back(new TabCarouselButton( + this, btnCoords, menu->tabs, index, + [&, index]() { + menu->setCurrentTab(index); + setCurrentIndex(index); + + for (auto& b : buttons) b->check(false); + + buttons[index]->check(true); + return true; + }, + TRANSPARENT | NO_FOCUS)); + if (index == 0) buttons[index]->check(true); } - while(buttons.size() > menu->tabs.size()) - { + while (buttons.size() > menu->tabs.size()) { buttons.back()->deleteLater(); buttons.pop_back(); } @@ -120,28 +119,25 @@ void TabsCarousel::update() void TabsCarousel::setCurrentIndex(uint8_t index) { - if(buttons.size() <= index) - return; + if (buttons.size() <= index) return; buttons[currentIndex]->check(false); currentIndex = index; buttons[currentIndex]->check(true); } -void TabsCarousel::paint(BitmapBuffer * dc) -{ -} +void TabsCarousel::paint(BitmapBuffer* dc) {} static constexpr rect_t _get_body_rect() { - return { 0, MENU_BODY_TOP, LCD_W, MENU_BODY_HEIGHT }; + return {0, MENU_BODY_TOP, LCD_W, MENU_BODY_HEIGHT}; } TabsGroup* TabsGroup::activeTabsGroup = nullptr; -TabsGroup::TabsGroup(uint8_t icon): - Window(Layer::back(), { 0, 0, LCD_W, LCD_H }, OPAQUE), - header(this, icon), - body(this, _get_body_rect(), NO_FOCUS) +TabsGroup::TabsGroup(uint8_t icon) : + Window(Layer::back(), {0, 0, LCD_W, LCD_H}, OPAQUE), + header(this, icon), + body(this, _get_body_rect(), NO_FOCUS) { Layer::push(this); @@ -153,10 +149,9 @@ TabsGroup::TabsGroup(uint8_t icon): TabsGroup::~TabsGroup() { - if (activeTabsGroup == this) - activeTabsGroup = nullptr; + if (activeTabsGroup == this) activeTabsGroup = nullptr; - for (auto tab: tabs) { + for (auto tab : tabs) { delete tab; } } @@ -164,13 +159,13 @@ TabsGroup::~TabsGroup() void TabsGroup::refreshTheme() { if (activeTabsGroup) - lv_obj_set_style_bg_color(activeTabsGroup->getLvObj(), makeLvColor(COLOR_THEME_SECONDARY3), 0); + lv_obj_set_style_bg_color(activeTabsGroup->getLvObj(), + makeLvColor(COLOR_THEME_SECONDARY3), 0); } void TabsGroup::deleteLater(bool detach, bool trash) { - if (_deleted) - return; + if (_deleted) return; Layer::pop(this); @@ -180,7 +175,7 @@ void TabsGroup::deleteLater(bool detach, bool trash) Window::deleteLater(detach, trash); } -void TabsGroup::addTab(PageTab * page) +void TabsGroup::addTab(PageTab* page) { tabs.push_back(page); if (!currentTab) { @@ -190,7 +185,7 @@ void TabsGroup::addTab(PageTab * page) invalidate(); } -int TabsGroup::removeTab(PageTab * page) +int TabsGroup::removeTab(PageTab* page) { auto tabIter = std::find(tabs.begin(), tabs.end(), page); if (tabIter != tabs.end()) { @@ -214,7 +209,7 @@ void TabsGroup::removeTab(unsigned index) void TabsGroup::removeAllTabs() { - for (auto * tab: tabs) { + for (auto* tab : tabs) { delete tab; } tabs.clear(); @@ -272,7 +267,8 @@ void TabsGroup::checkEvents() void TabsGroup::onEvent(event_t event) { #if defined(HARDWARE_KEYS) - TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString().c_str(), event); + TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString().c_str(), + event); #if defined(KEYS_GPIO_REG_PAGEUP) if (event == EVT_KEY_FIRST(KEY_PAGEDN)) { @@ -295,15 +291,9 @@ void TabsGroup::onEvent(event_t event) #endif } -void TabsGroup::onClicked() -{ - Keyboard::hide(); -} +void TabsGroup::onClicked() { Keyboard::hide(); } -void TabsGroup::onCancel() -{ - deleteLater(); -} +void TabsGroup::onCancel() { deleteLater(); } #if defined(HARDWARE_TOUCH) bool TabsGroup::onTouchEnd(coord_t x, coord_t y) diff --git a/radio/src/gui/colorlcd/view_channels.cpp b/radio/src/gui/colorlcd/view_channels.cpp index dfccd935596..c3d90593afe 100644 --- a/radio/src/gui/colorlcd/view_channels.cpp +++ b/radio/src/gui/colorlcd/view_channels.cpp @@ -19,16 +19,20 @@ * GNU General Public License for more details. */ -#include "opentx.h" -#include "libopenui.h" #include "view_channels.h" + #include "channel_bar.h" +#include "libopenui.h" +#include "menu_model.h" +#include "menu_radio.h" +#include "model_select.h" +#include "opentx.h" #include "view_logical_switches.h" constexpr coord_t CHANNEL_VIEW_FOOTER_HEIGHT = 16; -ChannelsViewMenu::ChannelsViewMenu(): - TabsGroup(ICON_MONITOR) +ChannelsViewMenu::ChannelsViewMenu(ModelMenu* parent) : + TabsGroup(ICON_MONITOR), parentMenu(parent) { addTab(new ChannelsViewPage(0)); addTab(new ChannelsViewPage(1)); @@ -37,33 +41,70 @@ ChannelsViewMenu::ChannelsViewMenu(): addTab(new LogicalSwitchesViewPage()); } -class ChannelsViewFooter: public Window { - public: - explicit ChannelsViewFooter(Window * parent): - Window(parent, {0, parent->height() - MODEL_SELECT_FOOTER_HEIGHT, LCD_W, MODEL_SELECT_FOOTER_HEIGHT}, OPAQUE) - { +void ChannelsViewMenu::onEvent(event_t event) +{ +#if defined(HARDWARE_KEYS) + if (event == EVT_KEY_BREAK(KEY_MODEL)) { + killEvents(event); + onCancel(); + if (!parentMenu) { + new ModelMenu(); } + } else if (event == EVT_KEY_LONG(KEY_MODEL)) { + killEvents(KEY_MODEL); + onCancel(); + if (parentMenu) parentMenu->onCancel(); + new ModelLabelsWindow(); + } else if (event == EVT_KEY_BREAK(KEY_SYS)) { + onCancel(); + if (parentMenu) parentMenu->onCancel(); + new RadioMenu(); + } else if (event == EVT_KEY_LONG(KEY_SYS)) { + killEvents(KEY_SYS); + onCancel(); + if (parentMenu) parentMenu->onCancel(); + // Radio setup + (new RadioMenu())->setCurrentTab(2); + } else { + TabsGroup::onEvent(event); + } +#endif +} - // Draw single legend - coord_t drawChannelsMonitorLegend(BitmapBuffer * dc, coord_t x, const char * s, int color) - { - dc->drawSolidFilledRect(x, 4, LEG_COLORBOX + 2, LEG_COLORBOX + 2, COLOR_THEME_SECONDARY3); - dc->drawSolidFilledRect(x + 1, 5, LEG_COLORBOX, LEG_COLORBOX, color); - dc->drawText(x + 20, 4, s, COLOR_THEME_PRIMARY2); - return x + 25 + getTextWidth(s); - } +class ChannelsViewFooter : public Window +{ + public: + explicit ChannelsViewFooter(Window* parent) : + Window(parent, + {0, parent->height() - MODEL_SELECT_FOOTER_HEIGHT, LCD_W, + MODEL_SELECT_FOOTER_HEIGHT}, + OPAQUE) + { + } - void paint(BitmapBuffer * dc) override - { - // Draw legend bar - coord_t x = 10; - dc->drawSolidFilledRect(0, 0, width(), height(), COLOR_THEME_SECONDARY1); - x = drawChannelsMonitorLegend(dc, MENUS_MARGIN_LEFT, STR_MONITOR_OUTPUT_DESC, COLOR_THEME_ACTIVE); - drawChannelsMonitorLegend(dc, x, STR_MONITOR_MIXER_DESC, COLOR_THEME_FOCUS); - } + // Draw single legend + coord_t drawChannelsMonitorLegend(BitmapBuffer* dc, coord_t x, const char* s, + int color) + { + dc->drawSolidFilledRect(x, 4, LEG_COLORBOX + 2, LEG_COLORBOX + 2, + COLOR_THEME_SECONDARY3); + dc->drawSolidFilledRect(x + 1, 5, LEG_COLORBOX, LEG_COLORBOX, color); + dc->drawText(x + 20, 4, s, COLOR_THEME_PRIMARY2); + return x + 25 + getTextWidth(s); + } + + void paint(BitmapBuffer* dc) override + { + // Draw legend bar + coord_t x = 10; + dc->drawSolidFilledRect(0, 0, width(), height(), COLOR_THEME_SECONDARY1); + x = drawChannelsMonitorLegend(dc, MENUS_MARGIN_LEFT, + STR_MONITOR_OUTPUT_DESC, COLOR_THEME_ACTIVE); + drawChannelsMonitorLegend(dc, x, STR_MONITOR_MIXER_DESC, COLOR_THEME_FOCUS); + } }; -void ChannelsViewPage::build(FormWindow * window) +void ChannelsViewPage::build(FormWindow* window) { constexpr coord_t hmargin = 5; window->padAll(0); @@ -73,11 +114,13 @@ void ChannelsViewPage::build(FormWindow * window) #if LCD_H > LCD_W coord_t width = window->width() - (hmargin * 2); coord_t xPos = hmargin; - coord_t yPos = (chan % 8) * ((window->height() - CHANNEL_VIEW_FOOTER_HEIGHT - 8) / 8); + coord_t yPos = + (chan % 8) * ((window->height() - CHANNEL_VIEW_FOOTER_HEIGHT - 8) / 8); #else coord_t width = window->width() / 2 - (hmargin * 2); coord_t xPos = (chan % 8) >= 4 ? width + (hmargin * 2) : hmargin; - coord_t yPos = (chan % 4) * ((window->height() - CHANNEL_VIEW_FOOTER_HEIGHT - 4) / 4); + coord_t yPos = + (chan % 4) * ((window->height() - CHANNEL_VIEW_FOOTER_HEIGHT - 4) / 4); #endif new ComboChannelBar(window, {xPos, yPos, width, 3 * BAR_HEIGHT + 3}, chan); } diff --git a/radio/src/gui/colorlcd/view_channels.h b/radio/src/gui/colorlcd/view_channels.h index 8b119b4f95c..68d988f981a 100644 --- a/radio/src/gui/colorlcd/view_channels.h +++ b/radio/src/gui/colorlcd/view_channels.h @@ -24,6 +24,8 @@ #include "opentx.h" #include "tabsgroup.h" +class ModelMenu; + class ChannelsViewPage: public PageTab { public: @@ -40,5 +42,10 @@ class ChannelsViewPage: public PageTab class ChannelsViewMenu: public TabsGroup { public: - ChannelsViewMenu(); + ChannelsViewMenu(ModelMenu* parent = nullptr); + + protected: + ModelMenu* parentMenu = nullptr; + + void onEvent(event_t event) override; }; diff --git a/radio/src/gui/colorlcd/view_main.cpp b/radio/src/gui/colorlcd/view_main.cpp index 8c4bc52d827..7a7d474d613 100644 --- a/radio/src/gui/colorlcd/view_main.cpp +++ b/radio/src/gui/colorlcd/view_main.cpp @@ -267,12 +267,10 @@ void ViewMain::onEvent(event_t event) break; case EVT_KEY_LONG(KEY_SYS): - { - killEvents(KEY_SYS); - // Radio setup - auto m = new RadioMenu(); - m->setCurrentTab(2); - } + killEvents(KEY_SYS); + if (viewMainMenu) viewMainMenu->onCancel(); + // Radio setup + (new RadioMenu())->setCurrentTab(2); break; case EVT_KEY_FIRST(KEY_TELE):