cool
This commit is contained in:
@@ -1,78 +1,207 @@
|
||||
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
|
||||
public class UXLocalization:IDisposable
|
||||
{
|
||||
public string USS { get; set; } = "localized";
|
||||
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)
|
||||
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;
|
||||
if (_uxService.Root is not VisualElement visualElement) return;
|
||||
|
||||
foreach (var x in visualElement.Query<Label>(className:USS).ToList())
|
||||
{
|
||||
if (string.IsNullOrEmpty(x.viewDataKey))continue;
|
||||
x.text = _localizationService.GetLocalizedString('#'+x.viewDataKey);
|
||||
}
|
||||
Localize(visualElement);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
ContinueWithBaseType(x.GetType());
|
||||
continue;
|
||||
|
||||
void ContinueWithBaseType(Type type)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (type == null || type == typeof(object)) return;
|
||||
if (type.GetProperty("label", ReflectionHelper.Flags) is { } propertyInfo)
|
||||
{
|
||||
//Debug.Log($"{x.name}:#{x.viewDataKey}");
|
||||
propertyInfo.SetValue(x, _localizationService.GetLocalizedString('#' + x.viewDataKey));
|
||||
}
|
||||
else
|
||||
{
|
||||
type = type.BaseType;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
_ticker.Remove(OnTick);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user