diff --git a/radio/src/gui/colorlcd/controls/switch_warn_dialog.cpp b/radio/src/gui/colorlcd/controls/switch_warn_dialog.cpp index d5d3e48c9..1dd3eb313 100644 --- a/radio/src/gui/colorlcd/controls/switch_warn_dialog.cpp +++ b/radio/src/gui/colorlcd/controls/switch_warn_dialog.cpp @@ -34,6 +34,7 @@ SwitchWarnDialog::SwitchWarnDialog() : void SwitchWarnDialog::delayedInit() { + FullScreenDialog::delayedInit(); lv_label_set_long_mode(messageLabel->getLvObj(), LV_LABEL_LONG_WRAP); AUDIO_ERROR_MESSAGE(AU_SWITCH_ALERT); } @@ -103,6 +104,7 @@ ThrottleWarnDialog::ThrottleWarnDialog(const char* msg) : void ThrottleWarnDialog::delayedInit() { + FullScreenDialog::delayedInit(); lv_label_set_long_mode(messageLabel->getLvObj(), LV_LABEL_LONG_WRAP); AUDIO_ERROR_MESSAGE(AU_THROTTLE_ALERT); } diff --git a/radio/src/gui/colorlcd/controls/switch_warn_dialog.h b/radio/src/gui/colorlcd/controls/switch_warn_dialog.h index c948dddb1..2d862fd78 100644 --- a/radio/src/gui/colorlcd/controls/switch_warn_dialog.h +++ b/radio/src/gui/colorlcd/controls/switch_warn_dialog.h @@ -39,7 +39,7 @@ class SwitchWarnDialog : public FullScreenDialog uint16_t last_bad_pots; bool warningInactive(); - + void delayedInit() override; void checkEvents() override; @@ -56,6 +56,6 @@ class ThrottleWarnDialog : public FullScreenDialog protected: bool warningInactive(); - + void delayedInit() override; }; diff --git a/radio/src/gui/colorlcd/libui/fullscreen_dialog.cpp b/radio/src/gui/colorlcd/libui/fullscreen_dialog.cpp index a332b760b..0b1554ba8 100644 --- a/radio/src/gui/colorlcd/libui/fullscreen_dialog.cpp +++ b/radio/src/gui/colorlcd/libui/fullscreen_dialog.cpp @@ -49,11 +49,14 @@ FullScreenDialog::FullScreenDialog( bringToTop(); - build(); - delayLoad(); } +void FullScreenDialog::delayedInit() +{ + build(); +} + void FullScreenDialog::build() { auto div = new Window(this, {0, ALERT_FRAME_TOP, LCD_W, ALERT_FRAME_HEIGHT}); diff --git a/radio/src/gui/colorlcd/libui/fullscreen_dialog.h b/radio/src/gui/colorlcd/libui/fullscreen_dialog.h index ea1317872..ed7063c9a 100644 --- a/radio/src/gui/colorlcd/libui/fullscreen_dialog.h +++ b/radio/src/gui/colorlcd/libui/fullscreen_dialog.h @@ -27,63 +27,65 @@ class StaticText; class FullScreenDialog : public Window { - public: - FullScreenDialog(uint8_t type, std::string title, std::string message = "", - std::string action = "", - const std::function& confirmHandler = nullptr); + public: + FullScreenDialog(uint8_t type, std::string title, std::string message = "", + std::string action = "", + const std::function& confirmHandler = nullptr); #if defined(DEBUG_WINDOWS) - std::string getName() const override - { - return "FullScreenDialog"; - } + std::string getName() const override + { + return "FullScreenDialog"; + } #endif - void setMessage(std::string text); + void setMessage(std::string text); - void onEvent(event_t event) override; - void onCancel() override; - bool onLongPress() override; + void onEvent(event_t event) override; + void onCancel() override; + bool onLongPress() override; - void deleteLater(bool detach = true, bool trash = true) override; + void deleteLater(bool detach = true, bool trash = true) override; - void checkEvents() override; + void checkEvents() override; - void setCloseCondition(std::function handler) - { - closeCondition = std::move(handler); - } + void setCloseCondition(std::function handler) + { + closeCondition = std::move(handler); + } - void runForever(bool checkPwr = true); + void runForever(bool checkPwr = true); - void closeDialog(); + void closeDialog(); - static LAYOUT_SIZE_SCALED(ALERT_FRAME_TOP, 50, 70) - static LAYOUT_SIZE(ALERT_FRAME_HO, LAYOUT_SCALE(120), 2 * ALERT_FRAME_TOP) - static constexpr coord_t ALERT_FRAME_HEIGHT = LCD_H - ALERT_FRAME_HO; - static LAYOUT_SIZE_SCALED(ALERT_BMO, 25, 15) - static constexpr coord_t ALERT_BITMAP_TOP = ALERT_FRAME_TOP + ALERT_BMO; - static LAYOUT_SIZE_SCALED(ALERT_BITMAP_LEFT, 20, 15) - static LAYOUT_SIZE_SCALED(ALERT_TO, 5, 10) - static constexpr coord_t ALERT_TITLE_TOP = ALERT_FRAME_TOP + ALERT_TO; - static LAYOUT_SIZE_SCALED(ALERT_TITLE_LEFT, 146, 140) - static LAYOUT_SIZE_SCALED(ALERT_MO, 85, 130) - static constexpr coord_t ALERT_MESSAGE_TOP = ALERT_TITLE_TOP + ALERT_MO; - static LAYOUT_SIZE_SCALED(ALERT_MESSAGE_LEFT, 146, 15) - static LAYOUT_VAL_SCALED(ONEBTN_W, 280) - static LAYOUT_VAL_SCALED(ONEBTN_H, 40) - static LAYOUT_VAL_SCALED(TWOBTN_W, 100) - static LAYOUT_VAL_SCALED(TWOBTN_H, 40) + static LAYOUT_SIZE_SCALED(ALERT_FRAME_TOP, 50, 70) + static LAYOUT_SIZE(ALERT_FRAME_HO, LAYOUT_SCALE(120), 2 * ALERT_FRAME_TOP) + static constexpr coord_t ALERT_FRAME_HEIGHT = LCD_H - ALERT_FRAME_HO; + static LAYOUT_SIZE_SCALED(ALERT_BMO, 25, 15) + static constexpr coord_t ALERT_BITMAP_TOP = ALERT_FRAME_TOP + ALERT_BMO; + static LAYOUT_SIZE_SCALED(ALERT_BITMAP_LEFT, 20, 15) + static LAYOUT_SIZE_SCALED(ALERT_TO, 5, 10) + static constexpr coord_t ALERT_TITLE_TOP = ALERT_FRAME_TOP + ALERT_TO; + static LAYOUT_SIZE_SCALED(ALERT_TITLE_LEFT, 146, 140) + static LAYOUT_SIZE_SCALED(ALERT_MO, 85, 130) + static constexpr coord_t ALERT_MESSAGE_TOP = ALERT_TITLE_TOP + ALERT_MO; + static LAYOUT_SIZE_SCALED(ALERT_MESSAGE_LEFT, 146, 15) + static LAYOUT_VAL_SCALED(ONEBTN_W, 280) + static LAYOUT_VAL_SCALED(ONEBTN_H, 40) + static LAYOUT_VAL_SCALED(TWOBTN_W, 100) + static LAYOUT_VAL_SCALED(TWOBTN_H, 40) - protected: - uint8_t type; - std::string title; - std::string message; - std::string action; - bool running = false; - std::function closeCondition; - std::function confirmHandler; - StaticText* messageLabel; + protected: + uint8_t type; + std::string title; + std::string message; + std::string action; + bool running = false; + std::function closeCondition; + std::function confirmHandler; + StaticText* messageLabel; - void build(); + void build(); + + void delayedInit() override; }; diff --git a/radio/src/gui/colorlcd/libui/view_text.cpp b/radio/src/gui/colorlcd/libui/view_text.cpp index 9a1544a3b..f1ac932e7 100644 --- a/radio/src/gui/colorlcd/libui/view_text.cpp +++ b/radio/src/gui/colorlcd/libui/view_text.cpp @@ -27,7 +27,7 @@ #include "fullscreen_dialog.h" #include "lib_file.h" -// Used on startup to block until checlist is closed. +// Used on startup to block until checklist is closed. static bool checkListOpen = false; // Check Box @@ -67,198 +67,236 @@ static lv_obj_t* checkbox_create(lv_obj_t* parent) constexpr int maxTxtBuffSize = 64 * 1024; +class TextViewer +{ + public: + TextViewer(const std::string path, const std::string name) : name(std::move(name)) + { + fullPath = path + std::string(PATH_SEPARATOR) + name; + extractNameSansExt(); + } + + ~TextViewer() + { + if (buffer) { + free(buffer); + buffer = nullptr; + } + } + + void onEvent(event_t event) + { + #if defined(HARDWARE_KEYS) + if (int(bufSize) < fileLength) { + if (event == EVT_KEY_BREAK(KEY_PAGEDN)) { + offset += bufSize; + } + + if (event == EVT_KEY_BREAK(KEY_PAGEUP)) { + offset -= bufSize; + } + + offset = std::max(offset, 0); + offset = std::min(offset, fileLength - (int)bufSize); + + sdReadTextFileBlock(bufSize, offset); + lv_label_set_text_static(lb, buffer); + } + #endif + } + + void build(Window* window) + { + if (openFile()) { + auto obj = window->getLvObj(); + lv_obj_add_flag( + obj, LV_OBJ_FLAG_SCROLLABLE | LV_OBJ_FLAG_SCROLL_WITH_ARROW | + LV_OBJ_FLAG_SCROLL_MOMENTUM | LV_OBJ_FLAG_CLICK_FOCUSABLE); + etx_scrollbar(obj); + // prevents resetting the group's edit mode + lv_obj_clear_flag(obj, LV_OBJ_FLAG_CLICK_FOCUSABLE); + + auto g = lv_group_get_default(); + lb = lv_label_create(obj); + lv_obj_set_size(lb, lv_pct(100), LV_SIZE_CONTENT); + etx_obj_add_style(lb, styles->pad_medium, LV_PART_MAIN); + + lv_group_add_obj(g, obj); + lv_group_set_editing(g, true); + lv_label_set_text_static(lb, buffer); + + if (openFromEnd) + lv_obj_scroll_to_y(obj, LV_COORD_MAX, LV_ANIM_OFF); + else + lv_obj_scroll_to_y(obj, 0, LV_ANIM_OFF); + } + } + + protected: + std::string name; + std::string fullPath; + + lv_obj_t* lb; + + int offset = 0; + char* buffer = nullptr; + size_t bufSize = 0; + int fileLength = 0; + bool openFromEnd; + + void extractNameSansExt() + { + uint8_t nameLength; + uint8_t extLength; + + const char* ext = + getFileExtension(name.c_str(), 0, 0, &nameLength, &extLength); + + openFromEnd = !strcmp(ext, LOGS_EXT); + } + + bool openFile() + { + FILINFO info; + + if (buffer) { + free(buffer); + buffer = nullptr; + bufSize = 0; + } + + auto res = f_stat((TCHAR*)fullPath.c_str(), &info); + if (res == FR_OK) { + fileLength = int(info.fsize); + bufSize = std::min(fileLength, maxTxtBuffSize) + 1; + + buffer = (char*)malloc(bufSize); + if (buffer) { + offset = std::max(int(openFromEnd ? int(info.fsize) - bufSize + 1 : 0), 0); + if (sdReadTextFileBlock(bufSize, offset) == FR_OK) { + return true; + } + } + } + + return false; + } + + FRESULT sdReadTextFileBlock(const uint32_t bufSize, const uint32_t offset) + { + FIL file; + char escape_chars[4]; + int escape = 0; + + auto res = + f_open(&file, (TCHAR*)fullPath.c_str(), FA_OPEN_EXISTING | FA_READ); + if (res == FR_OK) { + res = f_lseek(&file, offset); + if (res == FR_OK) { + UINT br; + char c; + char* ptr = buffer; + for (int i = 0; i < (int)bufSize; i++) { + res = f_read(&file, &c, 1, &br); + if (res == FR_OK && br == 1) { + if (c == '\\' && escape == 0) { + escape = 1; + continue; + } else if (c != '\\' && escape > 0 && + escape < (int)sizeof(escape_chars)) { + escape_chars[escape - 1] = c; + + if (escape == 2 && !strncmp(escape_chars, "up", 2)) { + *ptr++ = STR_CHAR_UP[0]; + c = STR_CHAR_UP[1]; + escape = 0; + } else if (escape == 2 && !strncmp(escape_chars, "dn", 2)) { + *ptr++ = STR_CHAR_DOWN[0]; + c = STR_CHAR_DOWN[1]; + escape = 0; + } else if (escape == 3) { + int val = atoi(escape_chars); + if (val >= 200 && val < 225) { + *ptr++ = '\302'; + c = '\200' + val - 200; + } + } else if (escape == 1 && c == '~') { + c = 'z' + 1; + } else { + escape++; + continue; + } + } else if (c == '\t') { + c = 0x1D; // tab + } + escape = 0; + + if (c == 0xA && *(ptr - 1) == 0xD) { + *(ptr - 1) = '\n'; + continue; + } + *ptr++ = c; + } + } + *ptr = '\0'; + } + f_close(&file); + } + return res; + } +}; + ViewTextWindow::ViewTextWindow(const std::string path, const std::string name, EdgeTxIcon icon) : - Page(icon, PAD_ZERO), path(std::move(path)), name(std::move(name)) + Page(icon, PAD_ZERO) { - fullPath = this->path + std::string(PATH_SEPARATOR) + this->name; - extractNameSansExt(); + textViewer = new TextViewer(path, name); - header->setTitle(this->name); + header->setTitle(name); delayLoad(); }; void ViewTextWindow::delayedInit() { - if (buffer == nullptr) buildBody(body); + textViewer->build(body); } void ViewTextWindow::onCancel() { + if (textViewer) delete textViewer; Page::onCancel(); checkListOpen = false; } -void ViewTextWindow::extractNameSansExt() -{ - uint8_t nameLength; - uint8_t extLength; - - const char* ext = - getFileExtension(name.c_str(), 0, 0, &nameLength, &extLength); - extension = std::string(ext); - - openFromEnd = !strcmp(ext, LOGS_EXT); -} - -bool ViewTextWindow::openFile() -{ - FILINFO info; - - if (buffer) { - free(buffer); - buffer = nullptr; - bufSize = 0; - } - - auto res = f_stat((TCHAR*)fullPath.c_str(), &info); - if (res == FR_OK) { - fileLength = int(info.fsize); - bufSize = std::min(fileLength, maxTxtBuffSize) + 1; - - buffer = (char*)malloc(bufSize); - if (buffer) { - offset = - std::max(int(openFromEnd ? int(info.fsize) - bufSize + 1 : 0), 0); - TRACE("info.fsize=%d\tbufSize=%d\toffset=%d", info.fsize, bufSize, - int(info.fsize) - bufSize + 1); - if (sdReadTextFileBlock(bufSize, offset) == FR_OK) { - return true; - } - } - } - - return false; -} - -void ViewTextWindow::buildBody(Window* window) -{ - if (openFile()) { - auto obj = window->getLvObj(); - lv_obj_add_flag( - obj, LV_OBJ_FLAG_SCROLLABLE | LV_OBJ_FLAG_SCROLL_WITH_ARROW | - LV_OBJ_FLAG_SCROLL_MOMENTUM | LV_OBJ_FLAG_CLICK_FOCUSABLE); - etx_scrollbar(obj); - // prevents resetting the group's edit mode - lv_obj_clear_flag(obj, LV_OBJ_FLAG_CLICK_FOCUSABLE); - - auto g = lv_group_get_default(); - lb = lv_label_create(obj); - lv_obj_set_size(lb, lv_pct(100), LV_SIZE_CONTENT); - etx_obj_add_style(lb, styles->pad_medium, LV_PART_MAIN); - - lv_group_add_obj(g, obj); - lv_group_set_editing(g, true); - lv_label_set_text_static(lb, buffer); - - if (openFromEnd) - lv_obj_scroll_to_y(obj, LV_COORD_MAX, LV_ANIM_OFF); - else - lv_obj_scroll_to_y(obj, 0, LV_ANIM_OFF); - } -} - -FRESULT ViewTextWindow::sdReadTextFileBlock(const uint32_t bufSize, - const uint32_t offset) -{ - FIL file; - char escape_chars[4]; - int escape = 0; - - auto res = - f_open(&file, (TCHAR*)fullPath.c_str(), FA_OPEN_EXISTING | FA_READ); - if (res == FR_OK) { - res = f_lseek(&file, offset); - if (res == FR_OK) { - UINT br; - char c; - char* ptr = buffer; - for (int i = 0; i < (int)bufSize; i++) { - res = f_read(&file, &c, 1, &br); - if (res == FR_OK && br == 1) { - if (c == '\\' && escape == 0) { - escape = 1; - continue; - } else if (c != '\\' && escape > 0 && - escape < (int)sizeof(escape_chars)) { - escape_chars[escape - 1] = c; - - if (escape == 2 && !strncmp(escape_chars, "up", 2)) { - *ptr++ = STR_CHAR_UP[0]; - c = STR_CHAR_UP[1]; - escape = 0; - } else if (escape == 2 && !strncmp(escape_chars, "dn", 2)) { - *ptr++ = STR_CHAR_DOWN[0]; - c = STR_CHAR_DOWN[1]; - escape = 0; - } else if (escape == 3) { - int val = atoi(escape_chars); - if (val >= 200 && val < 225) { - *ptr++ = '\302'; - c = '\200' + val - 200; - } - } else if (escape == 1 && c == '~') { - c = 'z' + 1; - } else { - escape++; - continue; - } - } else if (c == '\t') { - c = 0x1D; // tab - } - escape = 0; - - if (c == 0xA && *(ptr - 1) == 0xD) { - *(ptr - 1) = '\n'; - continue; - } - *ptr++ = c; - } - } - *ptr = '\0'; - } - f_close(&file); - } - return res; -} - void ViewTextWindow::onEvent(event_t event) { #if defined(HARDWARE_KEYS) - if (int(bufSize) < fileLength) { - TRACE("BEFORE offset=%d", offset); - if (event == EVT_KEY_BREAK(KEY_PAGEDN)) { - offset += bufSize; - TRACE("event=DOWN"); - } - - if (event == EVT_KEY_BREAK(KEY_PAGEUP)) { - TRACE("event=UP"); - offset -= bufSize; - } - - offset = std::max(offset, 0); - offset = std::min(offset, fileLength - (int)bufSize); - - TRACE("AFTER offset=%d", offset); - sdReadTextFileBlock(bufSize, offset); - lv_label_set_text_static(lb, buffer); - } + if (textViewer) textViewer->onEvent(event); if (event == EVT_KEY_BREAK(KEY_EXIT)) onCancel(); #endif } -class ViewChecklistWindow : public ViewTextWindow +class ViewChecklistWindow : public Page, public TextViewer { public: ViewChecklistWindow(const std::string path, const std::string name, EdgeTxIcon icon) : - ViewTextWindow(path, name, icon) + Page(icon, PAD_ZERO), TextViewer(path, name) { header->setTitle(g_model.header.name); header->setTitle2(STR_PREFLIGHT); + + fullPath = path + std::string(PATH_SEPARATOR) + name; + extractNameSansExt(); + + delayLoad(); + } + + void delayedInit() override + { + if (buffer == nullptr) buildBody(body); } #if defined(DEBUG_WINDOWS) @@ -267,7 +305,10 @@ class ViewChecklistWindow : public ViewTextWindow void onCancel() override { - if (allChecked()) ViewTextWindow::onCancel(); + if (allChecked()) { + Page::onCancel(); + checkListOpen = false; + } } protected: @@ -330,7 +371,7 @@ class ViewChecklistWindow : public ViewTextWindow if (vtw) vtw->updateCheckboxes(); } - void buildBody(Window* window) override + void buildBody(Window* window) { if (openFile()) { auto obj = window->getLvObj(); @@ -456,27 +497,19 @@ static std::string getModelNotesFile() return std::string(""); } -static bool openNotes(std::string modelNotesName, - bool fromMenu = false) -{ - std::string fullPath = std::string(MODELS_PATH) + PATH_SEPARATOR + modelNotesName; - - if (isFileAvailable(fullPath.c_str())) { - if (fromMenu || !g_model.checklistInteractive) - new ViewTextWindow(std::string(MODELS_PATH), modelNotesName, ICON_MODEL); - else - new ViewChecklistWindow(std::string(MODELS_PATH), modelNotesName, ICON_MODEL); - return true; - } else { - return false; - } -} - void readModelNotes(bool fromMenu) { std::string modelNotesName = getModelNotesFile(); if (!modelNotesName.empty()) { - openNotes(modelNotesName, fromMenu); + std::string fullPath = std::string(MODELS_PATH) + PATH_SEPARATOR + modelNotesName; + + if (isFileAvailable(fullPath.c_str())) { + if (fromMenu || !g_model.checklistInteractive) + new ViewTextWindow(std::string(MODELS_PATH), modelNotesName, ICON_MODEL); + else + new ViewChecklistWindow(std::string(MODELS_PATH), modelNotesName, ICON_MODEL); + } else { + } } } @@ -500,8 +533,10 @@ class CheckListDialog : public FullScreenDialog bool warningInactive() { - if (!checkListOpen) + if (!checkListOpen) { LED_ERROR_END(); + deleteLater(); + } return !checkListOpen; } }; @@ -515,3 +550,19 @@ void readChecklist() dialog->runForever(); } } + +ModelNotesPage::ModelNotesPage(PageDef& pageDef) : PageGroupItem(pageDef, PAD_ZERO) +{ +} + +void ModelNotesPage::build(Window* window) +{ + if (!textViewer) textViewer = new TextViewer(MODELS_PATH, getModelNotesFile()); + if (textViewer) textViewer->build(window); +} + +void ModelNotesPage::cleanup() +{ + if (textViewer) delete textViewer; + textViewer = nullptr; +} diff --git a/radio/src/gui/colorlcd/libui/view_text.h b/radio/src/gui/colorlcd/libui/view_text.h index 825d7703b..8f575bf78 100644 --- a/radio/src/gui/colorlcd/libui/view_text.h +++ b/radio/src/gui/colorlcd/libui/view_text.h @@ -20,8 +20,11 @@ #pragma once -#include "ff.h" #include "page.h" +#include "pagegroup.h" +#include "gui_common.h" + +class TextViewer; class ViewTextWindow : public Page { @@ -32,42 +35,33 @@ class ViewTextWindow : public Page FRESULT sdReadTextFileBlock(const uint32_t bufSize, const uint32_t offset); - ~ViewTextWindow() - { - if (buffer) { - free(buffer); - buffer = nullptr; - } - } - void onCancel() override; #if defined(DEBUG_WINDOWS) std::string getName() const override { return "ViewTextWindow"; }; #endif + void delayedInit() override; + protected: - std::string path; - std::string name; - std::string fullPath; - std::string extension; - - lv_obj_t* lb; - - int offset = 0; - char* buffer = nullptr; - size_t bufSize = 0; - int fileLength = 0; - bool openFromEnd; - - void extractNameSansExt(void); - virtual void buildBody(Window* window); - - bool openFile(); + TextViewer* textViewer = nullptr; void onEvent(event_t event) override; +}; - void delayedInit() override; +class ModelNotesPage : public PageGroupItem +{ + public: + ModelNotesPage(PageDef& pageDef); + + bool isVisible() const override { return modelHasNotes(); } + + void build(Window* window) override; + + void cleanup() override; + + protected: + TextViewer* textViewer = nullptr; }; void readModelNotes(bool fromMenu = false); diff --git a/radio/src/gui/colorlcd/setup_menus/menu_model.cpp b/radio/src/gui/colorlcd/setup_menus/menu_model.cpp index 3700f5724..f65326af1 100644 --- a/radio/src/gui/colorlcd/setup_menus/menu_model.cpp +++ b/radio/src/gui/colorlcd/setup_menus/menu_model.cpp @@ -33,6 +33,7 @@ #include "model_setup.h" #include "model_telemetry.h" #include "special_functions.h" +#include "view_text.h" PageDef modelMenuItems[] = { { ICON_MODEL_SETUP, STR_QM_GEN_SETTINGS, STR_MAIN_MENU_SETTINGS, PAGE_CREATE, QuickMenu::MODEL_SETUP, [](PageDef& pageDef) { return new ModelSetupPage(pageDef); }}, @@ -52,5 +53,6 @@ PageDef modelMenuItems[] = { { ICON_MODEL_LUA_SCRIPTS, STR_QM_CUSTOM_LUA, STR_MENUCUSTOMSCRIPTS, PAGE_CREATE, QuickMenu::MODEL_SCRIPTS, [](PageDef& pageDef) { return new ModelMixerScriptsPage(pageDef); }, modelCustomScriptsEnabled}, #endif { ICON_MODEL_TELEMETRY, STR_QM_TELEM, STR_MENUTELEMETRY, PAGE_CREATE, QuickMenu::MODEL_TELEMETRY, [](PageDef& pageDef) { return new ModelTelemetryPage(pageDef); }, modelTelemetryEnabled}, + { ICON_MODEL_NOTES, STR_MAIN_MENU_MODEL_NOTES, 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/quick_menu.cpp b/radio/src/gui/colorlcd/setup_menus/quick_menu.cpp index 87a2f12cc..90d50635f 100644 --- a/radio/src/gui/colorlcd/setup_menus/quick_menu.cpp +++ b/radio/src/gui/colorlcd/setup_menus/quick_menu.cpp @@ -25,7 +25,6 @@ #include "edgetx.h" #include "quick_menu_group.h" #include "etx_lv_theme.h" -#include "view_text.h" #include "view_main.h" #include "screen_setup.h" #include "theme_manager.h" @@ -245,16 +244,6 @@ QuickMenu::QuickMenu() : sub = new QuickSubMenu(box, this, ICON_RADIO_TOOLS, STR_QM_TOOLS, STR_QM_TOOLS, toolsMenuItems); sub->addButton(); subMenus.emplace_back(sub); - - mainMenu->addButton(ICON_MODEL_NOTES, STR_MAIN_MENU_MODEL_NOTES, - [=]() -> uint8_t { - onSelect(true); - readModelNotes(true); - return 0; - }, - [=]() -> bool { - return modelHasNotes(); - }); } void QuickMenu::deleteLater(bool detach, bool trash) @@ -288,7 +277,7 @@ void QuickMenu::openQM(std::function cancelHandler, setFocus(curPage); } else { pageGroup = nullptr; - if (curPage > QuickMenu::MANAGE_MODELS) { + if (curPage >= QuickMenu::FIRST_SUB_MENU_ITEM) { mainMenu->setDisabled(false); mainMenu->clearFocus(); setFocus(curPage); diff --git a/radio/src/gui/colorlcd/setup_menus/quick_menu.h b/radio/src/gui/colorlcd/setup_menus/quick_menu.h index ff05d92c6..86e33fb49 100644 --- a/radio/src/gui/colorlcd/setup_menus/quick_menu.h +++ b/radio/src/gui/colorlcd/setup_menus/quick_menu.h @@ -45,8 +45,9 @@ class QuickMenu : public NavWindow enum SubMenu { NONE = 0, MANAGE_MODELS, + FIRST_SUB_MENU_ITEM, // Model menu - MODEL_SETUP, + MODEL_SETUP = FIRST_SUB_MENU_ITEM, MODEL_HELI, MODEL_FLIGHTMODES, MODEL_INPUTS, @@ -58,6 +59,7 @@ class QuickMenu : public NavWindow MODEL_SF, MODEL_SCRIPTS, MODEL_TELEMETRY, + MODEL_NOTES, // Radio menu RADIO_SETUP, RADIO_GF,