diff --git a/sphaira/include/app.hpp b/sphaira/include/app.hpp index 3650397..6d108cb 100644 --- a/sphaira/include/app.hpp +++ b/sphaira/include/app.hpp @@ -240,7 +240,8 @@ public: option::OptionBool m_theme_music{INI_SECTION, "theme_music", true}; option::OptionBool m_12hour_time{INI_SECTION, "12hour_time", false}; option::OptionLong m_language{INI_SECTION, "language", 0}; // auto - option::OptionString m_right_side_menu{INI_SECTION, "right_side_menu", "Appstore"}; + option::OptionString m_left_menu{INI_SECTION, "left_side_menu", "FileBrowser"}; + option::OptionString m_right_menu{INI_SECTION, "right_side_menu", "Appstore"}; option::OptionBool m_progress_boost_mode{INI_SECTION, "progress_boost_mode", true}; // install options diff --git a/sphaira/include/ui/menus/appstore.hpp b/sphaira/include/ui/menus/appstore.hpp index d5b6081..7bd3ecb 100644 --- a/sphaira/include/ui/menus/appstore.hpp +++ b/sphaira/include/ui/menus/appstore.hpp @@ -139,7 +139,7 @@ enum OrderType { using LayoutType = grid::LayoutType; struct Menu final : grid::Menu { - Menu(); + Menu(u32 flags); ~Menu(); auto GetShortTitle() const -> const char* override { return "Store"; }; diff --git a/sphaira/include/ui/menus/filebrowser.hpp b/sphaira/include/ui/menus/filebrowser.hpp index 0b73fbc..c76f451 100644 --- a/sphaira/include/ui/menus/filebrowser.hpp +++ b/sphaira/include/ui/menus/filebrowser.hpp @@ -3,7 +3,6 @@ #include "ui/menus/menu_base.hpp" #include "ui/scrolling_text.hpp" #include "ui/list.hpp" -#include "nro.hpp" #include "fs.hpp" #include "option.hpp" #include "hasher.hpp" @@ -341,7 +340,7 @@ struct SelectedStash { struct Menu final : MenuBase { friend class FsView; - Menu(const std::vector& nro_entries); + Menu(u32 flags); ~Menu(); auto GetShortTitle() const -> const char* override { return "Files"; }; @@ -381,10 +380,11 @@ private: void UpdateSubheading(); + void PromptIfShouldExit(); + private: static constexpr inline const char* INI_SECTION = "filebrowser"; - const std::vector& m_nro_entries; std::shared_ptr view{}; std::shared_ptr view_left{}; std::shared_ptr view_right{}; diff --git a/sphaira/include/ui/menus/ftp_menu.hpp b/sphaira/include/ui/menus/ftp_menu.hpp index ad2a2c3..99d65c2 100644 --- a/sphaira/include/ui/menus/ftp_menu.hpp +++ b/sphaira/include/ui/menus/ftp_menu.hpp @@ -35,7 +35,7 @@ struct StreamFtp final : yati::source::Stream { }; struct Menu final : MenuBase { - Menu(); + Menu(u32 flags); ~Menu(); auto GetShortTitle() const -> const char* override { return "FTP"; }; diff --git a/sphaira/include/ui/menus/game_menu.hpp b/sphaira/include/ui/menus/game_menu.hpp index 89301d1..e940faf 100644 --- a/sphaira/include/ui/menus/game_menu.hpp +++ b/sphaira/include/ui/menus/game_menu.hpp @@ -88,7 +88,7 @@ enum OrderType { using LayoutType = grid::LayoutType; struct Menu final : grid::Menu { - Menu(); + Menu(u32 flags); ~Menu(); auto GetShortTitle() const -> const char* override { return "Games"; }; diff --git a/sphaira/include/ui/menus/gc_menu.hpp b/sphaira/include/ui/menus/gc_menu.hpp index 3194bb2..74d5772 100644 --- a/sphaira/include/ui/menus/gc_menu.hpp +++ b/sphaira/include/ui/menus/gc_menu.hpp @@ -166,7 +166,7 @@ struct ApplicationEntry { }; struct Menu final : MenuBase { - Menu(); + Menu(u32 flags); ~Menu(); auto GetShortTitle() const -> const char* override { return "GC"; }; diff --git a/sphaira/include/ui/menus/ghdl.hpp b/sphaira/include/ui/menus/ghdl.hpp index 74e4d49..edc85a9 100644 --- a/sphaira/include/ui/menus/ghdl.hpp +++ b/sphaira/include/ui/menus/ghdl.hpp @@ -42,7 +42,7 @@ struct GhApiEntry { }; struct Menu final : MenuBase { - Menu(); + Menu(u32 flags); ~Menu(); auto GetShortTitle() const -> const char* override { return "GitHub"; }; diff --git a/sphaira/include/ui/menus/homebrew.hpp b/sphaira/include/ui/menus/homebrew.hpp index 685ef72..595c859 100644 --- a/sphaira/include/ui/menus/homebrew.hpp +++ b/sphaira/include/ui/menus/homebrew.hpp @@ -24,6 +24,8 @@ enum OrderType { using LayoutType = grid::LayoutType; +auto GetNroEntries() -> std::span; + struct Menu final : grid::Menu { Menu(); ~Menu(); diff --git a/sphaira/include/ui/menus/irs_menu.hpp b/sphaira/include/ui/menus/irs_menu.hpp index 83ceea9..bcdc3c8 100644 --- a/sphaira/include/ui/menus/irs_menu.hpp +++ b/sphaira/include/ui/menus/irs_menu.hpp @@ -27,7 +27,7 @@ struct Entry { }; struct Menu final : MenuBase { - Menu(); + Menu(u32 flags); ~Menu(); auto GetShortTitle() const -> const char* override { return "IRS"; }; diff --git a/sphaira/include/ui/menus/main_menu.hpp b/sphaira/include/ui/menus/main_menu.hpp index c076975..d30e69b 100644 --- a/sphaira/include/ui/menus/main_menu.hpp +++ b/sphaira/include/ui/menus/main_menu.hpp @@ -1,8 +1,8 @@ #pragma once #include "ui/widget.hpp" -#include "ui/menus/homebrew.hpp" -#include "ui/menus/filebrowser.hpp" +#include "ui/menus/menu_base.hpp" +#include namespace sphaira::ui::menu::main { @@ -17,7 +17,7 @@ enum class UpdateState { Error, }; -using MiscMenuFunction = std::function(void)>; +using MiscMenuFunction = std::function(u32 flags)>; enum MiscMenuFlag : u8 { // can be set as the rightside menu. @@ -62,9 +62,9 @@ private: void AddOnLRPress(); private: - std::shared_ptr m_homebrew_menu{}; - std::shared_ptr m_filebrowser_menu{}; - std::shared_ptr m_right_side_menu{}; + std::shared_ptr m_centre_menu{}; + std::shared_ptr m_left_menu{}; + std::shared_ptr m_right_menu{}; std::shared_ptr m_current_menu{}; std::string m_update_url{}; diff --git a/sphaira/include/ui/menus/menu_base.hpp b/sphaira/include/ui/menus/menu_base.hpp index f657c29..c211ba7 100644 --- a/sphaira/include/ui/menus/menu_base.hpp +++ b/sphaira/include/ui/menus/menu_base.hpp @@ -6,6 +6,11 @@ namespace sphaira::ui::menu { +enum MenuFlag { + MenuFlag_None = 0, + MenuFlag_Tab = 1 << 1, +}; + struct PolledData { struct tm tm{}; u32 battery_percetange{}; @@ -17,7 +22,7 @@ struct PolledData { }; struct MenuBase : Widget { - MenuBase(std::string title); + MenuBase(const std::string& title, u32 flags); virtual ~MenuBase(); virtual auto GetShortTitle() const -> const char* = 0; @@ -36,6 +41,10 @@ struct MenuBase : Widget { return m_title; } + auto IsTab() const -> bool { + return m_flags & MenuFlag_Tab; + } + static auto GetPolledData(bool force_refresh = false) -> PolledData; private: @@ -45,6 +54,8 @@ private: ScrollingText m_scroll_title_sub_heading{}; ScrollingText m_scroll_sub_heading{}; + + u32 m_flags{}; }; } // namespace sphaira::ui::menu diff --git a/sphaira/include/ui/menus/themezer.hpp b/sphaira/include/ui/menus/themezer.hpp index 8050d80..ece5f96 100644 --- a/sphaira/include/ui/menus/themezer.hpp +++ b/sphaira/include/ui/menus/themezer.hpp @@ -130,7 +130,7 @@ struct PageEntry { }; struct Menu final : MenuBase { - Menu(); + Menu(u32 flags); ~Menu(); auto GetShortTitle() const -> const char* override { return "Themezer"; }; diff --git a/sphaira/include/ui/menus/usb_menu.hpp b/sphaira/include/ui/menus/usb_menu.hpp index 60b7757..4ba57dc 100644 --- a/sphaira/include/ui/menus/usb_menu.hpp +++ b/sphaira/include/ui/menus/usb_menu.hpp @@ -21,7 +21,7 @@ enum class State { }; struct Menu final : MenuBase { - Menu(); + Menu(u32 flags); ~Menu(); auto GetShortTitle() const -> const char* override { return "USB"; }; diff --git a/sphaira/source/app.cpp b/sphaira/source/app.cpp index 62e686d..30be2da 100644 --- a/sphaira/source/app.cpp +++ b/sphaira/source/app.cpp @@ -1310,7 +1310,8 @@ App::App(const char* argv0) { else if (app->m_theme_music.LoadFrom(Key, Value)) {} else if (app->m_12hour_time.LoadFrom(Key, Value)) {} else if (app->m_language.LoadFrom(Key, Value)) {} - else if (app->m_right_side_menu.LoadFrom(Key, Value)) {} + else if (app->m_left_menu.LoadFrom(Key, Value)) {} + else if (app->m_right_menu.LoadFrom(Key, Value)) {} else if (app->m_install_sysmmc.LoadFrom(Key, Value)) {} else if (app->m_install_emummc.LoadFrom(Key, Value)) {} else if (app->m_install_sd.LoadFrom(Key, Value)) {} @@ -1581,7 +1582,7 @@ void App::DisplayMiscOptions(bool left_side) { ON_SCOPE_EXIT(App::Push(options)); for (auto& e : ui::menu::main::GetMiscMenuEntries()) { - if (e.name == g_app->m_right_side_menu.Get()) { + if (e.name == g_app->m_right_menu.Get()) { continue; } @@ -1590,7 +1591,7 @@ void App::DisplayMiscOptions(bool left_side) { } options->Add(std::make_shared(i18n::get(e.title), [e](){ - App::Push(e.func()); + App::Push(e.func(ui::menu::MenuFlag_None)); })); } } @@ -1617,14 +1618,14 @@ void App::DisplayAdvancedOptions(bool left_side) { menu_names.emplace_back(e.name); } - ui::SidebarEntryArray::Items right_side_menu_items; + ui::SidebarEntryArray::Items side_menu_items; for (auto& str : menu_names) { - right_side_menu_items.push_back(i18n::get(str)); + side_menu_items.push_back(i18n::get(str)); } - const auto it = std::find(menu_names.cbegin(), menu_names.cend(), g_app->m_right_side_menu.Get()); + const auto it = std::find(menu_names.cbegin(), menu_names.cend(), g_app->m_right_menu.Get()); if (it == menu_names.cend()) { - g_app->m_right_side_menu.Set(menu_names[0]); + g_app->m_right_menu.Set(menu_names[0]); } options->Add(std::make_shared("Logging"_i18n, App::GetLogEnable(), [](bool& enable){ @@ -1643,17 +1644,29 @@ void App::DisplayAdvancedOptions(bool left_side) { App::SetTextScrollSpeed(index_out); }, App::GetTextScrollSpeed())); - options->Add(std::make_shared("Set right-side menu"_i18n, right_side_menu_items, [menu_names](s64& index_out){ + options->Add(std::make_shared("Set left-side menu"_i18n, side_menu_items, [menu_names](s64& index_out){ const auto e = menu_names[index_out]; - if (g_app->m_right_side_menu.Get() != e) { - g_app->m_right_side_menu.Set(e); + if (g_app->m_left_menu.Get() != e) { + g_app->m_left_menu.Set(e); App::Push(std::make_shared( "Press OK to restart Sphaira"_i18n, "OK"_i18n, [](auto){ App::ExitRestart(); } )); } - }, i18n::get(g_app->m_right_side_menu.Get()))); + }, i18n::get(g_app->m_left_menu.Get()))); + + options->Add(std::make_shared("Set right-side menu"_i18n, side_menu_items, [menu_names](s64& index_out){ + const auto e = menu_names[index_out]; + if (g_app->m_right_menu.Get() != e) { + g_app->m_right_menu.Set(e); + App::Push(std::make_shared( + "Press OK to restart Sphaira"_i18n, "OK"_i18n, [](auto){ + App::ExitRestart(); + } + )); + } + }, i18n::get(g_app->m_right_menu.Get()))); options->Add(std::make_shared("Install options"_i18n, [left_side](){ App::DisplayInstallOptions(left_side); diff --git a/sphaira/source/ui/menus/appstore.cpp b/sphaira/source/ui/menus/appstore.cpp index ca018a7..f5acdfb 100644 --- a/sphaira/source/ui/menus/appstore.cpp +++ b/sphaira/source/ui/menus/appstore.cpp @@ -603,7 +603,7 @@ auto FindCaseInsensitive(std::string_view base, std::string_view term) -> bool { } // namespace EntryMenu::EntryMenu(Entry& entry, const LazyImage& default_icon, Menu& menu) -: MenuBase{entry.title} +: MenuBase{entry.title, MenuFlag_None} , m_entry{entry} , m_default_icon{default_icon} , m_menu{menu} { @@ -852,7 +852,7 @@ void EntryMenu::SetIndex(s64 index) { } } -Menu::Menu() : grid::Menu{"AppStore"_i18n} { +Menu::Menu(u32 flags) : grid::Menu{"AppStore"_i18n, flags} { fs::FsNativeSd fs; fs.CreateDirectoryRecursively("/switch/sphaira/cache/appstore/icons"); fs.CreateDirectoryRecursively("/switch/sphaira/cache/appstore/banners"); diff --git a/sphaira/source/ui/menus/file_viewer.cpp b/sphaira/source/ui/menus/file_viewer.cpp index d0b3eb9..92ae3f4 100644 --- a/sphaira/source/ui/menus/file_viewer.cpp +++ b/sphaira/source/ui/menus/file_viewer.cpp @@ -6,7 +6,7 @@ namespace { } // namespace -Menu::Menu(const fs::FsPath& path) : MenuBase{path}, m_path{path} { +Menu::Menu(const fs::FsPath& path) : MenuBase{path, MenuFlag_None}, m_path{path} { SetAction(Button::B, Action{"Back"_i18n, [this](){ SetPop(); }}); diff --git a/sphaira/source/ui/menus/filebrowser.cpp b/sphaira/source/ui/menus/filebrowser.cpp index b1a3056..6b2953d 100644 --- a/sphaira/source/ui/menus/filebrowser.cpp +++ b/sphaira/source/ui/menus/filebrowser.cpp @@ -382,6 +382,11 @@ FsView::FsView(Menu* menu, const fs::FsPath& path, const FsEntry& entry, ViewSid }}), std::make_pair(Button::B, Action{"Back"_i18n, [this](){ + if (!m_menu->IsTab() && App::GetApp()->m_controller.GotHeld(Button::R2)) { + m_menu->PromptIfShouldExit(); + return; + } + std::string_view view{m_path}; if (view != m_fs->Root()) { const auto end = view.find_last_of('/'); @@ -392,6 +397,10 @@ FsView::FsView(Menu* menu, const fs::FsPath& path, const FsEntry& entry, ViewSid } else { Scan(view.substr(0, end), true); } + } else { + if (!m_menu->IsTab()) { + m_menu->PromptIfShouldExit(); + } } }}), @@ -1390,7 +1399,7 @@ auto FsView::CheckIfUpdateFolder() -> Result { if (!m_daybreak_path.has_value()) { auto daybreak_path = DAYBREAK_PATH; if (!m_fs->FileExists(DAYBREAK_PATH)) { - if (auto e = nro_find(m_menu->m_nro_entries, "Daybreak", "Atmosphere-NX", {}); e.has_value()) { + if (auto e = nro_find(homebrew::GetNroEntries(), "Daybreak", "Atmosphere-NX", {}); e.has_value()) { daybreak_path = e.value().path; } else { log_write("failed to find daybreak\n"); @@ -1893,11 +1902,17 @@ void FsView::DisplayAdvancedOptions() { })); } -Menu::Menu(const std::vector& nro_entries) : MenuBase{"FileBrowser"_i18n}, m_nro_entries{nro_entries} { +Menu::Menu(u32 flags) : MenuBase{"FileBrowser"_i18n, flags} { SetAction(Button::L3, Action{"Split"_i18n, [this](){ SetSplitScreen(IsSplitScreen() ^ 1); }}); + if (!IsTab()) { + SetAction(Button::SELECT, Action{"Close"_i18n, [this](){ + PromptIfShouldExit(); + }}); + } + view = view_left = std::make_shared(this, ViewSide::Left); } @@ -2063,7 +2078,7 @@ void Menu::LoadAssocEntriesPath(const fs::FsPath& path) { file_exists = view->m_fs->FileExists(assoc.path); } else { const auto nro_name = assoc.name + ".nro"; - for (const auto& nro : m_nro_entries) { + for (const auto& nro : homebrew::GetNroEntries()) { const auto len = std::strlen(nro.path); if (len < nro_name.length()) { continue; @@ -2160,4 +2175,19 @@ void Menu::RefreshViews() { } } +void Menu::PromptIfShouldExit() { + if (IsTab()) { + return; + } + + App::Push(std::make_shared( + "Close FileBrowser?"_i18n, + "No"_i18n, "Yes"_i18n, 1, [this](auto op_index){ + if (op_index && *op_index) { + SetPop(); + } + } + )); +} + } // namespace sphaira::ui::menu::filebrowser diff --git a/sphaira/source/ui/menus/ftp_menu.cpp b/sphaira/source/ui/menus/ftp_menu.cpp index e2e6ee9..b6033aa 100644 --- a/sphaira/source/ui/menus/ftp_menu.cpp +++ b/sphaira/source/ui/menus/ftp_menu.cpp @@ -142,7 +142,7 @@ void StreamFtp::Disable() { m_active = false; } -Menu::Menu() : MenuBase{"FTP Install (EXPERIMENTAL)"_i18n} { +Menu::Menu(u32 flags) : MenuBase{"FTP Install (EXPERIMENTAL)"_i18n, flags} { SetAction(Button::B, Action{"Back"_i18n, [this](){ SetPop(); }}); diff --git a/sphaira/source/ui/menus/game_menu.cpp b/sphaira/source/ui/menus/game_menu.cpp index f9aedf7..5566f00 100644 --- a/sphaira/source/ui/menus/game_menu.cpp +++ b/sphaira/source/ui/menus/game_menu.cpp @@ -691,7 +691,7 @@ void ThreadData::Pop(std::vector& out) { m_result.clear(); } -Menu::Menu() : grid::Menu{"Games"_i18n} { +Menu::Menu(u32 flags) : grid::Menu{"Games"_i18n, flags} { this->SetActions( std::make_pair(Button::L3, Action{[this](){ if (m_entries.empty()) { diff --git a/sphaira/source/ui/menus/gc_menu.cpp b/sphaira/source/ui/menus/gc_menu.cpp index 007e4d5..17fb452 100644 --- a/sphaira/source/ui/menus/gc_menu.cpp +++ b/sphaira/source/ui/menus/gc_menu.cpp @@ -390,7 +390,7 @@ auto ApplicationEntry::GetSize() const -> s64 { return size; } -Menu::Menu() : MenuBase{"GameCard"_i18n} { +Menu::Menu(u32 flags) : MenuBase{"GameCard"_i18n, flags} { this->SetActions( std::make_pair(Button::B, Action{"Back"_i18n, [this](){ SetPop(); diff --git a/sphaira/source/ui/menus/ghdl.cpp b/sphaira/source/ui/menus/ghdl.cpp index aa78a54..93ef510 100644 --- a/sphaira/source/ui/menus/ghdl.cpp +++ b/sphaira/source/ui/menus/ghdl.cpp @@ -222,7 +222,7 @@ auto DownloadAssetJson(ProgressBox* pbox, const std::string& url, GhApiEntry& ou } // namespace -Menu::Menu() : MenuBase{"GitHub"_i18n} { +Menu::Menu(u32 flags) : MenuBase{"GitHub"_i18n, flags} { fs::FsNativeSd().CreateDirectoryRecursively(CACHE_PATH); this->SetActions( diff --git a/sphaira/source/ui/menus/homebrew.cpp b/sphaira/source/ui/menus/homebrew.cpp index 4008c59..a5bb566 100644 --- a/sphaira/source/ui/menus/homebrew.cpp +++ b/sphaira/source/ui/menus/homebrew.cpp @@ -18,6 +18,8 @@ namespace sphaira::ui::menu::homebrew { namespace { +Menu* g_menu{}; + auto GenerateStarPath(const fs::FsPath& nro_path) -> fs::FsPath { fs::FsPath out{}; const auto dilem = std::strrchr(nro_path.s, '/'); @@ -32,7 +34,17 @@ void FreeEntry(NVGcontext* vg, NroEntry& e) { } // namespace -Menu::Menu() : grid::Menu{"Homebrew"_i18n} { +auto GetNroEntries() -> std::span { + if (!g_menu) { + return {}; + } + + return g_menu->GetHomebrewList(); +} + +Menu::Menu() : grid::Menu{"Homebrew"_i18n, MenuFlag_Tab} { + g_menu = this; + this->SetActions( std::make_pair(Button::A, Action{"Launch"_i18n, [this](){ nro_launch(m_entries[m_index].path); @@ -129,6 +141,7 @@ Menu::Menu() : grid::Menu{"Homebrew"_i18n} { } Menu::~Menu() { + g_menu = {}; FreeEntries(); } diff --git a/sphaira/source/ui/menus/irs_menu.cpp b/sphaira/source/ui/menus/irs_menu.cpp index 5d0e021..dea1f69 100644 --- a/sphaira/source/ui/menus/irs_menu.cpp +++ b/sphaira/source/ui/menus/irs_menu.cpp @@ -75,7 +75,7 @@ void irsConvertConfigNormalToEx(const IrsImageTransferProcessorConfig* nor, IrsI } // namespace -Menu::Menu() : MenuBase{"Irs"_i18n} { +Menu::Menu(u32 flags) : MenuBase{"Irs"_i18n, flags} { SetAction(Button::B, Action{"Back"_i18n, [this](){ SetPop(); }}); diff --git a/sphaira/source/ui/menus/main_menu.cpp b/sphaira/source/ui/menus/main_menu.cpp index 52ad207..ab2dc8e 100644 --- a/sphaira/source/ui/menus/main_menu.cpp +++ b/sphaira/source/ui/menus/main_menu.cpp @@ -6,6 +6,8 @@ #include "ui/progress_box.hpp" #include "ui/error_box.hpp" +#include "ui/menus/homebrew.hpp" +#include "ui/menus/filebrowser.hpp" #include "ui/menus/irs_menu.hpp" #include "ui/menus/themezer.hpp" #include "ui/menus/ghdl.hpp" @@ -32,13 +34,14 @@ constexpr const char* GITHUB_URL{"https://api.github.com/repos/ITotalJustice/sph constexpr fs::FsPath CACHE_PATH{"/switch/sphaira/cache/sphaira_latest.json"}; template -auto MiscMenuFuncGenerator() { - return std::make_shared(); +auto MiscMenuFuncGenerator(u32 flags) { + return std::make_shared(flags); } const MiscMenuEntry MISC_MENU_ENTRIES[] = { { .name = "Appstore", .title = "Appstore", .func = MiscMenuFuncGenerator, .flag = MiscMenuFlag_Shortcut }, { .name = "Games", .title = "Games", .func = MiscMenuFuncGenerator, .flag = MiscMenuFlag_Shortcut }, + { .name = "FileBrowser", .title = "FileBrowser", .func = MiscMenuFuncGenerator, .flag = MiscMenuFlag_Shortcut }, { .name = "Themezer", .title = "Themezer", .func = MiscMenuFuncGenerator, .flag = MiscMenuFlag_Shortcut }, { .name = "GitHub", .title = "GitHub", .func = MiscMenuFuncGenerator, .flag = MiscMenuFlag_Shortcut }, { .name = "FTP", .title = "FTP Install", .func = MiscMenuFuncGenerator, .flag = MiscMenuFlag_Install }, @@ -149,16 +152,41 @@ auto InstallUpdate(ProgressBox* pbox, const std::string url, const std::string v R_SUCCEED(); } -auto CreateRightSideMenu() -> std::shared_ptr { - const auto name = App::GetApp()->m_right_side_menu.Get(); +auto CreateLeftSideMenu(std::string& name_out) -> std::shared_ptr { + const auto name = App::GetApp()->m_left_menu.Get(); for (auto& e : GetMiscMenuEntries()) { if (e.name == name) { - return e.func(); + name_out = name; + return e.func(MenuFlag_Tab); } } - return std::make_shared(); + name_out = "FileBrowser"; + return std::make_shared(MenuFlag_Tab); +} + +auto CreateRightSideMenu(std::string_view left_name) -> std::shared_ptr { + const auto name = App::GetApp()->m_right_menu.Get(); + + // handle if the user tries to mount the same menu twice. + if (name == left_name) { + // check if we can mount the default. + if (left_name != "AppStore") { + return std::make_shared(MenuFlag_Tab); + } else { + // otherwise, fallback to left side default. + return std::make_shared(MenuFlag_Tab); + } + } + + for (auto& e : GetMiscMenuEntries()) { + if (e.name == name) { + return e.func(MenuFlag_Tab); + } + } + + return std::make_shared(MenuFlag_Tab); } } // namespace @@ -319,10 +347,13 @@ MainMenu::MainMenu() { }}) ); - m_homebrew_menu = std::make_shared(); - m_filebrowser_menu = std::make_shared(m_homebrew_menu->GetHomebrewList()); - m_right_side_menu = CreateRightSideMenu(); - m_current_menu = m_homebrew_menu; + m_centre_menu = std::make_shared(); + m_current_menu = m_centre_menu; + + + std::string left_side_name; + m_left_menu = CreateLeftSideMenu(left_side_name); + m_right_menu = CreateRightSideMenu(left_side_name); AddOnLRPress(); @@ -355,11 +386,11 @@ void MainMenu::OnFocusLost() { void MainMenu::OnLRPress(std::shared_ptr menu, Button b) { m_current_menu->OnFocusLost(); - if (m_current_menu == m_homebrew_menu) { + if (m_current_menu == m_centre_menu) { m_current_menu = menu; RemoveAction(b); } else { - m_current_menu = m_homebrew_menu; + m_current_menu = m_centre_menu; } AddOnLRPress(); @@ -371,17 +402,17 @@ void MainMenu::OnLRPress(std::shared_ptr menu, Button b) { } void MainMenu::AddOnLRPress() { - if (m_current_menu != m_filebrowser_menu) { - const auto label = m_current_menu == m_homebrew_menu ? m_filebrowser_menu->GetShortTitle() : m_homebrew_menu->GetShortTitle(); + if (m_current_menu != m_left_menu) { + const auto label = m_current_menu == m_centre_menu ? m_left_menu->GetShortTitle() : m_centre_menu->GetShortTitle(); SetAction(Button::L, Action{i18n::get(label), [this]{ - OnLRPress(m_filebrowser_menu, Button::L); + OnLRPress(m_left_menu, Button::L); }}); } - if (m_current_menu != m_right_side_menu) { - const auto label = m_current_menu == m_homebrew_menu ? m_right_side_menu->GetShortTitle() : m_homebrew_menu->GetShortTitle(); + if (m_current_menu != m_right_menu) { + const auto label = m_current_menu == m_centre_menu ? m_right_menu->GetShortTitle() : m_centre_menu->GetShortTitle(); SetAction(Button::R, Action{i18n::get(label), [this]{ - OnLRPress(m_right_side_menu, Button::R); + OnLRPress(m_right_menu, Button::R); }}); } } diff --git a/sphaira/source/ui/menus/menu_base.cpp b/sphaira/source/ui/menus/menu_base.cpp index 5ad0c58..6d88ffc 100644 --- a/sphaira/source/ui/menus/menu_base.cpp +++ b/sphaira/source/ui/menus/menu_base.cpp @@ -40,7 +40,7 @@ auto MenuBase::GetPolledData(bool force_refresh) -> PolledData { return data; } -MenuBase::MenuBase(std::string title) : m_title{title} { +MenuBase::MenuBase(const std::string& title, u32 flags) : m_title{title}, m_flags{flags} { // this->SetParent(this); this->SetPos(30, 87, 1220 - 30, 646 - 87); SetAction(Button::START, Action{App::Exit}); diff --git a/sphaira/source/ui/menus/themezer.cpp b/sphaira/source/ui/menus/themezer.cpp index 12f7d33..18d4c81 100644 --- a/sphaira/source/ui/menus/themezer.cpp +++ b/sphaira/source/ui/menus/themezer.cpp @@ -346,7 +346,7 @@ LazyImage::~LazyImage() { } } -Menu::Menu() : MenuBase{"Themezer"_i18n} { +Menu::Menu(u32 flags) : MenuBase{"Themezer"_i18n, flags} { fs::FsNativeSd().CreateDirectoryRecursively(CACHE_PATH); SetAction(Button::B, Action{"Back"_i18n, [this]{ diff --git a/sphaira/source/ui/menus/usb_menu.cpp b/sphaira/source/ui/menus/usb_menu.cpp index 11dfd89..7f8ac48 100644 --- a/sphaira/source/ui/menus/usb_menu.cpp +++ b/sphaira/source/ui/menus/usb_menu.cpp @@ -51,7 +51,7 @@ void thread_func(void* user) { } // namespace -Menu::Menu() : MenuBase{"USB"_i18n} { +Menu::Menu(u32 flags) : MenuBase{"USB"_i18n, flags} { SetAction(Button::B, Action{"Back"_i18n, [this](){ SetPop(); }});