mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Select language on first start based on user locale
On first client start (when `cl_show_welcome` is `1`), determine the user locale with `os_locale_str` and initially select the most fitting language for this locale. For this the language index must also be loaded immediately on client launch, before the initial language is loaded.
This commit is contained in:
parent
cddbc78592
commit
a91b51c8a2
|
@ -2028,19 +2028,22 @@ void CMenus::RenderSettingsSound(CUIRect MainView)
|
|||
|
||||
bool CMenus::RenderLanguageSelection(CUIRect MainView)
|
||||
{
|
||||
static int s_SelectedLanguage = -1;
|
||||
static int s_SelectedLanguage = -2; // -2 = unloaded, -1 = unset
|
||||
static CListBox s_ListBox;
|
||||
|
||||
if(g_Localization.Languages().empty())
|
||||
if(s_SelectedLanguage == -2)
|
||||
{
|
||||
g_Localization.LoadIndexfile(Storage(), Console());
|
||||
s_SelectedLanguage = -1;
|
||||
for(size_t i = 0; i < g_Localization.Languages().size(); i++)
|
||||
{
|
||||
if(str_comp(g_Localization.Languages()[i].m_FileName.c_str(), g_Config.m_ClLanguagefile) == 0)
|
||||
{
|
||||
s_SelectedLanguage = i;
|
||||
s_ListBox.ScrollToSelected();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const int OldSelected = s_SelectedLanguage;
|
||||
|
||||
|
|
|
@ -243,6 +243,9 @@ void CGameClient::OnInit()
|
|||
}
|
||||
|
||||
// set the language
|
||||
g_Localization.LoadIndexfile(Storage(), Console());
|
||||
if(g_Config.m_ClShowWelcome)
|
||||
g_Localization.SelectDefaultLanguage(Console(), g_Config.m_ClLanguagefile, sizeof(g_Config.m_ClLanguagefile));
|
||||
g_Localization.Load(g_Config.m_ClLanguagefile, Storage(), Console());
|
||||
|
||||
// TODO: this should be different
|
||||
|
|
|
@ -146,6 +146,59 @@ void CLocalizationDatabase::LoadIndexfile(IStorage *pStorage, IConsole *pConsole
|
|||
std::sort(m_vLanguages.begin(), m_vLanguages.end());
|
||||
}
|
||||
|
||||
void CLocalizationDatabase::SelectDefaultLanguage(IConsole *pConsole, char *pFilename, size_t Length) const
|
||||
{
|
||||
char aLocaleStr[128];
|
||||
os_locale_str(aLocaleStr, sizeof(aLocaleStr));
|
||||
|
||||
char aBuf[256];
|
||||
str_format(aBuf, sizeof(aBuf), "Choosing default language based on user locale '%s'", aLocaleStr);
|
||||
pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "localization", aBuf);
|
||||
|
||||
while(true)
|
||||
{
|
||||
const CLanguage *pPrefixMatch = nullptr;
|
||||
for(const auto &Language : Languages())
|
||||
{
|
||||
for(const auto &LanguageCode : Language.m_vLanguageCodes)
|
||||
{
|
||||
if(LanguageCode == aLocaleStr)
|
||||
{
|
||||
// Exact match found, use it immediately
|
||||
str_copy(pFilename, Language.m_FileName.c_str(), Length);
|
||||
return;
|
||||
}
|
||||
else if(LanguageCode.rfind(aLocaleStr, 0) == 0)
|
||||
{
|
||||
// Locale is prefix of language code, e.g. locale is "en" and current language is "en-US"
|
||||
pPrefixMatch = &Language;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Use prefix match if no exact match was found
|
||||
if(pPrefixMatch)
|
||||
{
|
||||
str_copy(pFilename, pPrefixMatch->m_FileName.c_str(), Length);
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove last segment of locale string and try again with more generic locale, e.g. "en-US" -> "en"
|
||||
int i = str_length(aLocaleStr) - 1;
|
||||
for(; i >= 0; --i)
|
||||
{
|
||||
if(aLocaleStr[i] == '-')
|
||||
{
|
||||
aLocaleStr[i] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Stop if no more locale segments are left
|
||||
if(i == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool CLocalizationDatabase::Load(const char *pFilename, IStorage *pStorage, IConsole *pConsole)
|
||||
{
|
||||
// empty string means unload
|
||||
|
|
|
@ -56,6 +56,7 @@ public:
|
|||
|
||||
void LoadIndexfile(class IStorage *pStorage, class IConsole *pConsole);
|
||||
const std::vector<CLanguage> &Languages() const { return m_vLanguages; }
|
||||
void SelectDefaultLanguage(class IConsole *pConsole, char *pFilename, size_t Length) const;
|
||||
|
||||
bool Load(const char *pFilename, class IStorage *pStorage, class IConsole *pConsole);
|
||||
|
||||
|
|
Loading…
Reference in a new issue