mirror of
https://github.com/J-D-K/JKSV.git
synced 2026-08-25 20:09:31 -05:00
Implement/complete TitleInfoState
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include "system/Timer.hpp"
|
||||
#include "ui/Menu.hpp"
|
||||
#include "ui/SlideOutPanel.hpp"
|
||||
#include "ui/TextScroll.hpp"
|
||||
#include <memory>
|
||||
|
||||
/// @brief This is the state where the user can backup and restore saves.
|
||||
@@ -49,6 +50,9 @@ class BackupMenuState : public AppState
|
||||
/// @brief Directory listing of the above.
|
||||
fslib::Directory m_directoryListing;
|
||||
|
||||
/// @brief This is the scrolling text at the top.
|
||||
ui::TextScroll m_titleScroll;
|
||||
|
||||
/// @brief Variable that saves whether or not the filesystem has data in it.
|
||||
bool m_saveHasData = false;
|
||||
|
||||
|
||||
@@ -34,12 +34,36 @@ class TitleInfoState : public AppState
|
||||
/// @brief This is a pointer to the title's icon.
|
||||
sdl::SharedTexture m_icon;
|
||||
|
||||
/// @brief This is the scrolling text for the title.
|
||||
ui::TextScroll m_titleScroll;
|
||||
|
||||
/// @brief This is the scrolling text for the publisher.
|
||||
ui::TextScroll m_publisherScroll;
|
||||
|
||||
/// @brief This string holds the application ID.
|
||||
std::string m_applicationID;
|
||||
|
||||
/// @brief This holds the hex save data id of the file on nand.
|
||||
std::string m_saveDataID;
|
||||
|
||||
/// @brief This holds the play time string.
|
||||
std::string m_playTime;
|
||||
|
||||
/// @brief This holds the total launches string.
|
||||
std::string m_totalLaunches;
|
||||
|
||||
/// @brief This holds the save data type string.
|
||||
std::string m_saveDataType;
|
||||
|
||||
/// @brief Bool to tell whether or not static members are initialized.
|
||||
static inline bool sm_initialized = false;
|
||||
|
||||
/// @brief This is the render target for the title text just in case it needs scrolling.
|
||||
static inline sdl::SharedTexture sm_titleTarget = nullptr;
|
||||
|
||||
/// @brief This is the render target for the publisher string.
|
||||
static inline sdl::SharedTexture sm_publisherTarget = nullptr;
|
||||
|
||||
/// @brief Slide panel.
|
||||
static inline std::unique_ptr<ui::SlideOutPanel> sm_slidePanel = nullptr;
|
||||
};
|
||||
|
||||
@@ -33,6 +33,7 @@ namespace strings
|
||||
static constexpr std::string_view TITLE_OPTION_STATUS = "TitleOptionStatus";
|
||||
static constexpr std::string_view TITLE_OPTION_POPS = "TitleOptionPops";
|
||||
static constexpr std::string_view TITLE_OPTION_CONFIRMATIONS = "TitleOptionConfirmations";
|
||||
static constexpr std::string_view TITLE_INFO_STRINGS = "TitleInfo";
|
||||
static constexpr std::string_view POP_MESSAGES_GENERAL = "PopMessagesGeneral";
|
||||
static constexpr std::string_view POP_MESSAGES_BACKUP_MENU = "PopMessagesBackupMenu";
|
||||
static constexpr std::string_view POP_MESSAGES_SAVE_CREATE = "PopMessagesSaveCreate";
|
||||
|
||||
@@ -15,11 +15,6 @@ namespace sys
|
||||
/// @param triggerTicks Number of ticks the timer is triggered at.
|
||||
Timer(uint64_t triggerTicks);
|
||||
|
||||
/// @brief Copy operator.
|
||||
/// @param timer Timer to copy.
|
||||
/// @return Reference to copied timer.
|
||||
Timer &operator=(const Timer &timer);
|
||||
|
||||
/// @brief Starts the timer.
|
||||
/// @param triggerTicks Number of ticks to trigger at.
|
||||
void start(uint64_t triggerTicks);
|
||||
|
||||
@@ -12,18 +12,26 @@ namespace ui
|
||||
/// @brief This is only here so I can get around the backup menu having static members.
|
||||
TextScroll(void) = default;
|
||||
|
||||
/// @brief Constructs a new TextScroll.
|
||||
/// @param text Text to be scrolled.
|
||||
/// @param availableWidth Maximum width. If this is not exceeded,text is just rendered centered according to it.
|
||||
TextScroll(std::string_view text, int fontSize, int availableWidth, int y, sdl::Color color);
|
||||
/// @brief Constructor for TextScroll.
|
||||
/// @param text Text to create the textscroll with.
|
||||
/// @param fontSize Size of the font in pixels to use.
|
||||
/// @param availableWidth Available width of the render target.
|
||||
/// @param y Y coordinate to render to.
|
||||
/// @param center Whether or not text should be centered if it's not wide enough for scrolling.
|
||||
/// @param color Color to use to render the text.
|
||||
TextScroll(std::string_view text, int fontSize, int availableWidth, int y, bool center, sdl::Color color);
|
||||
|
||||
/// @brief Required destructor.
|
||||
~TextScroll() {};
|
||||
|
||||
/// @brief Same as the default constructor. To do: Figure this out better sometime.
|
||||
/// @param textScroll TextScroll to copy.
|
||||
/// @return Reference to itself?
|
||||
TextScroll &operator=(const TextScroll &textScroll);
|
||||
/// @brief Creates/sets the text and parameters for TextScroll.
|
||||
/// @param text Text to display/scroll.
|
||||
/// @param fontSize Font size to use when rendering.
|
||||
/// @param availableWidth Available width of the target buffer.
|
||||
/// @param y Y coordinate used to render text.
|
||||
/// @param center Whether or not text should be centered if it's not wide enough for scrolling.
|
||||
/// @param color Color to use to render text.
|
||||
void create(std::string_view text, int fontSize, int availableWidth, int y, bool center, sdl::Color color);
|
||||
|
||||
/// @brief Runs the update routine.
|
||||
/// @param hasFocus Whether or not the calling state has focus.
|
||||
|
||||
@@ -159,6 +159,13 @@
|
||||
"Are you sure you would like to reset the save data for #%s#? *This will delete the current save data for the title as if it were never run!*",
|
||||
"Are you sure you want to delete `%s`'s save data for #%s#? This will permanently delete it from the system."
|
||||
],
|
||||
"TitleInfo": [
|
||||
"App ID: %016lX",
|
||||
"Save ID: %016lx",
|
||||
"Play Time: %02d:%02d:%02d",
|
||||
"Launches: %i",
|
||||
"Save Type: %s"
|
||||
],
|
||||
"PopMessagesGeneral": [
|
||||
"Unable to exit JKSV while tasks are running!"
|
||||
],
|
||||
|
||||
@@ -75,7 +75,7 @@ BackupMenuState::BackupMenuState(data::User *user, data::TitleInfo *titleInfo, F
|
||||
stringutil::get_formatted_string("`%s` - %s", m_user->get_nickname(), m_titleInfo->get_title());
|
||||
|
||||
// This needs sm_panelWidth or it'd be in the initializer list.
|
||||
sm_slidePanel->push_new_element(std::make_shared<ui::TextScroll>(panelString, 22, sm_panelWidth, 8, colors::WHITE));
|
||||
m_titleScroll.create(panelString, 22, sm_panelWidth, 8, true, colors::WHITE);
|
||||
|
||||
fslib::Directory saveCheck(fs::DEFAULT_SAVE_ROOT);
|
||||
m_saveHasData = saveCheck.get_count() > 0;
|
||||
@@ -90,6 +90,8 @@ BackupMenuState::~BackupMenuState()
|
||||
|
||||
void BackupMenuState::update(void)
|
||||
{
|
||||
bool hasFocus = AppState::has_focus();
|
||||
|
||||
if (input::button_pressed(HidNpadButton_A) && sm_backupMenu->get_selected() == 0 && m_saveHasData)
|
||||
{
|
||||
// get name for backup.
|
||||
@@ -230,20 +232,29 @@ void BackupMenuState::update(void)
|
||||
AppState::deactivate();
|
||||
}
|
||||
|
||||
// Update title scrolling.
|
||||
m_titleScroll.update(hasFocus);
|
||||
|
||||
// Update panel.
|
||||
sm_slidePanel->update(AppState::has_focus());
|
||||
sm_slidePanel->update(hasFocus);
|
||||
// This state bypasses the Slideout panel's normal behavior because it kind of has to.
|
||||
sm_backupMenu->update(AppState::has_focus());
|
||||
sm_backupMenu->update(hasFocus);
|
||||
}
|
||||
|
||||
void BackupMenuState::render(void)
|
||||
{
|
||||
// Save this locally.
|
||||
bool hasFocus = AppState::has_focus();
|
||||
|
||||
// Clear panel target.
|
||||
sm_slidePanel->clear_target();
|
||||
|
||||
// Grab the render target.
|
||||
SDL_Texture *slideTarget = sm_slidePanel->get_target();
|
||||
|
||||
// Start with [Name] - [Title]
|
||||
m_titleScroll.render(slideTarget, hasFocus);
|
||||
|
||||
sdl::render_line(slideTarget, 10, 42, sm_panelWidth - 10, 42, colors::WHITE);
|
||||
sdl::render_line(slideTarget, 10, 648, sm_panelWidth - 10, 648, colors::WHITE);
|
||||
sdl::text::render(slideTarget,
|
||||
@@ -257,11 +268,11 @@ void BackupMenuState::render(void)
|
||||
// Clear menu target.
|
||||
sm_menuRenderTarget->clear(colors::TRANSPARENT);
|
||||
// render menu to it.
|
||||
sm_backupMenu->render(sm_menuRenderTarget->get(), AppState::has_focus());
|
||||
sm_backupMenu->render(sm_menuRenderTarget->get(), hasFocus);
|
||||
// render it to panel target.
|
||||
sm_menuRenderTarget->render(slideTarget, 0, 43);
|
||||
|
||||
sm_slidePanel->render(NULL, AppState::has_focus());
|
||||
sm_slidePanel->render(NULL, hasFocus);
|
||||
}
|
||||
|
||||
void BackupMenuState::refresh(void)
|
||||
|
||||
@@ -2,11 +2,22 @@
|
||||
#include "colors.hpp"
|
||||
#include "input.hpp"
|
||||
#include "sdl.hpp"
|
||||
#include "strings.hpp"
|
||||
#include "stringutil.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
/// @brief This is the width of the panel in pixels.
|
||||
constexpr int SIZE_PANEL_WIDTH = 480;
|
||||
|
||||
/// @brief This is the gap on both sides
|
||||
constexpr int SIZE_PANEL_SUB = 16;
|
||||
|
||||
/// @brief This is the size used for rendering text here.
|
||||
constexpr int SIZE_FONT = 24;
|
||||
|
||||
/// @brief This is the vertical size in pixels of the render targets for title/publisher.
|
||||
constexpr int SIZE_TEXT_TARGET_HEIGHT = 40;
|
||||
} // namespace
|
||||
|
||||
TitleInfoState::TitleInfoState(data::User *user, data::TitleInfo *titleInfo)
|
||||
@@ -17,12 +28,59 @@ TitleInfoState::TitleInfoState(data::User *user, data::TitleInfo *titleInfo)
|
||||
{
|
||||
// This is the slide panel everything is rendered to.
|
||||
sm_slidePanel = std::make_unique<ui::SlideOutPanel>(SIZE_PANEL_WIDTH, ui::SlideOutPanel::Side::Right);
|
||||
|
||||
// This is the render target for the title.
|
||||
sm_titleTarget = sdl::TextureManager::create_load_texture("infoTitleTarget",
|
||||
SIZE_PANEL_WIDTH - 32,
|
||||
32,
|
||||
SIZE_PANEL_WIDTH - SIZE_PANEL_SUB,
|
||||
SIZE_TEXT_TARGET_HEIGHT,
|
||||
SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET);
|
||||
|
||||
// This is the render target for the publisher.
|
||||
sm_publisherTarget =
|
||||
sdl::TextureManager::create_load_texture("infoPublisherTarget",
|
||||
SIZE_PANEL_WIDTH - SIZE_PANEL_SUB,
|
||||
SIZE_TEXT_TARGET_HEIGHT,
|
||||
SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET);
|
||||
sm_initialized = true;
|
||||
}
|
||||
|
||||
// Do this instead of calling the function everytime.
|
||||
uint64_t applicationID = m_titleInfo->get_application_id();
|
||||
|
||||
// These is needed at some point.
|
||||
FsSaveDataInfo *saveInfo = m_user->get_save_info_by_id(applicationID);
|
||||
PdmPlayStatistics *playStats = m_user->get_play_stats_by_id(applicationID);
|
||||
|
||||
// Title text.
|
||||
m_titleScroll
|
||||
.create(m_titleInfo->get_title(), SIZE_FONT, SIZE_PANEL_WIDTH - SIZE_PANEL_SUB, 6, false, colors::WHITE);
|
||||
// Publisher.
|
||||
m_publisherScroll
|
||||
.create(m_titleInfo->get_publisher(), SIZE_FONT, SIZE_PANEL_WIDTH - SIZE_PANEL_SUB, 6, false, colors::WHITE);
|
||||
|
||||
// Grab the application ID string.
|
||||
m_applicationID =
|
||||
stringutil::get_formatted_string(strings::get_by_name(strings::names::TITLE_INFO_STRINGS, 0), applicationID);
|
||||
// Same here. I think these use lower case characters on the NAND?
|
||||
m_saveDataID = stringutil::get_formatted_string(strings::get_by_name(strings::names::TITLE_INFO_STRINGS, 1),
|
||||
saveInfo->save_data_id);
|
||||
// This is simple.
|
||||
m_totalLaunches = stringutil::get_formatted_string(strings::get_by_name(strings::names::TITLE_INFO_STRINGS, 3),
|
||||
playStats->total_launches);
|
||||
// This should be semi-simple.
|
||||
m_saveDataType = stringutil::get_formatted_string(
|
||||
strings::get_by_name(strings::names::TITLE_INFO_STRINGS, 4),
|
||||
strings::get_by_name(strings::names::SAVE_DATA_TYPES, saveInfo->save_data_type));
|
||||
|
||||
// Calculate play time. We're going to use non-floating point to truncate the remainders.
|
||||
int64_t seconds = playStats->playtime / static_cast<int64_t>(1e+9);
|
||||
int64_t hours = seconds / 3600;
|
||||
int64_t minutes = (seconds % 3600) / 60;
|
||||
seconds %= 60;
|
||||
m_playTime = stringutil::get_formatted_string(strings::get_by_name(strings::names::TITLE_INFO_STRINGS, 2),
|
||||
hours,
|
||||
minutes,
|
||||
seconds);
|
||||
}
|
||||
|
||||
TitleInfoState::~TitleInfoState()
|
||||
@@ -33,8 +91,15 @@ TitleInfoState::~TitleInfoState()
|
||||
|
||||
void TitleInfoState::update(void)
|
||||
{
|
||||
// Grab this instead of calling the function over and over.
|
||||
bool hasFocus = AppState::has_focus();
|
||||
|
||||
// Update slide panel.
|
||||
sm_slidePanel->update(AppState::has_focus());
|
||||
sm_slidePanel->update(hasFocus);
|
||||
|
||||
// Update the scrolling text.
|
||||
m_titleScroll.update(hasFocus);
|
||||
m_publisherScroll.update(hasFocus);
|
||||
|
||||
if (input::button_pressed(HidNpadButton_B))
|
||||
{
|
||||
@@ -49,18 +114,110 @@ void TitleInfoState::update(void)
|
||||
|
||||
void TitleInfoState::render(void)
|
||||
{
|
||||
// This is the vertical gap for rendering text.
|
||||
static constexpr int SIZE_VERT_GAP = SIZE_TEXT_TARGET_HEIGHT + 4;
|
||||
// This is the size to render the rectangles at.
|
||||
static constexpr int SIZE_RECT_WIDTH = SIZE_PANEL_WIDTH - SIZE_PANEL_SUB;
|
||||
|
||||
// This is whether or not the state currently has focus.
|
||||
bool hasFocus = AppState::has_focus();
|
||||
|
||||
// Clear the title and publisher targets.
|
||||
sm_titleTarget->clear(colors::DIALOG_BOX);
|
||||
sm_publisherTarget->clear(colors::CLEAR_COLOR);
|
||||
|
||||
// Grab the panel's target and clear it. To do: This how I originally intended to.
|
||||
sm_slidePanel->clear_target();
|
||||
|
||||
// Grab the panel target for rendering to.
|
||||
SDL_Texture *panelTarget = sm_slidePanel->get_target();
|
||||
|
||||
// This is our Y rendering coordinate. It's easier to adjust this as needed than change everything.
|
||||
// This starts under the icon.
|
||||
int y = 304;
|
||||
|
||||
// Start by rendering the icon.
|
||||
m_icon->render(panelTarget, 112, 24);
|
||||
m_icon->render_stretched(panelTarget, 80, 8, 320, 320);
|
||||
|
||||
// Clear the title target and render the text scroll to it.
|
||||
sm_titleTarget->clear(colors::DIALOG_BOX);
|
||||
// Render the textscroll to the target, then target to the panel target.
|
||||
m_titleScroll.render(sm_titleTarget->get(), hasFocus);
|
||||
sm_titleTarget->render(panelTarget, 8, (y += SIZE_VERT_GAP));
|
||||
|
||||
// Publisher.
|
||||
m_publisherScroll.render(sm_publisherTarget->get(), hasFocus);
|
||||
sm_publisherTarget->render(panelTarget, 8, (y += SIZE_VERT_GAP));
|
||||
|
||||
// These are different since the probably won't go outside the bounds of the rectangle.
|
||||
sdl::render_rect_fill(panelTarget,
|
||||
8,
|
||||
(y += SIZE_VERT_GAP),
|
||||
SIZE_RECT_WIDTH,
|
||||
SIZE_TEXT_TARGET_HEIGHT,
|
||||
colors::DIALOG_BOX);
|
||||
// Text needs to be aligned like the scrolling text.
|
||||
sdl::text::render(panelTarget,
|
||||
16,
|
||||
y + 6,
|
||||
SIZE_FONT,
|
||||
sdl::text::NO_TEXT_WRAP,
|
||||
colors::WHITE,
|
||||
m_applicationID.c_str());
|
||||
|
||||
|
||||
// These are different since the probably won't go outside the bounds of the rectangle.
|
||||
sdl::render_rect_fill(panelTarget,
|
||||
8,
|
||||
(y += SIZE_VERT_GAP),
|
||||
SIZE_RECT_WIDTH,
|
||||
SIZE_TEXT_TARGET_HEIGHT,
|
||||
colors::CLEAR_COLOR);
|
||||
// Text needs to be aligned like the scrolling text.
|
||||
sdl::text::render(panelTarget, 16, y + 6, SIZE_FONT, sdl::text::NO_TEXT_WRAP, colors::WHITE, m_saveDataID.c_str());
|
||||
|
||||
|
||||
// These are different since the probably won't go outside the bounds of the rectangle.
|
||||
sdl::render_rect_fill(panelTarget,
|
||||
8,
|
||||
(y += SIZE_VERT_GAP),
|
||||
SIZE_RECT_WIDTH,
|
||||
SIZE_TEXT_TARGET_HEIGHT,
|
||||
colors::DIALOG_BOX);
|
||||
// Text needs to be aligned like the scrolling text.
|
||||
sdl::text::render(panelTarget, 16, y + 6, SIZE_FONT, sdl::text::NO_TEXT_WRAP, colors::WHITE, m_playTime.c_str());
|
||||
|
||||
|
||||
// These are different since the probably won't go outside the bounds of the rectangle.
|
||||
sdl::render_rect_fill(panelTarget,
|
||||
8,
|
||||
(y += SIZE_VERT_GAP),
|
||||
SIZE_RECT_WIDTH,
|
||||
SIZE_TEXT_TARGET_HEIGHT,
|
||||
colors::CLEAR_COLOR);
|
||||
// Text needs to be aligned like the scrolling text.
|
||||
sdl::text::render(panelTarget,
|
||||
16,
|
||||
y + 6,
|
||||
SIZE_FONT,
|
||||
sdl::text::NO_TEXT_WRAP,
|
||||
colors::WHITE,
|
||||
m_totalLaunches.c_str());
|
||||
|
||||
|
||||
// These are different since the probably won't go outside the bounds of the rectangle.
|
||||
sdl::render_rect_fill(panelTarget,
|
||||
8,
|
||||
(y += SIZE_VERT_GAP),
|
||||
SIZE_RECT_WIDTH,
|
||||
SIZE_TEXT_TARGET_HEIGHT,
|
||||
colors::DIALOG_BOX);
|
||||
// Text needs to be aligned like the scrolling text.
|
||||
sdl::text::render(panelTarget,
|
||||
16,
|
||||
y + 6,
|
||||
SIZE_FONT,
|
||||
sdl::text::NO_TEXT_WRAP,
|
||||
colors::WHITE,
|
||||
m_saveDataType.c_str());
|
||||
|
||||
sm_slidePanel->render(NULL, AppState::has_focus());
|
||||
}
|
||||
|
||||
@@ -21,9 +21,6 @@ data::TitleInfo::TitleInfo(uint64_t applicationID) : m_applicationID(application
|
||||
|
||||
if (R_FAILED(nsError) || nsAppControlSize < sizeof(m_data.nacp))
|
||||
{
|
||||
// This should be false by default, but just in case.
|
||||
m_hasData = false;
|
||||
|
||||
// This is the lowest four hex values of the title.
|
||||
std::string applicationIDHex = stringutil::get_formatted_string("%04X", m_applicationID & 0xFFFF);
|
||||
|
||||
|
||||
@@ -342,7 +342,7 @@ static void load_save_data_info(void)
|
||||
|
||||
default:
|
||||
{
|
||||
// Default is just the ID in the save info struct.
|
||||
// Default is just the ID in the save info struct. This should be fine for system saves too.
|
||||
accountID = saveInfo.uid;
|
||||
}
|
||||
break;
|
||||
@@ -383,9 +383,10 @@ static void load_save_data_info(void)
|
||||
// I feel weird allcating space for this even if it's not used, but whatever.
|
||||
PdmPlayStatistics stats = {0};
|
||||
// This should be an OKish way to filter out system titles...
|
||||
if (titleInfo.has_control_data() &&
|
||||
R_FAILED(
|
||||
pdmqryQueryPlayStatisticsByApplicationIdAndUserAccountId(applicationID, accountID, false, &stats)))
|
||||
if (R_FAILED(pdmqryQueryPlayStatisticsByApplicationIdAndUserAccountId(applicationID,
|
||||
saveInfo.uid,
|
||||
false,
|
||||
&stats)))
|
||||
{
|
||||
// This isn't fatal.
|
||||
logger::log("Error getting play stats for title %016llX!", applicationID);
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
#include "system/Timer.hpp"
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
#include "logger.hpp"
|
||||
|
||||
sys::Timer::Timer(uint64_t triggerTicks)
|
||||
{
|
||||
Timer::start(triggerTicks);
|
||||
}
|
||||
|
||||
sys::Timer &sys::Timer::operator=(const sys::Timer &timer)
|
||||
{
|
||||
m_startingTicks = timer.m_startingTicks;
|
||||
m_triggerTicks = timer.m_triggerTicks;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void sys::Timer::start(uint64_t triggerTicks)
|
||||
{
|
||||
m_startingTicks = SDL_GetTicks64();
|
||||
// Start by recording trigger ticks.
|
||||
m_triggerTicks = triggerTicks;
|
||||
|
||||
// Get the current tick count.
|
||||
m_startingTicks = SDL_GetTicks64();
|
||||
}
|
||||
|
||||
bool sys::Timer::is_triggered(void)
|
||||
@@ -27,8 +26,10 @@ bool sys::Timer::is_triggered(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Reset starting ticks.
|
||||
m_startingTicks = currentTicks;
|
||||
|
||||
// Trigger me timbers~
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,37 +1,59 @@
|
||||
#include "ui/TextScroll.hpp"
|
||||
#include "sdl.hpp"
|
||||
|
||||
ui::TextScroll::TextScroll(std::string_view text, int fontSize, int availableWidth, int y, sdl::Color color)
|
||||
: m_text(text.data()), m_y(y), m_fontSize(fontSize), m_textColor(color), m_scrollTimer(3000)
|
||||
{
|
||||
// Grab text width first.
|
||||
m_textWidth = sdl::text::get_width(m_fontSize, m_text.c_str());
|
||||
#include "logger.hpp"
|
||||
|
||||
// Check if text needs scrolling for width provided.
|
||||
namespace
|
||||
{
|
||||
/// @brief This is the number of ticks needed before the text starts scrolling.
|
||||
constexpr uint64_t TICKS_SCROLL_TRIGGER = 3000;
|
||||
} // namespace
|
||||
|
||||
ui::TextScroll::TextScroll(std::string_view text,
|
||||
int fontSize,
|
||||
int availableWidth,
|
||||
int y,
|
||||
bool center,
|
||||
sdl::Color color)
|
||||
{
|
||||
TextScroll::create(text, fontSize, availableWidth, y, center, color);
|
||||
}
|
||||
|
||||
void ui::TextScroll::create(std::string_view text,
|
||||
int fontSize,
|
||||
int availableWidth,
|
||||
int y,
|
||||
bool center,
|
||||
sdl::Color color)
|
||||
{
|
||||
// Copy the text and stuff.
|
||||
m_text = text;
|
||||
m_y = y;
|
||||
m_fontSize = fontSize;
|
||||
m_textColor = color;
|
||||
m_scrollTimer.start(TICKS_SCROLL_TRIGGER);
|
||||
|
||||
// Get the width and calculate X.
|
||||
m_textWidth = sdl::text::get_width(m_fontSize, m_text.c_str());
|
||||
if (m_textWidth > availableWidth)
|
||||
{
|
||||
// Set the X coordinate to 8 and make sure this knows it needs to scroll.
|
||||
m_x = 8;
|
||||
m_textScrolling = true;
|
||||
logger::log("Scrolling needed?");
|
||||
}
|
||||
else
|
||||
else if (center)
|
||||
{
|
||||
// Just center it.
|
||||
m_x = (availableWidth / 2) - (m_textWidth / 2);
|
||||
logger::log("Centered.");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just set this to 8. To do: Figure out how to make this cleaner.
|
||||
m_x = 8;
|
||||
logger::log("Aligned.");
|
||||
}
|
||||
}
|
||||
|
||||
ui::TextScroll &ui::TextScroll::operator=(const ui::TextScroll &textScroll)
|
||||
{
|
||||
m_text = textScroll.m_text;
|
||||
m_x = textScroll.m_x;
|
||||
m_y = textScroll.m_y;
|
||||
m_fontSize = textScroll.m_fontSize;
|
||||
m_textColor = textScroll.m_textColor;
|
||||
m_textWidth = textScroll.m_textWidth;
|
||||
m_textScrolling = textScroll.m_textScrolling;
|
||||
m_textScrollTriggered = textScroll.m_textScrollTriggered;
|
||||
m_scrollTimer = textScroll.m_scrollTimer;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void ui::TextScroll::update(bool hasFocus)
|
||||
@@ -39,6 +61,7 @@ void ui::TextScroll::update(bool hasFocus)
|
||||
// I don't think needs to care about having focus.
|
||||
if (m_textScrolling && m_scrollTimer.is_triggered())
|
||||
{
|
||||
logger::log("Text scroll triggered?");
|
||||
m_x -= 2;
|
||||
m_textScrollTriggered = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user