sidebar: add callback when a disabled option is clicked. install: option to enable when a disabled option is clicked.

This commit is contained in:
ITotalJustice
2025-08-02 18:30:56 +01:00
parent 620334439c
commit ed02b0f260
6 changed files with 75 additions and 51 deletions

View File

@@ -103,7 +103,6 @@ public:
static auto GetInstallSysmmcEnable() -> bool; static auto GetInstallSysmmcEnable() -> bool;
static auto GetInstallEmummcEnable() -> bool; static auto GetInstallEmummcEnable() -> bool;
static auto GetInstallSdEnable() -> bool; static auto GetInstallSdEnable() -> bool;
static auto GetInstallPrompt() -> bool;
static auto GetThemeMusicEnable() -> bool; static auto GetThemeMusicEnable() -> bool;
static auto Get12HourTimeEnable() -> bool; static auto Get12HourTimeEnable() -> bool;
static auto GetLanguage() -> long; static auto GetLanguage() -> long;
@@ -138,6 +137,11 @@ public:
static void DisplayInstallOptions(bool left_side = true); static void DisplayInstallOptions(bool left_side = true);
static void DisplayDumpOptions(bool left_side = true); static void DisplayDumpOptions(bool left_side = true);
// helper for sidebar options to toggle install on/off
static void ShowEnableInstallPromptOption(option::OptionBool& option, bool& enable);
// displays an option box to enable installing, shows warning.
static void ShowEnableInstallPrompt();
void Draw(); void Draw();
void Update(); void Update();
void Poll(); void Poll();
@@ -302,7 +306,6 @@ public:
option::OptionBool m_install_sysmmc{INI_SECTION, "install_sysmmc", false}; option::OptionBool m_install_sysmmc{INI_SECTION, "install_sysmmc", false};
option::OptionBool m_install_emummc{INI_SECTION, "install_emummc", false}; option::OptionBool m_install_emummc{INI_SECTION, "install_emummc", false};
option::OptionBool m_install_sd{INI_SECTION, "install_sd", true}; option::OptionBool m_install_sd{INI_SECTION, "install_sd", true};
option::OptionBool m_install_prompt{INI_SECTION, "install_prompt", true};
option::OptionBool m_allow_downgrade{INI_SECTION, "allow_downgrade", false}; option::OptionBool m_allow_downgrade{INI_SECTION, "allow_downgrade", false};
option::OptionBool m_skip_if_already_installed{INI_SECTION, "skip_if_already_installed", true}; option::OptionBool m_skip_if_already_installed{INI_SECTION, "skip_if_already_installed", true};
option::OptionBool m_ticket_only{INI_SECTION, "ticket_only", false}; option::OptionBool m_ticket_only{INI_SECTION, "ticket_only", false};

View File

