diff --git a/sphaira/include/app.hpp b/sphaira/include/app.hpp index db21651..f0a260c 100644 --- a/sphaira/include/app.hpp +++ b/sphaira/include/app.hpp @@ -184,6 +184,7 @@ 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"}; // install options option::OptionBool m_install{INI_SECTION, "install", false}; diff --git a/sphaira/include/ui/menus/appstore.hpp b/sphaira/include/ui/menus/appstore.hpp index cdad5d2..7f4085c 100644 --- a/sphaira/include/ui/menus/appstore.hpp +++ b/sphaira/include/ui/menus/appstore.hpp @@ -4,7 +4,6 @@ #include "ui/scrollable_text.hpp" #include "ui/scrolling_text.hpp" #include "ui/list.hpp" -#include "nro.hpp" #include "fs.hpp" #include @@ -74,6 +73,7 @@ struct EntryMenu final : MenuBase { EntryMenu(Entry& entry, const LazyImage& default_icon, Menu& menu); ~EntryMenu(); + auto GetShortTitle() const -> const char* override { return "Entry"; }; void Update(Controller* controller, TouchInfo* touch) override; void Draw(NVGcontext* vg, Theme* theme) override; // void OnFocusGained() override; @@ -136,9 +136,10 @@ enum OrderType { }; struct Menu final : MenuBase { - Menu(const std::vector& nro_entries); + Menu(); ~Menu(); + auto GetShortTitle() const -> const char* override { return "Store"; }; void Update(Controller* controller, TouchInfo* touch) override; void Draw(NVGcontext* vg, Theme* theme) override; void OnFocusGained() override; @@ -163,7 +164,6 @@ struct Menu final : MenuBase { } private: - const std::vector& m_nro_entries; std::vector m_entries{}; std::vector m_entries_index[Filter_MAX]{}; std::vector m_entries_index_author{}; diff --git a/sphaira/include/ui/menus/file_viewer.hpp b/sphaira/include/ui/menus/file_viewer.hpp index 9c85145..c48c641 100644 --- a/sphaira/include/ui/menus/file_viewer.hpp +++ b/sphaira/include/ui/menus/file_viewer.hpp @@ -10,6 +10,7 @@ struct Menu final : MenuBase { Menu(const fs::FsPath& path); ~Menu(); + auto GetShortTitle() const -> const char* override { return "File"; }; void Update(Controller* controller, TouchInfo* touch) override; void Draw(NVGcontext* vg, Theme* theme) override; void OnFocusGained() override; diff --git a/sphaira/include/ui/menus/filebrowser.hpp b/sphaira/include/ui/menus/filebrowser.hpp index 7d662b6..5de558b 100644 --- a/sphaira/include/ui/menus/filebrowser.hpp +++ b/sphaira/include/ui/menus/filebrowser.hpp @@ -124,6 +124,7 @@ struct Menu final : MenuBase { Menu(const std::vector& nro_entries); ~Menu(); + auto GetShortTitle() const -> const char* override { return "Files"; }; void Update(Controller* controller, TouchInfo* touch) override; void Draw(NVGcontext* vg, Theme* theme) override; void OnFocusGained() override; diff --git a/sphaira/include/ui/menus/ftp_menu.hpp b/sphaira/include/ui/menus/ftp_menu.hpp index 1fac789..e9d24c3 100644 --- a/sphaira/include/ui/menus/ftp_menu.hpp +++ b/sphaira/include/ui/menus/ftp_menu.hpp @@ -38,6 +38,7 @@ struct Menu final : MenuBase { Menu(); ~Menu(); + auto GetShortTitle() const -> const char* override { return "FTP"; }; void Update(Controller* controller, TouchInfo* touch) override; void Draw(NVGcontext* vg, Theme* theme) override; void OnFocusGained() override; diff --git a/sphaira/include/ui/menus/game_menu.hpp b/sphaira/include/ui/menus/game_menu.hpp index 4de03aa..14041b1 100644 --- a/sphaira/include/ui/menus/game_menu.hpp +++ b/sphaira/include/ui/menus/game_menu.hpp @@ -45,6 +45,7 @@ struct Menu final : MenuBase { Menu(); ~Menu(); + auto GetShortTitle() const -> const char* override { return "Games"; }; void Update(Controller* controller, TouchInfo* touch) override; void Draw(NVGcontext* vg, Theme* theme) override; void OnFocusGained() override; diff --git a/sphaira/include/ui/menus/gc_menu.hpp b/sphaira/include/ui/menus/gc_menu.hpp index 9170d39..2c1e42c 100644 --- a/sphaira/include/ui/menus/gc_menu.hpp +++ b/sphaira/include/ui/menus/gc_menu.hpp @@ -43,6 +43,7 @@ struct Menu final : MenuBase { Menu(); ~Menu(); + auto GetShortTitle() const -> const char* override { return "GC"; }; void Update(Controller* controller, TouchInfo* touch) override; void Draw(NVGcontext* vg, Theme* theme) override; diff --git a/sphaira/include/ui/menus/ghdl.hpp b/sphaira/include/ui/menus/ghdl.hpp index 295a578..74e4d49 100644 --- a/sphaira/include/ui/menus/ghdl.hpp +++ b/sphaira/include/ui/menus/ghdl.hpp @@ -45,6 +45,7 @@ struct Menu final : MenuBase { Menu(); ~Menu(); + auto GetShortTitle() const -> const char* override { return "GitHub"; }; void Update(Controller* controller, TouchInfo* touch) override; void Draw(NVGcontext* vg, Theme* theme) override; void OnFocusGained() override; diff --git a/sphaira/include/ui/menus/homebrew.hpp b/sphaira/include/ui/menus/homebrew.hpp index 4255085..17aecfa 100644 --- a/sphaira/include/ui/menus/homebrew.hpp +++ b/sphaira/include/ui/menus/homebrew.hpp @@ -27,6 +27,7 @@ struct Menu final : MenuBase { Menu(); ~Menu(); + auto GetShortTitle() const -> const char* override { return "Apps"; }; void Update(Controller* controller, TouchInfo* touch) override; void Draw(NVGcontext* vg, Theme* theme) override; void OnFocusGained() override; diff --git a/sphaira/include/ui/menus/irs_menu.hpp b/sphaira/include/ui/menus/irs_menu.hpp index 9c7702a..83ceea9 100644 --- a/sphaira/include/ui/menus/irs_menu.hpp +++ b/sphaira/include/ui/menus/irs_menu.hpp @@ -30,6 +30,7 @@ struct Menu final : MenuBase { Menu(); ~Menu(); + auto GetShortTitle() const -> const char* override { return "IRS"; }; void Update(Controller* controller, TouchInfo* touch) override; void Draw(NVGcontext* vg, Theme* theme) override; void OnFocusGained() override; diff --git a/sphaira/include/ui/menus/main_menu.hpp b/sphaira/include/ui/menus/main_menu.hpp index b37fbf9..35178b0 100644 --- a/sphaira/include/ui/menus/main_menu.hpp +++ b/sphaira/include/ui/menus/main_menu.hpp @@ -3,7 +3,6 @@ #include "ui/widget.hpp" #include "ui/menus/homebrew.hpp" #include "ui/menus/filebrowser.hpp" -#include "ui/menus/appstore.hpp" namespace sphaira::ui::menu::main { @@ -39,7 +38,7 @@ private: private: std::shared_ptr m_homebrew_menu{}; std::shared_ptr m_filebrowser_menu{}; - std::shared_ptr m_app_store_menu{}; + std::shared_ptr m_right_side_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 a79ee35..20a044f 100644 --- a/sphaira/include/ui/menus/menu_base.hpp +++ b/sphaira/include/ui/menus/menu_base.hpp @@ -10,6 +10,7 @@ struct MenuBase : Widget { MenuBase(std::string title); virtual ~MenuBase(); + virtual auto GetShortTitle() const -> const char* = 0; virtual void Update(Controller* controller, TouchInfo* touch); virtual void Draw(NVGcontext* vg, Theme* theme); @@ -21,6 +22,10 @@ struct MenuBase : Widget { void SetTitleSubHeading(std::string sub_heading); void SetSubHeading(std::string sub_heading); + auto GetTitle() const { + return m_title; + } + private: void UpdateVars(); diff --git a/sphaira/include/ui/menus/themezer.hpp b/sphaira/include/ui/menus/themezer.hpp index aa6a43f..8050d80 100644 --- a/sphaira/include/ui/menus/themezer.hpp +++ b/sphaira/include/ui/menus/themezer.hpp @@ -133,6 +133,7 @@ struct Menu final : MenuBase { Menu(); ~Menu(); + auto GetShortTitle() const -> const char* override { return "Themezer"; }; void Update(Controller* controller, TouchInfo* touch) override; void Draw(NVGcontext* vg, Theme* theme) override; void OnFocusGained() override; diff --git a/sphaira/include/ui/menus/usb_menu.hpp b/sphaira/include/ui/menus/usb_menu.hpp index b9b2c5f..60b7757 100644 --- a/sphaira/include/ui/menus/usb_menu.hpp +++ b/sphaira/include/ui/menus/usb_menu.hpp @@ -24,6 +24,7 @@ struct Menu final : MenuBase { Menu(); ~Menu(); + auto GetShortTitle() const -> const char* override { return "USB"; }; void Update(Controller* controller, TouchInfo* touch) override; void Draw(NVGcontext* vg, Theme* theme) override; void OnFocusGained() override; diff --git a/sphaira/source/app.cpp b/sphaira/source/app.cpp index 1dfce6b..88565a2 100644 --- a/sphaira/source/app.cpp +++ b/sphaira/source/app.cpp @@ -14,6 +14,7 @@ #include "ui/menus/ftp_menu.hpp" #include "ui/menus/gc_menu.hpp" #include "ui/menus/game_menu.hpp" +#include "ui/menus/appstore.hpp" #include "app.hpp" #include "log.hpp" @@ -1519,37 +1520,24 @@ void App::DisplayMiscOptions(bool left_side) { auto options = std::make_shared("Misc Options"_i18n, left_side ? ui::Sidebar::Side::LEFT : ui::Sidebar::Side::RIGHT); ON_SCOPE_EXIT(App::Push(options)); - options->Add(std::make_shared("Games"_i18n, [](){ - App::Push(std::make_shared()); - })); - - options->Add(std::make_shared("Themezer"_i18n, [](){ - App::Push(std::make_shared()); - })); - - options->Add(std::make_shared("GitHub"_i18n, [](){ - App::Push(std::make_shared()); - })); - - if (App::GetApp()->m_install.Get()) { - if (App::GetFtpEnable()) { - options->Add(std::make_shared("Ftp Install"_i18n, [](){ - App::Push(std::make_shared()); + const auto push_if_not_same = [&](const char* name, const char* title){ + if (g_app->m_right_side_menu.Get() != name) { + options->Add(std::make_shared(i18n::get(title), [](){ + App::Push(std::make_shared()); })); } + }; - options->Add(std::make_shared("Usb Install"_i18n, [](){ - App::Push(std::make_shared()); - })); - - options->Add(std::make_shared("GameCard Install"_i18n, [](){ - App::Push(std::make_shared()); - })); + push_if_not_same.template operator()("Appstore", "Appstore"); + push_if_not_same.template operator()("Games", "Games"); + push_if_not_same.template operator()("Themezer", "Themezer"); + push_if_not_same.template operator()("GitHub", "GitHub"); + if (App::GetInstallEnable()) { + push_if_not_same.template operator()("FTP", "FTP Install"); + push_if_not_same.template operator()("USB", "USB Install"); + push_if_not_same.template operator()("GameCard", "GameCard Install"); } - - options->Add(std::make_shared("Irs (Infrared Joycon Camera)"_i18n, [](){ - App::Push(std::make_shared()); - })); + push_if_not_same.template operator()("IRS", "IRS (Infrared Joycon Camera)"); } void App::DisplayAdvancedOptions(bool left_side) { @@ -1561,6 +1549,25 @@ void App::DisplayAdvancedOptions(bool left_side) { text_scroll_speed_items.push_back("Normal"_i18n); text_scroll_speed_items.push_back("Fast"_i18n); + ui::SidebarEntryArray::Items right_side_menu_items; + right_side_menu_items.push_back("Appstore"_i18n); + right_side_menu_items.push_back("Games"_i18n); + // not valid as themezer uses l/r for swapping pages. + // right_side_menu_items.push_back("Themezer"_i18n); + right_side_menu_items.push_back("GitHub"_i18n); + right_side_menu_items.push_back("IRS"_i18n); + if (0 && App::GetInstallEnable()) { + // not supported yet + // right_side_menu_items.push_back("FTP"_i18n); + // right_side_menu_items.push_back("USB"_i18n); + // right_side_menu_items.push_back("GameCard"_i18n); + } + + const auto it = std::find(right_side_menu_items.cbegin(), right_side_menu_items.cend(), g_app->m_right_side_menu.Get()); + if (it == right_side_menu_items.cend()) { + g_app->m_right_side_menu.Set(right_side_menu_items[0]); + } + options->Add(std::make_shared("Logging"_i18n, App::GetLogEnable(), [](bool& enable){ App::SetLogEnable(enable); }, "Enabled"_i18n, "Disabled"_i18n)); @@ -1571,7 +1578,19 @@ void App::DisplayAdvancedOptions(bool left_side) { options->Add(std::make_shared("Text scroll speed"_i18n, text_scroll_speed_items, [](s64& index_out){ App::SetTextScrollSpeed(index_out); - }, (s64)App::GetTextScrollSpeed())); + }, App::GetTextScrollSpeed())); + + options->Add(std::make_shared("Set right-side menu"_i18n, right_side_menu_items, [right_side_menu_items](s64& index_out){ + const auto e = right_side_menu_items[index_out]; + if (g_app->m_right_side_menu.Get() != e) { + g_app->m_right_side_menu.Set(e); + App::Push(std::make_shared( + "Press OK to restart Sphaira"_i18n, "OK"_i18n, [](auto){ + App::ExitRestart(); + } + )); + } + }, g_app->m_right_side_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 a0c7663..e8928dd 100644 --- a/sphaira/source/ui/menus/appstore.cpp +++ b/sphaira/source/ui/menus/appstore.cpp @@ -846,13 +846,42 @@ void EntryMenu::SetIndex(s64 index) { } } -Menu::Menu(const std::vector& nro_entries) : MenuBase{"AppStore"_i18n}, m_nro_entries{nro_entries} { +Menu::Menu() : MenuBase{"AppStore"_i18n} { fs::FsNativeSd fs; fs.CreateDirectoryRecursively("/switch/sphaira/cache/appstore/icons"); fs.CreateDirectoryRecursively("/switch/sphaira/cache/appstore/banners"); fs.CreateDirectoryRecursively("/switch/sphaira/cache/appstore/screens"); this->SetActions( + std::make_pair(Button::B, Action{"Back"_i18n, [this](){ + if (m_is_author) { + m_is_author = false; + if (m_is_search) { + SetSearch(m_search_term); + } else { + SetFilter(m_filter); + } + + SetIndex(m_entry_author_jump_back); + if (m_entry_author_jump_back >= 9) { + m_list->SetYoff((((m_entry_author_jump_back - 9) + 3) / 3) * m_list->GetMaxY()); + } else { + m_list->SetYoff(0); + } + } else if (m_is_search) { + m_is_search = false; + SetFilter(m_filter); + SetIndex(m_entry_search_jump_back); + if (m_entry_search_jump_back >= 9) { + m_list->SetYoff(0); + m_list->SetYoff((((m_entry_search_jump_back - 9) + 3) / 3) * m_list->GetMaxY()); + } else { + m_list->SetYoff(0); + } + } else { + SetPop(); + } + }}), std::make_pair(Button::A, Action{"Info"_i18n, [this](){ if (m_entries_current.empty()) { // log_write("pushing A when empty: size: %zu count: %zu\n", repo_json.size(), m_entries_current.size()); @@ -1264,7 +1293,6 @@ void Menu::Sort() { void Menu::SetFilter(Filter filter) { m_is_search = false; m_is_author = false; - RemoveAction(Button::B); m_filter = filter; m_entries_current = m_entries_index[m_filter]; @@ -1303,17 +1331,6 @@ void Menu::SetSearch(const std::string& term) { } } - SetAction(Button::B, Action{"Back"_i18n, [this](){ - SetFilter(m_filter); - SetIndex(m_entry_search_jump_back); - if (m_entry_search_jump_back >= 9) { - m_list->SetYoff(0); - m_list->SetYoff((((m_entry_search_jump_back - 9) + 3) / 3) * m_list->GetMaxY()); - } else { - m_list->SetYoff(0); - } - }}); - m_is_search = true; m_entries_current = m_entries_index_search; SetIndex(0); @@ -1336,21 +1353,6 @@ void Menu::SetAuthor() { } } - SetAction(Button::B, Action{"Back"_i18n, [this](){ - if (m_is_search) { - SetSearch(m_search_term); - } else { - SetFilter(m_filter); - } - - SetIndex(m_entry_author_jump_back); - if (m_entry_author_jump_back >= 9) { - m_list->SetYoff((((m_entry_author_jump_back - 9) + 3) / 3) * m_list->GetMaxY()); - } else { - m_list->SetYoff(0); - } - }}); - m_is_author = true; m_entries_current = m_entries_index_author; SetIndex(0); diff --git a/sphaira/source/ui/menus/irs_menu.cpp b/sphaira/source/ui/menus/irs_menu.cpp index 1c01e00..4e17685 100644 --- a/sphaira/source/ui/menus/irs_menu.cpp +++ b/sphaira/source/ui/menus/irs_menu.cpp @@ -204,17 +204,6 @@ Menu::Menu() : MenuBase{"Irs"_i18n} { PollCameraStatus(true); // load default config LoadDefaultConfig(); - // poll to get first available handle. - PollCameraStatus(false); - - // find the first available entry and connect to that. - for (s64 i = 0; i < std::size(m_entries); i++) { - if (m_entries[i].status == IrsIrCameraStatus_Available) { - m_index = i; - UpdateConfig(&m_config); - break; - } - } } Menu::~Menu() { @@ -307,6 +296,20 @@ void Menu::Draw(NVGcontext* vg, Theme* theme) { void Menu::OnFocusGained() { MenuBase::OnFocusGained(); + + if (m_entries[m_index].status != IrsIrCameraStatus_Available) { + // poll to get first available handle. + PollCameraStatus(false); + + // find the first available entry and connect to that. + for (s64 i = 0; i < std::size(m_entries); i++) { + if (m_entries[i].status == IrsIrCameraStatus_Available) { + m_index = i; + UpdateConfig(&m_config); + break; + } + } + } } void Menu::PollCameraStatus(bool statup) { diff --git a/sphaira/source/ui/menus/main_menu.cpp b/sphaira/source/ui/menus/main_menu.cpp index 7c94393..c782d49 100644 --- a/sphaira/source/ui/menus/main_menu.cpp +++ b/sphaira/source/ui/menus/main_menu.cpp @@ -6,12 +6,20 @@ #include "ui/progress_box.hpp" #include "ui/error_box.hpp" +#include "ui/menus/irs_menu.hpp" +#include "ui/menus/themezer.hpp" +#include "ui/menus/ghdl.hpp" +#include "ui/menus/usb_menu.hpp" +#include "ui/menus/ftp_menu.hpp" +#include "ui/menus/gc_menu.hpp" +#include "ui/menus/game_menu.hpp" +#include "ui/menus/appstore.hpp" + #include "app.hpp" #include "log.hpp" #include "download.hpp" #include "defines.hpp" #include "i18n.hpp" -#include "ui/menus/usb_menu.hpp" #include #include @@ -140,6 +148,30 @@ auto InstallUpdate(ProgressBox* pbox, const std::string url, const std::string v return true; } +auto CreateRightSideMenu() -> std::shared_ptr { + const auto name = App::GetApp()->m_right_side_menu.Get(); + + if ("Games" == name) { + return std::make_shared(); + }/*else if ("Themezer" == name) { + return std::make_shared(); + }*/else if ("GitHub" == name) { + return std::make_shared(); + } else if ("IRS" == name) { + return std::make_shared(); + } else if (App::GetInstallEnable()) { + // if ("FTP" == name) { + // return std::make_shared(); + // } else if ("USB" == name) { + // return std::make_shared(); + // } else if ("GameCard" == name) { + // return std::make_shared(); + // } + } + + return std::make_shared(); +} + } // namespace MainMenu::MainMenu() { @@ -289,7 +321,7 @@ MainMenu::MainMenu() { m_homebrew_menu = std::make_shared(); m_filebrowser_menu = std::make_shared(m_homebrew_menu->GetHomebrewList()); - m_app_store_menu = std::make_shared(m_homebrew_menu->GetHomebrewList()); + m_right_side_menu = CreateRightSideMenu(); m_current_menu = m_homebrew_menu; AddOnLRPress(); @@ -340,16 +372,16 @@ 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 ? "Files" : "Apps"; + const auto label = m_current_menu == m_homebrew_menu ? m_filebrowser_menu->GetShortTitle() : m_homebrew_menu->GetShortTitle(); SetAction(Button::L, Action{i18n::get(label), [this]{ OnLRPress(m_filebrowser_menu, Button::L); }}); } - if (m_current_menu != m_app_store_menu) { - const auto label = m_current_menu == m_homebrew_menu ? "Store" : "Apps"; + 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(); SetAction(Button::R, Action{i18n::get(label), [this]{ - OnLRPress(m_app_store_menu, Button::R); + OnLRPress(m_right_side_menu, Button::R); }}); } }