209 lines
7.3 KiB
C#
209 lines
7.3 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using BITKit;
|
|
using BITKit.UX;
|
|
using Cysharp.Threading.Tasks;
|
|
using Net.BITKit.Localization;
|
|
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
using UnityEngine.UIElements;
|
|
|
|
namespace Net.BITKit.UX
|
|
{
|
|
public class UXLocalization:IDisposable
|
|
{
|
|
public string[] Lang { get; set; } =
|
|
{
|
|
"zh-CN",
|
|
"en-US",
|
|
"ja-JP",
|
|
};
|
|
public static string USS { get; set; } = "localized";
|
|
private readonly IUXService _uxService;
|
|
private readonly ILocalizationService _localizationService;
|
|
private readonly IMainTicker _ticker;
|
|
|
|
public UXLocalization(IUXService uxService, ILocalizationService localizationService, IMainTicker ticker)
|
|
{
|
|
_uxService = uxService;
|
|
_localizationService = localizationService;
|
|
_ticker = ticker;
|
|
|
|
_localizationService.OnLanguageChanged += OnLanguageChanged;
|
|
_localizationService.OnLocalizeAsync += OnLocalizeAsync;
|
|
|
|
_ticker.Add(OnTick);
|
|
}
|
|
|
|
private void OnTick(float obj)
|
|
{
|
|
if (Mouse.current.rightButton.wasPressedThisFrame is false) return;
|
|
if (_uxService.TryPick(Mouse.current.position.ReadValue(), out var o) is false) return;
|
|
if (o is not VisualElement visualElement) return;
|
|
if (visualElement.ClassListContains(USS) is false) return;
|
|
var builder =
|
|
ContextMenuBuilder
|
|
.Create()
|
|
.BuildText(_localizationService.GetLocalizedString("Translate"));
|
|
|
|
foreach (var lang in Lang)
|
|
{
|
|
builder.BuildAction(lang, () => Localize(visualElement, lang));
|
|
}
|
|
/*
|
|
foreach (var lang in Enum.GetValues(typeof(Lang)))
|
|
{
|
|
var code = lang.GetType().GetMember(lang.ToString())[0].GetCustomAttribute<DescriptionAttribute>()
|
|
.Description;
|
|
builder.BuildAction(code, () => Localize(visualElement, code));
|
|
}
|
|
*/
|
|
|
|
builder.BuildAction("Default", () => Localize(visualElement, _localizationService.CurrentLanguage));
|
|
builder.Build();
|
|
}
|
|
|
|
private UniTask<bool> OnLocalizeAsync(string arg1, object arg2)
|
|
{
|
|
if (arg2 is not VisualElement visualElement) return UniTask.FromResult(false);
|
|
|
|
Localize((object)visualElement);
|
|
return UniTask.FromResult(true);
|
|
}
|
|
|
|
private void Localize(VisualElement visualElement, string lang = null)
|
|
{
|
|
if (string.IsNullOrEmpty(lang))
|
|
{
|
|
lang = _localizationService.CurrentLanguage;
|
|
}
|
|
|
|
var currentLang = _localizationService.GetLocalizedString('#' + visualElement.viewDataKey,
|
|
_localizationService.CurrentLanguage);
|
|
|
|
var translate = _localizationService.GetLocalizedString('#' + visualElement.viewDataKey, lang);
|
|
|
|
if (string.Equals(visualElement.tooltip, currentLang))
|
|
{
|
|
visualElement.tooltip = translate;
|
|
foreach (var child in visualElement.Children())
|
|
{
|
|
if (child.pickingMode is PickingMode.Position)
|
|
{
|
|
child.tooltip = translate;
|
|
}
|
|
}
|
|
}
|
|
|
|
switch (visualElement)
|
|
{
|
|
case Label label:
|
|
{
|
|
label.text = translate;
|
|
}
|
|
break;
|
|
case Button button:
|
|
{
|
|
button.text = translate;
|
|
}
|
|
break;
|
|
case ProgressBar progressBar:
|
|
{
|
|
progressBar.title = translate;
|
|
}
|
|
break;
|
|
case Foldout foldout:
|
|
{
|
|
foldout.text = translate;
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
ContinueWithBaseType(visualElement.GetType());
|
|
void ContinueWithBaseType(Type type)
|
|
{
|
|
while (true)
|
|
{
|
|
if (type is not null)
|
|
{
|
|
if (type.GetProperty("label", ReflectionHelper.Flags) is { } propertyInfo)
|
|
{
|
|
//Debug.Log($"{x.name}:#{x.viewDataKey}");
|
|
propertyInfo.SetValue(visualElement,translate);
|
|
}
|
|
else
|
|
{
|
|
type = type.BaseType;
|
|
continue;
|
|
}
|
|
}
|
|
if (type == null || type == typeof(object))
|
|
{
|
|
break;
|
|
//throw new NotImplementedException($"{visualElement.GetType().Name} is not translatable");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
private void Localize(object obj)
|
|
{
|
|
switch (obj)
|
|
{
|
|
case VisualElement visualElement:
|
|
{
|
|
foreach (var x in visualElement.Query(className:USS).Build())
|
|
{
|
|
Localize(x);
|
|
}
|
|
/*
|
|
foreach (var x in visualElement.Query<Label>(className:USS).ToList())
|
|
{
|
|
if (string.IsNullOrEmpty(x.viewDataKey))continue;
|
|
x.text = _localizationService.GetLocalizedString('#'+x.viewDataKey);
|
|
}
|
|
|
|
foreach (var x in visualElement.Query<Button>(className:USS).ToList())
|
|
{
|
|
if(string.IsNullOrEmpty(x.viewDataKey))continue;
|
|
x.text = _localizationService.GetLocalizedString('#'+x.viewDataKey);
|
|
}
|
|
|
|
foreach (var x in visualElement.Query<ProgressBar>(className:USS).ToList())
|
|
{
|
|
if(string.IsNullOrEmpty(x.viewDataKey))continue;
|
|
x.title = _localizationService.GetLocalizedString('#'+x.viewDataKey);
|
|
}
|
|
|
|
foreach (var x in visualElement.Query(className:USS).ToList())
|
|
{
|
|
if(string.IsNullOrEmpty(x.viewDataKey))continue;
|
|
continue;
|
|
}
|
|
*/
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void OnLanguageChanged(string arg1, string arg2)
|
|
{
|
|
if (_uxService.Root is not VisualElement visualElement) return;
|
|
|
|
Localize(visualElement);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_ticker.Remove(OnTick);
|
|
}
|
|
}
|
|
|
|
}
|