2023-05-21 16:12:48 +08:00
|
|
|
using System;
|
2022-10-17 05:05:26 +08:00
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Collections.Immutable;
|
|
|
|
using System.IO;
|
|
|
|
using System.Linq;
|
2024-02-17 18:20:08 +08:00
|
|
|
using nadena.dev.modular_avatar.ui;
|
2023-12-21 16:38:46 +08:00
|
|
|
using nadena.dev.ndmf.localization;
|
|
|
|
using nadena.dev.ndmf.ui;
|
2022-10-17 05:05:26 +08:00
|
|
|
using Newtonsoft.Json;
|
|
|
|
using UnityEditor;
|
|
|
|
using UnityEngine;
|
|
|
|
|
2022-11-11 12:39:58 +08:00
|
|
|
namespace nadena.dev.modular_avatar.core.editor
|
2022-10-17 05:05:26 +08:00
|
|
|
{
|
2024-01-14 15:57:48 +08:00
|
|
|
[InitializeOnLoad] // ensure that we register languages with NDMF on domain load
|
2022-11-28 05:51:39 +08:00
|
|
|
internal static class Localization
|
2022-10-17 05:05:26 +08:00
|
|
|
{
|
2023-01-19 20:32:44 +08:00
|
|
|
public static event Action OnLangChange;
|
2023-01-17 19:06:50 +08:00
|
|
|
private const string FallbackLanguage = "en";
|
|
|
|
|
2022-10-17 05:05:26 +08:00
|
|
|
private const string localizationPathGuid = "488c994003974b3ab2796371cf627bca";
|
|
|
|
private static string localizationPathRoot = AssetDatabase.GUIDToAssetPath(localizationPathGuid);
|
|
|
|
|
|
|
|
private static ImmutableDictionary<string, string> SupportedLanguageDisplayNames
|
|
|
|
= ImmutableDictionary<string, string>.Empty
|
2024-03-09 17:57:38 +08:00
|
|
|
.Add("en-US", "English")
|
|
|
|
.Add("ja-JP", "日本語")
|
|
|
|
.Add("zh-Hans", "简体中文")
|
2024-03-09 17:58:52 +08:00
|
|
|
.Add("zh-Hant", "繁體中文")
|
2024-03-09 17:57:38 +08:00
|
|
|
.Add("ko-KR", "한국어");
|
2022-10-17 05:05:26 +08:00
|
|
|
|
2023-01-19 20:32:44 +08:00
|
|
|
private static ImmutableList<string>
|
2024-03-09 17:58:52 +08:00
|
|
|
SupportedLanguages = new string[] {"en-US", "ja-JP", "zh-Hans", "zh-Hant", "ko-KR"}.ToImmutableList();
|
2022-10-17 05:05:26 +08:00
|
|
|
|
|
|
|
private static string[] DisplayNames = SupportedLanguages.Select(l =>
|
|
|
|
{
|
|
|
|
return SupportedLanguageDisplayNames.TryGetValue(l, out var displayName) ? displayName : l;
|
|
|
|
}).ToArray();
|
|
|
|
|
|
|
|
private static Dictionary<string, ImmutableDictionary<string, string>> Cache
|
|
|
|
= new Dictionary<string, ImmutableDictionary<string, string>>();
|
|
|
|
|
2023-01-17 19:06:50 +08:00
|
|
|
internal static string OverrideLanguage { get; set; } = null;
|
|
|
|
|
2023-12-21 16:38:46 +08:00
|
|
|
public static Localizer L { get; private set; }
|
2024-01-27 19:06:22 +08:00
|
|
|
public static UIElementLocalizer UI;
|
2022-10-17 05:05:26 +08:00
|
|
|
|
2023-12-21 16:38:46 +08:00
|
|
|
static Localization()
|
2022-10-17 05:05:26 +08:00
|
|
|
{
|
2023-12-21 16:38:46 +08:00
|
|
|
Localizer localizer = new Localizer(SupportedLanguages[0], () =>
|
2022-10-17 05:05:26 +08:00
|
|
|
{
|
2023-12-21 16:38:46 +08:00
|
|
|
List<(string, Func<string, string>)> languages = new List<(string, Func<string, string>)>();
|
|
|
|
|
|
|
|
foreach (var lang in SupportedLanguages)
|
|
|
|
{
|
|
|
|
languages.Add((lang, LanguageLookup(lang)));
|
|
|
|
}
|
2022-10-17 05:05:26 +08:00
|
|
|
|
2023-12-21 16:38:46 +08:00
|
|
|
return languages;
|
|
|
|
});
|
|
|
|
|
|
|
|
L = localizer;
|
2024-01-27 19:06:22 +08:00
|
|
|
UI = new UIElementLocalizer(L);
|
2023-12-21 16:38:46 +08:00
|
|
|
|
|
|
|
LanguagePrefs.RegisterLanguageChangeCallback(typeof(Localization), _ => OnLangChange?.Invoke());
|
|
|
|
}
|
2023-01-17 19:06:50 +08:00
|
|
|
|
2023-12-21 16:38:46 +08:00
|
|
|
private static Func<string,string> LanguageLookup(string lang)
|
|
|
|
{
|
2022-10-17 05:05:26 +08:00
|
|
|
var filename = localizationPathRoot + "/" + lang + ".json";
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
var langData = File.ReadAllText(filename);
|
2023-12-21 16:38:46 +08:00
|
|
|
var langMap = JsonConvert.DeserializeObject<Dictionary<string, string>>(langData);
|
2023-01-17 19:06:50 +08:00
|
|
|
|
2023-12-21 16:38:46 +08:00
|
|
|
// return langMap.GetValueOrDefault; - Unity 2019 doesn't have this extension method
|
|
|
|
return key =>
|
2023-01-17 19:06:50 +08:00
|
|
|
{
|
2023-12-21 16:38:46 +08:00
|
|
|
if (langMap.TryGetValue(key, out var val)) return val;
|
|
|
|
else return null;
|
|
|
|
};
|
2022-10-17 05:05:26 +08:00
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
Debug.LogError("Failed to load language file " + filename);
|
|
|
|
Debug.LogException(e);
|
2023-12-21 16:38:46 +08:00
|
|
|
return (k) => null;
|
2022-10-17 05:05:26 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-17 18:20:08 +08:00
|
|
|
[MenuItem(UnityMenuItems.TopMenu_ReloadLocalizations, false, UnityMenuItems.TopMenu_ReloadLocalizationsOrder)]
|
2023-12-21 16:38:46 +08:00
|
|
|
public static void Reload()
|
|
|
|
{
|
|
|
|
Localizer.ReloadLocalizations();
|
|
|
|
Cache.Clear();
|
|
|
|
}
|
|
|
|
|
2022-10-17 05:05:26 +08:00
|
|
|
public static GUIContent G(string key)
|
|
|
|
{
|
|
|
|
var tooltip = S(key + ".tooltip", null);
|
|
|
|
return tooltip != null ? new GUIContent(S(key), tooltip) : new GUIContent(S(key));
|
|
|
|
}
|
|
|
|
|
|
|
|
public static string S(string key)
|
|
|
|
{
|
|
|
|
return S(key, key);
|
|
|
|
}
|
2023-09-08 18:42:16 +08:00
|
|
|
|
|
|
|
public static string S_f(string key, params string[] format)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
return string.Format(S(key, key), format);
|
|
|
|
}
|
2023-12-21 16:38:46 +08:00
|
|
|
catch (FormatException)
|
2023-09-08 18:42:16 +08:00
|
|
|
{
|
|
|
|
return S(key, key) + "(" + string.Join(", ", format) + ")";
|
|
|
|
}
|
|
|
|
}
|
2022-10-17 05:05:26 +08:00
|
|
|
|
|
|
|
public static string S(string key, string defValue)
|
|
|
|
{
|
2023-12-21 16:38:46 +08:00
|
|
|
if (L.TryGetLocalizedString(key, out var val))
|
2022-10-17 05:05:26 +08:00
|
|
|
{
|
2023-12-21 16:38:46 +08:00
|
|
|
return val;
|
2022-10-17 05:05:26 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return defValue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-24 11:20:31 +08:00
|
|
|
public static string GetSelectedLocalization()
|
2022-10-17 05:05:26 +08:00
|
|
|
{
|
2023-12-21 16:38:46 +08:00
|
|
|
return LanguagePrefs.Language;
|
2022-10-17 05:05:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public static void ShowLanguageUI()
|
|
|
|
{
|
|
|
|
EditorGUILayout.Separator();
|
2023-12-21 16:38:46 +08:00
|
|
|
|
|
|
|
LanguageSwitcher.DrawImmediate();
|
2022-10-17 05:05:26 +08:00
|
|
|
}
|
|
|
|
}
|
2023-05-21 16:12:48 +08:00
|
|
|
}
|