feat(service-menu): submenu RESOLUCIO amb canvi en calent de l'offscreen
This commit is contained in:
@@ -61,6 +61,7 @@ service_menu:
|
|||||||
video_vsync: "VSYNC"
|
video_vsync: "VSYNC"
|
||||||
video_aa: "ANTIALIAS"
|
video_aa: "ANTIALIAS"
|
||||||
video_postfx: "POSTPROCESSAT"
|
video_postfx: "POSTPROCESSAT"
|
||||||
|
video_resolution: "RESOLUCIO"
|
||||||
# Items del submenu OPCIONS
|
# Items del submenu OPCIONS
|
||||||
options_language: "IDIOMA"
|
options_language: "IDIOMA"
|
||||||
options_show_info: "MOSTRAR INFO"
|
options_show_info: "MOSTRAR INFO"
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ service_menu:
|
|||||||
video_vsync: "VSYNC"
|
video_vsync: "VSYNC"
|
||||||
video_aa: "ANTIALIAS"
|
video_aa: "ANTIALIAS"
|
||||||
video_postfx: "POSTPROCESS"
|
video_postfx: "POSTPROCESS"
|
||||||
|
video_resolution: "RESOLUTION"
|
||||||
# Items of OPTIONS submenu
|
# Items of OPTIONS submenu
|
||||||
options_language: "LANGUAGE"
|
options_language: "LANGUAGE"
|
||||||
options_show_info: "SHOW INFO"
|
options_show_info: "SHOW INFO"
|
||||||
|
|||||||
@@ -385,6 +385,26 @@ void SDLManager::toggleAntialias() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SDLManager::setRenderResolution(int w, int h) {
|
||||||
|
if (!Defaults::Rendering::isValidRenderResolution(w, h)) {
|
||||||
|
std::cerr << "[SDLManager] Resolucio no valida (" << w << "x" << h
|
||||||
|
<< "), ignorant.\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (w == cfg_->rendering.render_width && h == cfg_->rendering.render_height) {
|
||||||
|
return; // ja era l'actual
|
||||||
|
}
|
||||||
|
if (!gpu_renderer_.resizeRenderTarget(static_cast<float>(w), static_cast<float>(h))) {
|
||||||
|
std::cerr << "[SDLManager] resizeRenderTarget ha fallat.\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cfg_->rendering.render_width = w;
|
||||||
|
cfg_->rendering.render_height = h;
|
||||||
|
if (on_persist_) {
|
||||||
|
on_persist_();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SDLManager::togglePostFx() {
|
void SDLManager::togglePostFx() {
|
||||||
const bool NEW_STATE = !gpu_renderer_.isPostFxEnabled();
|
const bool NEW_STATE = !gpu_renderer_.isPostFxEnabled();
|
||||||
gpu_renderer_.setPostFxEnabled(NEW_STATE);
|
gpu_renderer_.setPostFxEnabled(NEW_STATE);
|
||||||
|
|||||||
@@ -30,12 +30,16 @@ class SDLManager {
|
|||||||
auto operator=(const SDLManager&) -> SDLManager& = delete;
|
auto operator=(const SDLManager&) -> SDLManager& = delete;
|
||||||
|
|
||||||
// [NUEVO] Gestió de finestra dinàmica
|
// [NUEVO] Gestió de finestra dinàmica
|
||||||
void increaseWindowSize(); // F2: +100px
|
void increaseWindowSize(); // F2: +100px
|
||||||
void decreaseWindowSize(); // F1: -100px
|
void decreaseWindowSize(); // F1: -100px
|
||||||
void toggleFullscreen(); // F3
|
void toggleFullscreen(); // F3
|
||||||
void toggleVSync(); // F4
|
void toggleVSync(); // F4
|
||||||
void toggleAntialias(); // F5
|
void toggleAntialias(); // F5
|
||||||
void togglePostFx(); // F6
|
void togglePostFx(); // F6
|
||||||
|
// Canvia la resolució del render target offscreen (recrea la textura).
|
||||||
|
// Cal cridar-lo fora d'un frame (event phase, no draw phase). Si el
|
||||||
|
// valor no es un preset valid o ja es l'actual, es no-op.
|
||||||
|
void setRenderResolution(int w, int h);
|
||||||
auto handleWindowEvent(const SDL_Event& event) -> bool; // Per a SDL_EVENT_WINDOW_RESIZED
|
auto handleWindowEvent(const SDL_Event& event) -> bool; // Per a SDL_EVENT_WINDOW_RESIZED
|
||||||
|
|
||||||
// Funciones principals (renderizado).
|
// Funciones principals (renderizado).
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "core/audio/audio.hpp"
|
#include "core/audio/audio.hpp"
|
||||||
#include "core/config/engine_config.hpp"
|
#include "core/config/engine_config.hpp"
|
||||||
#include "core/defaults/audio.hpp"
|
#include "core/defaults/audio.hpp"
|
||||||
|
#include "core/defaults/rendering.hpp"
|
||||||
#include "core/defaults/service_menu.hpp"
|
#include "core/defaults/service_menu.hpp"
|
||||||
#include "core/locale/locale.hpp"
|
#include "core/locale/locale.hpp"
|
||||||
#include "core/rendering/sdl_manager.hpp"
|
#include "core/rendering/sdl_manager.hpp"
|
||||||
@@ -64,6 +65,18 @@ namespace {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resol el text del label d'un item: prioritza label_text (literal) sobre
|
||||||
|
// label_key (locale). Retorna cadena buida si tots dos son buits.
|
||||||
|
auto resolveLabel(const System::ServiceMenu::Item& item) -> std::string {
|
||||||
|
if (!item.label_text.empty()) {
|
||||||
|
return item.label_text;
|
||||||
|
}
|
||||||
|
if (item.label_key.empty()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return Locale::get().text(item.label_key);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace System {
|
namespace System {
|
||||||
@@ -123,6 +136,7 @@ namespace System {
|
|||||||
return ServiceMenu::Item{
|
return ServiceMenu::Item{
|
||||||
.kind = ServiceMenu::Kind::SUBMENU,
|
.kind = ServiceMenu::Kind::SUBMENU,
|
||||||
.label_key = label_key,
|
.label_key = label_key,
|
||||||
|
.label_text = {},
|
||||||
.selectable = true,
|
.selectable = true,
|
||||||
.on_activate = std::move(on_activate),
|
.on_activate = std::move(on_activate),
|
||||||
.get_value_text = {},
|
.get_value_text = {},
|
||||||
@@ -145,7 +159,7 @@ namespace System {
|
|||||||
stack_.push_back(std::move(root));
|
stack_.push_back(std::move(root));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ServiceMenu::buildVideoPage() const -> Page {
|
auto ServiceMenu::buildVideoPage() -> Page {
|
||||||
// Helper: localitza ON/OFF per a TOGGLE items.
|
// Helper: localitza ON/OFF per a TOGGLE items.
|
||||||
auto on_off_text = [](bool v) -> std::string {
|
auto on_off_text = [](bool v) -> std::string {
|
||||||
return Locale::get().text(v ? "service_menu.value_on" : "service_menu.value_off");
|
return Locale::get().text(v ? "service_menu.value_on" : "service_menu.value_off");
|
||||||
@@ -160,6 +174,7 @@ namespace System {
|
|||||||
Item{
|
Item{
|
||||||
.kind = Kind::INT_RANGE,
|
.kind = Kind::INT_RANGE,
|
||||||
.label_key = "service_menu.video_zoom",
|
.label_key = "service_menu.video_zoom",
|
||||||
|
.label_text = {},
|
||||||
.selectable = true,
|
.selectable = true,
|
||||||
.on_activate = {},
|
.on_activate = {},
|
||||||
.get_value_text = [sdl] { return std::format("{:.1f}X", sdl->getScaleFactor()); },
|
.get_value_text = [sdl] { return std::format("{:.1f}X", sdl->getScaleFactor()); },
|
||||||
@@ -174,6 +189,7 @@ namespace System {
|
|||||||
Item{
|
Item{
|
||||||
.kind = Kind::TOGGLE,
|
.kind = Kind::TOGGLE,
|
||||||
.label_key = "service_menu.video_fullscreen",
|
.label_key = "service_menu.video_fullscreen",
|
||||||
|
.label_text = {},
|
||||||
.selectable = true,
|
.selectable = true,
|
||||||
.on_activate = {},
|
.on_activate = {},
|
||||||
.get_value_text = [sdl, on_off_text] { return on_off_text(sdl->isFullscreen()); },
|
.get_value_text = [sdl, on_off_text] { return on_off_text(sdl->isFullscreen()); },
|
||||||
@@ -183,15 +199,29 @@ namespace System {
|
|||||||
Item{
|
Item{
|
||||||
.kind = Kind::TOGGLE,
|
.kind = Kind::TOGGLE,
|
||||||
.label_key = "service_menu.video_vsync",
|
.label_key = "service_menu.video_vsync",
|
||||||
|
.label_text = {},
|
||||||
.selectable = true,
|
.selectable = true,
|
||||||
.on_activate = {},
|
.on_activate = {},
|
||||||
.get_value_text = [on_off_text] { return on_off_text(ConfigYaml::engine_config.rendering.vsync != 0); },
|
.get_value_text = [on_off_text] { return on_off_text(ConfigYaml::engine_config.rendering.vsync != 0); },
|
||||||
.on_change = [sdl](int) { sdl->toggleVSync(); },
|
.on_change = [sdl](int) { sdl->toggleVSync(); },
|
||||||
},
|
},
|
||||||
|
// RESOLUCIO (sub-submenu amb els 5 presets; mostra l'actual com a valor)
|
||||||
|
Item{
|
||||||
|
.kind = Kind::SUBMENU,
|
||||||
|
.label_key = "service_menu.video_resolution",
|
||||||
|
.label_text = {},
|
||||||
|
.selectable = true,
|
||||||
|
.on_activate = [this] { pushPage(buildResolutionPage()); },
|
||||||
|
.get_value_text = [] { return std::format("{}X{}",
|
||||||
|
ConfigYaml::engine_config.rendering.render_width,
|
||||||
|
ConfigYaml::engine_config.rendering.render_height); },
|
||||||
|
.on_change = {},
|
||||||
|
},
|
||||||
// ANTIALIAS
|
// ANTIALIAS
|
||||||
Item{
|
Item{
|
||||||
.kind = Kind::TOGGLE,
|
.kind = Kind::TOGGLE,
|
||||||
.label_key = "service_menu.video_aa",
|
.label_key = "service_menu.video_aa",
|
||||||
|
.label_text = {},
|
||||||
.selectable = true,
|
.selectable = true,
|
||||||
.on_activate = {},
|
.on_activate = {},
|
||||||
.get_value_text = [on_off_text] { return on_off_text(ConfigYaml::engine_config.rendering.antialias != 0); },
|
.get_value_text = [on_off_text] { return on_off_text(ConfigYaml::engine_config.rendering.antialias != 0); },
|
||||||
@@ -201,6 +231,7 @@ namespace System {
|
|||||||
Item{
|
Item{
|
||||||
.kind = Kind::TOGGLE,
|
.kind = Kind::TOGGLE,
|
||||||
.label_key = "service_menu.video_postfx",
|
.label_key = "service_menu.video_postfx",
|
||||||
|
.label_text = {},
|
||||||
.selectable = true,
|
.selectable = true,
|
||||||
.on_activate = {},
|
.on_activate = {},
|
||||||
.get_value_text = [sdl, on_off_text] { return on_off_text(sdl->isPostFxEnabled()); },
|
.get_value_text = [sdl, on_off_text] { return on_off_text(sdl->isPostFxEnabled()); },
|
||||||
@@ -210,6 +241,36 @@ namespace System {
|
|||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto ServiceMenu::buildResolutionPage() const -> Page {
|
||||||
|
Page page;
|
||||||
|
page.title_key = "service_menu.video_resolution";
|
||||||
|
// El cursor arrenca sobre el preset actual perquè l'usuari vegi quin
|
||||||
|
// esta seleccionat sense buscar-lo.
|
||||||
|
const int CURR_W = ConfigYaml::engine_config.rendering.render_width;
|
||||||
|
const int CURR_H = ConfigYaml::engine_config.rendering.render_height;
|
||||||
|
std::size_t cursor = 0;
|
||||||
|
SDLManager* sdl = sdl_;
|
||||||
|
for (std::size_t i = 0; i < Defaults::Rendering::RESOLUTION_PRESETS.size(); ++i) {
|
||||||
|
const auto& preset = Defaults::Rendering::RESOLUTION_PRESETS[i];
|
||||||
|
if (preset.w == CURR_W && preset.h == CURR_H) {
|
||||||
|
cursor = i;
|
||||||
|
}
|
||||||
|
const int PW = preset.w;
|
||||||
|
const int PH = preset.h;
|
||||||
|
page.items.push_back(Item{
|
||||||
|
.kind = Kind::ACTION,
|
||||||
|
.label_key = {},
|
||||||
|
.label_text = std::format("{}X{}", PW, PH),
|
||||||
|
.selectable = true,
|
||||||
|
.on_activate = [sdl, PW, PH] { sdl->setRenderResolution(PW, PH); },
|
||||||
|
.get_value_text = {},
|
||||||
|
.on_change = {},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
page.cursor = cursor;
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
auto ServiceMenu::buildAudioPage() -> Page {
|
auto ServiceMenu::buildAudioPage() -> Page {
|
||||||
auto on_off_text = [](bool v) -> std::string {
|
auto on_off_text = [](bool v) -> std::string {
|
||||||
return Locale::get().text(v ? "service_menu.value_on" : "service_menu.value_off");
|
return Locale::get().text(v ? "service_menu.value_on" : "service_menu.value_off");
|
||||||
@@ -229,6 +290,7 @@ namespace System {
|
|||||||
Item{
|
Item{
|
||||||
.kind = Kind::TOGGLE,
|
.kind = Kind::TOGGLE,
|
||||||
.label_key = "service_menu.audio_master",
|
.label_key = "service_menu.audio_master",
|
||||||
|
.label_text = {},
|
||||||
.selectable = true,
|
.selectable = true,
|
||||||
.on_activate = {},
|
.on_activate = {},
|
||||||
.get_value_text = [on_off_text] {
|
.get_value_text = [on_off_text] {
|
||||||
@@ -243,6 +305,7 @@ namespace System {
|
|||||||
Item{
|
Item{
|
||||||
.kind = Kind::INT_RANGE,
|
.kind = Kind::INT_RANGE,
|
||||||
.label_key = "service_menu.audio_master_volume",
|
.label_key = "service_menu.audio_master_volume",
|
||||||
|
.label_text = {},
|
||||||
.selectable = true,
|
.selectable = true,
|
||||||
.on_activate = {},
|
.on_activate = {},
|
||||||
.get_value_text = [] {
|
.get_value_text = [] {
|
||||||
@@ -258,6 +321,7 @@ namespace System {
|
|||||||
Item{
|
Item{
|
||||||
.kind = Kind::TOGGLE,
|
.kind = Kind::TOGGLE,
|
||||||
.label_key = "service_menu.audio_music",
|
.label_key = "service_menu.audio_music",
|
||||||
|
.label_text = {},
|
||||||
.selectable = true,
|
.selectable = true,
|
||||||
.on_activate = {},
|
.on_activate = {},
|
||||||
.get_value_text = [on_off_text] {
|
.get_value_text = [on_off_text] {
|
||||||
@@ -272,6 +336,7 @@ namespace System {
|
|||||||
Item{
|
Item{
|
||||||
.kind = Kind::INT_RANGE,
|
.kind = Kind::INT_RANGE,
|
||||||
.label_key = "service_menu.audio_music_volume",
|
.label_key = "service_menu.audio_music_volume",
|
||||||
|
.label_text = {},
|
||||||
.selectable = true,
|
.selectable = true,
|
||||||
.on_activate = {},
|
.on_activate = {},
|
||||||
.get_value_text = [] {
|
.get_value_text = [] {
|
||||||
@@ -287,6 +352,7 @@ namespace System {
|
|||||||
Item{
|
Item{
|
||||||
.kind = Kind::TOGGLE,
|
.kind = Kind::TOGGLE,
|
||||||
.label_key = "service_menu.audio_sound",
|
.label_key = "service_menu.audio_sound",
|
||||||
|
.label_text = {},
|
||||||
.selectable = true,
|
.selectable = true,
|
||||||
.on_activate = {},
|
.on_activate = {},
|
||||||
.get_value_text = [on_off_text] {
|
.get_value_text = [on_off_text] {
|
||||||
@@ -301,6 +367,7 @@ namespace System {
|
|||||||
Item{
|
Item{
|
||||||
.kind = Kind::INT_RANGE,
|
.kind = Kind::INT_RANGE,
|
||||||
.label_key = "service_menu.audio_sound_volume",
|
.label_key = "service_menu.audio_sound_volume",
|
||||||
|
.label_text = {},
|
||||||
.selectable = true,
|
.selectable = true,
|
||||||
.on_activate = {},
|
.on_activate = {},
|
||||||
.get_value_text = [] {
|
.get_value_text = [] {
|
||||||
@@ -330,6 +397,7 @@ namespace System {
|
|||||||
Item{
|
Item{
|
||||||
.kind = Kind::CYCLE,
|
.kind = Kind::CYCLE,
|
||||||
.label_key = "service_menu.options_language",
|
.label_key = "service_menu.options_language",
|
||||||
|
.label_text = {},
|
||||||
.selectable = true,
|
.selectable = true,
|
||||||
.on_activate = {},
|
.on_activate = {},
|
||||||
.get_value_text = [] { return Locale::get().text("language." + ConfigYaml::engine_config.locale); },
|
.get_value_text = [] { return Locale::get().text("language." + ConfigYaml::engine_config.locale); },
|
||||||
@@ -344,6 +412,7 @@ namespace System {
|
|||||||
Item{
|
Item{
|
||||||
.kind = Kind::TOGGLE,
|
.kind = Kind::TOGGLE,
|
||||||
.label_key = "service_menu.options_show_info",
|
.label_key = "service_menu.options_show_info",
|
||||||
|
.label_text = {},
|
||||||
.selectable = true,
|
.selectable = true,
|
||||||
.on_activate = {},
|
.on_activate = {},
|
||||||
.get_value_text = [debug, on_off_text] { return on_off_text(debug != nullptr && debug->isVisible()); },
|
.get_value_text = [debug, on_off_text] { return on_off_text(debug != nullptr && debug->isVisible()); },
|
||||||
@@ -369,6 +438,7 @@ namespace System {
|
|||||||
Item{
|
Item{
|
||||||
.kind = Kind::ACTION,
|
.kind = Kind::ACTION,
|
||||||
.label_key = "service_menu.system_restart",
|
.label_key = "service_menu.system_restart",
|
||||||
|
.label_text = {},
|
||||||
.selectable = true,
|
.selectable = true,
|
||||||
.on_activate = [this] {
|
.on_activate = [this] {
|
||||||
pushConfirmPage("service_menu.confirm_restart", [] {
|
pushConfirmPage("service_menu.confirm_restart", [] {
|
||||||
@@ -385,6 +455,7 @@ namespace System {
|
|||||||
Item{
|
Item{
|
||||||
.kind = Kind::ACTION,
|
.kind = Kind::ACTION,
|
||||||
.label_key = "service_menu.exit",
|
.label_key = "service_menu.exit",
|
||||||
|
.label_text = {},
|
||||||
.selectable = true,
|
.selectable = true,
|
||||||
.on_activate = [this] {
|
.on_activate = [this] {
|
||||||
pushConfirmPage("service_menu.confirm_exit", [] {
|
pushConfirmPage("service_menu.confirm_exit", [] {
|
||||||
@@ -409,6 +480,7 @@ namespace System {
|
|||||||
Item{
|
Item{
|
||||||
.kind = Kind::ACTION,
|
.kind = Kind::ACTION,
|
||||||
.label_key = "service_menu.confirm_no",
|
.label_key = "service_menu.confirm_no",
|
||||||
|
.label_text = {},
|
||||||
.selectable = true,
|
.selectable = true,
|
||||||
.on_activate = [this] { popPage(); },
|
.on_activate = [this] { popPage(); },
|
||||||
.get_value_text = {},
|
.get_value_text = {},
|
||||||
@@ -417,6 +489,7 @@ namespace System {
|
|||||||
Item{
|
Item{
|
||||||
.kind = Kind::ACTION,
|
.kind = Kind::ACTION,
|
||||||
.label_key = "service_menu.confirm_yes",
|
.label_key = "service_menu.confirm_yes",
|
||||||
|
.label_text = {},
|
||||||
.selectable = true,
|
.selectable = true,
|
||||||
.on_activate = std::move(yes_callback),
|
.on_activate = std::move(yes_callback),
|
||||||
.get_value_text = {},
|
.get_value_text = {},
|
||||||
@@ -572,10 +645,8 @@ namespace System {
|
|||||||
content_w = std::max(content_w, Graphics::VectorText::getTextWidth(page.subtitle_provider(), SUBTITLE_SCALE, TEXT_SPACING));
|
content_w = std::max(content_w, Graphics::VectorText::getTextWidth(page.subtitle_provider(), SUBTITLE_SCALE, TEXT_SPACING));
|
||||||
}
|
}
|
||||||
for (const Item& item : page.items) {
|
for (const Item& item : page.items) {
|
||||||
const std::string LABEL = item.label_key.empty()
|
const std::string LABEL = resolveLabel(item);
|
||||||
? std::string{}
|
if (LABEL.empty() && item.get_value_text) {
|
||||||
: Locale::get().text(item.label_key);
|
|
||||||
if (item.label_key.empty() && item.get_value_text) {
|
|
||||||
content_w = std::max(content_w, Graphics::VectorText::getTextWidth(item.get_value_text(), ITEM_SCALE, TEXT_SPACING));
|
content_w = std::max(content_w, Graphics::VectorText::getTextWidth(item.get_value_text(), ITEM_SCALE, TEXT_SPACING));
|
||||||
} else if (item.get_value_text) {
|
} else if (item.get_value_text) {
|
||||||
const float LABEL_W = Graphics::VectorText::getTextWidth(LABEL, ITEM_SCALE, TEXT_SPACING);
|
const float LABEL_W = Graphics::VectorText::getTextWidth(LABEL, ITEM_SCALE, TEXT_SPACING);
|
||||||
@@ -810,15 +881,13 @@ namespace System {
|
|||||||
for (std::size_t i = 0; i < page.items.size(); ++i) {
|
for (std::size_t i = 0; i < page.items.size(); ++i) {
|
||||||
const Item& item = page.items[i];
|
const Item& item = page.items[i];
|
||||||
const SDL_Color COL = (i == page.cursor) ? CURSOR_COLOR : LABEL_COLOR;
|
const SDL_Color COL = (i == page.cursor) ? CURSOR_COLOR : LABEL_COLOR;
|
||||||
// Salta el Locale lookup si label_key esta buit (item nomes-valor).
|
// resolveLabel prioritza label_text (literal) sobre label_key (locale).
|
||||||
const std::string LABEL = item.label_key.empty()
|
const std::string LABEL = resolveLabel(item);
|
||||||
? std::string{}
|
|
||||||
: Locale::get().text(item.label_key);
|
|
||||||
const float ITEM_TOP = computeItemTopY(BOX_Y, i, HAS_SUBTITLE);
|
const float ITEM_TOP = computeItemTopY(BOX_Y, i, HAS_SUBTITLE);
|
||||||
const float ITEM_CY = ITEM_TOP + (static_cast<float>(ITEM_HEIGHT) * 0.5F);
|
const float ITEM_CY = ITEM_TOP + (static_cast<float>(ITEM_HEIGHT) * 0.5F);
|
||||||
|
|
||||||
if (item.label_key.empty() && item.get_value_text) {
|
if (LABEL.empty() && item.get_value_text) {
|
||||||
// Item nomes-valor (sense label_key): el text del valor es
|
// Item nomes-valor (sense label): el text del valor es
|
||||||
// renderitza centrat com a label decoratiu. Util per a items
|
// renderitza centrat com a label decoratiu. Util per a items
|
||||||
// d'informacio com la versio/hash a SISTEMA.
|
// d'informacio com la versio/hash a SISTEMA.
|
||||||
text_.renderCentered(item.get_value_text(),
|
text_.renderCentered(item.get_value_text(),
|
||||||
|
|||||||
@@ -50,7 +50,8 @@ namespace System {
|
|||||||
|
|
||||||
struct Item {
|
struct Item {
|
||||||
Kind kind = Kind::LABEL;
|
Kind kind = Kind::LABEL;
|
||||||
std::string label_key; // Clau de locale
|
std::string label_key; // Clau de locale (s'ignora si label_text no esta buit)
|
||||||
|
std::string label_text; // Text literal (no locale). Util per a labels que no necessiten traduccio (resolucions, etc.)
|
||||||
bool selectable = true;
|
bool selectable = true;
|
||||||
// SUBMENU / ACTION: callback en ENTER / RIGHT.
|
// SUBMENU / ACTION: callback en ENTER / RIGHT.
|
||||||
std::function<void()> on_activate;
|
std::function<void()> on_activate;
|
||||||
@@ -92,7 +93,8 @@ namespace System {
|
|||||||
ServiceMenu(Rendering::Renderer* renderer, SDLManager* sdl, DebugOverlay* debug_overlay);
|
ServiceMenu(Rendering::Renderer* renderer, SDLManager* sdl, DebugOverlay* debug_overlay);
|
||||||
|
|
||||||
void buildRootPage();
|
void buildRootPage();
|
||||||
[[nodiscard]] auto buildVideoPage() const -> Page;
|
[[nodiscard]] auto buildVideoPage() -> Page;
|
||||||
|
[[nodiscard]] auto buildResolutionPage() const -> Page;
|
||||||
[[nodiscard]] static auto buildAudioPage() -> Page;
|
[[nodiscard]] static auto buildAudioPage() -> Page;
|
||||||
[[nodiscard]] auto buildOptionsPage() const -> Page;
|
[[nodiscard]] auto buildOptionsPage() const -> Page;
|
||||||
[[nodiscard]] auto buildSystemPage() -> Page;
|
[[nodiscard]] auto buildSystemPage() -> Page;
|
||||||
|
|||||||
Reference in New Issue
Block a user