Change menu text from gray to white

This commit is contained in:
NeilClack
2026-08-13 14:34:49 -05:00
parent c35f928c85
commit 4abcfa473f
2 changed files with 249 additions and 151 deletions
+102 -50
View File
@@ -16,7 +16,7 @@
#include <algorithm> #include <algorithm>
#ifndef APP_VERSION #ifndef APP_VERSION
#define APP_VERSION "unknown" #define APP_VERSION "dev"
#endif #endif
static TextLine renderText(SDL_Renderer *renderer, TTF_Font *font, const char *text, SDL_Color color) static TextLine renderText(SDL_Renderer *renderer, TTF_Font *font, const char *text, SDL_Color color)
@@ -47,12 +47,10 @@ void Home::onPush(AppState &state)
refreshStatus(); refreshStatus();
state.licenseTracker.refresh(); state.licenseTracker.refresh();
state.keybinds.bind(SDLK_UP, "menu_up", [this]() { state.keybinds.bind(SDLK_UP, "menu_up", [this]()
state_->currentMenuItem = (state_->currentMenuItem + 1) % 2; { state_->currentMenuItem = (state_->currentMenuItem + 1) % 2; });
}); state.keybinds.bind(SDLK_DOWN, "menu_down", [this]()
state.keybinds.bind(SDLK_DOWN, "menu_down", [this]() { { state_->currentMenuItem = (state_->currentMenuItem + 1) % 2; });
state_->currentMenuItem = (state_->currentMenuItem + 1) % 2;
});
} }
void Home::onResume(AppState &state) void Home::onResume(AppState &state)
@@ -63,12 +61,10 @@ void Home::onResume(AppState &state)
refreshStatus(); refreshStatus();
state.licenseTracker.refresh(); state.licenseTracker.refresh();
state.keybinds.bind(SDLK_UP, "menu_up", [this]() { state.keybinds.bind(SDLK_UP, "menu_up", [this]()
state_->currentMenuItem = (state_->currentMenuItem + 1) % 2; { state_->currentMenuItem = (state_->currentMenuItem + 1) % 2; });
}); state.keybinds.bind(SDLK_DOWN, "menu_down", [this]()
state.keybinds.bind(SDLK_DOWN, "menu_down", [this]() { { state_->currentMenuItem = (state_->currentMenuItem + 1) % 2; });
state_->currentMenuItem = (state_->currentMenuItem + 1) % 2;
});
} }
void Home::onPause(AppState &state) void Home::onPause(AppState &state)
@@ -85,15 +81,22 @@ void Home::onPop(AppState &state)
void Home::handleEvent(const SDL_Event &event) void Home::handleEvent(const SDL_Event &event)
{ {
if (event.type == SDL_EVENT_KEY_DOWN && event.key.key == SDLK_RETURN) { if (event.type == SDL_EVENT_KEY_DOWN && event.key.key == SDLK_RETURN)
if (state_->currentMenuItem == 0) { {
if (state_->currentMenuItem == 0)
{
// Only a confirmed-valid license unlocks the scroller. // Only a confirmed-valid license unlocks the scroller.
if (state_->licenseTracker.isValid()) { if (state_->licenseTracker.isValid())
{
state_->pages.push(*state_, std::make_unique<ScrollerPage>()); state_->pages.push(*state_, std::make_unique<ScrollerPage>());
} else { }
else
{
state_->pages.push(*state_, std::make_unique<LicenseBlockedPage>()); state_->pages.push(*state_, std::make_unique<LicenseBlockedPage>());
} }
} else if (state_->currentMenuItem == 1) { }
else if (state_->currentMenuItem == 1)
{
state_->pages.replace(*state_, std::make_unique<Settings>()); state_->pages.replace(*state_, std::make_unique<Settings>());
} }
} }
@@ -102,7 +105,8 @@ void Home::handleEvent(const SDL_Event &event)
void Home::update(float dt) void Home::update(float dt)
{ {
internetRefreshTimer_ -= dt; internetRefreshTimer_ -= dt;
if (internetRefreshTimer_ <= 0.0f) { if (internetRefreshTimer_ <= 0.0f)
{
internetRefreshTimer_ = 5.0f; internetRefreshTimer_ = 5.0f;
refreshStatus(); refreshStatus();
} }
@@ -133,7 +137,8 @@ void Home::render(SDL_Renderer *renderer)
SDL_FRect overlay{0, 0, fw, fh}; SDL_FRect overlay{0, 0, fw, fh};
SDL_RenderFillRect(renderer, &overlay); SDL_RenderFillRect(renderer, &overlay);
if (!title_.texture) return; if (!title_.texture)
return;
float titleX = (fw - title_.width) / 2.0f; float titleX = (fw - title_.width) / 2.0f;
float titleY = fh / 3.0f - 60.0f; float titleY = fh / 3.0f - 60.0f;
@@ -194,7 +199,8 @@ void Home::render(SDL_Renderer *renderer)
std::string licenseValue; std::string licenseValue;
SDL_Color licenseColor = footerColor; SDL_Color licenseColor = footerColor;
bool licenseBold = false; bool licenseBold = false;
switch (licenseStatus) { switch (licenseStatus)
{
case radiantwave::license::Status::Valid: case radiantwave::license::Status::Valid:
licenseValue = "OK"; licenseValue = "OK";
licenseColor = okGreen; licenseColor = okGreen;
@@ -250,23 +256,32 @@ void Home::render(SDL_Renderer *renderer)
valueColors[1] = licenseColor; valueColors[1] = licenseColor;
valueBold[1] = licenseBold; valueBold[1] = licenseBold;
if (footerNames_.size() != names.size()) footerNames_.resize(names.size()); if (footerNames_.size() != names.size())
if (footerValues_.size() != values.size()) footerValues_.resize(values.size()); footerNames_.resize(names.size());
for (size_t i = 0; i < names.size(); ++i) { if (footerValues_.size() != values.size())
footerValues_.resize(values.size());
for (size_t i = 0; i < names.size(); ++i)
{
footerNames_[i].ensure(renderer, footerFont_, names[i], footerColor); footerNames_[i].ensure(renderer, footerFont_, names[i], footerColor);
} }
for (size_t i = 0; i < values.size(); ++i) { for (size_t i = 0; i < values.size(); ++i)
if (valueBold[i]) TTF_SetFontStyle(footerFont_, TTF_STYLE_BOLD); {
if (valueBold[i])
TTF_SetFontStyle(footerFont_, TTF_STYLE_BOLD);
footerValues_[i].ensure(renderer, footerFont_, values[i], valueColors[i], footerValues_[i].ensure(renderer, footerFont_, values[i], valueColors[i],
valueBold[i] ? TTF_STYLE_BOLD : TTF_STYLE_NORMAL); valueBold[i] ? TTF_STYLE_BOLD : TTF_STYLE_NORMAL);
if (valueBold[i]) TTF_SetFontStyle(footerFont_, TTF_STYLE_NORMAL); if (valueBold[i])
TTF_SetFontStyle(footerFont_, TTF_STYLE_NORMAL);
} }
float maxNameW = 0.0f; float maxNameW = 0.0f;
float maxValueW = 0.0f; float maxValueW = 0.0f;
for (size_t i = 0; i < footerNames_.size(); ++i) { for (size_t i = 0; i < footerNames_.size(); ++i)
if (footerNames_[i].width > maxNameW) maxNameW = footerNames_[i].width; {
if (footerValues_[i].width > maxValueW) maxValueW = footerValues_[i].width; if (footerNames_[i].width > maxNameW)
maxNameW = footerNames_[i].width;
if (footerValues_[i].width > maxValueW)
maxValueW = footerValues_[i].width;
} }
CachedText fourSpaces; CachedText fourSpaces;
@@ -283,11 +298,13 @@ void Home::render(SDL_Renderer *renderer)
for (size_t i = footerNames_.size(); i-- > 0;) for (size_t i = footerNames_.size(); i-- > 0;)
{ {
float h = std::max(footerNames_[i].height, footerValues_[i].height); float h = std::max(footerNames_[i].height, footerValues_[i].height);
if (footerNames_[i].texture) { if (footerNames_[i].texture)
{
SDL_FRect dst{rectLeft, lineY - h, footerNames_[i].width, footerNames_[i].height}; SDL_FRect dst{rectLeft, lineY - h, footerNames_[i].width, footerNames_[i].height};
SDL_RenderTexture(renderer, footerNames_[i].texture, nullptr, &dst); SDL_RenderTexture(renderer, footerNames_[i].texture, nullptr, &dst);
} }
if (footerValues_[i].texture) { if (footerValues_[i].texture)
{
SDL_FRect dst{rectRight - footerValues_[i].width, lineY - h, footerValues_[i].width, footerValues_[i].height}; SDL_FRect dst{rectRight - footerValues_[i].width, lineY - h, footerValues_[i].width, footerValues_[i].height};
SDL_RenderTexture(renderer, footerValues_[i].texture, nullptr, &dst); SDL_RenderTexture(renderer, footerValues_[i].texture, nullptr, &dst);
} }
@@ -309,7 +326,8 @@ void Home::createTextures(AppState &state)
TextLine textWidthRef = renderText(state.renderer, font, "Radiant Wave", white); TextLine textWidthRef = renderText(state.renderer, font, "Radiant Wave", white);
float targetWidth = textWidthRef.width * 1.5f; float targetWidth = textWidthRef.width * 1.5f;
if (textWidthRef.texture) SDL_DestroyTexture(textWidthRef.texture); if (textWidthRef.texture)
SDL_DestroyTexture(textWidthRef.texture);
TTF_CloseFont(font); TTF_CloseFont(font);
@@ -338,9 +356,8 @@ void Home::createTextures(AppState &state)
return; return;
} }
SDL_Color gray = {180, 180, 180, 255}; play_ = renderText(state.renderer, font, "Play", white);
play_ = renderText(state.renderer, font, "Play", gray); settings_ = renderText(state.renderer, font, "Settings", white);
settings_ = renderText(state.renderer, font, "Settings", gray);
TTF_CloseFont(font); TTF_CloseFont(font);
@@ -356,16 +373,26 @@ void Home::createTextures(AppState &state)
footerFont_ = TTF_OpenFont("assets/fonts/Roboto-Regular.ttf", 20); footerFont_ = TTF_OpenFont("assets/fonts/Roboto-Regular.ttf", 20);
const std::vector<std::string> footerNames = { const std::vector<std::string> footerNames = {
"Version:", "License:", "Key:", "Email:", "Subscription:", "WiFi:", "Version:",
"Internet:", "Audio:", "Date:", "Time:", "License:",
"Key:",
"Email:",
"Subscription:",
"WiFi:",
"Internet:",
"Audio:",
"Date:",
"Time:",
}; };
footerNames_.clear(); footerNames_.clear();
footerValues_.clear(); footerValues_.clear();
footerNames_.resize(footerNames.size()); footerNames_.resize(footerNames.size());
footerValues_.resize(footerNames.size()); footerValues_.resize(footerNames.size());
SDL_Color footerColor = {200, 200, 200, 255}; SDL_Color footerColor = {200, 200, 200, 255};
if (footerFont_) { if (footerFont_)
for (size_t i = 0; i < footerNames.size(); ++i) { {
for (size_t i = 0; i < footerNames.size(); ++i)
{
footerNames_[i].ensure(state.renderer, footerFont_, footerNames[i], footerColor); footerNames_[i].ensure(state.renderer, footerFont_, footerNames[i], footerColor);
} }
} }
@@ -373,20 +400,43 @@ void Home::createTextures(AppState &state)
void Home::destroyTextures() void Home::destroyTextures()
{ {
if (bg_.texture) { SDL_DestroyTexture(bg_.texture); bg_.texture = nullptr; } if (bg_.texture)
if (title_.texture) { SDL_DestroyTexture(title_.texture); title_.texture = nullptr; } {
if (play_.texture) { SDL_DestroyTexture(play_.texture); play_.texture = nullptr; } SDL_DestroyTexture(bg_.texture);
if (settings_.texture) { SDL_DestroyTexture(settings_.texture); settings_.texture = nullptr; } bg_.texture = nullptr;
for (auto& t : footerNames_) t.destroy(); }
for (auto& t : footerValues_) t.destroy(); if (title_.texture)
{
SDL_DestroyTexture(title_.texture);
title_.texture = nullptr;
}
if (play_.texture)
{
SDL_DestroyTexture(play_.texture);
play_.texture = nullptr;
}
if (settings_.texture)
{
SDL_DestroyTexture(settings_.texture);
settings_.texture = nullptr;
}
for (auto &t : footerNames_)
t.destroy();
for (auto &t : footerValues_)
t.destroy();
footerNames_.clear(); footerNames_.clear();
footerValues_.clear(); footerValues_.clear();
if (footerFont_) { TTF_CloseFont(footerFont_); footerFont_ = nullptr; } if (footerFont_)
{
TTF_CloseFont(footerFont_);
footerFont_ = nullptr;
}
} }
void Home::refreshStatus() void Home::refreshStatus()
{ {
if (!state_) return; if (!state_)
return;
email_ = state_->db.getKV(radiantwave::db::KV_EMAIL_ADDRESS); email_ = state_->db.getKV(radiantwave::db::KV_EMAIL_ADDRESS);
license_ = state_->db.getKV(radiantwave::db::KV_LICENSE_KEY); license_ = state_->db.getKV(radiantwave::db::KV_LICENSE_KEY);
dateFormat_ = state_->db.getKV("date_format", radiantwave::datetime::DEFAULT_DATE_FORMAT); dateFormat_ = state_->db.getKV("date_format", radiantwave::datetime::DEFAULT_DATE_FORMAT);
@@ -401,7 +451,8 @@ void Home::syncProclamationsIfEmpty(AppState &state)
// Proclamation options. Skipped once the database has content so a // Proclamation options. Skipped once the database has content so a
// blocking sync never runs on every Home push. The API call is also // blocking sync never runs on every Home push. The API call is also
// skipped when the database is closed (fallback path in provisioning). // skipped when the database is closed (fallback path in provisioning).
if (state.db.isOpen() && state.db.getActiveProclamations().empty()) { if (state.db.isOpen() && state.db.getActiveProclamations().empty())
{
// TODO(portal #4/#5): once the portal exposes color palettes, sync them // TODO(portal #4/#5): once the portal exposes color palettes, sync them
// alongside proclamations here (sync::syncColorPalettesFromApi) so Play's // alongside proclamations here (sync::syncColorPalettesFromApi) so Play's
// scroller has portal colors from the very first run. // scroller has portal colors from the very first run.
@@ -411,7 +462,8 @@ void Home::syncProclamationsIfEmpty(AppState &state)
std::string Home::audioStatus() const std::string Home::audioStatus() const
{ {
if (!state_) return "Idle"; if (!state_)
return "Idle";
std::string status = state_->audioDownloader.statusString(); std::string status = state_->audioDownloader.statusString();
return status.empty() ? "Idle" : status; return status.empty() ? "Idle" : status;
} }
+93 -47
View File
@@ -14,7 +14,8 @@
#include <SDL3_image/SDL_image.h> #include <SDL3_image/SDL_image.h>
#include <algorithm> #include <algorithm>
namespace { namespace
{
constexpr int MENU_ITEM_COUNT = 9; constexpr int MENU_ITEM_COUNT = 9;
// 0 = WiFi Setup, 1 = Audio Options, 2 = Time Zone Setup, 3 = Proclamations, // 0 = WiFi Setup, 1 = Audio Options, 2 = Time Zone Setup, 3 = Proclamations,
@@ -40,12 +41,10 @@ void Settings::onPush(AppState& state)
TTF_Init(); TTF_Init();
createTextures(state); createTextures(state);
state.keybinds.bind(SDLK_UP, "menu_up", [this]() { state.keybinds.bind(SDLK_UP, "menu_up", [this]()
selectedItem_ = (selectedItem_ - 1 + MENU_ITEM_COUNT) % MENU_ITEM_COUNT; { selectedItem_ = (selectedItem_ - 1 + MENU_ITEM_COUNT) % MENU_ITEM_COUNT; });
}); state.keybinds.bind(SDLK_DOWN, "menu_down", [this]()
state.keybinds.bind(SDLK_DOWN, "menu_down", [this]() { { selectedItem_ = (selectedItem_ + 1) % MENU_ITEM_COUNT; });
selectedItem_ = (selectedItem_ + 1) % MENU_ITEM_COUNT;
});
} }
void Settings::onResume(AppState &state) void Settings::onResume(AppState &state)
@@ -53,12 +52,10 @@ void Settings::onResume(AppState& state)
state_ = &state; state_ = &state;
createTextures(state); createTextures(state);
state.keybinds.bind(SDLK_UP, "menu_up", [this]() { state.keybinds.bind(SDLK_UP, "menu_up", [this]()
selectedItem_ = (selectedItem_ - 1 + MENU_ITEM_COUNT) % MENU_ITEM_COUNT; { selectedItem_ = (selectedItem_ - 1 + MENU_ITEM_COUNT) % MENU_ITEM_COUNT; });
}); state.keybinds.bind(SDLK_DOWN, "menu_down", [this]()
state.keybinds.bind(SDLK_DOWN, "menu_down", [this]() { { selectedItem_ = (selectedItem_ + 1) % MENU_ITEM_COUNT; });
selectedItem_ = (selectedItem_ + 1) % MENU_ITEM_COUNT;
});
} }
void Settings::onPause(AppState &state) void Settings::onPause(AppState &state)
@@ -75,27 +72,51 @@ void Settings::onPop(AppState& state)
void Settings::handleEvent(const SDL_Event &event) void Settings::handleEvent(const SDL_Event &event)
{ {
if (event.type == SDL_EVENT_KEY_DOWN && event.key.key == SDLK_RETURN) { if (event.type == SDL_EVENT_KEY_DOWN && event.key.key == SDLK_RETURN)
switch (selectedItem_) { {
case 0: state_->pages.push(*state_, std::make_unique<WiFiSetupPage>()); break; switch (selectedItem_)
case 1: state_->pages.push(*state_, std::make_unique<AudioSettingsPage>()); break; {
case 2: state_->pages.push(*state_, std::make_unique<TimeZonePage>()); break; case 0:
state_->pages.push(*state_, std::make_unique<WiFiSetupPage>());
break;
case 1:
state_->pages.push(*state_, std::make_unique<AudioSettingsPage>());
break;
case 2:
state_->pages.push(*state_, std::make_unique<TimeZonePage>());
break;
case 3: case 3:
// The Proclamation list is license-gated like Play. // The Proclamation list is license-gated like Play.
if (state_->licenseTracker.isValid()) { if (state_->licenseTracker.isValid())
{
state_->pages.push(*state_, std::make_unique<ProclamationOptionsPage>()); state_->pages.push(*state_, std::make_unique<ProclamationOptionsPage>());
} else { }
else
{
state_->pages.push(*state_, std::make_unique<LicenseBlockedPage>()); state_->pages.push(*state_, std::make_unique<LicenseBlockedPage>());
} }
break; break;
case 4: state_->pages.push(*state_, std::make_unique<EmailAddressPage>()); break; case 4:
case 5: state_->pages.push(*state_, std::make_unique<LicenseKeyPage>()); break; state_->pages.push(*state_, std::make_unique<EmailAddressPage>());
case 6: state_->pages.push(*state_, std::make_unique<DateFormatPage>()); break; break;
case 7: state_->pages.push(*state_, std::make_unique<LogViewerPage>()); break; case 5:
case 8: state_->pages.replace(*state_, std::make_unique<Home>()); break; state_->pages.push(*state_, std::make_unique<LicenseKeyPage>());
default: break; break;
case 6:
state_->pages.push(*state_, std::make_unique<DateFormatPage>());
break;
case 7:
state_->pages.push(*state_, std::make_unique<LogViewerPage>());
break;
case 8:
state_->pages.replace(*state_, std::make_unique<Home>());
break;
default:
break;
} }
} else if (event.type == SDL_EVENT_KEY_DOWN && (event.key.key == SDLK_ESCAPE || event.key.key == SDLK_TAB)) { }
else if (event.type == SDL_EVENT_KEY_DOWN && (event.key.key == SDLK_ESCAPE || event.key.key == SDLK_TAB))
{
state_->pages.replace(*state_, std::make_unique<Home>()); state_->pages.replace(*state_, std::make_unique<Home>());
} }
} }
@@ -112,7 +133,8 @@ void Settings::render(SDL_Renderer* renderer)
float fh = static_cast<float>(winH); float fh = static_cast<float>(winH);
// 1. Logo Background Image // 1. Logo Background Image
if (bgTexture_) { if (bgTexture_)
{
float scaleX = fw / bgWidth_; float scaleX = fw / bgWidth_;
float scaleY = fh / bgHeight_; float scaleY = fh / bgHeight_;
float scale = std::min(scaleX, scaleY); float scale = std::min(scaleX, scaleY);
@@ -132,7 +154,8 @@ void Settings::render(SDL_Renderer* renderer)
// 3. Title Text // 3. Title Text
float titleY = 60.0f; float titleY = 60.0f;
if (titleTexture_) { if (titleTexture_)
{
float x = (fw - titleWidth_) / 2.0f; float x = (fw - titleWidth_) / 2.0f;
SDL_FRect dst{x, titleY, titleWidth_, titleHeight_}; SDL_FRect dst{x, titleY, titleWidth_, titleHeight_};
SDL_RenderTexture(renderer, titleTexture_, nullptr, &dst); SDL_RenderTexture(renderer, titleTexture_, nullptr, &dst);
@@ -140,7 +163,8 @@ void Settings::render(SDL_Renderer* renderer)
// Compute bounding box for all menu items // Compute bounding box for all menu items
float maxWidth = 0.0f; float maxWidth = 0.0f;
for (const auto& item : items_) { for (const auto &item : items_)
{
maxWidth = std::max(maxWidth, item.width); maxWidth = std::max(maxWidth, item.width);
} }
float margin = 12.0f; // 12px vertical margin rule float margin = 12.0f; // 12px vertical margin rule
@@ -151,9 +175,11 @@ void Settings::render(SDL_Renderer* renderer)
// Start menu list exactly 24 pixels below title text // Start menu list exactly 24 pixels below title text
float currentY = titleY + titleHeight_ + 24.0f; float currentY = titleY + titleHeight_ + 24.0f;
for (auto& item : items_) { for (auto &item : items_)
{
item.y = currentY; item.y = currentY;
if (item.texture) { if (item.texture)
{
SDL_FRect dst{sharedX, item.y, item.width, item.height}; SDL_FRect dst{sharedX, item.y, item.width, item.height};
SDL_RenderTexture(renderer, item.texture, nullptr, &dst); SDL_RenderTexture(renderer, item.texture, nullptr, &dst);
} }
@@ -161,9 +187,11 @@ void Settings::render(SDL_Renderer* renderer)
} }
// 6px Underline for selected item occupying half of the 12px margin space // 6px Underline for selected item occupying half of the 12px margin space
if (selectedItem_ >= 0 && selectedItem_ < static_cast<int>(items_.size())) { if (selectedItem_ >= 0 && selectedItem_ < static_cast<int>(items_.size()))
{
const auto &item = items_[selectedItem_]; const auto &item = items_[selectedItem_];
if (item.texture) { if (item.texture)
{
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_FRect line{sharedX, item.y + item.height + 2.0f, item.width, 6.0f}; SDL_FRect line{sharedX, item.y + item.height + 2.0f, item.width, 6.0f};
SDL_RenderFillRect(renderer, &line); SDL_RenderFillRect(renderer, &line);
@@ -177,7 +205,8 @@ void Settings::createTextures(AppState& state)
// Background Image // Background Image
SDL_Surface *bgSurface = IMG_Load("assets/images/RWT-Circular-Color-ForOnDark-NoText.png"); SDL_Surface *bgSurface = IMG_Load("assets/images/RWT-Circular-Color-ForOnDark-NoText.png");
if (bgSurface) { if (bgSurface)
{
bgTexture_ = SDL_CreateTextureFromSurface(state.renderer, bgSurface); bgTexture_ = SDL_CreateTextureFromSurface(state.renderer, bgSurface);
bgWidth_ = static_cast<float>(bgSurface->w); bgWidth_ = static_cast<float>(bgSurface->w);
bgHeight_ = static_cast<float>(bgSurface->h); bgHeight_ = static_cast<float>(bgSurface->h);
@@ -185,12 +214,14 @@ void Settings::createTextures(AppState& state)
SDL_SetTextureAlphaMod(bgTexture_, 204); SDL_SetTextureAlphaMod(bgTexture_, 204);
} }
SDL_Color white = {255, 255, 255, 255};
// Title Font // Title Font
TTF_Font *fontLarge = TTF_OpenFont("assets/fonts/Roboto-Regular.ttf", 64); TTF_Font *fontLarge = TTF_OpenFont("assets/fonts/Roboto-Regular.ttf", 64);
if (fontLarge) { if (fontLarge)
SDL_Color white = {255, 255, 255, 255}; {
SDL_Surface *surface = TTF_RenderText_Blended(fontLarge, "Settings", 0, white); SDL_Surface *surface = TTF_RenderText_Blended(fontLarge, "Settings", 0, white);
if (surface) { if (surface)
{
titleTexture_ = SDL_CreateTextureFromSurface(state.renderer, surface); titleTexture_ = SDL_CreateTextureFromSurface(state.renderer, surface);
titleWidth_ = static_cast<float>(surface->w); titleWidth_ = static_cast<float>(surface->w);
titleHeight_ = static_cast<float>(surface->h); titleHeight_ = static_cast<float>(surface->h);
@@ -201,17 +232,19 @@ void Settings::createTextures(AppState& state)
// Item Font // Item Font
TTF_Font *fontItem = TTF_OpenFont("assets/fonts/Roboto-Regular.ttf", 36); TTF_Font *fontItem = TTF_OpenFont("assets/fonts/Roboto-Regular.ttf", 36);
if (!fontItem) return; if (!fontItem)
return;
SDL_Color gray = {200, 200, 200, 255};
items_.reserve(MENU_ITEM_COUNT); items_.reserve(MENU_ITEM_COUNT);
for (int i = 0; i < MENU_ITEM_COUNT; ++i) { for (int i = 0; i < MENU_ITEM_COUNT; ++i)
{
MenuItem item; MenuItem item;
item.label = MENU_LABELS[i]; item.label = MENU_LABELS[i];
SDL_Surface* surface = TTF_RenderText_Blended(fontItem, MENU_LABELS[i], 0, gray); SDL_Surface *surface = TTF_RenderText_Blended(fontItem, MENU_LABELS[i], 0, white);
if (surface) { if (surface)
{
item.texture = SDL_CreateTextureFromSurface(state.renderer, surface); item.texture = SDL_CreateTextureFromSurface(state.renderer, surface);
item.width = static_cast<float>(surface->w); item.width = static_cast<float>(surface->w);
item.height = static_cast<float>(surface->h); item.height = static_cast<float>(surface->h);
@@ -225,10 +258,23 @@ void Settings::createTextures(AppState& state)
void Settings::destroyTextures() void Settings::destroyTextures()
{ {
if (bgTexture_) { SDL_DestroyTexture(bgTexture_); bgTexture_ = nullptr; } if (bgTexture_)
if (titleTexture_) { SDL_DestroyTexture(titleTexture_); titleTexture_ = nullptr; } {
for (auto& item : items_) { SDL_DestroyTexture(bgTexture_);
if (item.texture) { SDL_DestroyTexture(item.texture); item.texture = nullptr; } bgTexture_ = nullptr;
}
if (titleTexture_)
{
SDL_DestroyTexture(titleTexture_);
titleTexture_ = nullptr;
}
for (auto &item : items_)
{
if (item.texture)
{
SDL_DestroyTexture(item.texture);
item.texture = nullptr;
}
} }
items_.clear(); items_.clear();
} }