Change menu text from gray to white
This commit is contained in:
+126
-80
@@ -14,88 +14,109 @@
|
||||
#include <SDL3_image/SDL_image.h>
|
||||
#include <algorithm>
|
||||
|
||||
namespace {
|
||||
namespace
|
||||
{
|
||||
|
||||
constexpr int MENU_ITEM_COUNT = 9;
|
||||
// 0 = WiFi Setup, 1 = Audio Options, 2 = Time Zone Setup, 3 = Proclamations,
|
||||
// 4 = Email Address, 5 = License Key, 6 = Date Format,
|
||||
// 7 = View System Logs, 8 = Back
|
||||
constexpr const char* MENU_LABELS[MENU_ITEM_COUNT] = {
|
||||
"WiFi Setup",
|
||||
"Audio Options",
|
||||
"Time Zone Setup",
|
||||
"Proclamations",
|
||||
"Email Address",
|
||||
"License Key",
|
||||
"Date Format",
|
||||
"View System Logs",
|
||||
"Back to Home",
|
||||
};
|
||||
constexpr int MENU_ITEM_COUNT = 9;
|
||||
// 0 = WiFi Setup, 1 = Audio Options, 2 = Time Zone Setup, 3 = Proclamations,
|
||||
// 4 = Email Address, 5 = License Key, 6 = Date Format,
|
||||
// 7 = View System Logs, 8 = Back
|
||||
constexpr const char *MENU_LABELS[MENU_ITEM_COUNT] = {
|
||||
"WiFi Setup",
|
||||
"Audio Options",
|
||||
"Time Zone Setup",
|
||||
"Proclamations",
|
||||
"Email Address",
|
||||
"License Key",
|
||||
"Date Format",
|
||||
"View System Logs",
|
||||
"Back to Home",
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
void Settings::onPush(AppState& state)
|
||||
void Settings::onPush(AppState &state)
|
||||
{
|
||||
state_ = &state;
|
||||
TTF_Init();
|
||||
createTextures(state);
|
||||
|
||||
state.keybinds.bind(SDLK_UP, "menu_up", [this]() {
|
||||
selectedItem_ = (selectedItem_ - 1 + MENU_ITEM_COUNT) % MENU_ITEM_COUNT;
|
||||
});
|
||||
state.keybinds.bind(SDLK_DOWN, "menu_down", [this]() {
|
||||
selectedItem_ = (selectedItem_ + 1) % MENU_ITEM_COUNT;
|
||||
});
|
||||
state.keybinds.bind(SDLK_UP, "menu_up", [this]()
|
||||
{ selectedItem_ = (selectedItem_ - 1 + MENU_ITEM_COUNT) % MENU_ITEM_COUNT; });
|
||||
state.keybinds.bind(SDLK_DOWN, "menu_down", [this]()
|
||||
{ selectedItem_ = (selectedItem_ + 1) % MENU_ITEM_COUNT; });
|
||||
}
|
||||
|
||||
void Settings::onResume(AppState& state)
|
||||
void Settings::onResume(AppState &state)
|
||||
{
|
||||
state_ = &state;
|
||||
createTextures(state);
|
||||
|
||||
state.keybinds.bind(SDLK_UP, "menu_up", [this]() {
|
||||
selectedItem_ = (selectedItem_ - 1 + MENU_ITEM_COUNT) % MENU_ITEM_COUNT;
|
||||
});
|
||||
state.keybinds.bind(SDLK_DOWN, "menu_down", [this]() {
|
||||
selectedItem_ = (selectedItem_ + 1) % MENU_ITEM_COUNT;
|
||||
});
|
||||
state.keybinds.bind(SDLK_UP, "menu_up", [this]()
|
||||
{ selectedItem_ = (selectedItem_ - 1 + MENU_ITEM_COUNT) % MENU_ITEM_COUNT; });
|
||||
state.keybinds.bind(SDLK_DOWN, "menu_down", [this]()
|
||||
{ selectedItem_ = (selectedItem_ + 1) % MENU_ITEM_COUNT; });
|
||||
}
|
||||
|
||||
void Settings::onPause(AppState& state)
|
||||
void Settings::onPause(AppState &state)
|
||||
{
|
||||
state.keybinds.unbindAll();
|
||||
destroyTextures();
|
||||
}
|
||||
|
||||
void Settings::onPop(AppState& state)
|
||||
void Settings::onPop(AppState &state)
|
||||
{
|
||||
destroyTextures();
|
||||
TTF_Quit();
|
||||
}
|
||||
|
||||
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) {
|
||||
switch (selectedItem_) {
|
||||
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:
|
||||
// The Proclamation list is license-gated like Play.
|
||||
if (state_->licenseTracker.isValid()) {
|
||||
state_->pages.push(*state_, std::make_unique<ProclamationOptionsPage>());
|
||||
} else {
|
||||
state_->pages.push(*state_, std::make_unique<LicenseBlockedPage>());
|
||||
}
|
||||
break;
|
||||
case 4: state_->pages.push(*state_, std::make_unique<EmailAddressPage>()); break;
|
||||
case 5: state_->pages.push(*state_, std::make_unique<LicenseKeyPage>()); 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;
|
||||
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;
|
||||
case 1:
|
||||
state_->pages.push(*state_, std::make_unique<AudioSettingsPage>());
|
||||
break;
|
||||
case 2:
|
||||
state_->pages.push(*state_, std::make_unique<TimeZonePage>());
|
||||
break;
|
||||
case 3:
|
||||
// The Proclamation list is license-gated like Play.
|
||||
if (state_->licenseTracker.isValid())
|
||||
{
|
||||
state_->pages.push(*state_, std::make_unique<ProclamationOptionsPage>());
|
||||
}
|
||||
else
|
||||
{
|
||||
state_->pages.push(*state_, std::make_unique<LicenseBlockedPage>());
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
state_->pages.push(*state_, std::make_unique<EmailAddressPage>());
|
||||
break;
|
||||
case 5:
|
||||
state_->pages.push(*state_, std::make_unique<LicenseKeyPage>());
|
||||
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>());
|
||||
}
|
||||
}
|
||||
@@ -104,7 +125,7 @@ void Settings::update(float dt)
|
||||
{
|
||||
}
|
||||
|
||||
void Settings::render(SDL_Renderer* renderer)
|
||||
void Settings::render(SDL_Renderer *renderer)
|
||||
{
|
||||
int winW, winH;
|
||||
SDL_GetWindowSize(SDL_GetRenderWindow(renderer), &winW, &winH);
|
||||
@@ -112,7 +133,8 @@ void Settings::render(SDL_Renderer* renderer)
|
||||
float fh = static_cast<float>(winH);
|
||||
|
||||
// 1. Logo Background Image
|
||||
if (bgTexture_) {
|
||||
if (bgTexture_)
|
||||
{
|
||||
float scaleX = fw / bgWidth_;
|
||||
float scaleY = fh / bgHeight_;
|
||||
float scale = std::min(scaleX, scaleY);
|
||||
@@ -132,7 +154,8 @@ void Settings::render(SDL_Renderer* renderer)
|
||||
|
||||
// 3. Title Text
|
||||
float titleY = 60.0f;
|
||||
if (titleTexture_) {
|
||||
if (titleTexture_)
|
||||
{
|
||||
float x = (fw - titleWidth_) / 2.0f;
|
||||
SDL_FRect dst{x, titleY, titleWidth_, titleHeight_};
|
||||
SDL_RenderTexture(renderer, titleTexture_, nullptr, &dst);
|
||||
@@ -140,7 +163,8 @@ void Settings::render(SDL_Renderer* renderer)
|
||||
|
||||
// Compute bounding box for all menu items
|
||||
float maxWidth = 0.0f;
|
||||
for (const auto& item : items_) {
|
||||
for (const auto &item : items_)
|
||||
{
|
||||
maxWidth = std::max(maxWidth, item.width);
|
||||
}
|
||||
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
|
||||
float currentY = titleY + titleHeight_ + 24.0f;
|
||||
|
||||
for (auto& item : items_) {
|
||||
for (auto &item : items_)
|
||||
{
|
||||
item.y = currentY;
|
||||
if (item.texture) {
|
||||
if (item.texture)
|
||||
{
|
||||
SDL_FRect dst{sharedX, item.y, item.width, item.height};
|
||||
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
|
||||
if (selectedItem_ >= 0 && selectedItem_ < static_cast<int>(items_.size())) {
|
||||
const auto& item = items_[selectedItem_];
|
||||
if (item.texture) {
|
||||
if (selectedItem_ >= 0 && selectedItem_ < static_cast<int>(items_.size()))
|
||||
{
|
||||
const auto &item = items_[selectedItem_];
|
||||
if (item.texture)
|
||||
{
|
||||
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
|
||||
SDL_FRect line{sharedX, item.y + item.height + 2.0f, item.width, 6.0f};
|
||||
SDL_RenderFillRect(renderer, &line);
|
||||
@@ -171,13 +199,14 @@ void Settings::render(SDL_Renderer* renderer)
|
||||
}
|
||||
}
|
||||
|
||||
void Settings::createTextures(AppState& state)
|
||||
void Settings::createTextures(AppState &state)
|
||||
{
|
||||
destroyTextures();
|
||||
|
||||
// Background Image
|
||||
SDL_Surface* bgSurface = IMG_Load("assets/images/RWT-Circular-Color-ForOnDark-NoText.png");
|
||||
if (bgSurface) {
|
||||
SDL_Surface *bgSurface = IMG_Load("assets/images/RWT-Circular-Color-ForOnDark-NoText.png");
|
||||
if (bgSurface)
|
||||
{
|
||||
bgTexture_ = SDL_CreateTextureFromSurface(state.renderer, bgSurface);
|
||||
bgWidth_ = static_cast<float>(bgSurface->w);
|
||||
bgHeight_ = static_cast<float>(bgSurface->h);
|
||||
@@ -185,12 +214,14 @@ void Settings::createTextures(AppState& state)
|
||||
SDL_SetTextureAlphaMod(bgTexture_, 204);
|
||||
}
|
||||
|
||||
SDL_Color white = {255, 255, 255, 255};
|
||||
// Title Font
|
||||
TTF_Font* fontLarge = TTF_OpenFont("assets/fonts/Roboto-Regular.ttf", 64);
|
||||
if (fontLarge) {
|
||||
SDL_Color white = {255, 255, 255, 255};
|
||||
SDL_Surface* surface = TTF_RenderText_Blended(fontLarge, "Settings", 0, white);
|
||||
if (surface) {
|
||||
TTF_Font *fontLarge = TTF_OpenFont("assets/fonts/Roboto-Regular.ttf", 64);
|
||||
if (fontLarge)
|
||||
{
|
||||
SDL_Surface *surface = TTF_RenderText_Blended(fontLarge, "Settings", 0, white);
|
||||
if (surface)
|
||||
{
|
||||
titleTexture_ = SDL_CreateTextureFromSurface(state.renderer, surface);
|
||||
titleWidth_ = static_cast<float>(surface->w);
|
||||
titleHeight_ = static_cast<float>(surface->h);
|
||||
@@ -200,18 +231,20 @@ void Settings::createTextures(AppState& state)
|
||||
}
|
||||
|
||||
// Item Font
|
||||
TTF_Font* fontItem = TTF_OpenFont("assets/fonts/Roboto-Regular.ttf", 36);
|
||||
if (!fontItem) return;
|
||||
TTF_Font *fontItem = TTF_OpenFont("assets/fonts/Roboto-Regular.ttf", 36);
|
||||
if (!fontItem)
|
||||
return;
|
||||
|
||||
SDL_Color gray = {200, 200, 200, 255};
|
||||
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;
|
||||
item.label = MENU_LABELS[i];
|
||||
|
||||
SDL_Surface* surface = TTF_RenderText_Blended(fontItem, MENU_LABELS[i], 0, gray);
|
||||
if (surface) {
|
||||
SDL_Surface *surface = TTF_RenderText_Blended(fontItem, MENU_LABELS[i], 0, white);
|
||||
if (surface)
|
||||
{
|
||||
item.texture = SDL_CreateTextureFromSurface(state.renderer, surface);
|
||||
item.width = static_cast<float>(surface->w);
|
||||
item.height = static_cast<float>(surface->h);
|
||||
@@ -225,10 +258,23 @@ void Settings::createTextures(AppState& state)
|
||||
|
||||
void Settings::destroyTextures()
|
||||
{
|
||||
if (bgTexture_) { SDL_DestroyTexture(bgTexture_); bgTexture_ = nullptr; }
|
||||
if (titleTexture_) { SDL_DestroyTexture(titleTexture_); titleTexture_ = nullptr; }
|
||||
for (auto& item : items_) {
|
||||
if (item.texture) { SDL_DestroyTexture(item.texture); item.texture = nullptr; }
|
||||
if (bgTexture_)
|
||||
{
|
||||
SDL_DestroyTexture(bgTexture_);
|
||||
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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user