mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-01-30 20:15:38 +00:00
Added basic configuration support and menu entries for theme localization
This commit is contained in:
parent
3f4ed60649
commit
eecd84ac09
|
@ -479,6 +479,49 @@ void GuiMenu::openUIOptions()
|
||||||
themeTransitionsFunc(Settings::getInstance()->getString("Theme"),
|
themeTransitionsFunc(Settings::getInstance()->getString("Theme"),
|
||||||
Settings::getInstance()->getString("ThemeTransitions"));
|
Settings::getInstance()->getString("ThemeTransitions"));
|
||||||
|
|
||||||
|
// Theme language.
|
||||||
|
auto themeLanguage = std::make_shared<OptionListComponent<std::string>>(
|
||||||
|
getHelpStyle(), _("THEME LANGUAGE"), false);
|
||||||
|
s->addWithLabel(_("THEME LANGUAGE"), themeLanguage);
|
||||||
|
s->addSaveFunc([themeLanguage, s] {
|
||||||
|
if (themeLanguage->getSelected() != Settings::getInstance()->getString("ThemeLanguage")) {
|
||||||
|
Settings::getInstance()->setString("ThemeLanguage", themeLanguage->getSelected());
|
||||||
|
s->setNeedsSaving();
|
||||||
|
s->setNeedsReloading();
|
||||||
|
s->setInvalidateCachedBackground();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
auto themeLanguageFunc = [=](const std::string& selectedTheme,
|
||||||
|
const std::string& selectedLanguage) {
|
||||||
|
std::map<std::string, ThemeData::Theme, ThemeData::StringComparator>::const_iterator
|
||||||
|
currentSet {themes.find(selectedTheme)};
|
||||||
|
if (currentSet == themes.cend())
|
||||||
|
return;
|
||||||
|
// We need to recreate the OptionListComponent entries.
|
||||||
|
themeLanguage->clearEntries();
|
||||||
|
if (currentSet->second.capabilities.languages.size() > 0) {
|
||||||
|
for (auto& language : currentSet->second.capabilities.languages) {
|
||||||
|
themeLanguage->add(
|
||||||
|
Utils::String::toUpper(_(ThemeData::getLanguageLabel(language).c_str())),
|
||||||
|
language, language == selectedLanguage);
|
||||||
|
}
|
||||||
|
if (themeLanguage->getSelectedObjects().size() == 0)
|
||||||
|
themeLanguage->selectEntry(0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
themeLanguage->add(_("NONE DEFINED"), "none", true);
|
||||||
|
themeLanguage->setEnabled(false);
|
||||||
|
themeLanguage->setOpacity(DISABLED_OPACITY);
|
||||||
|
themeLanguage->getParent()
|
||||||
|
->getChild(themeLanguage->getChildIndex() - 1)
|
||||||
|
->setOpacity(DISABLED_OPACITY);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
themeLanguageFunc(Settings::getInstance()->getString("Theme"),
|
||||||
|
Settings::getInstance()->getString("ThemeLanguage"));
|
||||||
|
|
||||||
// Application language.
|
// Application language.
|
||||||
auto applicationLanguage = std::make_shared<OptionListComponent<std::string>>(
|
auto applicationLanguage = std::make_shared<OptionListComponent<std::string>>(
|
||||||
getHelpStyle(), _("APPLICATION LANGUAGE"), false);
|
getHelpStyle(), _("APPLICATION LANGUAGE"), false);
|
||||||
|
@ -519,6 +562,8 @@ void GuiMenu::openUIOptions()
|
||||||
s->setNeedsSaving();
|
s->setNeedsSaving();
|
||||||
s->setNeedsCloseMenu([this] { delete this; });
|
s->setNeedsCloseMenu([this] { delete this; });
|
||||||
s->setNeedsRescanROMDirectory();
|
s->setNeedsRescanROMDirectory();
|
||||||
|
s->setNeedsReloading();
|
||||||
|
s->setNeedsCollectionsUpdate();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1008,6 +1053,7 @@ void GuiMenu::openUIOptions()
|
||||||
themeColorSchemesFunc(themeName, themeColorScheme->getSelected());
|
themeColorSchemesFunc(themeName, themeColorScheme->getSelected());
|
||||||
themeFontSizeFunc(themeName, themeFontSize->getSelected());
|
themeFontSizeFunc(themeName, themeFontSize->getSelected());
|
||||||
themeAspectRatiosFunc(themeName, themeAspectRatio->getSelected());
|
themeAspectRatiosFunc(themeName, themeAspectRatio->getSelected());
|
||||||
|
themeLanguageFunc(themeName, themeLanguage->getSelected());
|
||||||
themeTransitionsFunc(themeName, themeTransitions->getSelected());
|
themeTransitionsFunc(themeName, themeTransitions->getSelected());
|
||||||
}
|
}
|
||||||
int selectableVariants {0};
|
int selectableVariants {0};
|
||||||
|
@ -1057,6 +1103,20 @@ void GuiMenu::openUIOptions()
|
||||||
->getChild(themeFontSize->getChildIndex() - 1)
|
->getChild(themeFontSize->getChildIndex() - 1)
|
||||||
->setOpacity(DISABLED_OPACITY);
|
->setOpacity(DISABLED_OPACITY);
|
||||||
}
|
}
|
||||||
|
if (selectedTheme->second.capabilities.languages.size() > 0) {
|
||||||
|
themeLanguage->setEnabled(true);
|
||||||
|
themeLanguage->setOpacity(1.0f);
|
||||||
|
themeLanguage->getParent()
|
||||||
|
->getChild(themeLanguage->getChildIndex() - 1)
|
||||||
|
->setOpacity(1.0f);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
themeLanguage->setEnabled(false);
|
||||||
|
themeLanguage->setOpacity(DISABLED_OPACITY);
|
||||||
|
themeLanguage->getParent()
|
||||||
|
->getChild(themeLanguage->getChildIndex() - 1)
|
||||||
|
->setOpacity(DISABLED_OPACITY);
|
||||||
|
}
|
||||||
if (selectedTheme->second.capabilities.aspectRatios.size() > 0) {
|
if (selectedTheme->second.capabilities.aspectRatios.size() > 0) {
|
||||||
themeAspectRatio->setEnabled(true);
|
themeAspectRatio->setEnabled(true);
|
||||||
themeAspectRatio->setOpacity(1.0f);
|
themeAspectRatio->setOpacity(1.0f);
|
||||||
|
|
|
@ -77,7 +77,6 @@ void GuiSettings::save()
|
||||||
mCloseMenuFunction = nullptr;
|
mCloseMenuFunction = nullptr;
|
||||||
}
|
}
|
||||||
ViewController::getInstance()->rescanROMDirectory();
|
ViewController::getInstance()->rescanROMDirectory();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mNeedsCollectionsUpdate) {
|
if (mNeedsCollectionsUpdate) {
|
||||||
|
|
|
@ -169,6 +169,7 @@ void Settings::setDefaults()
|
||||||
mStringMap["ThemeFontSize"] = {"", ""};
|
mStringMap["ThemeFontSize"] = {"", ""};
|
||||||
mStringMap["ThemeAspectRatio"] = {"", ""};
|
mStringMap["ThemeAspectRatio"] = {"", ""};
|
||||||
mStringMap["ThemeTransitions"] = {"automatic", "automatic"};
|
mStringMap["ThemeTransitions"] = {"automatic", "automatic"};
|
||||||
|
mStringMap["ThemeLanguage"] = {"automatic", "automatic"};
|
||||||
mStringMap["ApplicationLanguage"] = {"automatic", "automatic"};
|
mStringMap["ApplicationLanguage"] = {"automatic", "automatic"};
|
||||||
mStringMap["QuickSystemSelect"] = {"leftrightshoulders", "leftrightshoulders"};
|
mStringMap["QuickSystemSelect"] = {"leftrightshoulders", "leftrightshoulders"};
|
||||||
mStringMap["StartupSystem"] = {"", ""};
|
mStringMap["StartupSystem"] = {"", ""};
|
||||||
|
|
|
@ -102,6 +102,25 @@ std::map<std::string, float> ThemeData::sAspectRatioMap {
|
||||||
{"32:9_vertical", 0.2813f},
|
{"32:9_vertical", 0.2813f},
|
||||||
{"1:1", 1.0f}};
|
{"1:1", 1.0f}};
|
||||||
|
|
||||||
|
std::vector<std::pair<std::string, std::string>> ThemeData::sSupportedLanguages {
|
||||||
|
{"automatic", "automatic"},
|
||||||
|
{"en_US", "ENGLISH (UNITED STATES)"},
|
||||||
|
{"en_GB", "ENGLISH (UNITED KINGDOM)"},
|
||||||
|
{"el_GR", "ΕΛΛΗΝΙΚΆ"},
|
||||||
|
{"de_DE", "DEUTSCH"},
|
||||||
|
{"es_ES", "ESPAÑOL (ESPAÑA)"},
|
||||||
|
{"fr_FR", "FRANÇAIS"},
|
||||||
|
{"it_IT", "ITALIANO"},
|
||||||
|
{"nl_NL", "NEDERLANDS"},
|
||||||
|
{"pl_PL", "POLSKI"},
|
||||||
|
{"pt_BR", "PORTUGUÊS (BRASIL)"},
|
||||||
|
{"ro_RO", "ROMÂNĂ"},
|
||||||
|
{"ru_RU", "РУССКИЙ"},
|
||||||
|
{"sv_SE", "SVENSKA"},
|
||||||
|
{"ja_JP", "日本語"},
|
||||||
|
{"zh_CN", "简体中文"},
|
||||||
|
{"ar_EG", "العربية"}};
|
||||||
|
|
||||||
std::map<std::string, std::map<std::string, std::string>> ThemeData::sPropertyAttributeMap
|
std::map<std::string, std::map<std::string, std::string>> ThemeData::sPropertyAttributeMap
|
||||||
// The data type is defined by the parent property.
|
// The data type is defined by the parent property.
|
||||||
{
|
{
|
||||||
|
@ -629,6 +648,7 @@ void ThemeData::loadFile(const std::map<std::string, std::string>& sysDataMap,
|
||||||
}
|
}
|
||||||
|
|
||||||
sAspectRatioMatch = false;
|
sAspectRatioMatch = false;
|
||||||
|
sThemeLanguage = "";
|
||||||
|
|
||||||
if (sCurrentTheme->second.capabilities.aspectRatios.size() > 0) {
|
if (sCurrentTheme->second.capabilities.aspectRatios.size() > 0) {
|
||||||
if (std::find(sCurrentTheme->second.capabilities.aspectRatios.cbegin(),
|
if (std::find(sCurrentTheme->second.capabilities.aspectRatios.cbegin(),
|
||||||
|
@ -663,6 +683,35 @@ void ThemeData::loadFile(const std::map<std::string, std::string>& sysDataMap,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sCurrentTheme->second.capabilities.languages.size() > 0) {
|
||||||
|
std::string langSetting {Settings::getInstance()->getString("ThemeLanguage")};
|
||||||
|
if (langSetting == "automatic")
|
||||||
|
langSetting = Utils::Localization::sCurrentLocale;
|
||||||
|
|
||||||
|
// Check if there is an exact match.
|
||||||
|
if (std::find(sCurrentTheme->second.capabilities.languages.cbegin(),
|
||||||
|
sCurrentTheme->second.capabilities.languages.cend(),
|
||||||
|
langSetting) != sCurrentTheme->second.capabilities.languages.cend()) {
|
||||||
|
sThemeLanguage = langSetting;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// We assume all locales are in the correct format.
|
||||||
|
const std::string currLanguage {langSetting.substr(0, 2)};
|
||||||
|
// Select the closest matching locale (i.e. same language but possibly for a
|
||||||
|
// different country).
|
||||||
|
for (const auto& lang : sCurrentTheme->second.capabilities.languages) {
|
||||||
|
if (lang.substr(0, 2) == currLanguage) {
|
||||||
|
sThemeLanguage = lang;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If there is no match then fall back to the default language en_US, which is
|
||||||
|
// mandatory for all themes that provide language support.
|
||||||
|
if (sThemeLanguage == "")
|
||||||
|
sThemeLanguage = "en_US";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
parseVariables(root);
|
parseVariables(root);
|
||||||
parseColorSchemes(root);
|
parseColorSchemes(root);
|
||||||
parseFontSizes(root);
|
parseFontSizes(root);
|
||||||
|
@ -795,8 +844,11 @@ void ThemeData::populateThemes()
|
||||||
LOG(LogInfo) << "Added theme \"" << *it << "\"" << themeName;
|
LOG(LogInfo) << "Added theme \"" << *it << "\"" << themeName;
|
||||||
#endif
|
#endif
|
||||||
int aspectRatios {0};
|
int aspectRatios {0};
|
||||||
|
int languages {0};
|
||||||
if (capabilities.aspectRatios.size() > 0)
|
if (capabilities.aspectRatios.size() > 0)
|
||||||
aspectRatios = static_cast<int>(capabilities.aspectRatios.size()) - 1;
|
aspectRatios = static_cast<int>(capabilities.aspectRatios.size()) - 1;
|
||||||
|
if (capabilities.languages.size() > 0)
|
||||||
|
languages = static_cast<int>(capabilities.languages.size()) - 1;
|
||||||
LOG(LogDebug) << "Theme includes support for " << capabilities.variants.size()
|
LOG(LogDebug) << "Theme includes support for " << capabilities.variants.size()
|
||||||
<< " variant" << (capabilities.variants.size() != 1 ? "s" : "")
|
<< " variant" << (capabilities.variants.size() != 1 ? "s" : "")
|
||||||
<< ", " << capabilities.colorSchemes.size() << " color scheme"
|
<< ", " << capabilities.colorSchemes.size() << " color scheme"
|
||||||
|
@ -804,6 +856,7 @@ void ThemeData::populateThemes()
|
||||||
<< capabilities.fontSizes.size() << " font size"
|
<< capabilities.fontSizes.size() << " font size"
|
||||||
<< (capabilities.fontSizes.size() != 1 ? "s" : "") << ", "
|
<< (capabilities.fontSizes.size() != 1 ? "s" : "") << ", "
|
||||||
<< aspectRatios << " aspect ratio" << (aspectRatios != 1 ? "s" : "")
|
<< aspectRatios << " aspect ratio" << (aspectRatios != 1 ? "s" : "")
|
||||||
|
<< ", " << languages << " language" << (languages != 1 ? "s" : "")
|
||||||
<< " and " << capabilities.transitions.size() << " transition"
|
<< " and " << capabilities.transitions.size() << " transition"
|
||||||
<< (capabilities.transitions.size() != 1 ? "s" : "");
|
<< (capabilities.transitions.size() != 1 ? "s" : "");
|
||||||
|
|
||||||
|
@ -878,6 +931,18 @@ const std::string ThemeData::getAspectRatioLabel(const std::string& aspectRatio)
|
||||||
return "invalid ratio";
|
return "invalid ratio";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string ThemeData::getLanguageLabel(const std::string& language)
|
||||||
|
{
|
||||||
|
auto it = std::find_if(sSupportedLanguages.cbegin(), sSupportedLanguages.cend(),
|
||||||
|
[&language](const std::pair<std::string, std::string>& entry) {
|
||||||
|
return entry.first == language;
|
||||||
|
});
|
||||||
|
if (it != sSupportedLanguages.cend())
|
||||||
|
return it->second;
|
||||||
|
else
|
||||||
|
return "invalid language";
|
||||||
|
}
|
||||||
|
|
||||||
void ThemeData::setThemeTransitions()
|
void ThemeData::setThemeTransitions()
|
||||||
{
|
{
|
||||||
auto setTransitionsFunc = [](int transitionAnim) {
|
auto setTransitionsFunc = [](int transitionAnim) {
|
||||||
|
@ -971,6 +1036,7 @@ ThemeData::getCurrentThemeSelectedVariantOverrides()
|
||||||
const void ThemeData::themeLoadedLogOutput()
|
const void ThemeData::themeLoadedLogOutput()
|
||||||
{
|
{
|
||||||
LOG(LogInfo) << "Finished loading theme \"" << sCurrentTheme->first << "\"";
|
LOG(LogInfo) << "Finished loading theme \"" << sCurrentTheme->first << "\"";
|
||||||
|
|
||||||
if (sSelectedAspectRatio != "") {
|
if (sSelectedAspectRatio != "") {
|
||||||
const bool autoDetect {Settings::getInstance()->getString("ThemeAspectRatio") ==
|
const bool autoDetect {Settings::getInstance()->getString("ThemeAspectRatio") ==
|
||||||
"automatic"};
|
"automatic"};
|
||||||
|
@ -980,6 +1046,13 @@ const void ThemeData::themeLoadedLogOutput()
|
||||||
<< "set to " << (autoDetect ? match : "") << "\""
|
<< "set to " << (autoDetect ? match : "") << "\""
|
||||||
<< Utils::String::replace(sSelectedAspectRatio, "_", " ") << "\"";
|
<< Utils::String::replace(sSelectedAspectRatio, "_", " ") << "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sThemeLanguage != "") {
|
||||||
|
LOG(LogInfo) << "Theme language set to \"" << sThemeLanguage << "\"";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG(LogInfo) << "Theme does not have multilingual support";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int ThemeData::getHexColor(const std::string& str)
|
unsigned int ThemeData::getHexColor(const std::string& str)
|
||||||
|
@ -1028,6 +1101,7 @@ ThemeData::ThemeCapability ThemeData::parseThemeCapabilities(const std::string&
|
||||||
ThemeCapability capabilities;
|
ThemeCapability capabilities;
|
||||||
std::vector<std::string> aspectRatiosTemp;
|
std::vector<std::string> aspectRatiosTemp;
|
||||||
std::vector<std::string> fontSizesTemp;
|
std::vector<std::string> fontSizesTemp;
|
||||||
|
std::vector<std::string> languagesTemp;
|
||||||
bool hasTriggers {false};
|
bool hasTriggers {false};
|
||||||
|
|
||||||
const std::string capFile {path + "/capabilities.xml"};
|
const std::string capFile {path + "/capabilities.xml"};
|
||||||
|
@ -1305,6 +1379,36 @@ ThemeData::ThemeCapability ThemeData::parseThemeCapabilities(const std::string&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (pugi::xml_node language {themeCapabilities.child("language")}; language;
|
||||||
|
language = language.next_sibling("language")) {
|
||||||
|
const std::string& value {language.text().get()};
|
||||||
|
if (std::find_if(sSupportedLanguages.cbegin(), sSupportedLanguages.cend(),
|
||||||
|
[&value](const std::pair<std::string, std::string>& entry) {
|
||||||
|
return entry.first == value;
|
||||||
|
}) == sSupportedLanguages.cend()) {
|
||||||
|
LOG(LogWarning) << "Declared language \"" << value
|
||||||
|
<< "\" is not supported, ignoring entry in \"" << capFile << "\"";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (std::find(languagesTemp.cbegin(), languagesTemp.cend(), value) !=
|
||||||
|
languagesTemp.cend()) {
|
||||||
|
LOG(LogWarning)
|
||||||
|
<< "Language \"" << value
|
||||||
|
<< "\" is declared multiple times, ignoring entry in \"" << capFile << "\"";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
languagesTemp.emplace_back(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (languagesTemp.size() > 0 && std::find(languagesTemp.cbegin(), languagesTemp.cend(),
|
||||||
|
"en_US") == languagesTemp.cend()) {
|
||||||
|
LOG(LogError) << "Theme has declared language support but is missing mandatory "
|
||||||
|
<< "\"en_US\" entry in \"" << capFile << "\"";
|
||||||
|
languagesTemp.clear();
|
||||||
|
}
|
||||||
|
|
||||||
for (pugi::xml_node transitions {themeCapabilities.child("transitions")}; transitions;
|
for (pugi::xml_node transitions {themeCapabilities.child("transitions")}; transitions;
|
||||||
transitions = transitions.next_sibling("transitions")) {
|
transitions = transitions.next_sibling("transitions")) {
|
||||||
std::map<ViewTransition, ViewTransitionAnimation> readTransitions;
|
std::map<ViewTransition, ViewTransitionAnimation> readTransitions;
|
||||||
|
@ -1482,6 +1586,20 @@ ThemeData::ThemeCapability ThemeData::parseThemeCapabilities(const std::string&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add the languages in the order they are defined in sSupportedLanguages so they always
|
||||||
|
// show up in the same order in the UI Settings menu.
|
||||||
|
if (!languagesTemp.empty()) {
|
||||||
|
// Add the "automatic" language if there is at least one entry.
|
||||||
|
if (!languagesTemp.empty())
|
||||||
|
capabilities.languages.emplace_back(sSupportedLanguages.front().first);
|
||||||
|
for (auto& language : sSupportedLanguages) {
|
||||||
|
if (std::find(languagesTemp.cbegin(), languagesTemp.cend(), language.first) !=
|
||||||
|
languagesTemp.cend()) {
|
||||||
|
capabilities.languages.emplace_back(language.first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add the font sizes in the order they are defined in sSupportedFontSizes so they always
|
// Add the font sizes in the order they are defined in sSupportedFontSizes so they always
|
||||||
// show up in the same order in the UI Settings menu.
|
// show up in the same order in the UI Settings menu.
|
||||||
if (!fontSizesTemp.empty()) {
|
if (!fontSizesTemp.empty()) {
|
||||||
|
|
|
@ -186,6 +186,7 @@ public:
|
||||||
std::vector<ThemeColorScheme> colorSchemes;
|
std::vector<ThemeColorScheme> colorSchemes;
|
||||||
std::vector<std::string> fontSizes;
|
std::vector<std::string> fontSizes;
|
||||||
std::vector<std::string> aspectRatios;
|
std::vector<std::string> aspectRatios;
|
||||||
|
std::vector<std::string> languages;
|
||||||
std::vector<ThemeTransitions> transitions;
|
std::vector<ThemeTransitions> transitions;
|
||||||
std::vector<std::string> suppressedTransitionProfiles;
|
std::vector<std::string> suppressedTransitionProfiles;
|
||||||
bool validTheme;
|
bool validTheme;
|
||||||
|
@ -225,6 +226,7 @@ public:
|
||||||
const static std::string getSystemThemeFile(const std::string& system);
|
const static std::string getSystemThemeFile(const std::string& system);
|
||||||
const static std::string getFontSizeLabel(const std::string& fontSize);
|
const static std::string getFontSizeLabel(const std::string& fontSize);
|
||||||
const static std::string getAspectRatioLabel(const std::string& aspectRatio);
|
const static std::string getAspectRatioLabel(const std::string& aspectRatio);
|
||||||
|
const static std::string getLanguageLabel(const std::string& language);
|
||||||
static void setThemeTransitions();
|
static void setThemeTransitions();
|
||||||
|
|
||||||
const std::map<ThemeTriggers::TriggerType, std::pair<std::string, std::vector<std::string>>>
|
const std::map<ThemeTriggers::TriggerType, std::pair<std::string, std::vector<std::string>>>
|
||||||
|
@ -275,6 +277,7 @@ private:
|
||||||
|
|
||||||
static std::vector<std::pair<std::string, std::string>> sSupportedFontSizes;
|
static std::vector<std::pair<std::string, std::string>> sSupportedFontSizes;
|
||||||
static std::vector<std::pair<std::string, std::string>> sSupportedAspectRatios;
|
static std::vector<std::pair<std::string, std::string>> sSupportedAspectRatios;
|
||||||
|
static std::vector<std::pair<std::string, std::string>> sSupportedLanguages;
|
||||||
static std::map<std::string, float> sAspectRatioMap;
|
static std::map<std::string, float> sAspectRatioMap;
|
||||||
|
|
||||||
static std::map<std::string, std::map<std::string, std::string>> sPropertyAttributeMap;
|
static std::map<std::string, std::map<std::string, std::string>> sPropertyAttributeMap;
|
||||||
|
@ -295,6 +298,7 @@ private:
|
||||||
std::string mSelectedFontSize;
|
std::string mSelectedFontSize;
|
||||||
static inline std::string sSelectedAspectRatio;
|
static inline std::string sSelectedAspectRatio;
|
||||||
static inline bool sAspectRatioMatch {false};
|
static inline bool sAspectRatioMatch {false};
|
||||||
|
static inline std::string sThemeLanguage;
|
||||||
bool mCustomCollection;
|
bool mCustomCollection;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -28,23 +28,26 @@ namespace Utils
|
||||||
namespace Localization
|
namespace Localization
|
||||||
{
|
{
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
// When adding a new locale, then make sure to also update ThemeData::sSupportedLanguages.
|
||||||
const std::vector<std::pair<std::string, std::string>> sSupportedLocales {{{"en"}, {"US"}},
|
const std::vector<std::pair<std::string, std::string>> sSupportedLocales {{{"en"}, {"US"}},
|
||||||
{{"en"}, {"GB"}},
|
{{"en"}, {"GB"}},
|
||||||
{{"ar"}, {"EG"}},
|
|
||||||
{{"de"}, {"DE"}},
|
|
||||||
{{"el"}, {"GR"}},
|
{{"el"}, {"GR"}},
|
||||||
|
{{"de"}, {"DE"}},
|
||||||
{{"es"}, {"ES"}},
|
{{"es"}, {"ES"}},
|
||||||
{{"fr"}, {"FR"}},
|
{{"fr"}, {"FR"}},
|
||||||
{{"it"}, {"IT"}},
|
{{"it"}, {"IT"}},
|
||||||
{{"ja"}, {"JP"}},
|
|
||||||
{{"nl"}, {"NL"}},
|
{{"nl"}, {"NL"}},
|
||||||
{{"pl"}, {"PL"}},
|
{{"pl"}, {"PL"}},
|
||||||
{{"pt"}, {"BR"}},
|
{{"pt"}, {"BR"}},
|
||||||
{{"ro"}, {"RO"}},
|
{{"ro"}, {"RO"}},
|
||||||
{{"ru"}, {"RU"}},
|
{{"ru"}, {"RU"}},
|
||||||
{{"sv"}, {"SE"}},
|
{{"sv"}, {"SE"}},
|
||||||
{{"zh"}, {"CN"}}};
|
{{"ja"}, {"JP"}},
|
||||||
|
{{"zh"}, {"CN"}},
|
||||||
|
{{"ar"}, {"EG"}}};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
std::string sCurrentLocale {"en_US"};
|
||||||
float sMenuTitleScaleFactor {1.0f};
|
float sMenuTitleScaleFactor {1.0f};
|
||||||
|
|
||||||
const char* pgettextBuiltin(const char* msgctxt, const char* msgid)
|
const char* pgettextBuiltin(const char* msgctxt, const char* msgid)
|
||||||
|
@ -136,6 +139,7 @@ namespace Utils
|
||||||
}
|
}
|
||||||
|
|
||||||
sMenuTitleScaleFactor = 1.0f;
|
sMenuTitleScaleFactor = 1.0f;
|
||||||
|
sCurrentLocale = "en_US";
|
||||||
std::string languageSetting {Settings::getInstance()->getString("ApplicationLanguage")};
|
std::string languageSetting {Settings::getInstance()->getString("ApplicationLanguage")};
|
||||||
std::vector<std::string> localeVector;
|
std::vector<std::string> localeVector;
|
||||||
std::pair<std::string, std::string> localePair;
|
std::pair<std::string, std::string> localePair;
|
||||||
|
@ -163,12 +167,12 @@ namespace Utils
|
||||||
if (std::find(sSupportedLocales.cbegin(), sSupportedLocales.cend(), localePair) !=
|
if (std::find(sSupportedLocales.cbegin(), sSupportedLocales.cend(), localePair) !=
|
||||||
sSupportedLocales.cend()) {
|
sSupportedLocales.cend()) {
|
||||||
locale = localePairCombined;
|
locale = localePairCombined;
|
||||||
LOG(LogInfo) << "Setting application locale to \"" << locale << "\"";
|
LOG(LogInfo) << "Application language set to \"" << locale << "\"";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (auto& localeEntry : sSupportedLocales) {
|
for (auto& localeEntry : sSupportedLocales) {
|
||||||
if (localeEntry.first == localePair.first) {
|
if (localeEntry.first == localePair.first) {
|
||||||
LOG(LogInfo) << "No support for locale \"" << localePairCombined
|
LOG(LogInfo) << "No support for language \"" << localePairCombined
|
||||||
<< "\", falling back to closest match \""
|
<< "\", falling back to closest match \""
|
||||||
<< localeEntry.first + "_" + localeEntry.second << "\"";
|
<< localeEntry.first + "_" + localeEntry.second << "\"";
|
||||||
locale = localeEntry.first + "_" + localeEntry.second;
|
locale = localeEntry.first + "_" + localeEntry.second;
|
||||||
|
@ -178,16 +182,16 @@ namespace Utils
|
||||||
}
|
}
|
||||||
|
|
||||||
if (locale == "") {
|
if (locale == "") {
|
||||||
LOG(LogInfo) << "No support for locale \"" << localePairCombined
|
LOG(LogInfo) << "No support for language \"" << localePairCombined
|
||||||
<< "\", falling back to default \"en_US\"";
|
<< "\", falling back to default \"en_US\"";
|
||||||
locale = "en_US";
|
locale = "en_US";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Language-specific menu title scale factor.
|
// Language-specific menu title scale factor.
|
||||||
if (localePair.first == "de")
|
if (localePair.first == "el")
|
||||||
sMenuTitleScaleFactor = 0.92f;
|
|
||||||
else if (localePair.first == "el")
|
|
||||||
sMenuTitleScaleFactor = 0.94f;
|
sMenuTitleScaleFactor = 0.94f;
|
||||||
|
else if (localePair.first == "de")
|
||||||
|
sMenuTitleScaleFactor = 0.92f;
|
||||||
else if (localePair.first == "es")
|
else if (localePair.first == "es")
|
||||||
sMenuTitleScaleFactor = 0.90f;
|
sMenuTitleScaleFactor = 0.90f;
|
||||||
else if (localePair.first == "fr")
|
else if (localePair.first == "fr")
|
||||||
|
@ -243,6 +247,7 @@ namespace Utils
|
||||||
textdomain(locale.c_str());
|
textdomain(locale.c_str());
|
||||||
bindtextdomain(locale.c_str(), objectPath.c_str());
|
bindtextdomain(locale.c_str(), objectPath.c_str());
|
||||||
bind_textdomain_codeset(locale.c_str(), "UTF-8");
|
bind_textdomain_codeset(locale.c_str(), "UTF-8");
|
||||||
|
sCurrentLocale = locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Localization
|
} // namespace Localization
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace Utils
|
||||||
namespace Localization
|
namespace Localization
|
||||||
{
|
{
|
||||||
extern const std::vector<std::pair<std::string, std::string>> sSupportedLocales;
|
extern const std::vector<std::pair<std::string, std::string>> sSupportedLocales;
|
||||||
|
extern std::string sCurrentLocale;
|
||||||
extern float sMenuTitleScaleFactor;
|
extern float sMenuTitleScaleFactor;
|
||||||
|
|
||||||
const char* pgettextBuiltin(const char* msgctxt, const char* msgid);
|
const char* pgettextBuiltin(const char* msgctxt, const char* msgid);
|
||||||
|
|
Loading…
Reference in a new issue