@@ -62,6 +62,7 @@ add_executable(sphaira
|
|||||||
source/ui/widget.cpp
|
source/ui/widget.cpp
|
||||||
source/ui/list.cpp
|
source/ui/list.cpp
|
||||||
source/ui/bubbles.cpp
|
source/ui/bubbles.cpp
|
||||||
|
source/ui/scrolling_text.cpp
|
||||||
|
|
||||||
source/app.cpp
|
source/app.cpp
|
||||||
source/download.cpp
|
source/download.cpp
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "ui/menus/menu_base.hpp"
|
#include "ui/menus/menu_base.hpp"
|
||||||
#include "ui/scrollable_text.hpp"
|
#include "ui/scrollable_text.hpp"
|
||||||
|
#include "ui/scrolling_text.hpp"
|
||||||
#include "ui/list.hpp"
|
#include "ui/list.hpp"
|
||||||
#include "nro.hpp"
|
#include "nro.hpp"
|
||||||
#include "fs.hpp"
|
#include "fs.hpp"
|
||||||
@@ -169,6 +170,10 @@ private:
|
|||||||
std::vector<EntryMini> m_entries_index_search{};
|
std::vector<EntryMini> m_entries_index_search{};
|
||||||
std::span<EntryMini> m_entries_current{};
|
std::span<EntryMini> m_entries_current{};
|
||||||
|
|
||||||
|
ScrollingText m_scroll_name{};
|
||||||
|
ScrollingText m_scroll_author{};
|
||||||
|
ScrollingText m_scroll_version{};
|
||||||
|
|
||||||
Filter m_filter{Filter::Filter_All};
|
Filter m_filter{Filter::Filter_All};
|
||||||
SortType m_sort{SortType::SortType_Updated};
|
SortType m_sort{SortType::SortType_Updated};
|
||||||
OrderType m_order{OrderType::OrderType_Descending};
|
OrderType m_order{OrderType::OrderType_Descending};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ui/menus/menu_base.hpp"
|
#include "ui/menus/menu_base.hpp"
|
||||||
|
#include "ui/scrolling_text.hpp"
|
||||||
#include "ui/list.hpp"
|
#include "ui/list.hpp"
|
||||||
#include "fs.hpp"
|
#include "fs.hpp"
|
||||||
#include "option.hpp"
|
#include "option.hpp"
|
||||||
@@ -57,6 +58,10 @@ private:
|
|||||||
std::vector<Entry> m_entries{};
|
std::vector<Entry> m_entries{};
|
||||||
s64 m_index{}; // where i am in the array
|
s64 m_index{}; // where i am in the array
|
||||||
std::unique_ptr<List> m_list{};
|
std::unique_ptr<List> m_list{};
|
||||||
|
|
||||||
|
ScrollingText m_scroll_name{};
|
||||||
|
ScrollingText m_scroll_author{};
|
||||||
|
ScrollingText m_scroll_version{};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sphaira::ui::menu::game
|
} // namespace sphaira::ui::menu::game
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ui/menus/menu_base.hpp"
|
#include "ui/menus/menu_base.hpp"
|
||||||
|
#include "ui/scrolling_text.hpp"
|
||||||
#include "ui/list.hpp"
|
#include "ui/list.hpp"
|
||||||
#include "nro.hpp"
|
#include "nro.hpp"
|
||||||
#include "fs.hpp"
|
#include "fs.hpp"
|
||||||
@@ -56,6 +57,10 @@ private:
|
|||||||
s64 m_index{}; // where i am in the array
|
s64 m_index{}; // where i am in the array
|
||||||
std::unique_ptr<List> m_list{};
|
std::unique_ptr<List> m_list{};
|
||||||
|
|
||||||
|
ScrollingText m_scroll_name{};
|
||||||
|
ScrollingText m_scroll_author{};
|
||||||
|
ScrollingText m_scroll_version{};
|
||||||
|
|
||||||
option::OptionLong m_sort{INI_SECTION, "sort", SortType::SortType_AlphabeticalStar};
|
option::OptionLong m_sort{INI_SECTION, "sort", SortType::SortType_AlphabeticalStar};
|
||||||
option::OptionLong m_order{INI_SECTION, "order", OrderType::OrderType_Descending};
|
option::OptionLong m_order{INI_SECTION, "order", OrderType::OrderType_Descending};
|
||||||
option::OptionBool m_hide_sphaira{INI_SECTION, "hide_sphaira", false};
|
option::OptionBool m_hide_sphaira{INI_SECTION, "hide_sphaira", false};
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "ui/menus/menu_base.hpp"
|
#include "ui/menus/menu_base.hpp"
|
||||||
#include "ui/scrollable_text.hpp"
|
#include "ui/scrollable_text.hpp"
|
||||||
|
#include "ui/scrolling_text.hpp"
|
||||||
#include "ui/list.hpp"
|
#include "ui/list.hpp"
|
||||||
#include "option.hpp"
|
#include "option.hpp"
|
||||||
#include <span>
|
#include <span>
|
||||||
@@ -160,6 +161,9 @@ private:
|
|||||||
s64 m_index{}; // where i am in the array
|
s64 m_index{}; // where i am in the array
|
||||||
std::unique_ptr<List> m_list{};
|
std::unique_ptr<List> m_list{};
|
||||||
|
|
||||||
|
ScrollingText m_scroll_name{};
|
||||||
|
ScrollingText m_scroll_author{};
|
||||||
|
|
||||||
// options
|
// options
|
||||||
option::OptionLong m_sort{INI_SECTION, "sort", 0};
|
option::OptionLong m_sort{INI_SECTION, "sort", 0};
|
||||||
option::OptionLong m_order{INI_SECTION, "order", 0};
|
option::OptionLong m_order{INI_SECTION, "order", 0};
|
||||||
|
|||||||
19
sphaira/include/ui/scrolling_text.hpp
Normal file
19
sphaira/include/ui/scrolling_text.hpp
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ui/widget.hpp"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace sphaira::ui {
|
||||||
|
|
||||||
|
struct ScrollingText final {
|
||||||
|
public:
|
||||||
|
void Draw(NVGcontext*, bool focus, float x, float y, float w, float size, int align, const NVGcolor& colour, const std::string& text_entry);
|
||||||
|
void DrawArgs(NVGcontext*, bool focus, float x, float y, float w, float size, int align, const NVGcolor& colour, const char* s, ...) __attribute__ ((format (printf, 10, 11)));
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_str;
|
||||||
|
s64 m_tick;
|
||||||
|
float m_text_xoff;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace sphaira::ui
|
||||||
@@ -1027,7 +1027,8 @@ void Menu::Draw(NVGcontext* vg, Theme* theme) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto text_id = ThemeEntryID_TEXT;
|
auto text_id = ThemeEntryID_TEXT;
|
||||||
if (pos == m_index) {
|
const auto selected = pos == m_index;
|
||||||
|
if (selected) {
|
||||||
text_id = ThemeEntryID_TEXT_SELECTED;
|
text_id = ThemeEntryID_TEXT_SELECTED;
|
||||||
gfx::drawRectOutline(vg, theme, 4.f, v);
|
gfx::drawRectOutline(vg, theme, 4.f, v);
|
||||||
} else {
|
} else {
|
||||||
@@ -1040,13 +1041,16 @@ void Menu::Draw(NVGcontext* vg, Theme* theme) {
|
|||||||
DrawIcon(vg, e.image, m_default_image, x + 20, y + 20, 115, 115, true, image_scale);
|
DrawIcon(vg, e.image, m_default_image, x + 20, y + 20, 115, 115, true, image_scale);
|
||||||
// gfx::drawImage(vg, x + 20, y + 20, image_size, image_size_h, image.image ? image.image : m_default_image);
|
// gfx::drawImage(vg, x + 20, y + 20, image_size, image_size_h, image.image ? image.image : m_default_image);
|
||||||
|
|
||||||
|
const auto text_off = 148;
|
||||||
|
const auto text_x = x + text_off;
|
||||||
|
const auto text_clip_w = w - 30.f - text_off;
|
||||||
nvgSave(vg);
|
nvgSave(vg);
|
||||||
nvgIntersectScissor(vg, v.x, v.y, w - 30.f, h); // clip
|
nvgIntersectScissor(vg, text_x, y, text_clip_w, h); // clip
|
||||||
{
|
{
|
||||||
const float font_size = 18;
|
const float font_size = 18;
|
||||||
gfx::drawTextArgs(vg, x + 148, y + 45, font_size, NVG_ALIGN_LEFT, theme->GetColour(text_id), e.title.c_str());
|
m_scroll_name.Draw(vg, selected, text_x, y + 45, text_clip_w, font_size, NVG_ALIGN_LEFT, theme->GetColour(text_id), e.title.c_str());
|
||||||
gfx::drawTextArgs(vg, x + 148, y + 80, font_size, NVG_ALIGN_LEFT, theme->GetColour(text_id), e.author.c_str());
|
m_scroll_author.Draw(vg, selected, text_x, y + 80, text_clip_w, font_size, NVG_ALIGN_LEFT, theme->GetColour(text_id), e.author.c_str());
|
||||||
gfx::drawTextArgs(vg, x + 148, y + 115, font_size, NVG_ALIGN_LEFT, theme->GetColour(text_id), e.version.c_str());
|
m_scroll_version.Draw(vg, selected, text_x, y + 115, text_clip_w, font_size, NVG_ALIGN_LEFT, theme->GetColour(text_id), e.version.c_str());
|
||||||
}
|
}
|
||||||
nvgRestore(vg);
|
nvgRestore(vg);
|
||||||
|
|
||||||
|
|||||||
@@ -734,7 +734,8 @@ void Menu::Draw(NVGcontext* vg, Theme* theme) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto text_id = ThemeEntryID_TEXT;
|
auto text_id = ThemeEntryID_TEXT;
|
||||||
if (m_index == i) {
|
const auto selected = m_index == i;
|
||||||
|
if (selected) {
|
||||||
text_id = ThemeEntryID_TEXT_SELECTED;
|
text_id = ThemeEntryID_TEXT_SELECTED;
|
||||||
gfx::drawRectOutline(vg, theme, 4.f, v);
|
gfx::drawRectOutline(vg, theme, 4.f, v);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -133,23 +133,6 @@ Menu::Menu() : MenuBase{"Games"_i18n} {
|
|||||||
}, m_entries[m_index].image
|
}, m_entries[m_index].image
|
||||||
));
|
));
|
||||||
}, true));
|
}, true));
|
||||||
|
|
||||||
#if 0
|
|
||||||
options->Add(std::make_shared<SidebarEntryCallback>("Enable auto delete"_i18n, [this](){
|
|
||||||
const auto rc = nsEnableApplicationAutoDelete(m_entries[m_index].app_id);
|
|
||||||
Notify(rc, "Failed to enable auto delete");
|
|
||||||
}));
|
|
||||||
|
|
||||||
options->Add(std::make_shared<SidebarEntryCallback>("Disable auto delete"_i18n, [this](){
|
|
||||||
const auto rc = nsDisableApplicationAutoDelete(m_entries[m_index].app_id);
|
|
||||||
Notify(rc, "Failed to disable auto delete");
|
|
||||||
}));
|
|
||||||
|
|
||||||
options->Add(std::make_shared<SidebarEntryCallback>("Withdraw update request"_i18n, [this](){
|
|
||||||
const auto rc = nsWithdrawApplicationUpdateRequest(m_entries[m_index].app_id);
|
|
||||||
Notify(rc, "Failed to withdraw update request");
|
|
||||||
}));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}})
|
}})
|
||||||
);
|
);
|
||||||
@@ -200,7 +183,8 @@ void Menu::Draw(NVGcontext* vg, Theme* theme) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto text_id = ThemeEntryID_TEXT;
|
auto text_id = ThemeEntryID_TEXT;
|
||||||
if (pos == m_index) {
|
const auto selected = pos == m_index;
|
||||||
|
if (selected) {
|
||||||
text_id = ThemeEntryID_TEXT_SELECTED;
|
text_id = ThemeEntryID_TEXT_SELECTED;
|
||||||
gfx::drawRectOutline(vg, theme, 4.f, v);
|
gfx::drawRectOutline(vg, theme, 4.f, v);
|
||||||
} else {
|
} else {
|
||||||
@@ -210,13 +194,16 @@ void Menu::Draw(NVGcontext* vg, Theme* theme) {
|
|||||||
const float image_size = 115;
|
const float image_size = 115;
|
||||||
gfx::drawImage(vg, x + 20, y + 20, image_size, image_size, e.image ? e.image : App::GetDefaultImage(), 5);
|
gfx::drawImage(vg, x + 20, y + 20, image_size, image_size, e.image ? e.image : App::GetDefaultImage(), 5);
|
||||||
|
|
||||||
|
const auto text_off = 148;
|
||||||
|
const auto text_x = x + text_off;
|
||||||
|
const auto text_clip_w = w - 30.f - text_off;
|
||||||
nvgSave(vg);
|
nvgSave(vg);
|
||||||
nvgIntersectScissor(vg, x, y, w - 30.f, h); // clip
|
nvgIntersectScissor(vg, text_x, y, text_clip_w, h); // clip
|
||||||
{
|
{
|
||||||
const float font_size = 18;
|
const float font_size = 18;
|
||||||
gfx::drawTextArgs(vg, x + 148, y + 45, font_size, NVG_ALIGN_LEFT, theme->GetColour(text_id), e.GetName());
|
m_scroll_name.Draw(vg, selected, text_x, y + 45, text_clip_w, font_size, NVG_ALIGN_LEFT, theme->GetColour(text_id), e.GetName());
|
||||||
gfx::drawTextArgs(vg, x + 148, y + 80, font_size, NVG_ALIGN_LEFT, theme->GetColour(text_id), e.GetAuthor());
|
m_scroll_author.Draw(vg, selected, text_x, y + 80, text_clip_w, font_size, NVG_ALIGN_LEFT, theme->GetColour(text_id), e.GetAuthor());
|
||||||
gfx::drawTextArgs(vg, x + 148, y + 115, font_size, NVG_ALIGN_LEFT, theme->GetColour(text_id), e.GetDisplayVersion());
|
m_scroll_version.Draw(vg, selected, text_x, y + 115, text_clip_w, font_size, NVG_ALIGN_LEFT, theme->GetColour(text_id), e.GetDisplayVersion());
|
||||||
}
|
}
|
||||||
nvgRestore(vg);
|
nvgRestore(vg);
|
||||||
});
|
});
|
||||||
@@ -235,7 +222,6 @@ void Menu::SetIndex(s64 index) {
|
|||||||
m_list->SetYoff(0);
|
m_list->SetYoff(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: set subheadering.
|
|
||||||
char title_id[33];
|
char title_id[33];
|
||||||
std::snprintf(title_id, sizeof(title_id), "%016lX", m_entries[m_index].app_id);
|
std::snprintf(title_id, sizeof(title_id), "%016lX", m_entries[m_index].app_id);
|
||||||
SetTitleSubHeading(title_id);
|
SetTitleSubHeading(title_id);
|
||||||
|
|||||||
@@ -162,7 +162,8 @@ void Menu::Draw(NVGcontext* vg, Theme* theme) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto text_id = ThemeEntryID_TEXT;
|
auto text_id = ThemeEntryID_TEXT;
|
||||||
if (pos == m_index) {
|
const auto selected = pos == m_index;
|
||||||
|
if (selected) {
|
||||||
text_id = ThemeEntryID_TEXT_SELECTED;
|
text_id = ThemeEntryID_TEXT_SELECTED;
|
||||||
gfx::drawRectOutline(vg, theme, 4.f, v);
|
gfx::drawRectOutline(vg, theme, 4.f, v);
|
||||||
} else {
|
} else {
|
||||||
@@ -172,8 +173,11 @@ void Menu::Draw(NVGcontext* vg, Theme* theme) {
|
|||||||
const float image_size = 115;
|
const float image_size = 115;
|
||||||
gfx::drawImage(vg, x + 20, y + 20, image_size, image_size, e.image ? e.image : App::GetDefaultImage(), 15);
|
gfx::drawImage(vg, x + 20, y + 20, image_size, image_size, e.image ? e.image : App::GetDefaultImage(), 15);
|
||||||
|
|
||||||
|
const auto text_off = 148;
|
||||||
|
const auto text_x = x + text_off;
|
||||||
|
const auto text_clip_w = w - 30.f - text_off;
|
||||||
nvgSave(vg);
|
nvgSave(vg);
|
||||||
nvgIntersectScissor(vg, x, y, w - 30.f, h); // clip
|
nvgIntersectScissor(vg, text_x, y, text_clip_w, h); // clip
|
||||||
{
|
{
|
||||||
bool has_star = false;
|
bool has_star = false;
|
||||||
if (IsStarEnabled()) {
|
if (IsStarEnabled()) {
|
||||||
@@ -184,9 +188,9 @@ void Menu::Draw(NVGcontext* vg, Theme* theme) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const float font_size = 18;
|
const float font_size = 18;
|
||||||
gfx::drawTextArgs(vg, x + 148, y + 45, font_size, NVG_ALIGN_LEFT, theme->GetColour(text_id), "%s%s", has_star ? "\u2605 " : "", e.GetName());
|
m_scroll_name.DrawArgs(vg, selected, text_x, y + 45, text_clip_w, font_size, NVG_ALIGN_LEFT, theme->GetColour(text_id), "%s%s", has_star ? "\u2605 " : "", e.GetName());
|
||||||
gfx::drawTextArgs(vg, x + 148, y + 80, font_size, NVG_ALIGN_LEFT, theme->GetColour(text_id), e.GetAuthor());
|
m_scroll_author.Draw(vg, selected, text_x, y + 80, text_clip_w, font_size, NVG_ALIGN_LEFT, theme->GetColour(text_id), e.GetAuthor());
|
||||||
gfx::drawTextArgs(vg, x + 148, y + 115, font_size, NVG_ALIGN_LEFT, theme->GetColour(text_id), e.GetDisplayVersion());
|
m_scroll_version.Draw(vg, selected, text_x, y + 115, text_clip_w, font_size, NVG_ALIGN_LEFT, theme->GetColour(text_id), e.GetDisplayVersion());
|
||||||
}
|
}
|
||||||
nvgRestore(vg);
|
nvgRestore(vg);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -537,7 +537,8 @@ void Menu::Draw(NVGcontext* vg, Theme* theme) {
|
|||||||
auto& e = page.m_packList[pos];
|
auto& e = page.m_packList[pos];
|
||||||
|
|
||||||
auto text_id = ThemeEntryID_TEXT;
|
auto text_id = ThemeEntryID_TEXT;
|
||||||
if (pos == m_index) {
|
const auto selected = pos == m_index;
|
||||||
|
if (selected) {
|
||||||
text_id = ThemeEntryID_TEXT_SELECTED;
|
text_id = ThemeEntryID_TEXT_SELECTED;
|
||||||
gfx::drawRectOutline(vg, theme, 4.f, v);
|
gfx::drawRectOutline(vg, theme, 4.f, v);
|
||||||
} else {
|
} else {
|
||||||
@@ -607,11 +608,14 @@ void Menu::Draw(NVGcontext* vg, Theme* theme) {
|
|||||||
gfx::drawImage(vg, x + xoff, y, 320, 180, image.image ? image.image : App::GetDefaultImage(), 15);
|
gfx::drawImage(vg, x + xoff, y, 320, 180, image.image ? image.image : App::GetDefaultImage(), 15);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto text_x = x + xoff;
|
||||||
|
const auto text_clip_w = w - 30.f - xoff;
|
||||||
nvgSave(vg);
|
nvgSave(vg);
|
||||||
nvgIntersectScissor(vg, x, y, w - 30.f, h); // clip
|
nvgIntersectScissor(vg, text_x, y, text_clip_w, h); // clip
|
||||||
{
|
{
|
||||||
gfx::drawTextArgs(vg, x + xoff, y + 180 + 20, 18, NVG_ALIGN_LEFT, theme->GetColour(text_id), "%s", e.details.name.c_str());
|
const float font_size = 18;
|
||||||
gfx::drawTextArgs(vg, x + xoff, y + 180 + 55, 18, NVG_ALIGN_LEFT, theme->GetColour(text_id), "%s", e.creator.display_name.c_str());
|
m_scroll_name.Draw(vg, selected, text_x, y + 180 + 20, text_clip_w, font_size, NVG_ALIGN_LEFT, theme->GetColour(text_id), e.details.name.c_str());
|
||||||
|
m_scroll_author.Draw(vg, selected, text_x, y + 180 + 55, text_clip_w, font_size, NVG_ALIGN_LEFT, theme->GetColour(text_id), e.creator.display_name.c_str());
|
||||||
}
|
}
|
||||||
nvgRestore(vg);
|
nvgRestore(vg);
|
||||||
});
|
});
|
||||||
|
|||||||
72
sphaira/source/ui/scrolling_text.cpp
Normal file
72
sphaira/source/ui/scrolling_text.cpp
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#include "ui/scrolling_text.hpp"
|
||||||
|
#include "ui/nvg_util.hpp"
|
||||||
|
#include "app.hpp"
|
||||||
|
#include <cstdarg>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // 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) {
|
||||||
|
if (!focus) {
|
||||||
|
gfx::drawText(vg, x, y, size, colour, text_entry.c_str(), align);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_str != text_entry) {
|
||||||
|
m_str = text_entry;
|
||||||
|
m_tick = 0;
|
||||||
|
m_text_xoff = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float bounds[4];
|
||||||
|
auto value_str = text_entry;
|
||||||
|
nvgFontSize(vg, size);
|
||||||
|
nvgTextAlign(vg, align);
|
||||||
|
nvgTextBounds(vg, 0, 0, value_str.c_str(), nullptr, bounds);
|
||||||
|
|
||||||
|
if (focus) {
|
||||||
|
const auto scroll_amount = GetTextScrollSpeed();
|
||||||
|
if (bounds[2] > w) {
|
||||||
|
value_str += " ";
|
||||||
|
nvgTextBounds(vg, 0, 0, value_str.c_str(), nullptr, bounds);
|
||||||
|
|
||||||
|
if (!m_text_xoff) {
|
||||||
|
m_tick++;
|
||||||
|
if (m_tick >= 90) {
|
||||||
|
m_tick = 0;
|
||||||
|
m_text_xoff += scroll_amount;
|
||||||
|
}
|
||||||
|
} else if (bounds[2] > m_text_xoff) {
|
||||||
|
m_text_xoff += std::min(scroll_amount, bounds[2] - m_text_xoff);
|
||||||
|
} else {
|
||||||
|
m_text_xoff = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
value_str += text_entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Vec2 pos{x - m_text_xoff, y};
|
||||||
|
gfx::drawText(vg, pos, size, colour, value_str.c_str(), align);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScrollingText::DrawArgs(NVGcontext* vg, bool focus, float x, float y, float w, float size, int align, const NVGcolor& colour, const char* s, ...) {
|
||||||
|
std::va_list v{};
|
||||||
|
va_start(v, s);
|
||||||
|
char buffer[0x100];
|
||||||
|
std::vsnprintf(buffer, sizeof(buffer), s, v);
|
||||||
|
va_end(v);
|
||||||
|
Draw(vg, focus, x, y, w, size, align, colour, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace sphaira::ui
|
||||||
Reference in New Issue
Block a user