using System;
using System.Collections.Generic;
using AppUI.Localization;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
///
/// AppUI Prefab 用多语言组件。行为对齐 ,但查词走 (新表优先 + 旧表回退)。
///
[ExecuteAlways]
public class AppUITextAutoLanguage : MonoBehaviour
{
internal static readonly HashSet RegisteredComponents = new HashSet();
[SerializeField] string textKey;
[Tooltip("textKey 为空时使用的明文;有 key 时仅作 Editor 预览 fallback")]
[SerializeField]
string fallbackText;
[SerializeField] RectTransform layoutRebuildObject;
public object[] textFormatArgs = { };
[SerializeField] LanguageFontSize[] languageFontSizes = {};
int defaultFontSize = -1;
void Awake()
{
AppUILocalization.Init();
}
void OnEnable()
{
AppUILocalization.OnLanguageChanged += HandleLanguageChanged;
if (!string.IsNullOrEmpty(textKey) || !string.IsNullOrEmpty(fallbackText))
ApplyToText();
}
void Start()
{
RegisteredComponents.Add(this);
ApplyToText();
}
void OnDisable()
{
AppUILocalization.OnLanguageChanged -= HandleLanguageChanged;
}
void OnDestroy()
{
RegisteredComponents.Remove(this);
}
#if UNITY_EDITOR
void OnValidate()
{
if (string.IsNullOrEmpty(textKey) && string.IsNullOrEmpty(fallbackText))
return;
ApplyToText();
}
#endif
void HandleLanguageChanged(LanguageEnum _) => ApplyToText();
public void SetTextKey(string key)
{
textKey = key;
ApplyResolvedText();
}
void ApplyResolvedText()
{
string text = ResolveDisplayText();
if (textFormatArgs != null && textFormatArgs.Length > 0)
text = string.Format(text, textFormatArgs);
else if (text != null && text.IndexOf("{0}", StringComparison.Ordinal) >= 0)
return;
Text textComp = GetComponent();
if (textComp != null)
{
textComp.text = text;
ApplyFontSize(textComp, value => textComp.fontSize = value, value => textComp.lineSpacing = value);
if (layoutRebuildObject)
LayoutRebuilder.ForceRebuildLayoutImmediate(layoutRebuildObject);
return;
}
ApplyLocalizationToTmpText(text);
}
string ResolveDisplayText()
{
if (!string.IsNullOrEmpty(textKey))
{
#if UNITY_EDITOR
if (!Application.isPlaying)
AppUILocalization.Reload();
#endif
AppUILocalization.Init();
return AppUILocalization.ResolveText(textKey);
}
return fallbackText ?? string.Empty;
}
static TMP_Text ResolveTmpTextTarget(TMP_InputField inputField, TextMeshProUGUI tmpOnSameObject)
{
if (inputField != null)
{
if (inputField.placeholder != null && inputField.placeholder is TMP_Text placeholderTmp)
return placeholderTmp;
if (inputField.textComponent != null)
return inputField.textComponent;
return tmpOnSameObject;
}
return tmpOnSameObject;
}
void ApplyLocalizationToTmpText(string text)
{
TMP_InputField tmpInput = GetComponent();
TextMeshProUGUI tmpUgUi = GetComponent();
TMP_Text tmpTarget = ResolveTmpTextTarget(tmpInput, tmpUgUi);
if (tmpTarget == null)
return;
tmpTarget.text = text;
ApplyFontSize(tmpTarget, value => tmpTarget.fontSize = value, value => tmpTarget.lineSpacing = value);
}
void ApplyFontSize(TMP_Text tmpTarget, Action setFontSize, Action setLineSpacing)
{
if (defaultFontSize == -1)
defaultFontSize = (int)tmpTarget.fontSize;
else
tmpTarget.fontSize = defaultFontSize;
if (languageFontSizes == null || languageFontSizes.Length == 0)
return;
LanguageEnum language = AppUILocalization.GetLanguage();
foreach (var languageFontSize in languageFontSizes)
{
if (languageFontSize.language != language)
continue;
if (languageFontSize.fontSize > 0)
setFontSize(languageFontSize.fontSize);
if (languageFontSize.lineSpacing > 0)
setLineSpacing(languageFontSize.lineSpacing);
break;
}
}
void ApplyFontSize(Text textComp, Action setFontSize, Action setLineSpacing)
{
if (defaultFontSize == -1)
defaultFontSize = textComp.fontSize;
else
textComp.fontSize = defaultFontSize;
if (languageFontSizes == null || languageFontSizes.Length == 0)
return;
LanguageEnum language = AppUILocalization.GetLanguage();
foreach (var languageFontSize in languageFontSizes)
{
if (languageFontSize.language != language)
continue;
if (languageFontSize.fontSize > 0)
setFontSize(languageFontSize.fontSize);
if (languageFontSize.lineSpacing > 0)
setLineSpacing(languageFontSize.lineSpacing);
break;
}
}
public string GetTextKey()
{
return textKey;
}
public void ApplyToText()
{
ApplyResolvedText();
Text text = GetComponent();
if (text)
onApplyToNext?.Invoke(text);
}
/// Editor 刷新按钮 / 改 json 后手动调用。
public void RefreshLocalizedPreview()
{
#if UNITY_EDITOR
if (!Application.isPlaying)
AppUILocalization.Reload();
#endif
ApplyToText();
}
public Action onApplyToNext;
}