diff --git a/firmware/application/apps/ui_settings.cpp b/firmware/application/apps/ui_settings.cpp index bdfff1419..92daf09f7 100644 --- a/firmware/application/apps/ui_settings.cpp +++ b/firmware/application/apps/ui_settings.cpp @@ -31,6 +31,7 @@ #include "ui_receiver.hpp" #include "ui_touch_calibration.hpp" #include "ui_text_editor.hpp" +#include "ui_external_items_menu_loader.hpp" #include "portapack_persistent_memory.hpp" #include "lpc43xx_cpp.hpp" @@ -839,6 +840,61 @@ void SetMenuColorView::focus() { button_save.focus(); } +/* SetAutostartView*/ +SetAutostartView::SetAutostartView(NavigationView& nav) { + add_children({&labels, + &button_save, + &button_cancel, + &options}); + + button_save.on_select = [&nav, this](Button&) { + nav_setting.save(); + nav.pop(); + }; + + button_cancel.on_select = [&nav, this](Button&) { + nav.pop(); + }; + + // options + i = 0; + OptionsField::option_t o{"-none-", i}; + opts.emplace_back(o); + for (auto& app : NavigationView::appList) { + if (app.id == nullptr) continue; + i++; + o = {app.displayName, i}; + opts.emplace_back(o); + full_app_list.emplace(i, app.id); + if (autostart_app == app.id) selected = i; + } + ExternalItemsMenuLoader::load_all_external_items_callback([this](ui::AppInfoConsole& app) { + if (app.appCallName == nullptr) return; + i++; + OptionsField::option_t o = {app.appFriendlyName, i}; + opts.emplace_back(o); + full_app_list.emplace(i, app.appCallName); + if (autostart_app == app.appCallName) selected = i; + }); + + options.set_options(opts); + options.on_change = [this](size_t, OptionsField::value_t v) { + if (v == 0) { + autostart_app = ""; + return; + } + auto it = full_app_list.find(v); + if (it != full_app_list.end()) { + autostart_app = it->second; + } + }; + options.set_selected_index(selected); +} + +void SetAutostartView::focus() { + options.focus(); +} + /* SettingsMenuView **************************************/ SettingsMenuView::SettingsMenuView(NavigationView& nav) @@ -866,6 +922,7 @@ void SettingsMenuView::on_populate() { //{"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(); }}, + {"Autostart", ui::Color::dark_cyan(), &bitmap_icon_setup, [this]() { nav_.push(); }}, }); } diff --git a/firmware/application/apps/ui_settings.hpp b/firmware/application/apps/ui_settings.hpp index 00292a0a8..9a0aeff0b 100644 --- a/firmware/application/apps/ui_settings.hpp +++ b/firmware/application/apps/ui_settings.hpp @@ -799,6 +799,41 @@ class SetMenuColorView : public View { }; }; +class SetAutostartView : public View { + public: + SetAutostartView(NavigationView& nav); + + void focus() override; + + std::string title() const override { return "Autostart"; }; + + private: + int32_t i = 0; + std::string autostart_app{""}; + OptionsField::options_t opts; + std::map full_app_list; // looking table + int32_t selected = 0; + SettingsStore nav_setting{ + "nav"sv, + {{"autostart_app"sv, &autostart_app}}}; + Labels labels{ + {{1 * 8, 1 * 16}, "Select app to start on boot", Color::light_grey()}}; + + Button button_save{ + {2 * 8, 16 * 16, 12 * 8, 32}, + "Save"}; + + OptionsField options{ + {0 * 8, 3 * 16}, + 30, + {}}; + + Button button_cancel{ + {16 * 8, 16 * 16, 12 * 8, 32}, + "Cancel", + }; +}; + class SettingsMenuView : public BtnGridView { public: SettingsMenuView(NavigationView& nav); diff --git a/firmware/application/main.cpp b/firmware/application/main.cpp index dd8f0f160..4ec395cb3 100755 --- a/firmware/application/main.cpp +++ b/firmware/application/main.cpp @@ -158,6 +158,7 @@ static void event_loop() { event_dispatcher.set_display_sleep(true); }}; portapack::setEventDispatcherToUSBSerial(&event_dispatcher); + system_view.get_navigation_view()->handle_autostart(); event_dispatcher.run(); } diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index 9b0d84ab2..67c586363 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -107,6 +107,10 @@ #include "file_reader.hpp" #include "png_writer.hpp" #include "file_path.hpp" +#include "ff.h" + +#include +#include using portapack::receiver_model; using portapack::transmitter_model; @@ -708,6 +712,23 @@ bool NavigationView::set_on_pop(std::function on_pop) { return true; } +void NavigationView::handle_autostart() { + std::string autostart_app{""}; + SettingsStore nav_setting{ + "nav"sv, + {{"autostart_app"sv, &autostart_app}}}; + if (!autostart_app.empty()) { + if (StartAppByName(autostart_app.c_str())) return; + // if returned false, check for external apps by that name, and try to start it + std::string appwithpath = "/" + apps_dir.string() + "/"; + appwithpath += autostart_app; + appwithpath += ".ppma"; + std::wstring_convert, char16_t> conv; + std::filesystem::path pth = conv.from_bytes(appwithpath.c_str()); + ui::ExternalItemsMenuLoader::run_external_app(*this, pth); + } +} + /* Helpers **************************************************************/ static void add_apps(NavigationView& nav, BtnGridView& grid, app_location_t loc) { diff --git a/firmware/application/ui_navigation.hpp b/firmware/application/ui_navigation.hpp index 05576663e..8144efd48 100644 --- a/firmware/application/ui_navigation.hpp +++ b/firmware/application/ui_navigation.hpp @@ -136,6 +136,8 @@ class NavigationView : public View { static const AppList appList; bool StartAppByName(const char* name); // Starts a View (app) by name stored in appListFC. This is to start apps from console + void handle_autostart(); + private: struct ViewState { std::unique_ptr view;