@@ -13,6 +13,7 @@ namespace sphaira::ui {
class SidebarEntryBase : public Widget { class SidebarEntryBase : public Widget {
public: public:
using DependsCallback = std::function<bool(void)>; using DependsCallback = std::function<bool(void)>;
using DependsClickCallback = std::function<void(void)>;
public: public:
explicit SidebarEntryBase(const std::string& title, const std::string& info); explicit SidebarEntryBase(const std::string& title, const std::string& info);
@@ -20,23 +21,26 @@ public:
using Widget::Draw; using Widget::Draw;
virtual void Draw(NVGcontext* vg, Theme* theme, const Vec4& root_pos, bool left); virtual void Draw(NVGcontext* vg, Theme* theme, const Vec4& root_pos, bool left);
void Depends(const DependsCallback& callback, const std::string& depends_info) { void Depends(const DependsCallback& callback, const std::string& depends_info, const DependsClickCallback& depends_click = {}) {
m_depends_callback = callback; m_depends_callback = callback;
m_depends_info = depends_info; m_depends_info = depends_info;
m_depends_click = depends_click;
} }
void Depends(bool& value, const std::string& depends_info) { void Depends(bool& value, const std::string& depends_info, const DependsClickCallback& depends_click = {}) {
m_depends_callback = [&value](){ return value; }; m_depends_callback = [&value](){ return value; };
m_depends_info = depends_info; m_depends_info = depends_info;
m_depends_click = depends_click;
} }
void Depends(option::OptionBool& value, const std::string& depends_info) { void Depends(option::OptionBool& value, const std::string& depends_info, const DependsClickCallback& depends_click = {}) {
m_depends_callback = [&value](){ return value.Get(); }; m_depends_callback = [&value](){ return value.Get(); };
m_depends_info = depends_info; m_depends_info = depends_info;
m_depends_click = depends_click;
} }
protected: protected:
auto IsEnabled() -> bool { auto IsEnabled() const -> bool {
if (m_depends_callback) { if (m_depends_callback) {
return m_depends_callback(); return m_depends_callback();
} }
@@ -44,6 +48,12 @@ protected:
return true; return true;
} }
void DependsClick() const {
if (m_depends_click) {
m_depends_click();
}
}
protected: protected:
std::string m_title; std::string m_title;
@@ -51,6 +61,7 @@ private:
std::string m_info{}; std::string m_info{};
std::string m_depends_info{}; std::string m_depends_info{};
DependsCallback m_depends_callback{}; DependsCallback m_depends_callback{};
DependsClickCallback m_depends_click{};
ScrollingText m_scolling_title{}; ScrollingText m_scolling_title{};
}; };

View File

@@ -661,10 +661,6 @@ auto App::GetInstallSdEnable() -> bool {
return g_app->m_install_sd.Get(); return g_app->m_install_sd.Get();
} }
auto App::GetInstallPrompt() -> bool {
return g_app->m_install_prompt.Get();
}
auto App::GetThemeMusicEnable() -> bool { auto App::GetThemeMusicEnable() -> bool {
return g_app->m_theme_music.Get(); return g_app->m_theme_music.Get();
} }
@@ -849,10 +845,6 @@ void App::SetInstallSdEnable(bool enable) {
g_app->m_install_sd.Set(enable); g_app->m_install_sd.Set(enable);
} }
void App::SetInstallPrompt(bool enable) {
g_app->m_install_prompt.Set(enable);
}
void App::SetThemeMusicEnable(bool enable) { void App::SetThemeMusicEnable(bool enable) {
g_app->m_theme_music.Set(enable); g_app->m_theme_music.Set(enable);
PlaySoundEffect(SoundEffect::SoundEffect_Music); PlaySoundEffect(SoundEffect::SoundEffect_Music);
@@ -1336,7 +1328,6 @@ App::App(const char* argv0) {
else if (app->m_install_sysmmc.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_emummc.LoadFrom(Key, Value)) {}
else if (app->m_install_sd.LoadFrom(Key, Value)) {} else if (app->m_install_sd.LoadFrom(Key, Value)) {}
else if (app->m_install_prompt.LoadFrom(Key, Value)) {}
else if (app->m_progress_boost_mode.LoadFrom(Key, Value)) {} else if (app->m_progress_boost_mode.LoadFrom(Key, Value)) {}
else if (app->m_allow_downgrade.LoadFrom(Key, Value)) {} else if (app->m_allow_downgrade.LoadFrom(Key, Value)) {}
else if (app->m_skip_if_already_installed.LoadFrom(Key, Value)) {} else if (app->m_skip_if_already_installed.LoadFrom(Key, Value)) {}
@@ -1665,7 +1656,7 @@ void App::DisplayMiscOptions(bool left_side) {
}, i18n::get(e.info)); }, i18n::get(e.info));
if (e.IsInstall()) { if (e.IsInstall()) {
entry->Depends(App::GetInstallEnable, i18n::get(App::INSTALL_DEPENDS_STR)); entry->Depends(App::GetInstallEnable, i18n::get(App::INSTALL_DEPENDS_STR), App::ShowEnableInstallPrompt);
} }
} }
@@ -1809,16 +1800,13 @@ void App::DisplayInstallOptions(bool left_side) {
install_items.push_back("microSD card"_i18n); install_items.push_back("microSD card"_i18n);
options->Add<ui::SidebarEntryBool>("Enable sysmmc"_i18n, App::GetInstallSysmmcEnable(), [](bool& enable){ options->Add<ui::SidebarEntryBool>("Enable sysmmc"_i18n, App::GetInstallSysmmcEnable(), [](bool& enable){
App::SetInstallSysmmcEnable(enable); ShowEnableInstallPromptOption(g_app->m_install_sysmmc, enable);
}, "Enables installing whilst in sysMMC mode."_i18n); }, "Enables installing whilst in sysMMC mode."_i18n);
options->Add<ui::SidebarEntryBool>("Enable emummc"_i18n, App::GetInstallEmummcEnable(), [](bool& enable){ options->Add<ui::SidebarEntryBool>("Enable emummc"_i18n, App::GetInstallEmummcEnable(), [](bool& enable){
App::SetInstallEmummcEnable(enable); ShowEnableInstallPromptOption(g_app->m_install_emummc, enable);
}, "Enables installing whilst in emuMMC mode."_i18n); }, "Enables installing whilst in emuMMC mode."_i18n);
options->Add<ui::SidebarEntryBool>("Show install warning"_i18n, App::GetApp()->m_install_prompt,
"When enabled, a warning is show when attempting to install a forwarder."_i18n);
options->Add<ui::SidebarEntryArray>("Install location"_i18n, install_items, [](s64& index_out){ options->Add<ui::SidebarEntryArray>("Install location"_i18n, install_items, [](s64& index_out){
App::SetInstallSdEnable(index_out); App::SetInstallSdEnable(index_out);
}, (s64)App::GetInstallSdEnable()); }, (s64)App::GetInstallSdEnable());
@@ -1921,6 +1909,44 @@ void App::DisplayDumpOptions(bool left_side) {
); );
} }
void App::ShowEnableInstallPrompt() {
// warn the user the dangers of installing.
App::Push<ui::OptionBox>(
"Installing is disabled, enable now?"_i18n,
"Back"_i18n, "Enable"_i18n, 0, [](auto op_index){
if (op_index && *op_index) {
// get the install option based on sysmmc/emummc.
auto& option = IsEmummc() ? g_app->m_install_emummc : g_app->m_install_sysmmc;
// dummy ref.
static bool enable{};
enable = true;
return ShowEnableInstallPromptOption(option, enable);
}
}
);
}
void App::ShowEnableInstallPromptOption(option::OptionBool& option, bool& enable) {
if (enable) {
// warn the user the dangers of installing.
App::Push<ui::OptionBox>(
"WARNING: Installing apps will lead to a ban!"_i18n,
"Back"_i18n, "Enable"_i18n, 0, [&option, &enable](auto op_index){
if (op_index && *op_index) {
option.Set(true);
App::Notify("Installing enabled!"_i18n);
} else {
enable = false;
}
}
);
} else {
option.Set(false);
}
}
App::~App() { App::~App() {
// boost mode is disabled in userAppExit(). // boost mode is disabled in userAppExit().
App::SetBoostMode(true); App::SetBoostMode(true);

View File

@@ -1689,27 +1689,16 @@ void FsView::DisplayOptions() {
auto entry = options->Add<SidebarEntryCallback>("Install"_i18n, [this](){ auto entry = options->Add<SidebarEntryCallback>("Install"_i18n, [this](){
InstallFiles(); InstallFiles();
}); });
entry->Depends(App::GetInstallEnable, i18n::get(App::INSTALL_DEPENDS_STR)); entry->Depends(App::GetInstallEnable, i18n::get(App::INSTALL_DEPENDS_STR), App::ShowEnableInstallPrompt);
} }
} }
if (IsSd() && m_entries_current.size() && !m_selected_count) { if (IsSd() && m_entries_current.size() && !m_selected_count) {
if (GetEntry().IsFile() && (IsSamePath(GetEntry().GetExtension(), "nro") || !m_menu->FindFileAssocFor().empty())) { if (GetEntry().IsFile() && (IsSamePath(GetEntry().GetExtension(), "nro") || !m_menu->FindFileAssocFor().empty())) {
auto entry = options->Add<SidebarEntryCallback>("Install Forwarder"_i18n, [this](){; auto entry = options->Add<SidebarEntryCallback>("Install Forwarder"_i18n, [this](){;
if (App::GetInstallPrompt()) { InstallForwarder();
App::Push<OptionBox>(
"WARNING: Installing forwarders will lead to a ban!"_i18n,
"Back"_i18n, "Install"_i18n, 0, [this](auto op_index){
if (op_index && *op_index) {
InstallForwarder();
}
}
);
} else {
InstallForwarder();
}
}); });
entry->Depends(App::GetInstallEnable, i18n::get(App::INSTALL_DEPENDS_STR)); entry->Depends(App::GetInstallEnable, i18n::get(App::INSTALL_DEPENDS_STR), App::ShowEnableInstallPrompt);
} }
} }

