@@ -80,6 +80,7 @@ public:
|
||||
static auto GetThemeShuffleEnable() -> bool;
|
||||
static auto GetThemeMusicEnable() -> bool;
|
||||
static auto GetLanguage() -> long;
|
||||
static auto GetTextScrollSpeed() -> long;
|
||||
|
||||
static void SetMtpEnable(bool enable);
|
||||
static void SetFtpEnable(bool enable);
|
||||
@@ -92,6 +93,7 @@ public:
|
||||
static void SetThemeShuffleEnable(bool enable);
|
||||
static void SetThemeMusicEnable(bool enable);
|
||||
static void SetLanguage(long index);
|
||||
static void SetTextScrollSpeed(long index);
|
||||
|
||||
static auto Install(OwoConfig& config) -> Result;
|
||||
static auto Install(ui::ProgressBox* pbox, OwoConfig& config) -> Result;
|
||||
@@ -161,6 +163,8 @@ public:
|
||||
option::OptionBool m_theme_shuffle{INI_SECTION, "theme_shuffle", false};
|
||||
option::OptionBool m_theme_music{INI_SECTION, "theme_music", true};
|
||||
option::OptionLong m_language{INI_SECTION, "language", 0}; // auto
|
||||
// todo: move this into it's own menu
|
||||
option::OptionLong m_text_scroll_speed{"accessibility", "text_scroll_speed", 1}; // normal
|
||||
|
||||
PLSR_BFSAR m_qlaunch_bfsar{};
|
||||
PLSR_PlayerSoundId m_sound_ids[SoundEffect_MAX]{};
|
||||
|
||||
@@ -57,12 +57,16 @@ public:
|
||||
SidebarEntryArray(std::string title, Items items, std::string& index);
|
||||
|
||||
auto Draw(NVGcontext* vg, Theme* theme) -> void override;
|
||||
auto OnFocusGained() noexcept -> void override;
|
||||
auto OnFocusLost() noexcept -> void override;
|
||||
|
||||
private:
|
||||
Items m_items;
|
||||
ListCallback m_list_callback;
|
||||
Callback m_callback;
|
||||
s64 m_index;
|
||||
s64 m_tick{};
|
||||
float m_text_yoff{};
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
|
||||
@@ -585,6 +585,10 @@ auto App::GetLanguage() -> long {
|
||||
return g_app->m_language.Get();
|
||||
}
|
||||
|
||||
auto App::GetTextScrollSpeed() -> long {
|
||||
return g_app->m_text_scroll_speed.Get();
|
||||
}
|
||||
|
||||
void App::SetNxlinkEnable(bool enable) {
|
||||
if (App::GetNxlinkEnable() != enable) {
|
||||
g_app->m_nxlink_enabled.Set(enable);
|
||||
@@ -767,6 +771,10 @@ void App::SetLanguage(long index) {
|
||||
}
|
||||
}
|
||||
|
||||
void App::SetTextScrollSpeed(long index) {
|
||||
g_app->m_text_scroll_speed.Set(index);
|
||||
}
|
||||
|
||||
auto App::Install(OwoConfig& config) -> Result {
|
||||
R_TRY(romfsInit());
|
||||
ON_SCOPE_EXIT(romfsExit());
|
||||
|
||||
@@ -329,6 +329,11 @@ MainMenu::MainMenu() {
|
||||
install_items.push_back("System memory"_i18n);
|
||||
install_items.push_back("microSD card"_i18n);
|
||||
|
||||
SidebarEntryArray::Items text_scroll_speed_items;
|
||||
text_scroll_speed_items.push_back("Slow"_i18n);
|
||||
text_scroll_speed_items.push_back("Normal"_i18n);
|
||||
text_scroll_speed_items.push_back("Fast"_i18n);
|
||||
|
||||
options->Add(std::make_shared<SidebarEntryBool>("Logging"_i18n, App::GetLogEnable(), [this](bool& enable){
|
||||
App::SetLogEnable(enable);
|
||||
}, "Enabled"_i18n, "Disabled"_i18n));
|
||||
@@ -348,6 +353,10 @@ MainMenu::MainMenu() {
|
||||
options->Add(std::make_shared<SidebarEntryBool>("Show install warning"_i18n, App::GetInstallPrompt(), [this](bool& enable){
|
||||
App::SetInstallPrompt(enable);
|
||||
}, "Enabled"_i18n, "Disabled"_i18n));
|
||||
|
||||
options->Add(std::make_shared<SidebarEntryArray>("Text scroll speed"_i18n, text_scroll_speed_items, [this](s64& index_out){
|
||||
App::SetTextScrollSpeed(index_out);
|
||||
}, (s64)App::GetTextScrollSpeed()));
|
||||
}));
|
||||
}})
|
||||
);
|
||||
|
||||
@@ -7,6 +7,14 @@
|
||||
namespace sphaira::ui {
|
||||
namespace {
|
||||
|
||||
auto GetTextScrollSpeed() -> float {
|
||||
switch (App::GetTextScrollSpeed()) {
|
||||
case 0: return 0.5;
|
||||
default: case 1: return 1.0;
|
||||
case 2: return 1.5;
|
||||
}
|
||||
}
|
||||
|
||||
auto DistanceBetweenY(Vec4 va, Vec4 vb) -> Vec4 {
|
||||
return Vec4{
|
||||
va.x, va.y,
|
||||
@@ -147,11 +155,59 @@ auto SidebarEntryArray::Draw(NVGcontext* vg, Theme* theme) -> void {
|
||||
SidebarEntryBase::Draw(vg, theme);
|
||||
|
||||
const auto& text_entry = m_items[m_index];
|
||||
// const auto& colour = HasFocus() ? theme->GetColour(ThemeEntryID_TEXT_SELECTED) : theme->GetColour(ThemeEntryID_TEXT);
|
||||
const auto& colour = theme->GetColour(ThemeEntryID_TEXT);
|
||||
|
||||
gfx::drawText(vg, Vec2{m_pos.x + 15.f, m_pos.y + (m_pos.h / 2.f)}, 20.f, colour, m_title.c_str(), NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE);
|
||||
gfx::drawText(vg, Vec2{m_pos.x + m_pos.w - 15.f, m_pos.y + (m_pos.h / 2.f)}, 20.f, theme->GetColour(ThemeEntryID_TEXT_SELECTED), text_entry.c_str(), NVG_ALIGN_RIGHT | NVG_ALIGN_MIDDLE);
|
||||
// scrolling text
|
||||
// todo: move below in a flexible class and use it for all text drawing.
|
||||
float bounds[4];
|
||||
nvgFontSize(vg, 20);
|
||||
nvgTextAlign(vg, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE);
|
||||
nvgTextBounds(vg, 0, 0, m_title.c_str(), nullptr, bounds);
|
||||
const float start_x = bounds[2] + 50;
|
||||
const float max_off = m_pos.w - start_x - 15.f;
|
||||
|
||||
auto value_str = m_items[m_index];
|
||||
nvgTextBounds(vg, 0, 0, value_str.c_str(), nullptr, bounds);
|
||||
|
||||
if (HasFocus()) {
|
||||
const auto scroll_amount = GetTextScrollSpeed();
|
||||
if (bounds[2] > max_off) {
|
||||
value_str += " ";
|
||||
nvgTextBounds(vg, 0, 0, value_str.c_str(), nullptr, bounds);
|
||||
|
||||
if (!m_text_yoff) {
|
||||
m_tick++;
|
||||
if (m_tick >= 90) {
|
||||
m_tick = 0;
|
||||
m_text_yoff += scroll_amount;
|
||||
}
|
||||
} else if (bounds[2] > m_text_yoff) {
|
||||
m_text_yoff += std::min(scroll_amount, bounds[2] - m_text_yoff);
|
||||
} else {
|
||||
m_text_yoff = 0;
|
||||
}
|
||||
|
||||
value_str += text_entry;
|
||||
}
|
||||
}
|
||||
|
||||
const Vec2 key_text_pos{m_pos.x + 15.f, m_pos.y + (m_pos.h / 2.f)};
|
||||
gfx::drawText(vg, key_text_pos, 20.f, theme->GetColour(ThemeEntryID_TEXT), m_title.c_str(), NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE);
|
||||
|
||||
nvgSave(vg);
|
||||
const float xpos = m_pos.x + m_pos.w - 15.f - std::min(max_off, bounds[2]);
|
||||
nvgIntersectScissor(vg, xpos, GetY(), max_off, GetH());
|
||||
const Vec2 value_text_pos{xpos - m_text_yoff, m_pos.y + (m_pos.h / 2.f)};
|
||||
gfx::drawText(vg, value_text_pos, 20.f, theme->GetColour(ThemeEntryID_TEXT_SELECTED), value_str.c_str(), NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE);
|
||||
nvgRestore(vg);
|
||||
}
|
||||
|
||||
auto SidebarEntryArray::OnFocusGained() noexcept -> void {
|
||||
Widget::OnFocusGained();
|
||||
}
|
||||
|
||||
auto SidebarEntryArray::OnFocusLost() noexcept -> void {
|
||||
Widget::OnFocusLost();
|
||||
m_text_yoff = 0;
|
||||
}
|
||||
|
||||
Sidebar::Sidebar(std::string title, Side side, Items&& items)
|
||||
|
||||
Reference in New Issue
Block a user