From e9b9ba4602c8c1904b01095d93543e887adffacf Mon Sep 17 00:00:00 2001 From: Mark Thompson <129641948+NotherNgineer@users.noreply.github.com> Date: Sun, 10 Mar 2024 14:49:36 -0500 Subject: [PATCH] Deallocate menu buttons to save memory (#1971) * Deallocate hidden menu buttons * Added Copyright * Added comments --- firmware/application/apps/ui_debug.cpp | 56 ++++++++++++++--------- firmware/application/apps/ui_debug.hpp | 12 +++++ firmware/application/apps/ui_settings.cpp | 47 ++++++++++--------- firmware/application/apps/ui_settings.hpp | 6 ++- firmware/application/ui/ui_btngrid.cpp | 24 ++++++++-- firmware/application/ui/ui_btngrid.hpp | 6 +++ firmware/application/ui_navigation.cpp | 50 ++++++++++++-------- firmware/application/ui_navigation.hpp | 14 ++++++ 8 files changed, 149 insertions(+), 66 deletions(-) diff --git a/firmware/application/apps/ui_debug.cpp b/firmware/application/apps/ui_debug.cpp index 50cd93f0..3f533e46 100644 --- a/firmware/application/apps/ui_debug.cpp +++ b/firmware/application/apps/ui_debug.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. * Copyright (C) 2024 Mark Thompson + * Copyright (C) 2024 u-foka * * This file is part of PortaPack. * @@ -445,14 +446,19 @@ void DebugControlsView::focus() { /* DebugPeripheralsMenuView **********************************************/ -DebugPeripheralsMenuView::DebugPeripheralsMenuView(NavigationView& nav) { +DebugPeripheralsMenuView::DebugPeripheralsMenuView(NavigationView& nav) + : nav_(nav) { + set_max_rows(2); // allow wider buttons +} + +void DebugPeripheralsMenuView::on_populate() { const char* max283x = hackrf_r9 ? "MAX2839" : "MAX2837"; const char* si5351x = hackrf_r9 ? "Si5351A" : "Si5351C"; add_items({ - {"RFFC5072", ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav]() { nav.push("RFFC5072", RegistersWidgetConfig{CT_RFFC5072, 31, 31, 16}); }}, - {max283x, ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav, max283x]() { nav.push(max283x, RegistersWidgetConfig{CT_MAX283X, 32, 32, 10}); }}, - {si5351x, ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav, si5351x]() { nav.push(si5351x, RegistersWidgetConfig{CT_SI5351, 188, 96, 8}); }}, - {audio::debug::codec_name(), ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav]() { nav.push(audio::debug::codec_name(), RegistersWidgetConfig{CT_AUDIO, audio::debug::reg_count(), audio::debug::reg_count(), audio::debug::reg_bits()}); }}, + {"RFFC5072", ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [this]() { nav_.push("RFFC5072", RegistersWidgetConfig{CT_RFFC5072, 31, 31, 16}); }}, + {max283x, ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [this, max283x]() { nav_.push(max283x, RegistersWidgetConfig{CT_MAX283X, 32, 32, 10}); }}, + {si5351x, ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [this, si5351x]() { nav_.push(si5351x, RegistersWidgetConfig{CT_SI5351, 188, 96, 8}); }}, + {audio::debug::codec_name(), ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [this]() { nav_.push(audio::debug::codec_name(), RegistersWidgetConfig{CT_AUDIO, audio::debug::reg_count(), audio::debug::reg_count(), audio::debug::reg_bits()}); }}, }); set_max_rows(2); // allow wider buttons } @@ -468,32 +474,38 @@ DebugReboot::DebugReboot(NavigationView& nav) { __WFE(); } +void DebugReboot::on_populate() { +} + /* DebugMenuView *********************************************************/ -DebugMenuView::DebugMenuView(NavigationView& nav) { +DebugMenuView::DebugMenuView(NavigationView& nav) + : nav_(nav) { + set_max_rows(2); // allow wider buttons +} + +void DebugMenuView::on_populate() { if (portapack::persistent_memory::show_gui_return_icon()) { - add_items({{"..", ui::Color::light_grey(), &bitmap_icon_previous, [&nav]() { nav.pop(); }}}); + add_items({{"..", ui::Color::light_grey(), &bitmap_icon_previous, [this]() { nav_.pop(); }}}); } add_items({ - {"Buttons Test", ui::Color::dark_cyan(), &bitmap_icon_controls, [&nav]() { nav.push(); }}, - {"Debug Dump", ui::Color::dark_cyan(), &bitmap_icon_memory, [&nav]() { portapack::persistent_memory::debug_dump(); }}, - {"M0 Stack Dump", ui::Color::dark_cyan(), &bitmap_icon_memory, [&nav]() { stack_dump(); }}, - {"Memory Dump", ui::Color::dark_cyan(), &bitmap_icon_memory, [&nav]() { nav.push(); }}, - //{"Memory Usage", ui::Color::dark_cyan(), &bitmap_icon_memory, [&nav]() { nav.push(); }}, - {"Peripherals", ui::Color::dark_cyan(), &bitmap_icon_peripherals, [&nav]() { nav.push(); }}, - {"Pers. Memory", ui::Color::dark_cyan(), &bitmap_icon_memory, [&nav]() { nav.push(); }}, - //{ "Radio State", ui::Color::white(), nullptr, [&nav](){ nav.push(); } }, - {"Reboot", ui::Color::dark_cyan(), &bitmap_icon_setup, [&nav]() { nav.push(); }}, - {"SD Card", ui::Color::dark_cyan(), &bitmap_icon_sdcard, [&nav]() { nav.push(); }}, - {"Temperature", ui::Color::dark_cyan(), &bitmap_icon_temperature, [&nav]() { nav.push(); }}, - {"Touch Test", ui::Color::dark_cyan(), &bitmap_icon_notepad, [&nav]() { nav.push(); }}, + {"Buttons Test", ui::Color::dark_cyan(), &bitmap_icon_controls, [this]() { nav_.push(); }}, + {"Debug Dump", ui::Color::dark_cyan(), &bitmap_icon_memory, [this]() { portapack::persistent_memory::debug_dump(); }}, + {"M0 Stack Dump", ui::Color::dark_cyan(), &bitmap_icon_memory, [this]() { stack_dump(); }}, + {"Memory Dump", ui::Color::dark_cyan(), &bitmap_icon_memory, [this]() { nav_.push(); }}, + //{"Memory Usage", ui::Color::dark_cyan(), &bitmap_icon_memory, [this]() { nav_.push(); }}, + {"Peripherals", ui::Color::dark_cyan(), &bitmap_icon_peripherals, [this]() { nav_.push(); }}, + {"Pers. Memory", ui::Color::dark_cyan(), &bitmap_icon_memory, [this]() { nav_.push(); }}, + //{ "Radio State", ui::Color::white(), nullptr, [this](){ nav_.push(); } }, + {"Reboot", ui::Color::dark_cyan(), &bitmap_icon_setup, [this]() { nav_.push(); }}, + {"SD Card", ui::Color::dark_cyan(), &bitmap_icon_sdcard, [this]() { nav_.push(); }}, + {"Temperature", ui::Color::dark_cyan(), &bitmap_icon_temperature, [this]() { nav_.push(); }}, + {"Touch Test", ui::Color::dark_cyan(), &bitmap_icon_notepad, [this]() { nav_.push(); }}, }); - for (auto const& gridItem : ExternalItemsMenuLoader::load_external_items(app_location_t::DEBUG, nav)) { + for (auto const& gridItem : ExternalItemsMenuLoader::load_external_items(app_location_t::DEBUG, nav_)) { add_item(gridItem); }; - - set_max_rows(2); // allow wider buttons } /* DebugMemoryDumpView *********************************************************/ diff --git a/firmware/application/apps/ui_debug.hpp b/firmware/application/apps/ui_debug.hpp index 571e2bfd..9665389b 100644 --- a/firmware/application/apps/ui_debug.hpp +++ b/firmware/application/apps/ui_debug.hpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. * Copyright (C) 2024 Mark Thompson + * Copyright (C) 2024 u-foka * * This file is part of PortaPack. * @@ -422,17 +423,28 @@ class DebugPeripheralsMenuView : public BtnGridView { public: DebugPeripheralsMenuView(NavigationView& nav); std::string title() const override { return "Peripherals"; }; + + private: + NavigationView& nav_; + void on_populate() override; }; class DebugReboot : public BtnGridView { public: DebugReboot(NavigationView& nav); + + private: + void on_populate() override; }; class DebugMenuView : public BtnGridView { public: DebugMenuView(NavigationView& nav); std::string title() const override { return "Debug"; }; + + private: + NavigationView& nav_; + void on_populate() override; }; } /* namespace ui */ diff --git a/firmware/application/apps/ui_settings.cpp b/firmware/application/apps/ui_settings.cpp index 24d15adc..a4479fe8 100644 --- a/firmware/application/apps/ui_settings.cpp +++ b/firmware/application/apps/ui_settings.cpp @@ -4,6 +4,7 @@ * Copyright (C) 2023 gullradriel, Nilorea Studio Inc. * Copyright (C) 2023 Kyle Reed * Copyright (C) 2024 Mark Thompson + * Copyright (C) 2024 u-foka * Copyleft (ɔ) 2024 zxkmm under GPL license * * This file is part of PortaPack. @@ -835,28 +836,32 @@ void SetMenuColorView::focus() { /* SettingsMenuView **************************************/ -SettingsMenuView::SettingsMenuView(NavigationView& nav) { - if (pmem::show_gui_return_icon()) { - add_items({{"..", ui::Color::light_grey(), &bitmap_icon_previous, [&nav]() { nav.pop(); }}}); - } - add_items({ - {"App Settings", ui::Color::dark_cyan(), &bitmap_icon_notepad, [&nav]() { nav.push(); }}, - {"Audio", ui::Color::dark_cyan(), &bitmap_icon_speaker, [&nav]() { nav.push(); }}, - {"Calibration", ui::Color::dark_cyan(), &bitmap_icon_options_touch, [&nav]() { nav.push(); }}, - {"Config Mode", ui::Color::dark_cyan(), &bitmap_icon_clk_ext, [&nav]() { nav.push(); }}, - {"Converter", ui::Color::dark_cyan(), &bitmap_icon_options_radio, [&nav]() { nav.push(); }}, - {"Date/Time", ui::Color::dark_cyan(), &bitmap_icon_options_datetime, [&nav]() { nav.push(); }}, - {"Encoder Dial", ui::Color::dark_cyan(), &bitmap_icon_setup, [&nav]() { nav.push(); }}, - {"Freq. Correct", ui::Color::dark_cyan(), &bitmap_icon_options_radio, [&nav]() { nav.push(); }}, - {"P.Memory Mgmt", ui::Color::dark_cyan(), &bitmap_icon_memory, [&nav]() { nav.push(); }}, - {"Radio", ui::Color::dark_cyan(), &bitmap_icon_options_radio, [&nav]() { nav.push(); }}, - {"SD Card", ui::Color::dark_cyan(), &bitmap_icon_sdcard, [&nav]() { nav.push(); }}, - {"User Interface", ui::Color::dark_cyan(), &bitmap_icon_options_ui, [&nav]() { nav.push(); }}, - {"QR Code", ui::Color::dark_cyan(), &bitmap_icon_qr_code, [&nav]() { nav.push(); }}, - {"Brightness", ui::Color::dark_cyan(), &bitmap_icon_brightness, [&nav]() { nav.push(); }}, - {"Menu Color", ui::Color::dark_cyan(), &bitmap_icon_brightness, [&nav]() { nav.push(); }}, - }); +SettingsMenuView::SettingsMenuView(NavigationView& nav) + : nav_(nav) { set_max_rows(2); // allow wider buttons } +void SettingsMenuView::on_populate() { + if (pmem::show_gui_return_icon()) { + add_items({{"..", ui::Color::light_grey(), &bitmap_icon_previous, [this]() { nav_.pop(); }}}); + } + add_items({ + {"App Settings", ui::Color::dark_cyan(), &bitmap_icon_notepad, [this]() { nav_.push(); }}, + {"Audio", ui::Color::dark_cyan(), &bitmap_icon_speaker, [this]() { nav_.push(); }}, + {"Calibration", ui::Color::dark_cyan(), &bitmap_icon_options_touch, [this]() { nav_.push(); }}, + {"Config Mode", ui::Color::dark_cyan(), &bitmap_icon_clk_ext, [this]() { nav_.push(); }}, + {"Converter", ui::Color::dark_cyan(), &bitmap_icon_options_radio, [this]() { nav_.push(); }}, + {"Date/Time", ui::Color::dark_cyan(), &bitmap_icon_options_datetime, [this]() { nav_.push(); }}, + {"Encoder Dial", ui::Color::dark_cyan(), &bitmap_icon_setup, [this]() { nav_.push(); }}, + {"Freq. Correct", ui::Color::dark_cyan(), &bitmap_icon_options_radio, [this]() { nav_.push(); }}, + {"P.Memory Mgmt", ui::Color::dark_cyan(), &bitmap_icon_memory, [this]() { nav_.push(); }}, + {"Radio", ui::Color::dark_cyan(), &bitmap_icon_options_radio, [this]() { nav_.push(); }}, + {"SD Card", ui::Color::dark_cyan(), &bitmap_icon_sdcard, [this]() { nav_.push(); }}, + {"User Interface", ui::Color::dark_cyan(), &bitmap_icon_options_ui, [this]() { nav_.push(); }}, + {"QR Code", ui::Color::dark_cyan(), &bitmap_icon_qr_code, [this]() { nav_.push(); }}, + {"Brightness", ui::Color::dark_cyan(), &bitmap_icon_brightness, [this]() { nav_.push(); }}, + {"Menu Color", ui::Color::dark_cyan(), &bitmap_icon_brightness, [this]() { nav_.push(); }}, + }); +} + } /* namespace ui */ diff --git a/firmware/application/apps/ui_settings.hpp b/firmware/application/apps/ui_settings.hpp index 83ef294d..77fc3a78 100644 --- a/firmware/application/apps/ui_settings.hpp +++ b/firmware/application/apps/ui_settings.hpp @@ -4,6 +4,7 @@ * Copyright (C) 2023 gullradriel, Nilorea Studio Inc. * Copyright (C) 2023 Kyle Reed * Copyright (C) 2024 Mark Thompson + * Copyright (C) 2024 u-foka * Copyleft (ɔ) 2024 zxkmm under GPL license * * This file is part of PortaPack. @@ -792,8 +793,11 @@ class SetMenuColorView : public View { class SettingsMenuView : public BtnGridView { public: SettingsMenuView(NavigationView& nav); - std::string title() const override { return "Settings"; }; + + private: + NavigationView& nav_; + void on_populate() override; }; } /* namespace ui */ diff --git a/firmware/application/ui/ui_btngrid.cpp b/firmware/application/ui/ui_btngrid.cpp index 92891e85..ec7cd193 100644 --- a/firmware/application/ui/ui_btngrid.cpp +++ b/firmware/application/ui/ui_btngrid.cpp @@ -3,6 +3,7 @@ * Copyright (C) 2016 Furrtek * Copyright (C) 2019 Elia Yehuda (z4ziggy) * Copyright (C) 2023 Mark Thompson + * Copyright (C) 2024 u-foka * * This file is part of PortaPack. * @@ -106,7 +107,12 @@ void BtnGridView::on_tick_second() { } void BtnGridView::clear() { - menu_items.clear(); + std::vector().swap(menu_items); // clear vector and release memory + + for (auto& item : menu_item_views) + remove_child(item.get()); + + std::vector>().swap(menu_item_views); // clear vector and release memory } void BtnGridView::add_items(std::initializer_list new_items) { @@ -207,11 +213,23 @@ void BtnGridView::on_focus() { void BtnGridView::on_blur() { #if 0 - if (!keep_highlight) - item_view(highlighted_item - offset)->unhighlight(); + if (!keep_highlight) + item_view(highlighted_item - offset)->unhighlight(); #endif } +void BtnGridView::on_show() { + on_populate(); + + View::on_show(); +} + +void BtnGridView::on_hide() { + View::on_hide(); + + clear(); +} + bool BtnGridView::on_key(const KeyEvent key) { switch (key) { case KeyEvent::Up: diff --git a/firmware/application/ui/ui_btngrid.hpp b/firmware/application/ui/ui_btngrid.hpp index 03ba22df..2256f766 100644 --- a/firmware/application/ui/ui_btngrid.hpp +++ b/firmware/application/ui/ui_btngrid.hpp @@ -2,6 +2,7 @@ * Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc. * Copyright (C) 2016 Furrtek * Copyright (C) 2019 Elia Yehuda (z4ziggy) + * Copyright (C) 2024 u-foka * * This file is part of PortaPack. * @@ -73,10 +74,15 @@ class BtnGridView : public View { void set_arrow_enabled(bool enabled); void on_focus() override; void on_blur() override; + void on_show() override; + void on_hide() override; bool on_key(const KeyEvent event) override; bool on_encoder(const EncoderEvent event) override; bool blacklisted_app(GridItem new_item); + protected: + virtual void on_populate() = 0; + private: int rows_{3}; void update_items(); diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index 6da3c71f..d417002d 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -740,40 +740,49 @@ void addExternalItems(NavigationView& nav, app_location_t location, BtnGridView& /* ReceiversMenuView *****************************************************/ -ReceiversMenuView::ReceiversMenuView(NavigationView& nav) { +ReceiversMenuView::ReceiversMenuView(NavigationView& nav) + : nav_(nav) {} + +void ReceiversMenuView::on_populate() { if (pmem::show_gui_return_icon()) { - add_item({"..", Color::light_grey(), &bitmap_icon_previous, [&nav]() { nav.pop(); }}); + add_item({"..", Color::light_grey(), &bitmap_icon_previous, [this]() { nav_.pop(); }}); } - add_apps(nav, *this, RX); + add_apps(nav_, *this, RX); - addExternalItems(nav, app_location_t::RX, *this); + addExternalItems(nav_, app_location_t::RX, *this); } /* TransmittersMenuView **************************************************/ -TransmittersMenuView::TransmittersMenuView(NavigationView& nav) { +TransmittersMenuView::TransmittersMenuView(NavigationView& nav) + : nav_(nav) {} + +void TransmittersMenuView::on_populate() { if (pmem::show_gui_return_icon()) { - add_items({{"..", Color::light_grey(), &bitmap_icon_previous, [&nav]() { nav.pop(); }}}); + add_items({{"..", Color::light_grey(), &bitmap_icon_previous, [this]() { nav_.pop(); }}}); } - add_apps(nav, *this, TX); + add_apps(nav_, *this, TX); - addExternalItems(nav, app_location_t::TX, *this); + addExternalItems(nav_, app_location_t::TX, *this); } /* UtilitiesMenuView *****************************************************/ -UtilitiesMenuView::UtilitiesMenuView(NavigationView& nav) { +UtilitiesMenuView::UtilitiesMenuView(NavigationView& nav) + : nav_(nav) { + set_max_rows(2); // allow wider buttons +} + +void UtilitiesMenuView::on_populate() { if (pmem::show_gui_return_icon()) { - add_items({{"..", Color::light_grey(), &bitmap_icon_previous, [&nav]() { nav.pop(); }}}); + add_items({{"..", Color::light_grey(), &bitmap_icon_previous, [this]() { nav_.pop(); }}}); } - add_apps(nav, *this, UTILITIES); + add_apps(nav_, *this, UTILITIES); - addExternalItems(nav, app_location_t::UTILITIES, *this); - - set_max_rows(2); // allow wider buttons + addExternalItems(nav_, app_location_t::UTILITIES, *this); } /* SystemMenuView ********************************************************/ @@ -790,15 +799,18 @@ void SystemMenuView::hackrf_mode(NavigationView& nav) { }); } -SystemMenuView::SystemMenuView(NavigationView& nav) { - add_apps(nav, *this, HOME); - - add_item({"HackRF", Color::cyan(), &bitmap_icon_hackrf, [this, &nav]() { hackrf_mode(nav); }}); - +SystemMenuView::SystemMenuView(NavigationView& nav) + : nav_(nav) { set_max_rows(2); // allow wider buttons set_arrow_enabled(false); } +void SystemMenuView::on_populate() { + add_apps(nav_, *this, HOME); + + add_item({"HackRF", Color::cyan(), &bitmap_icon_hackrf, [this]() { hackrf_mode(nav_); }}); +} + /* SystemView ************************************************************/ SystemView::SystemView( diff --git a/firmware/application/ui_navigation.hpp b/firmware/application/ui_navigation.hpp index 7facbe7c..05576663 100644 --- a/firmware/application/ui_navigation.hpp +++ b/firmware/application/ui_navigation.hpp @@ -329,18 +329,30 @@ class ReceiversMenuView : public BtnGridView { public: ReceiversMenuView(NavigationView& nav); std::string title() const override { return "Receive"; }; + + private: + NavigationView& nav_; + void on_populate() override; }; class TransmittersMenuView : public BtnGridView { public: TransmittersMenuView(NavigationView& nav); std::string title() const override { return "Transmit"; }; + + private: + NavigationView& nav_; + void on_populate() override; }; class UtilitiesMenuView : public BtnGridView { public: UtilitiesMenuView(NavigationView& nav); std::string title() const override { return "Utilities"; }; + + private: + NavigationView& nav_; + void on_populate() override; }; class SystemMenuView : public BtnGridView { @@ -348,6 +360,8 @@ class SystemMenuView : public BtnGridView { SystemMenuView(NavigationView& nav); private: + NavigationView& nav_; + void on_populate() override; void hackrf_mode(NavigationView& nav); };