View File

@@ -493,21 +493,10 @@ void Menu::DisplayOptions() {
"Use the FileBrowser to delete them."_i18n); "Use the FileBrowser to delete them."_i18n);
auto forwarder_entry = options->Add<SidebarEntryCallback>("Install Forwarder"_i18n, [this](){ auto forwarder_entry = options->Add<SidebarEntryCallback>("Install Forwarder"_i18n, [this](){
if (App::GetInstallPrompt()) { InstallHomebrew();
App::Push<OptionBox>(
"WARNING: Installing forwarders will lead to a ban!"_i18n,
"Back"_i18n, "Install"_i18n, 0, [this](auto op_index){
if (op_index && *op_index) {
InstallHomebrew();
}
}, GetEntry().image
);
} else {
InstallHomebrew();
}
}, true); }, true);
forwarder_entry->Depends(App::GetInstallEnable, i18n::get(App::INSTALL_DEPENDS_STR)); forwarder_entry->Depends(App::GetInstallEnable, i18n::get(App::INSTALL_DEPENDS_STR), App::ShowEnableInstallPrompt);
} }
} }

View File

@@ -93,7 +93,9 @@ SidebarEntryBool::SidebarEntryBool(const std::string& title, bool option, Callba
} }
SetAction(Button::A, Action{"OK"_i18n, [this](){ SetAction(Button::A, Action{"OK"_i18n, [this](){
if (IsEnabled()) { if (!IsEnabled()) {
DependsClick();
} else {
m_option ^= 1; m_option ^= 1;
m_callback(m_option); m_callback(m_option);
} } } }
@@ -144,7 +146,9 @@ SidebarEntryCallback::SidebarEntryCallback(const std::string& title, Callback cb
, m_callback{cb} , m_callback{cb}
, m_pop_on_click{pop_on_click} { , m_pop_on_click{pop_on_click} {
SetAction(Button::A, Action{"OK"_i18n, [this](){ SetAction(Button::A, Action{"OK"_i18n, [this](){
if (IsEnabled()) { if (!IsEnabled()) {
DependsClick();
} else {
m_callback(); m_callback();
if (m_pop_on_click) { if (m_pop_on_click) {
SetPop(); SetPop();
@@ -211,7 +215,9 @@ SidebarEntryArray::SidebarEntryArray(const std::string& title, const Items& item
}; };
SetAction(Button::A, Action{"OK"_i18n, [this](){ SetAction(Button::A, Action{"OK"_i18n, [this](){
if (IsEnabled()) { if (!IsEnabled()) {
DependsClick();
} else {
// m_callback(m_index); // m_callback(m_index);
m_list_callback(); m_list_callback();
}} }}