diff --git a/data/locale/ca.yaml b/data/locale/ca.yaml index 4ad3cf0..eefa10a 100644 --- a/data/locale/ca.yaml +++ b/data/locale/ca.yaml @@ -13,6 +13,11 @@ notification: antialias_off: "AA INACTIU" postfx_on: "POSTPROCESSAT ACTIU" postfx_off: "POSTPROCESSAT INACTIU" + locale_switched: "IDIOMA: {lang}" + +language: + ca: "CATALA" + en: "ANGLES" hud: level: "NIVELL " diff --git a/data/locale/en.yaml b/data/locale/en.yaml index c777739..1d7fdbe 100644 --- a/data/locale/en.yaml +++ b/data/locale/en.yaml @@ -12,6 +12,11 @@ notification: antialias_off: "AA OFF" postfx_on: "POSTPROCESS ON" postfx_off: "POSTPROCESS OFF" + locale_switched: "LANGUAGE: {lang}" + +language: + ca: "CATALAN" + en: "ENGLISH" hud: level: "LEVEL " diff --git a/source/core/locale/locale.cpp b/source/core/locale/locale.cpp index 9c8c3cf..ec1733a 100644 --- a/source/core/locale/locale.cpp +++ b/source/core/locale/locale.cpp @@ -51,7 +51,7 @@ auto Locale::get() -> Locale& { return instance_; } -void Locale::load(const std::string& file_path) { +auto Locale::load(const std::string& file_path) -> bool { // Normalitza traient prefix "data/" com fa StageLoader: el pack de // recursos indexa rutes relatives a `data/`. std::string normalized = file_path; @@ -62,7 +62,7 @@ void Locale::load(const std::string& file_path) { std::vector bytes = Resource::Helper::loadFile(normalized); if (bytes.empty()) { std::cerr << "[Locale] no s'ha pogut load " << normalized << '\n'; - return; + return false; } try { @@ -72,11 +72,17 @@ void Locale::load(const std::string& file_path) { strings_.clear(); flatten(yaml, "", strings_); std::cout << "[Locale] " << strings_.size() << " traduccions des de " << normalized << '\n'; + return true; } catch (const std::exception& e) { std::cerr << "[Locale] error parsejant " << normalized << ": " << e.what() << '\n'; + return false; } } +auto Locale::switchTo(const std::string& lang) -> bool { + return load("locale/" + lang + ".yaml"); +} + auto Locale::text(const std::string& key) const -> std::string { auto it = strings_.find(key); if (it != strings_.end()) { diff --git a/source/core/locale/locale.hpp b/source/core/locale/locale.hpp index 0b8ee21..20c6d6e 100644 --- a/source/core/locale/locale.hpp +++ b/source/core/locale/locale.hpp @@ -25,8 +25,15 @@ class Locale { // Llig el fitxer YAML i emplena el mapping intern. Si hi ha un error de // parse o el fitxer no existeix, deixa el mapping com estava i ho - // notifica per stderr. - void load(const std::string& file_path); + // notifica per stderr. Retorna true només si la càrrega ha tingut èxit. + auto load(const std::string& file_path) -> bool; + + // Canvi d'idioma en runtime. Recarrega `locale/.yaml`. Retorna true + // si la càrrega ha tingut èxit. Els lookups posteriors (tots els draw* + // criden Locale::text() cada frame) ja veuen el nou idioma. Els missatges + // ja capturats (toast actiu, banner de stage start ja triat) sobreviuen + // fins al seu cicle natural. + auto switchTo(const std::string& lang) -> bool; // Retorna la traducció; si la clau no existeix, retorna la pròpia clau // com a fallback visible (així una clau mal escrita es detecta sense diff --git a/source/core/system/global_events.cpp b/source/core/system/global_events.cpp index af665e9..3839b6a 100644 --- a/source/core/system/global_events.cpp +++ b/source/core/system/global_events.cpp @@ -10,6 +10,7 @@ #include "core/locale/locale.hpp" #include "core/rendering/sdl_manager.hpp" #include "core/system/notifier.hpp" +#include "game/config_yaml.hpp" #include "scene_context.hpp" // Using declarations per simplificar el codi @@ -63,6 +64,26 @@ namespace GlobalEvents { sdl.togglePostFx(); return true; + case SDL_SCANCODE_F7: { + // Toggle d'idioma en runtime entre català i anglès. Els + // strings ja capturats (toast actiu, banner stage start) + // sobreviuen fins al seu cicle; la resta (HUD, pantalles, + // pròxims toasts) es refresquen al següent frame perquè + // criden Locale::text() cada draw. + const std::string NEW_LANG = (ConfigYaml::engine_config.locale == "ca") ? "en" : "ca"; + if (Locale::get().switchTo(NEW_LANG)) { + ConfigYaml::engine_config.locale = NEW_LANG; + ConfigYaml::saveToFile(); + if (auto* notifier = System::Notifier::get(); notifier != nullptr) { + notifier->notifyInfo(localeSubstitute( + Locale::get().text("notification.locale_switched"), + "{lang}", + Locale::get().text("language." + NEW_LANG))); + } + } + return true; + } + case SDL_SCANCODE_ESCAPE: { // Doble pulsació per confirmar sortida: la primera ESC // dispara un toast d'avís; només si aquest toast concret