simplify right-side shortcuts impl, add gamecard and themezer to shortcut list, fix l2/r2 using wrong icons, sort l2/r2 so l2 displays first.
some other changes: - shorten the next page and prev page to just next/prev in themezer. - remove misc shortcut name. the function itself still exists.
This commit is contained in:
@@ -46,6 +46,7 @@ struct Menu final : MenuBase {
|
|||||||
auto GetShortTitle() const -> const char* override { return "GC"; };
|
auto GetShortTitle() const -> const char* override { return "GC"; };
|
||||||
void Update(Controller* controller, TouchInfo* touch) override;
|
void Update(Controller* controller, TouchInfo* touch) override;
|
||||||
void Draw(NVGcontext* vg, Theme* theme) override;
|
void Draw(NVGcontext* vg, Theme* theme) override;
|
||||||
|
void OnFocusGained() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Result GcMount();
|
Result GcMount();
|
||||||
|
|||||||
@@ -17,6 +17,32 @@ enum class UpdateState {
|
|||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using MiscMenuFunction = std::function<std::shared_ptr<ui::menu::MenuBase>(void)>;
|
||||||
|
|
||||||
|
enum MiscMenuFlag : u8 {
|
||||||
|
// can be set as the rightside menu.
|
||||||
|
MiscMenuFlag_Shortcut = 1 << 0,
|
||||||
|
// needs install option to be enabled.
|
||||||
|
MiscMenuFlag_Install = 1 << 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MiscMenuEntry {
|
||||||
|
const char* name;
|
||||||
|
const char* title;
|
||||||
|
MiscMenuFunction func;
|
||||||
|
u8 flag;
|
||||||
|
|
||||||
|
auto IsShortcut() const -> bool {
|
||||||
|
return flag & MiscMenuFlag_Shortcut;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto IsInstall() const -> bool {
|
||||||
|
return flag & MiscMenuFlag_Install;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto GetMiscMenuEntries() -> std::span<const MiscMenuEntry>;
|
||||||
|
|
||||||
// this holds 2 menus and allows for switching between them
|
// this holds 2 menus and allows for switching between them
|
||||||
struct MainMenu final : Widget {
|
struct MainMenu final : Widget {
|
||||||
MainMenu();
|
MainMenu();
|
||||||
|
|||||||
@@ -7,14 +7,6 @@
|
|||||||
#include "ui/error_box.hpp"
|
#include "ui/error_box.hpp"
|
||||||
|
|
||||||
#include "ui/menus/main_menu.hpp"
|
#include "ui/menus/main_menu.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 "app.hpp"
|
||||||
#include "log.hpp"
|
#include "log.hpp"
|
||||||
@@ -1520,24 +1512,19 @@ void App::DisplayMiscOptions(bool left_side) {
|
|||||||
auto options = std::make_shared<ui::Sidebar>("Misc Options"_i18n, left_side ? ui::Sidebar::Side::LEFT : ui::Sidebar::Side::RIGHT);
|
auto options = std::make_shared<ui::Sidebar>("Misc Options"_i18n, left_side ? ui::Sidebar::Side::LEFT : ui::Sidebar::Side::RIGHT);
|
||||||
ON_SCOPE_EXIT(App::Push(options));
|
ON_SCOPE_EXIT(App::Push(options));
|
||||||
|
|
||||||
const auto push_if_not_same = [&]<typename T>(const char* name, const char* title){
|
for (auto& e : ui::menu::main::GetMiscMenuEntries()) {
|
||||||
if (g_app->m_right_side_menu.Get() != name) {
|
if (e.name == g_app->m_right_side_menu.Get()) {
|
||||||
options->Add(std::make_shared<ui::SidebarEntryCallback>(i18n::get(title), [](){
|
continue;
|
||||||
App::Push(std::make_shared<T>());
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
push_if_not_same.template operator()<ui::menu::appstore::Menu>("Appstore", "Appstore");
|
if (e.IsInstall() && !App::GetInstallEnable()) {
|
||||||
push_if_not_same.template operator()<ui::menu::game::Menu>("Games", "Games");
|
continue;
|
||||||
push_if_not_same.template operator()<ui::menu::themezer::Menu>("Themezer", "Themezer");
|
}
|
||||||
push_if_not_same.template operator()<ui::menu::gh::Menu>("GitHub", "GitHub");
|
|
||||||
if (App::GetInstallEnable()) {
|
options->Add(std::make_shared<ui::SidebarEntryCallback>(i18n::get(e.title), [e](){
|
||||||
push_if_not_same.template operator()<ui::menu::ftp::Menu>("FTP", "FTP Install");
|
App::Push(e.func());
|
||||||
push_if_not_same.template operator()<ui::menu::usb::Menu>("USB", "USB Install");
|
}));
|
||||||
push_if_not_same.template operator()<ui::menu::gc::Menu>("GameCard", "GameCard Install");
|
|
||||||
}
|
}
|
||||||
push_if_not_same.template operator()<ui::menu::irs::Menu>("IRS", "IRS (Infrared Joycon Camera)");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::DisplayAdvancedOptions(bool left_side) {
|
void App::DisplayAdvancedOptions(bool left_side) {
|
||||||
@@ -1549,12 +1536,18 @@ void App::DisplayAdvancedOptions(bool left_side) {
|
|||||||
text_scroll_speed_items.push_back("Normal"_i18n);
|
text_scroll_speed_items.push_back("Normal"_i18n);
|
||||||
text_scroll_speed_items.push_back("Fast"_i18n);
|
text_scroll_speed_items.push_back("Fast"_i18n);
|
||||||
|
|
||||||
static constexpr std::array menu_names{
|
std::vector<const char*> menu_names;
|
||||||
"Appstore",
|
for (auto& e : ui::menu::main::GetMiscMenuEntries()) {
|
||||||
"Games",
|
if (!e.IsShortcut()) {
|
||||||
"GitHub",
|
continue;
|
||||||
"IRS",
|
}
|
||||||
};
|
|
||||||
|
if (e.IsInstall() && !App::GetInstallEnable()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
menu_names.emplace_back(e.name);
|
||||||
|
}
|
||||||
|
|
||||||
ui::SidebarEntryArray::Items right_side_menu_items;
|
ui::SidebarEntryArray::Items right_side_menu_items;
|
||||||
for (auto& str : menu_names) {
|
for (auto& str : menu_names) {
|
||||||
@@ -1578,7 +1571,7 @@ void App::DisplayAdvancedOptions(bool left_side) {
|
|||||||
App::SetTextScrollSpeed(index_out);
|
App::SetTextScrollSpeed(index_out);
|
||||||
}, App::GetTextScrollSpeed()));
|
}, App::GetTextScrollSpeed()));
|
||||||
|
|
||||||
options->Add(std::make_shared<ui::SidebarEntryArray>("Set right-side menu"_i18n, right_side_menu_items, [](s64& index_out){
|
options->Add(std::make_shared<ui::SidebarEntryArray>("Set right-side menu"_i18n, right_side_menu_items, [menu_names](s64& index_out){
|
||||||
const auto e = menu_names[index_out];
|
const auto e = menu_names[index_out];
|
||||||
if (g_app->m_right_side_menu.Get() != e) {
|
if (g_app->m_right_side_menu.Get() != e) {
|
||||||
g_app->m_right_side_menu.Set(e);
|
g_app->m_right_side_menu.Set(e);
|
||||||
|
|||||||
@@ -184,8 +184,6 @@ Menu::Menu() : MenuBase{"GameCard"_i18n} {
|
|||||||
fsOpenDeviceOperator(std::addressof(m_dev_op));
|
fsOpenDeviceOperator(std::addressof(m_dev_op));
|
||||||
fsOpenGameCardDetectionEventNotifier(std::addressof(m_event_notifier));
|
fsOpenGameCardDetectionEventNotifier(std::addressof(m_event_notifier));
|
||||||
fsEventNotifierGetEventHandle(std::addressof(m_event_notifier), std::addressof(m_event), true);
|
fsEventNotifierGetEventHandle(std::addressof(m_event_notifier), std::addressof(m_event), true);
|
||||||
GcOnEvent();
|
|
||||||
UpdateStorageSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Menu::~Menu() {
|
Menu::~Menu() {
|
||||||
@@ -269,6 +267,13 @@ void Menu::Draw(NVGcontext* vg, Theme* theme) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Menu::OnFocusGained() {
|
||||||
|
MenuBase::OnFocusGained();
|
||||||
|
|
||||||
|
GcOnEvent();
|
||||||
|
UpdateStorageSize();
|
||||||
|
}
|
||||||
|
|
||||||
Result Menu::GcMount() {
|
Result Menu::GcMount() {
|
||||||
GcUnmount();
|
GcUnmount();
|
||||||
|
|
||||||
@@ -391,20 +396,18 @@ Result Menu::GcMount() {
|
|||||||
} else {
|
} else {
|
||||||
App::Notify("Gc install failed!"_i18n);
|
App::Notify("Gc install failed!"_i18n);
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateStorageSize();
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}});
|
}});
|
||||||
|
|
||||||
if (m_entries.size() > 1) {
|
if (m_entries.size() > 1) {
|
||||||
SetAction(Button::L, Action{"Prev"_i18n, [this](){
|
SetAction(Button::L2, Action{"Prev"_i18n, [this](){
|
||||||
if (m_entry_index != 0) {
|
if (m_entry_index != 0) {
|
||||||
OnChangeIndex(m_entry_index - 1);
|
OnChangeIndex(m_entry_index - 1);
|
||||||
}
|
}
|
||||||
}});
|
}});
|
||||||
SetAction(Button::R, Action{"Next"_i18n, [this](){
|
SetAction(Button::R2, Action{"Next"_i18n, [this](){
|
||||||
if (m_entry_index < m_entries.size()) {
|
if (m_entry_index < m_entries.size()) {
|
||||||
OnChangeIndex(m_entry_index + 1);
|
OnChangeIndex(m_entry_index + 1);
|
||||||
}
|
}
|
||||||
@@ -424,8 +427,8 @@ void Menu::GcUnmount() {
|
|||||||
m_lang_entry = {};
|
m_lang_entry = {};
|
||||||
FreeImage();
|
FreeImage();
|
||||||
|
|
||||||
RemoveAction(Button::L);
|
RemoveAction(Button::L2);
|
||||||
RemoveAction(Button::R);
|
RemoveAction(Button::R2);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Menu::GcPoll(bool* inserted) {
|
Result Menu::GcPoll(bool* inserted) {
|
||||||
|
|||||||
@@ -31,6 +31,22 @@ namespace {
|
|||||||
constexpr const char* GITHUB_URL{"https://api.github.com/repos/ITotalJustice/sphaira/releases/latest"};
|
constexpr const char* GITHUB_URL{"https://api.github.com/repos/ITotalJustice/sphaira/releases/latest"};
|
||||||
constexpr fs::FsPath CACHE_PATH{"/switch/sphaira/cache/sphaira_latest.json"};
|
constexpr fs::FsPath CACHE_PATH{"/switch/sphaira/cache/sphaira_latest.json"};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
auto MiscMenuFuncGenerator() {
|
||||||
|
return std::make_shared<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
const MiscMenuEntry MISC_MENU_ENTRIES[] = {
|
||||||
|
{ .name = "Appstore", .title = "Appstore", .func = MiscMenuFuncGenerator<ui::menu::appstore::Menu>, .flag = MiscMenuFlag_Shortcut },
|
||||||
|
{ .name = "Games", .title = "Games", .func = MiscMenuFuncGenerator<ui::menu::game::Menu>, .flag = MiscMenuFlag_Shortcut },
|
||||||
|
{ .name = "Themezer", .title = "Themezer", .func = MiscMenuFuncGenerator<ui::menu::themezer::Menu>, .flag = MiscMenuFlag_Shortcut },
|
||||||
|
{ .name = "GitHub", .title = "GitHub", .func = MiscMenuFuncGenerator<ui::menu::gh::Menu>, .flag = MiscMenuFlag_Shortcut },
|
||||||
|
{ .name = "FTP", .title = "FTP Install", .func = MiscMenuFuncGenerator<ui::menu::ftp::Menu>, .flag = MiscMenuFlag_Install },
|
||||||
|
{ .name = "USB", .title = "USB Install", .func = MiscMenuFuncGenerator<ui::menu::usb::Menu>, .flag = MiscMenuFlag_Install },
|
||||||
|
{ .name = "GameCard", .title = "GameCard Install", .func = MiscMenuFuncGenerator<ui::menu::gc::Menu>, .flag = MiscMenuFlag_Shortcut|MiscMenuFlag_Install },
|
||||||
|
{ .name = "IRS", .title = "IRS (Infrared Joycon Camera)", .func = MiscMenuFuncGenerator<ui::menu::irs::Menu>, .flag = MiscMenuFlag_Shortcut },
|
||||||
|
};
|
||||||
|
|
||||||
auto InstallUpdate(ProgressBox* pbox, const std::string url, const std::string version) -> bool {
|
auto InstallUpdate(ProgressBox* pbox, const std::string url, const std::string version) -> bool {
|
||||||
static fs::FsPath zip_out{"/switch/sphaira/cache/update.zip"};
|
static fs::FsPath zip_out{"/switch/sphaira/cache/update.zip"};
|
||||||
constexpr auto chunk_size = 1024 * 512; // 512KiB
|
constexpr auto chunk_size = 1024 * 512; // 512KiB
|
||||||
@@ -151,22 +167,10 @@ auto InstallUpdate(ProgressBox* pbox, const std::string url, const std::string v
|
|||||||
auto CreateRightSideMenu() -> std::shared_ptr<MenuBase> {
|
auto CreateRightSideMenu() -> std::shared_ptr<MenuBase> {
|
||||||
const auto name = App::GetApp()->m_right_side_menu.Get();
|
const auto name = App::GetApp()->m_right_side_menu.Get();
|
||||||
|
|
||||||
if ("Games" == name) {
|
for (auto& e : GetMiscMenuEntries()) {
|
||||||
return std::make_shared<ui::menu::game::Menu>();
|
if (e.name == name) {
|
||||||
}/*else if ("Themezer" == name) {
|
return e.func();
|
||||||
return std::make_shared<ui::menu::themezer::Menu>();
|
}
|
||||||
}*/else if ("GitHub" == name) {
|
|
||||||
return std::make_shared<ui::menu::gh::Menu>();
|
|
||||||
} else if ("IRS" == name) {
|
|
||||||
return std::make_shared<ui::menu::irs::Menu>();
|
|
||||||
} else if (App::GetInstallEnable()) {
|
|
||||||
// if ("FTP" == name) {
|
|
||||||
// return std::make_shared<ui::menu::ftp::Menu>();
|
|
||||||
// } else if ("USB" == name) {
|
|
||||||
// return std::make_shared<ui::menu::usb::Menu>();
|
|
||||||
// } else if ("GameCard" == name) {
|
|
||||||
// return std::make_shared<ui::menu::gc::Menu>();
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::make_shared<ui::menu::appstore::Menu>();
|
return std::make_shared<ui::menu::appstore::Menu>();
|
||||||
@@ -174,6 +178,10 @@ auto CreateRightSideMenu() -> std::shared_ptr<MenuBase> {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
auto GetMiscMenuEntries() -> std::span<const MiscMenuEntry> {
|
||||||
|
return MISC_MENU_ENTRIES;
|
||||||
|
}
|
||||||
|
|
||||||
MainMenu::MainMenu() {
|
MainMenu::MainMenu() {
|
||||||
curl::Api().ToFileAsync(
|
curl::Api().ToFileAsync(
|
||||||
curl::Url{GITHUB_URL},
|
curl::Url{GITHUB_URL},
|
||||||
@@ -241,9 +249,7 @@ MainMenu::MainMenu() {
|
|||||||
|
|
||||||
this->SetActions(
|
this->SetActions(
|
||||||
std::make_pair(Button::START, Action{App::Exit}),
|
std::make_pair(Button::START, Action{App::Exit}),
|
||||||
std::make_pair(Button::SELECT, Action{"Misc"_i18n, [this](){
|
std::make_pair(Button::SELECT, Action{App::DisplayMiscOptions}),
|
||||||
App::DisplayMiscOptions();
|
|
||||||
}}),
|
|
||||||
std::make_pair(Button::Y, Action{"Menu"_i18n, [this](){
|
std::make_pair(Button::Y, Action{"Menu"_i18n, [this](){
|
||||||
auto options = std::make_shared<Sidebar>("Menu Options"_i18n, "v" APP_VERSION_HASH, Sidebar::Side::LEFT);
|
auto options = std::make_shared<Sidebar>("Menu Options"_i18n, "v" APP_VERSION_HASH, Sidebar::Side::LEFT);
|
||||||
ON_SCOPE_EXIT(App::Push(options));
|
ON_SCOPE_EXIT(App::Push(options));
|
||||||
|
|||||||
@@ -453,7 +453,7 @@ Menu::Menu() : MenuBase{"Themezer"_i18n} {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}}),
|
}}),
|
||||||
std::make_pair(Button::R, Action{"Next Page"_i18n, [this](){
|
std::make_pair(Button::R2, Action{"Next"_i18n, [this](){
|
||||||
m_page_index++;
|
m_page_index++;
|
||||||
if (m_page_index >= m_page_index_max) {
|
if (m_page_index >= m_page_index_max) {
|
||||||
m_page_index = m_page_index_max - 1;
|
m_page_index = m_page_index_max - 1;
|
||||||
@@ -461,7 +461,7 @@ Menu::Menu() : MenuBase{"Themezer"_i18n} {
|
|||||||
PackListDownload();
|
PackListDownload();
|
||||||
}
|
}
|
||||||
}}),
|
}}),
|
||||||
std::make_pair(Button::L, Action{"Prev Page"_i18n, [this](){
|
std::make_pair(Button::L2, Action{"Prev"_i18n, [this](){
|
||||||
if (m_page_index) {
|
if (m_page_index) {
|
||||||
m_page_index--;
|
m_page_index--;
|
||||||
PackListDownload();
|
PackListDownload();
|
||||||
|
|||||||
@@ -21,10 +21,8 @@ constexpr std::array buttons = {
|
|||||||
std::pair{Button::Y, "\uE0E3"},
|
std::pair{Button::Y, "\uE0E3"},
|
||||||
std::pair{Button::L, "\uE0E4"},
|
std::pair{Button::L, "\uE0E4"},
|
||||||
std::pair{Button::R, "\uE0E5"},
|
std::pair{Button::R, "\uE0E5"},
|
||||||
std::pair{Button::L, "\uE0E6"},
|
std::pair{Button::L2, "\uE0E6"},
|
||||||
std::pair{Button::R, "\uE0E7"},
|
std::pair{Button::R2, "\uE0E7"},
|
||||||
std::pair{Button::L2, "\uE0E8"},
|
|
||||||
std::pair{Button::R2, "\uE0E9"},
|
|
||||||
std::pair{Button::UP, "\uE0EB"},
|
std::pair{Button::UP, "\uE0EB"},
|
||||||
std::pair{Button::DOWN, "\uE0EC"},
|
std::pair{Button::DOWN, "\uE0EC"},
|
||||||
std::pair{Button::LEFT, "\uE0ED"},
|
std::pair{Button::LEFT, "\uE0ED"},
|
||||||
|
|||||||
@@ -86,6 +86,11 @@ auto Widget::GetUiButtons() const -> uiButtons {
|
|||||||
uiButtons draw_actions;
|
uiButtons draw_actions;
|
||||||
draw_actions.reserve(m_actions.size());
|
draw_actions.reserve(m_actions.size());
|
||||||
|
|
||||||
|
const std::pair<Button, Button> swap_buttons[] = {
|
||||||
|
{Button::L, Button::R},
|
||||||
|
{Button::L2, Button::R2},
|
||||||
|
};
|
||||||
|
|
||||||
// build array
|
// build array
|
||||||
for (const auto& [button, action] : m_actions) {
|
for (const auto& [button, action] : m_actions) {
|
||||||
if (action.IsHidden() || action.m_hint.empty()) {
|
if (action.IsHidden() || action.m_hint.empty()) {
|
||||||
@@ -94,13 +99,19 @@ auto Widget::GetUiButtons() const -> uiButtons {
|
|||||||
|
|
||||||
uiButton ui_button{button, action};
|
uiButton ui_button{button, action};
|
||||||
|
|
||||||
// swap
|
bool should_swap = false;
|
||||||
if (button == Button::R && draw_actions.size() && draw_actions.back().m_button == Button::L) {
|
for (auto [left, right] : swap_buttons) {
|
||||||
const auto s = draw_actions.back();
|
if (button == right && draw_actions.size() && draw_actions.back().m_button == left) {
|
||||||
draw_actions.back().m_button = button;
|
const auto s = draw_actions.back();
|
||||||
draw_actions.back().m_action = action;
|
draw_actions.back().m_button = button;
|
||||||
draw_actions.emplace_back(s);
|
draw_actions.back().m_action = action;
|
||||||
} else {
|
draw_actions.emplace_back(s);
|
||||||
|
should_swap = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!should_swap) {
|
||||||
draw_actions.emplace_back(ui_button);
|
draw_actions.emplace_back(ui_button);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user