backport widget changes from totalsms
This commit is contained in:
@@ -302,7 +302,7 @@ 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::OptionLong m_install_prompt{INI_SECTION, "install_prompt", 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};
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
namespace sphaira::ui::gfx {
|
namespace sphaira::ui::gfx {
|
||||||
|
|
||||||
void drawImage(NVGcontext*, float x, float y, float w, float h, int texture, float rounded = 0.F);
|
void drawImage(NVGcontext*, float x, float y, float w, float h, int texture, float rounded = 0.F, float alpha = 1.0F);
|
||||||
void drawImage(NVGcontext*, const Vec4& v, int texture, float rounded = 0.F);
|
void drawImage(NVGcontext*, const Vec4& v, int texture, float rounded = 0.F, float alpha = 1.0F);
|
||||||
|
|
||||||
void dimBackground(NVGcontext*);
|
void dimBackground(NVGcontext*);
|
||||||
|
|
||||||
|
|||||||
@@ -32,9 +32,10 @@ public:
|
|||||||
using Options = std::vector<Option>;
|
using Options = std::vector<Option>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OptionBox(const std::string& message, const Option& a, Callback cb = [](auto){}, int image = 0); // confirm
|
OptionBox(const std::string& message, const Option& a, const Callback& cb = [](auto){}, int image = 0, bool own_image = false); // confirm
|
||||||
OptionBox(const std::string& message, const Option& a, const Option& b, Callback cb, int image = 0); // yesno
|
OptionBox(const std::string& message, const Option& a, const Option& b, const Callback& cb, int image = 0, bool own_image = false); // yesno
|
||||||
OptionBox(const std::string& message, const Option& a, const Option& b, s64 index, Callback cb, int image = 0); // yesno
|
OptionBox(const std::string& message, const Option& a, const Option& b, s64 index, const Callback& cb, int image = 0, bool own_image = false); // yesno
|
||||||
|
~OptionBox();
|
||||||
|
|
||||||
auto Update(Controller* controller, TouchInfo* touch) -> void override;
|
auto Update(Controller* controller, TouchInfo* touch) -> void override;
|
||||||
auto Draw(NVGcontext* vg, Theme* theme) -> void override;
|
auto Draw(NVGcontext* vg, Theme* theme) -> void override;
|
||||||
@@ -46,9 +47,10 @@ private:
|
|||||||
void SetIndex(s64 index);
|
void SetIndex(s64 index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_message{};
|
const std::string m_message;
|
||||||
Callback m_callback{};
|
const Callback m_callback;
|
||||||
int m_image{};
|
const int m_image;
|
||||||
|
const bool m_own_image;
|
||||||
|
|
||||||
Vec4 m_spacer_line{};
|
Vec4 m_spacer_line{};
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr Vec2 m_title_pos{70.f, 28.f};
|
static constexpr Vec2 m_title_pos{70.f, 28.f};
|
||||||
static constexpr Vec4 m_block{280.f, 110.f, 720.f, 60.f};
|
static constexpr Vec4 m_block{280.f, 110.f, SCREEN_HEIGHT, 60.f};
|
||||||
static constexpr float m_text_xoffset{15.f};
|
static constexpr float m_text_xoffset{15.f};
|
||||||
static constexpr float m_line_width{1220.f};
|
static constexpr float m_line_width{1220.f};
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "ui/widget.hpp"
|
#include "ui/widget.hpp"
|
||||||
#include "ui/list.hpp"
|
#include "ui/list.hpp"
|
||||||
#include "ui/scrolling_text.hpp"
|
#include "ui/scrolling_text.hpp"
|
||||||
|
#include "option.hpp"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <concepts>
|
#include <concepts>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@@ -34,6 +35,8 @@ public:
|
|||||||
public:
|
public:
|
||||||
explicit SidebarEntryBool(const std::string& title, bool option, Callback cb, const std::string& info = "", const std::string& true_str = "On", const std::string& false_str = "Off");
|
explicit SidebarEntryBool(const std::string& title, bool option, Callback cb, const std::string& info = "", const std::string& true_str = "On", const std::string& false_str = "Off");
|
||||||
explicit SidebarEntryBool(const std::string& title, bool& option, const std::string& info = "", const std::string& true_str = "On", const std::string& false_str = "Off");
|
explicit SidebarEntryBool(const std::string& title, bool& option, const std::string& info = "", const std::string& true_str = "On", const std::string& false_str = "Off");
|
||||||
|
explicit SidebarEntryBool(const std::string& title, option::OptionBool& option, const Callback& cb, const std::string& info = "", const std::string& true_str = "On", const std::string& false_str = "Off");
|
||||||
|
explicit SidebarEntryBool(const std::string& title, option::OptionBool& option, const std::string& info = "", const std::string& true_str = "On", const std::string& false_str = "Off");
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Draw(NVGcontext* vg, Theme* theme, const Vec4& root_pos, bool left) override;
|
void Draw(NVGcontext* vg, Theme* theme, const Vec4& root_pos, bool left) override;
|
||||||
|
|||||||
@@ -274,6 +274,13 @@ enum class Button : u64 {
|
|||||||
START = static_cast<u64>(HidNpadButton_Plus),
|
START = static_cast<u64>(HidNpadButton_Plus),
|
||||||
SELECT = static_cast<u64>(HidNpadButton_Minus),
|
SELECT = static_cast<u64>(HidNpadButton_Minus),
|
||||||
|
|
||||||
|
SL_LEFT = static_cast<u64>(HidNpadButton_LeftSL),
|
||||||
|
SR_LEFT = static_cast<u64>(HidNpadButton_LeftSR),
|
||||||
|
SL_RIGHT = static_cast<u64>(HidNpadButton_RightSL),
|
||||||
|
SR_RIGHT = static_cast<u64>(HidNpadButton_RightSR),
|
||||||
|
SL_ANY = SL_LEFT | SL_RIGHT,
|
||||||
|
SR_ANY = SR_LEFT | SR_RIGHT,
|
||||||
|
|
||||||
// todo:
|
// todo:
|
||||||
DPAD_LEFT = static_cast<u64>(HidNpadButton_Left),
|
DPAD_LEFT = static_cast<u64>(HidNpadButton_Left),
|
||||||
DPAD_RIGHT = static_cast<u64>(HidNpadButton_Right),
|
DPAD_RIGHT = static_cast<u64>(HidNpadButton_Right),
|
||||||
|
|||||||
@@ -10,11 +10,14 @@
|
|||||||
namespace sphaira::ui {
|
namespace sphaira::ui {
|
||||||
|
|
||||||
struct uiButton final : Object {
|
struct uiButton final : Object {
|
||||||
uiButton(Button button, Action action) : m_button{button}, m_action{action} {}
|
uiButton(Button button, const std::string& button_str, const std::string& action_str);
|
||||||
|
uiButton(Button button, const std::string& action_str);
|
||||||
|
|
||||||
auto Draw(NVGcontext* vg, Theme* theme) -> void override;
|
auto Draw(NVGcontext* vg, Theme* theme) -> void override;
|
||||||
|
|
||||||
Button m_button;
|
Button m_button;
|
||||||
Action m_action;
|
std::string m_button_str;
|
||||||
|
std::string m_action_str;
|
||||||
Vec4 m_button_pos{};
|
Vec4 m_button_pos{};
|
||||||
Vec4 m_hint_pos{};
|
Vec4 m_hint_pos{};
|
||||||
};
|
};
|
||||||
@@ -84,6 +87,8 @@ struct Widget : public Object {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto GetUiButtons() const -> uiButtons;
|
auto GetUiButtons() const -> uiButtons;
|
||||||
|
static void SetupUiButtons(uiButtons& buttons, const Vec2& button_pos = {1220, 675});
|
||||||
|
static auto GetUiButtons(const Actions& actions, const Vec2& button_pos = {1220, 675}) -> uiButtons;
|
||||||
|
|
||||||
Actions m_actions{};
|
Actions m_actions{};
|
||||||
Vec2 m_button_pos{1220, 675};
|
Vec2 m_button_pos{1220, 675};
|
||||||
|
|||||||
@@ -1710,10 +1710,9 @@ void App::DisplayAdvancedOptions(bool left_side) {
|
|||||||
}, "When enabled, it replaces /hbmenu.nro with Sphaira, creating a backup of hbmenu to /switch/hbmenu.nro\n\n" \
|
}, "When enabled, it replaces /hbmenu.nro with Sphaira, creating a backup of hbmenu to /switch/hbmenu.nro\n\n" \
|
||||||
"Disabling will give you the option to restore hbmenu."_i18n);
|
"Disabling will give you the option to restore hbmenu."_i18n);
|
||||||
|
|
||||||
options->Add<ui::SidebarEntryBool>("Boost CPU during transfer"_i18n, App::GetApp()->m_progress_boost_mode.Get(), [](bool& enable){
|
options->Add<ui::SidebarEntryBool>("Boost CPU during transfer"_i18n, App::GetApp()->m_progress_boost_mode,
|
||||||
App::GetApp()->m_progress_boost_mode.Set(enable);
|
"Enables boost mode during transfers which can improve transfer speed. "\
|
||||||
}, "Enables boost mode during transfers which can improve transfer speed. "\
|
"This sets the CPU to 1785mhz and lowers the GPU 76mhz"_i18n);
|
||||||
"This sets the CPU to 1785mhz and lowers the GPU 76mhz"_i18n);
|
|
||||||
|
|
||||||
options->Add<ui::SidebarEntryArray>("Text scroll speed"_i18n, text_scroll_speed_items, [](s64& index_out){
|
options->Add<ui::SidebarEntryArray>("Text scroll speed"_i18n, text_scroll_speed_items, [](s64& index_out){
|
||||||
App::SetTextScrollSpeed(index_out);
|
App::SetTextScrollSpeed(index_out);
|
||||||
@@ -1797,124 +1796,90 @@ void App::DisplayInstallOptions(bool left_side) {
|
|||||||
App::SetInstallEmummcEnable(enable);
|
App::SetInstallEmummcEnable(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.Get(), [](bool& enable){
|
options->Add<ui::SidebarEntryBool>("Show install warning"_i18n, App::GetApp()->m_install_prompt,
|
||||||
App::GetApp()->m_install_prompt.Set(enable);
|
"When enabled, a warning is show when attempting to install a forwarder."_i18n);
|
||||||
}, "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());
|
||||||
|
|
||||||
options->Add<ui::SidebarEntryBool>("Allow downgrade"_i18n, App::GetApp()->m_allow_downgrade.Get(), [](bool& enable){
|
options->Add<ui::SidebarEntryBool>("Allow downgrade"_i18n, App::GetApp()->m_allow_downgrade,
|
||||||
App::GetApp()->m_allow_downgrade.Set(enable);
|
"Allows for installing title updates that are lower than the currently installed update."_i18n);
|
||||||
}, "Allows for installing title updates that are lower than the currently installed update."_i18n);
|
|
||||||
|
|
||||||
options->Add<ui::SidebarEntryBool>("Skip if already installed"_i18n, App::GetApp()->m_skip_if_already_installed.Get(), [](bool& enable){
|
options->Add<ui::SidebarEntryBool>("Skip if already installed"_i18n, App::GetApp()->m_skip_if_already_installed,
|
||||||
App::GetApp()->m_skip_if_already_installed.Set(enable);
|
"Skips installing titles / ncas if they're already installed."_i18n);
|
||||||
}, "Skips installing titles / ncas if they're already installed."_i18n);
|
|
||||||
|
|
||||||
options->Add<ui::SidebarEntryBool>("Ticket only"_i18n, App::GetApp()->m_ticket_only.Get(), [](bool& enable){
|
options->Add<ui::SidebarEntryBool>("Ticket only"_i18n, App::GetApp()->m_ticket_only,
|
||||||
App::GetApp()->m_ticket_only.Set(enable);
|
"Installs tickets only, useful if the title was already installed however the tickets were missing or corrupted."_i18n);
|
||||||
}, "Installs tickets only, useful if the title was already installed however the tickets were missing or corrupted."_i18n);
|
|
||||||
|
|
||||||
options->Add<ui::SidebarEntryBool>("Skip base"_i18n, App::GetApp()->m_skip_base.Get(), [](bool& enable){
|
options->Add<ui::SidebarEntryBool>("Skip base"_i18n, App::GetApp()->m_skip_base,
|
||||||
App::GetApp()->m_skip_base.Set(enable);
|
"Skips installing the base application."_i18n);
|
||||||
}, "Skips installing the base application."_i18n);
|
|
||||||
|
|
||||||
options->Add<ui::SidebarEntryBool>("Skip patch"_i18n, App::GetApp()->m_skip_patch.Get(), [](bool& enable){
|
options->Add<ui::SidebarEntryBool>("Skip patch"_i18n, App::GetApp()->m_skip_patch,
|
||||||
App::GetApp()->m_skip_patch.Set(enable);
|
"Skips installing updates."_i18n);
|
||||||
}, "Skips installing updates."_i18n);
|
|
||||||
|
|
||||||
options->Add<ui::SidebarEntryBool>("Skip dlc"_i18n, App::GetApp()->m_skip_addon.Get(), [](bool& enable){
|
options->Add<ui::SidebarEntryBool>("Skip dlc"_i18n, App::GetApp()->m_skip_addon,
|
||||||
App::GetApp()->m_skip_addon.Set(enable);
|
"Skips installing DLC."_i18n);
|
||||||
}, "Skips installing DLC."_i18n);
|
|
||||||
|
|
||||||
options->Add<ui::SidebarEntryBool>("Skip data patch"_i18n, App::GetApp()->m_skip_data_patch.Get(), [](bool& enable){
|
options->Add<ui::SidebarEntryBool>("Skip data patch"_i18n, App::GetApp()->m_skip_data_patch,
|
||||||
App::GetApp()->m_skip_data_patch.Set(enable);
|
"Skips installing DLC update (data patch)."_i18n);
|
||||||
}, "Skips installing DLC update (data patch)."_i18n);
|
|
||||||
|
|
||||||
options->Add<ui::SidebarEntryBool>("Skip ticket"_i18n, App::GetApp()->m_skip_ticket.Get(), [](bool& enable){
|
options->Add<ui::SidebarEntryBool>("Skip ticket"_i18n, App::GetApp()->m_skip_ticket,
|
||||||
App::GetApp()->m_skip_ticket.Set(enable);
|
"Skips installing tickets, not recommended."_i18n);
|
||||||
}, "Skips installing tickets, not recommended."_i18n);
|
|
||||||
|
|
||||||
options->Add<ui::SidebarEntryBool>("Skip NCA hash verify"_i18n, App::GetApp()->m_skip_nca_hash_verify.Get(), [](bool& enable){
|
options->Add<ui::SidebarEntryBool>("Skip NCA hash verify"_i18n, App::GetApp()->m_skip_nca_hash_verify,
|
||||||
App::GetApp()->m_skip_nca_hash_verify.Set(enable);
|
"Enables the option to skip sha256 verification. This is a hash over the entire NCA. "\
|
||||||
}, "Enables the option to skip sha256 verification. This is a hash over the entire NCA. "\
|
"It is used to verify that the NCA is valid / not corrupted. "\
|
||||||
"It is used to verify that the NCA is valid / not corrupted. "\
|
"You may have seen the option for \"checking for corrupted data\" when a corrupted game is installed. "\
|
||||||
"You may have seen the option for \"checking for corrupted data\" when a corrupted game is installed. "\
|
"That check performs various hash checks, including the hash over the NCA.\n\n"\
|
||||||
"That check performs various hash checks, including the hash over the NCA.\n\n"\
|
"It is recommended to keep this disabled."_i18n);
|
||||||
"It is recommended to keep this disabled."_i18n);
|
|
||||||
|
|
||||||
options->Add<ui::SidebarEntryBool>("Skip RSA header verify"_i18n, App::GetApp()->m_skip_rsa_header_fixed_key_verify.Get(), [](bool& enable){
|
options->Add<ui::SidebarEntryBool>("Skip RSA header verify"_i18n, App::GetApp()->m_skip_rsa_header_fixed_key_verify,
|
||||||
App::GetApp()->m_skip_rsa_header_fixed_key_verify.Set(enable);
|
"Enables the option to skip RSA NCA fixed key verification. "\
|
||||||
}, "Enables the option to skip RSA NCA fixed key verification. "\
|
"This is a hash over the NCA header. It is used to verify that the header has not been modified. "\
|
||||||
"This is a hash over the NCA header. It is used to verify that the header has not been modified. "\
|
"The header is signed by nintendo, thus it cannot be forged, and is reliable to detect modified NCA headers (such as NSP/XCI converts).\n\n"\
|
||||||
"The header is signed by nintendo, thus it cannot be forged, and is reliable to detect modified NCA headers (such as NSP/XCI converts).\n\n"\
|
"It is recommended to keep this disabled, unless you need to install nsp/xci converts."_i18n);
|
||||||
"It is recommended to keep this disabled, unless you need to install nsp/xci converts."_i18n);
|
|
||||||
|
|
||||||
options->Add<ui::SidebarEntryBool>("Skip RSA NPDM verify"_i18n, App::GetApp()->m_skip_rsa_npdm_fixed_key_verify.Get(), [](bool& enable){
|
options->Add<ui::SidebarEntryBool>("Skip RSA NPDM verify"_i18n, App::GetApp()->m_skip_rsa_npdm_fixed_key_verify,
|
||||||
App::GetApp()->m_skip_rsa_npdm_fixed_key_verify.Set(enable);
|
"Enables the option to skip RSA NPDM fixed key verification.\n\n"\
|
||||||
}, "Enables the option to skip RSA NPDM fixed key verification.\n\n"\
|
"Currently, this option is stubbed (not implemented)."_i18n);
|
||||||
"Currently, this option is stubbed (not implemented)."_i18n);
|
|
||||||
|
|
||||||
options->Add<ui::SidebarEntryBool>("Ignore distribution bit"_i18n, App::GetApp()->m_ignore_distribution_bit.Get(), [](bool& enable){
|
options->Add<ui::SidebarEntryBool>("Ignore distribution bit"_i18n, App::GetApp()->m_ignore_distribution_bit,
|
||||||
App::GetApp()->m_ignore_distribution_bit.Set(enable);
|
"If set, it will ignore the distribution bit in the NCA header. "\
|
||||||
}, "If set, it will ignore the distribution bit in the NCA header. "\
|
"The distribution bit is used to signify whether a NCA is Eshop or GameCard. "\
|
||||||
"The distribution bit is used to signify whether a NCA is Eshop or GameCard. "\
|
"You cannot (normally) launch install games that have the distruction bit set to GameCard.\n\n"\
|
||||||
"You cannot (normally) launch install games that have the distruction bit set to GameCard.\n\n"\
|
"It is recommended to keep this disabled."_i18n);
|
||||||
"It is recommended to keep this disabled."_i18n);
|
|
||||||
|
|
||||||
options->Add<ui::SidebarEntryBool>("Convert to common ticket"_i18n, App::GetApp()->m_convert_to_common_ticket.Get(), [](bool& enable){
|
options->Add<ui::SidebarEntryBool>("Convert to common ticket"_i18n, App::GetApp()->m_convert_to_common_ticket,
|
||||||
App::GetApp()->m_convert_to_common_ticket.Set(enable);
|
"[Requires keys] Converts personalised tickets to common (fake) tickets.\n\n"\
|
||||||
}, "[Requires keys] Converts personalised tickets to common (fake) tickets.\n\n"\
|
"It is recommended to keep this enabled."_i18n);
|
||||||
"It is recommended to keep this enabled."_i18n);
|
|
||||||
|
|
||||||
options->Add<ui::SidebarEntryBool>("Convert to standard crypto"_i18n, App::GetApp()->m_convert_to_standard_crypto.Get(), [](bool& enable){
|
options->Add<ui::SidebarEntryBool>("Convert to standard crypto"_i18n, App::GetApp()->m_convert_to_standard_crypto,
|
||||||
App::GetApp()->m_convert_to_standard_crypto.Set(enable);
|
"[Requires keys] Converts titlekey to standard crypto, also known as \"ticketless\".\n\n"\
|
||||||
}, "[Requires keys] Converts titlekey to standard crypto, also known as \"ticketless\".\n\n"\
|
"It is recommended to keep this disabled."_i18n);
|
||||||
"It is recommended to keep this disabled."_i18n);
|
|
||||||
|
|
||||||
options->Add<ui::SidebarEntryBool>("Lower master key"_i18n, App::GetApp()->m_lower_master_key.Get(), [](bool& enable){
|
options->Add<ui::SidebarEntryBool>("Lower master key"_i18n, App::GetApp()->m_lower_master_key,
|
||||||
App::GetApp()->m_lower_master_key.Set(enable);
|
"[Requires keys] Encrypts the keak (key area key) with master key 0, which allows the game to be launched on every fw. "\
|
||||||
}, "[Requires keys] Encrypts the keak (key area key) with master key 0, which allows the game to be launched on every fw. "\
|
"Implicitly performs standard crypto.\n\n"\
|
||||||
"Implicitly performs standard crypto.\n\n"\
|
"Do note that just because the game can be launched on any fw (as it can be decrypted), doesn't mean it will work. It is strongly recommened to update your firmware and Atmosphere version in order to play the game, rather than enabling this option.\n\n"\
|
||||||
"Do note that just because the game can be launched on any fw (as it can be decrypted), doesn't mean it will work. It is strongly recommened to update your firmware and Atmosphere version in order to play the game, rather than enabling this option.\n\n"\
|
"It is recommended to keep this disabled."_i18n);
|
||||||
"It is recommended to keep this disabled."_i18n);
|
|
||||||
|
|
||||||
options->Add<ui::SidebarEntryBool>("Lower system version"_i18n, App::GetApp()->m_lower_system_version.Get(), [](bool& enable){
|
options->Add<ui::SidebarEntryBool>("Lower system version"_i18n, App::GetApp()->m_lower_system_version,
|
||||||
App::GetApp()->m_lower_system_version.Set(enable);
|
"Sets the system_firmware field in the cnmt extended header to 0. "\
|
||||||
}, "Sets the system_firmware field in the cnmt extended header to 0. "\
|
"Note: if the master key is higher than fw version, the game still won't launch as the fw won't have the key to decrypt keak (see above).\n\n"\
|
||||||
"Note: if the master key is higher than fw version, the game still won't launch as the fw won't have the key to decrypt keak (see above).\n\n"\
|
"It is recommended to keep this disabled."_i18n);
|
||||||
"It is recommended to keep this disabled."_i18n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::DisplayDumpOptions(bool left_side) {
|
void App::DisplayDumpOptions(bool left_side) {
|
||||||
auto options = std::make_unique<ui::Sidebar>("Dump Options"_i18n, left_side ? ui::Sidebar::Side::LEFT : ui::Sidebar::Side::RIGHT);
|
auto options = std::make_unique<ui::Sidebar>("Dump Options"_i18n, left_side ? ui::Sidebar::Side::LEFT : ui::Sidebar::Side::RIGHT);
|
||||||
ON_SCOPE_EXIT(App::Push(std::move(options)));
|
ON_SCOPE_EXIT(App::Push(std::move(options)));
|
||||||
|
|
||||||
options->Add<ui::SidebarEntryBool>("Created nested folder"_i18n, App::GetApp()->m_dump_app_folder.Get(), [](bool& enable){
|
options->Add<ui::SidebarEntryBool>("Created nested folder"_i18n, App::GetApp()->m_dump_app_folder);
|
||||||
App::GetApp()->m_dump_app_folder.Set(enable);
|
options->Add<ui::SidebarEntryBool>("Append folder with .xci"_i18n, App::GetApp()->m_dump_append_folder_with_xci);
|
||||||
});
|
options->Add<ui::SidebarEntryBool>("Trim XCI"_i18n, App::GetApp()->m_dump_trim_xci);
|
||||||
|
options->Add<ui::SidebarEntryBool>("Label trimmed XCI"_i18n, App::GetApp()->m_dump_label_trim_xci);
|
||||||
options->Add<ui::SidebarEntryBool>("Append folder with .xci"_i18n, App::GetApp()->m_dump_append_folder_with_xci.Get(), [](bool& enable){
|
options->Add<ui::SidebarEntryBool>("Multi-threaded USB transfer"_i18n, App::GetApp()->m_dump_usb_transfer_stream);
|
||||||
App::GetApp()->m_dump_append_folder_with_xci.Set(enable);
|
options->Add<ui::SidebarEntryBool>("Convert to common ticket"_i18n, App::GetApp()->m_dump_convert_to_common_ticket);
|
||||||
});
|
|
||||||
|
|
||||||
options->Add<ui::SidebarEntryBool>("Trim XCI"_i18n, App::GetApp()->m_dump_trim_xci.Get(), [](bool& enable){
|
|
||||||
App::GetApp()->m_dump_trim_xci.Set(enable);
|
|
||||||
});
|
|
||||||
|
|
||||||
options->Add<ui::SidebarEntryBool>("Label trimmed XCI"_i18n, App::GetApp()->m_dump_label_trim_xci.Get(), [](bool& enable){
|
|
||||||
App::GetApp()->m_dump_label_trim_xci.Set(enable);
|
|
||||||
});
|
|
||||||
|
|
||||||
options->Add<ui::SidebarEntryBool>("Multi-threaded USB transfer"_i18n, App::GetApp()->m_dump_usb_transfer_stream.Get(), [](bool& enable){
|
|
||||||
App::GetApp()->m_dump_usb_transfer_stream.Set(enable);
|
|
||||||
});
|
|
||||||
|
|
||||||
options->Add<ui::SidebarEntryBool>("Convert to common ticket"_i18n, App::GetApp()->m_dump_convert_to_common_ticket.Get(), [](bool& enable){
|
|
||||||
App::GetApp()->m_dump_convert_to_common_ticket.Set(enable);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
App::~App() {
|
App::~App() {
|
||||||
|
|||||||
@@ -79,7 +79,8 @@ void drawRectOutlineInternal(NVGcontext* vg, const Theme* theme, float size, con
|
|||||||
float gradientX, gradientY, color;
|
float gradientX, gradientY, color;
|
||||||
getHighlightAnimation(&gradientX, &gradientY, &color);
|
getHighlightAnimation(&gradientX, &gradientY, &color);
|
||||||
|
|
||||||
const auto strokeWidth = 5.F;
|
const auto strokeWidth = size;
|
||||||
|
// const auto strokeWidth = 5.F;
|
||||||
auto v2 = v;
|
auto v2 = v;
|
||||||
v2.x -= strokeWidth / 2.F;
|
v2.x -= strokeWidth / 2.F;
|
||||||
v2.y -= strokeWidth / 2.F;
|
v2.y -= strokeWidth / 2.F;
|
||||||
@@ -209,13 +210,13 @@ void drawTextArgs(NVGcontext* vg, float x, float y, float size, int align, const
|
|||||||
drawText(vg, x, y, size, buffer, nullptr, align, c);
|
drawText(vg, x, y, size, buffer, nullptr, align, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawImage(NVGcontext* vg, const Vec4& v, int texture, float rounded) {
|
void drawImage(NVGcontext* vg, const Vec4& v, int texture, float rounded, float alpha) {
|
||||||
const auto paint = nvgImagePattern(vg, v.x, v.y, v.w, v.h, 0, texture, 1.f);
|
const auto paint = nvgImagePattern(vg, v.x, v.y, v.w, v.h, 0, texture, alpha);
|
||||||
drawRect(vg, v, paint, rounded);
|
drawRect(vg, v, paint, rounded);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawImage(NVGcontext* vg, float x, float y, float w, float h, int texture, float rounded) {
|
void drawImage(NVGcontext* vg, float x, float y, float w, float h, int texture, float rounded, float alpha) {
|
||||||
drawImage(vg, Vec4(x, y, w, h), texture, rounded);
|
drawImage(vg, Vec4(x, y, w, h), texture, rounded, alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawTextBox(NVGcontext* vg, float x, float y, float size, float bound, const NVGcolor& c, const char* str, int align, const char* end) {
|
void drawTextBox(NVGcontext* vg, float x, float y, float size, float bound, const NVGcolor& c, const char* str, int align, const char* end) {
|
||||||
|
|||||||
@@ -23,14 +23,16 @@ auto OptionBoxEntry::Selected(bool enable) -> void {
|
|||||||
m_selected = enable;
|
m_selected = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionBox::OptionBox(const std::string& message, const Option& a, Callback cb, int image)
|
OptionBox::OptionBox(const std::string& message, const Option& a, const Callback& cb, int image, bool own_image)
|
||||||
: m_message{message}
|
: m_message{message}
|
||||||
, m_callback{cb} {
|
, m_callback{cb}
|
||||||
|
, m_image{image}
|
||||||
|
, m_own_image{own_image} {
|
||||||
|
|
||||||
m_pos.w = 770.f;
|
m_pos.w = 770.f;
|
||||||
m_pos.h = 295.f;
|
m_pos.h = 295.f;
|
||||||
m_pos.x = (1280.f / 2.f) - (m_pos.w / 2.f);
|
m_pos.x = (SCREEN_WIDTH / 2.f) - (m_pos.w / 2.f);
|
||||||
m_pos.y = (720.f / 2.f) - (m_pos.h / 2.f);
|
m_pos.y = (SCREEN_HEIGHT / 2.f) - (m_pos.h / 2.f);
|
||||||
|
|
||||||
auto box = m_pos;
|
auto box = m_pos;
|
||||||
box.y += 220.f;
|
box.y += 220.f;
|
||||||
@@ -40,15 +42,16 @@ OptionBox::OptionBox(const std::string& message, const Option& a, Callback cb, i
|
|||||||
Setup(0);
|
Setup(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionBox::OptionBox(const std::string& message, const Option& a, const Option& b, Callback cb, int image)
|
OptionBox::OptionBox(const std::string& message, const Option& a, const Option& b, const Callback& cb, int image, bool own_image)
|
||||||
: OptionBox{message, a, b, 0, cb, image} {
|
: OptionBox{message, a, b, 0, cb, image, own_image} {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionBox::OptionBox(const std::string& message, const Option& a, const Option& b, s64 index, Callback cb, int image)
|
OptionBox::OptionBox(const std::string& message, const Option& a, const Option& b, s64 index, const Callback& cb, int image, bool own_image)
|
||||||
: m_message{message}
|
: m_message{message}
|
||||||
, m_callback{cb}
|
, m_callback{cb}
|
||||||
, m_image{image} {
|
, m_image{image}
|
||||||
|
, m_own_image{own_image} {
|
||||||
|
|
||||||
m_pos.w = 770.f;
|
m_pos.w = 770.f;
|
||||||
m_pos.h = 295.f;
|
m_pos.h = 295.f;
|
||||||
@@ -66,6 +69,12 @@ OptionBox::OptionBox(const std::string& message, const Option& a, const Option&
|
|||||||
Setup(index);
|
Setup(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OptionBox::~OptionBox() {
|
||||||
|
if (m_image && m_own_image) {
|
||||||
|
nvgDeleteImage(App::GetVg(), m_image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto OptionBox::Update(Controller* controller, TouchInfo* touch) -> void {
|
auto OptionBox::Update(Controller* controller, TouchInfo* touch) -> void {
|
||||||
Widget::Update(controller, touch);
|
Widget::Update(controller, touch);
|
||||||
|
|
||||||
|
|||||||
@@ -76,16 +76,16 @@ PopupList::PopupList(std::string title, Items items, Callback cb, s64 index)
|
|||||||
|
|
||||||
m_starting_index = m_index;
|
m_starting_index = m_index;
|
||||||
|
|
||||||
m_pos.w = 1280.f;
|
m_pos.w = SCREEN_WIDTH;
|
||||||
const float a = std::min(370.f, (60.f * static_cast<float>(m_items.size())));
|
const float a = std::min(370.f, (60.f * static_cast<float>(m_items.size())));
|
||||||
m_pos.h = 80.f + 140.f + a;
|
m_pos.h = 80.f + 140.f + a;
|
||||||
m_pos.y = 720.f - m_pos.h;
|
m_pos.y = SCREEN_HEIGHT - m_pos.h;
|
||||||
m_line_top = m_pos.y + 70.f;
|
m_line_top = m_pos.y + 70.f;
|
||||||
m_line_bottom = 720.f - 73.f;
|
m_line_bottom = SCREEN_HEIGHT - 73.f;
|
||||||
|
|
||||||
Vec4 v{m_block};
|
Vec4 v{m_block};
|
||||||
v.y = m_line_top + 1.f + 42.f;
|
v.y = m_line_top + 1.f + 42.f;
|
||||||
const Vec4 pos{0, m_line_top, 1280.f, m_line_bottom - m_line_top};
|
const Vec4 pos{0, m_line_top, SCREEN_WIDTH, m_line_bottom - m_line_top};
|
||||||
m_list = std::make_unique<List>(1, 6, pos, v);
|
m_list = std::make_unique<List>(1, 6, pos, v);
|
||||||
m_list->SetScrollBarPos(1250, m_line_top + 20, m_line_bottom - m_line_top - 40);
|
m_list->SetScrollBarPos(1250, m_line_top + 20, m_line_bottom - m_line_top - 40);
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ void DrawClipped(NVGcontext* vg, const Vec4& clip, float x, float y, float size,
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void ScrollingText::Draw(NVGcontext* vg, bool focus, float x, float y, float w, float size, int align, const NVGcolor& colour, const std::string& text_entry) {
|
void ScrollingText::Draw(NVGcontext* vg, bool focus, float x, float y, float w, float size, int align, const NVGcolor& colour, const std::string& text_entry) {
|
||||||
const Vec4 clip{x, 0, w, 720};
|
const Vec4 clip{x, 0, w, SCREEN_HEIGHT};
|
||||||
|
|
||||||
if (!focus) {
|
if (!focus) {
|
||||||
DrawClipped(vg, clip, x, y, size, align, colour, text_entry);
|
DrawClipped(vg, clip, x, y, size, align, colour, text_entry);
|
||||||
|
|||||||
@@ -99,11 +99,25 @@ SidebarEntryBool::SidebarEntryBool(const std::string& title, bool option, Callba
|
|||||||
|
|
||||||
SidebarEntryBool::SidebarEntryBool(const std::string& title, bool& option, const std::string& info, const std::string& true_str, const std::string& false_str)
|
SidebarEntryBool::SidebarEntryBool(const std::string& title, bool& option, const std::string& info, const std::string& true_str, const std::string& false_str)
|
||||||
: SidebarEntryBool{title, option, Callback{}, info, true_str, false_str} {
|
: SidebarEntryBool{title, option, Callback{}, info, true_str, false_str} {
|
||||||
m_callback = [](bool& option){
|
m_callback = [&option](bool&){
|
||||||
option ^= 1;
|
option ^= 1;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SidebarEntryBool::SidebarEntryBool(const std::string& title, option::OptionBool& option, const Callback& cb, const std::string& info, const std::string& true_str, const std::string& false_str)
|
||||||
|
: SidebarEntryBool{title, option.Get(), Callback{}, info, true_str, false_str} {
|
||||||
|
m_callback = [&option, cb](bool& v_out){
|
||||||
|
if (cb) {
|
||||||
|
cb(v_out);
|
||||||
|
}
|
||||||
|
option.Set(v_out);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
SidebarEntryBool::SidebarEntryBool(const std::string& title, option::OptionBool& option, const std::string& info, const std::string& true_str, const std::string& false_str)
|
||||||
|
: SidebarEntryBool{title, option, Callback{}, info, true_str, false_str} {
|
||||||
|
}
|
||||||
|
|
||||||
void SidebarEntryBool::Draw(NVGcontext* vg, Theme* theme, const Vec4& root_pos, bool left) {
|
void SidebarEntryBool::Draw(NVGcontext* vg, Theme* theme, const Vec4& root_pos, bool left) {
|
||||||
SidebarEntryBase::Draw(vg, theme, root_pos, left);
|
SidebarEntryBase::Draw(vg, theme, root_pos, left);
|
||||||
|
|
||||||
@@ -271,11 +285,11 @@ Sidebar::Sidebar(const std::string& title, const std::string& sub, Side side, It
|
|||||||
, m_items{std::forward<decltype(items)>(items)} {
|
, m_items{std::forward<decltype(items)>(items)} {
|
||||||
switch (m_side) {
|
switch (m_side) {
|
||||||
case Side::LEFT:
|
case Side::LEFT:
|
||||||
SetPos(Vec4{0.f, 0.f, 450.f, 720.f});
|
SetPos(Vec4{0.f, 0.f, 450.f, SCREEN_HEIGHT});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Side::RIGHT:
|
case Side::RIGHT:
|
||||||
SetPos(Vec4{1280.f - 450.f, 0.f, 450.f, 720.f});
|
SetPos(Vec4{SCREEN_WIDTH - 450.f, 0.f, 450.f, SCREEN_HEIGHT});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,18 @@
|
|||||||
|
|
||||||
namespace sphaira::ui {
|
namespace sphaira::ui {
|
||||||
|
|
||||||
|
uiButton::uiButton(Button button, const std::string& button_str, const std::string& action_str)
|
||||||
|
: m_button{button}
|
||||||
|
, m_button_str{button_str}
|
||||||
|
, m_action_str{action_str} {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uiButton::uiButton(Button button, const std::string& action_str)
|
||||||
|
: uiButton{button, gfx::getButton(button), action_str} {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
auto uiButton::Draw(NVGcontext* vg, Theme* theme) -> void {
|
auto uiButton::Draw(NVGcontext* vg, Theme* theme) -> void {
|
||||||
// enable to see button region
|
// enable to see button region
|
||||||
// gfx::drawRect(vg, m_pos, gfx::Colour::RED);
|
// gfx::drawRect(vg, m_pos, gfx::Colour::RED);
|
||||||
@@ -12,9 +24,9 @@ auto uiButton::Draw(NVGcontext* vg, Theme* theme) -> void {
|
|||||||
nvgTextAlign(vg, NVG_ALIGN_RIGHT | NVG_ALIGN_TOP);
|
nvgTextAlign(vg, NVG_ALIGN_RIGHT | NVG_ALIGN_TOP);
|
||||||
nvgFillColor(vg, theme->GetColour(ThemeEntryID_TEXT));
|
nvgFillColor(vg, theme->GetColour(ThemeEntryID_TEXT));
|
||||||
nvgFontSize(vg, 20);
|
nvgFontSize(vg, 20);
|
||||||
nvgText(vg, m_hint_pos.x, m_hint_pos.y, m_action.m_hint.c_str(), nullptr);
|
nvgText(vg, m_hint_pos.x, m_hint_pos.y, m_action_str.c_str(), nullptr);
|
||||||
nvgFontSize(vg, 26);
|
nvgFontSize(vg, 26);
|
||||||
nvgText(vg, m_button_pos.x, m_button_pos.y, gfx::getButton(m_button), nullptr);
|
nvgText(vg, m_button_pos.x, m_button_pos.y, m_button_str.c_str(), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::Update(Controller* controller, TouchInfo* touch) {
|
void Widget::Update(Controller* controller, TouchInfo* touch) {
|
||||||
@@ -39,7 +51,7 @@ void Widget::Update(Controller* controller, TouchInfo* touch) {
|
|||||||
auto draw_actions = GetUiButtons();
|
auto draw_actions = GetUiButtons();
|
||||||
for (auto& e : draw_actions) {
|
for (auto& e : draw_actions) {
|
||||||
if (touch->is_clicked && touch->in_range(e.GetPos())) {
|
if (touch->is_clicked && touch->in_range(e.GetPos())) {
|
||||||
log_write("got click: %s\n", e.m_action.m_hint.c_str());
|
log_write("got click: %s\n", e.m_action_str.c_str());
|
||||||
FireAction(e.m_button);
|
FireAction(e.m_button);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -79,12 +91,37 @@ auto Widget::FireAction(Button b, u8 type) -> bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Widget::GetUiButtons() const -> uiButtons {
|
void Widget::SetupUiButtons(uiButtons& buttons, const Vec2& button_pos) {
|
||||||
auto vg = App::GetVg();
|
auto vg = App::GetVg();
|
||||||
auto [x, y] = m_button_pos;
|
auto [x, y] = button_pos;
|
||||||
|
|
||||||
|
float bounds[4]{};
|
||||||
|
for (auto& e : buttons) {
|
||||||
|
nvgTextAlign(vg, NVG_ALIGN_RIGHT | NVG_ALIGN_TOP);
|
||||||
|
|
||||||
|
nvgFontSize(vg, 20.f);
|
||||||
|
nvgTextBounds(vg, x, y, e.m_action_str.c_str(), nullptr, bounds);
|
||||||
|
auto len = bounds[2] - bounds[0];
|
||||||
|
e.m_hint_pos = {x, y, len, 20};
|
||||||
|
|
||||||
|
x -= len + 8.f;
|
||||||
|
nvgFontSize(vg, 26.f);
|
||||||
|
nvgTextBounds(vg, x, y - 7.f, e.m_button_str.c_str(), nullptr, bounds);
|
||||||
|
len = bounds[2] - bounds[0];
|
||||||
|
e.m_button_pos = {x, y - 4.f, len, 26};
|
||||||
|
x -= len + 34.f;
|
||||||
|
|
||||||
|
e.SetPos(e.m_button_pos);
|
||||||
|
e.SetX(e.GetX() - 40);
|
||||||
|
e.SetW(e.m_hint_pos.x - e.m_button_pos.x + len + 25);
|
||||||
|
e.SetY(e.GetY() - 18);
|
||||||
|
e.SetH(26 + 18 * 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Widget::GetUiButtons(const Actions& actions, const Vec2& button_pos) -> uiButtons {
|
||||||
uiButtons draw_actions;
|
uiButtons draw_actions;
|
||||||
draw_actions.reserve(m_actions.size());
|
draw_actions.reserve(actions.size());
|
||||||
|
|
||||||
const std::pair<Button, Button> swap_buttons[] = {
|
const std::pair<Button, Button> swap_buttons[] = {
|
||||||
{Button::L, Button::R},
|
{Button::L, Button::R},
|
||||||
@@ -92,19 +129,20 @@ auto Widget::GetUiButtons() const -> uiButtons {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// build array
|
// build array
|
||||||
for (const auto& [button, action] : m_actions) {
|
for (const auto& [button, action] : actions) {
|
||||||
if (action.IsHidden() || action.m_hint.empty()) {
|
if (action.IsHidden() || action.m_hint.empty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
uiButton ui_button{button, action};
|
uiButton ui_button{button, action.m_hint};
|
||||||
|
|
||||||
bool should_swap = false;
|
bool should_swap = false;
|
||||||
for (auto [left, right] : swap_buttons) {
|
for (auto [left, right] : swap_buttons) {
|
||||||
if (button == right && draw_actions.size() && draw_actions.back().m_button == left) {
|
if (button == right && draw_actions.size() && draw_actions.back().m_button == left) {
|
||||||
const auto s = draw_actions.back();
|
const auto s = draw_actions.back();
|
||||||
draw_actions.back().m_button = button;
|
draw_actions.back().m_button = button;
|
||||||
draw_actions.back().m_action = action;
|
draw_actions.back().m_button_str = gfx::getButton(button);
|
||||||
|
draw_actions.back().m_action_str = action.m_hint;
|
||||||
draw_actions.emplace_back(s);
|
draw_actions.emplace_back(s);
|
||||||
should_swap = true;
|
should_swap = true;
|
||||||
break;
|
break;
|
||||||
@@ -116,30 +154,14 @@ auto Widget::GetUiButtons() const -> uiButtons {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float bounds[4]{};
|
// setup positions.
|
||||||
for (auto& e : draw_actions) {
|
SetupUiButtons(draw_actions, button_pos);
|
||||||
nvgTextAlign(vg, NVG_ALIGN_RIGHT | NVG_ALIGN_TOP);
|
|
||||||
|
|
||||||
nvgFontSize(vg, 20.f);
|
|
||||||
nvgTextBounds(vg, x, y, e.m_action.m_hint.c_str(), nullptr, bounds);
|
|
||||||
auto len = bounds[2] - bounds[0];
|
|
||||||
e.m_hint_pos = {x, 675, len, 20};
|
|
||||||
|
|
||||||
x -= len + 8.f;
|
|
||||||
nvgFontSize(vg, 26.f);
|
|
||||||
nvgTextBounds(vg, x, y - 7.f, gfx::getButton(e.m_button), nullptr, bounds);
|
|
||||||
len = bounds[2] - bounds[0];
|
|
||||||
e.m_button_pos = {x, 675 - 4.f, len, 26};
|
|
||||||
x -= len + 34.f;
|
|
||||||
|
|
||||||
e.SetPos(e.m_button_pos);
|
|
||||||
e.SetX(e.GetX() - 40);
|
|
||||||
e.SetW(e.m_hint_pos.x - e.m_button_pos.x + len + 25);
|
|
||||||
e.SetY(e.GetY() - 18);
|
|
||||||
e.SetH(26 + 18 * 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
return draw_actions;
|
return draw_actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto Widget::GetUiButtons() const -> uiButtons {
|
||||||
|
return GetUiButtons(m_actions, m_button_pos);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace sphaira::ui
|
} // namespace sphaira::ui
|
||||||
|
|||||||
Reference in New Issue
Block a user