using UnityEngine;
|
using UnityEditor;
|
using System.Collections.Generic;
|
|
/// <summary>
|
/// TextLanguageAdapter 自定义编辑器
|
/// 提供可视化的多语言排版配置界面
|
/// </summary>
|
[CustomEditor(typeof(TextLanguageAdapter), true)]
|
[CanEditMultipleObjects]
|
public class TextLanguageAdapterEditor : Editor
|
{
|
private Dictionary<string, bool> m_FoldoutStates = new Dictionary<string, bool>();
|
private Dictionary<string, string> m_LanguageShowDict;
|
private static readonly string[] m_PresetLanguageIds = { TextLanguageAdapter.DefaultLangId, "zh", "ft", "en"};
|
private static readonly string[] m_PresetLanguageNames = { "默认", "简体", "繁体", "English" };
|
private string m_CopySourceLanguageId = "";
|
|
protected virtual void OnEnable()
|
{
|
InitLanguageShowDict();
|
if (target is TextLanguageAdapter adapter)
|
{
|
// 确保 default 配置存在
|
if (!adapter.HasConfig(TextLanguageAdapter.DefaultLangId))
|
{
|
adapter.ReadCurrentToConfig(TextLanguageAdapter.DefaultLangId);
|
EditorUtility.SetDirty(adapter);
|
}
|
|
foreach (var langId in adapter.GetConfiguredLanguages())
|
{
|
m_FoldoutStates.TryAdd(langId, false);
|
}
|
}
|
}
|
|
public override void OnInspectorGUI()
|
{
|
TextLanguageAdapter adapter = target as TextLanguageAdapter;
|
|
DrawBasicInfo(adapter);
|
EditorGUILayout.Space();
|
DrawLanguageConfigs(adapter);
|
|
if (GUI.changed)
|
{
|
EditorUtility.SetDirty(target);
|
}
|
}
|
|
private void InitLanguageShowDict()
|
{
|
if (m_LanguageShowDict != null) return;
|
|
m_LanguageShowDict = new Dictionary<string, string>();
|
for (int i = 0; i < m_PresetLanguageIds.Length; i++)
|
{
|
m_LanguageShowDict[m_PresetLanguageIds[i]] = m_PresetLanguageNames[i];
|
}
|
}
|
|
private string GetLanguageDisplayName(string languageId)
|
{
|
if (m_LanguageShowDict != null && m_LanguageShowDict.TryGetValue(languageId, out string name))
|
{
|
return name;
|
}
|
return TextLanguageAdapter.GetLanguageShowName(languageId);
|
}
|
|
private void DrawBasicInfo(TextLanguageAdapter adapter)
|
{
|
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
|
EditorGUILayout.LabelField("基本信息", EditorStyles.boldLabel);
|
|
EditorGUI.BeginDisabledGroup(true);
|
// 使用新开放的 TargetTextComponent 属性,彻底消除反射
|
EditorGUILayout.ObjectField("目标组件", adapter.LanguageConfigs.keys.Count > 0 ? adapter.TargetTextComponent : null, typeof(Component), true);
|
EditorGUILayout.EnumPopup("组件类型", adapter.TargetTextType);
|
EditorGUI.EndDisabledGroup();
|
|
if (GUILayout.Button("刷新组件检测", GUILayout.Width(120)))
|
{
|
adapter.Editor_ForceRefreshDetection();
|
}
|
|
EditorGUILayout.EndVertical();
|
}
|
|
private void DrawLanguageConfigs(TextLanguageAdapter adapter)
|
{
|
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
|
EditorGUILayout.LabelField($"语言排版配置 (必须包含 {TextLanguageAdapter.DefaultLangId} 默认配置)", EditorStyles.boldLabel);
|
|
List<string> configuredLanguages = adapter.GetConfiguredLanguages();
|
foreach (var langId in configuredLanguages)
|
{
|
DrawLanguageConfigItem(adapter, langId);
|
}
|
|
EditorGUILayout.Space();
|
DrawAddLanguageConfig(adapter);
|
EditorGUILayout.EndVertical();
|
}
|
|
private void DrawLanguageConfigItem(TextLanguageAdapter adapter, string languageId)
|
{
|
m_FoldoutStates.TryAdd(languageId, false);
|
|
string displayName = GetLanguageDisplayName(languageId);
|
string foldoutLabel = string.IsNullOrEmpty(displayName) ? languageId : $"{languageId} ({displayName})";
|
|
EditorGUI.indentLevel++;
|
|
// 高亮默认配置
|
if (languageId == TextLanguageAdapter.DefaultLangId)
|
{
|
GUI.backgroundColor = new Color(1f, 0.9f, 0.7f);
|
}
|
|
m_FoldoutStates[languageId] = EditorGUILayout.Foldout(m_FoldoutStates[languageId], foldoutLabel, true);
|
GUI.backgroundColor = Color.white;
|
|
if (m_FoldoutStates[languageId])
|
{
|
EditorGUI.indentLevel++;
|
LanguageConfigItem config = adapter.LanguageConfigs.Get(languageId);
|
if (config != null)
|
{
|
DrawConfigItem(config);
|
EditorGUILayout.Space();
|
DrawConfigItemActions(adapter, languageId);
|
}
|
EditorGUI.indentLevel--;
|
}
|
|
EditorGUI.indentLevel--;
|
}
|
|
/// <summary>
|
/// 绘制 RectTransform 和指定的文本适配属性
|
/// </summary>
|
private void DrawConfigItem(LanguageConfigItem config)
|
{
|
// 1. RectTransform 配置
|
EditorGUILayout.LabelField("RectTransform 配置", EditorStyles.miniBoldLabel);
|
EditorGUI.BeginChangeCheck();
|
|
config.anchoredPosition = EditorGUILayout.Vector2Field("Anchored Position", config.anchoredPosition);
|
config.sizeDelta = EditorGUILayout.Vector2Field("Size Delta", config.sizeDelta);
|
config.anchorMin = EditorGUILayout.Vector2Field("Anchor Min", config.anchorMin);
|
config.anchorMax = EditorGUILayout.Vector2Field("Anchor Max", config.anchorMax);
|
config.pivot = EditorGUILayout.Vector2Field("Pivot", config.pivot);
|
config.localScale = EditorGUILayout.Vector3Field("Local Scale", config.localScale);
|
config.localRotation = EditorGUILayout.Vector3Field("Local Rotation", config.localRotation);
|
EditorGUILayout.Space();
|
|
// 2. 文本排版与适配配置
|
EditorGUILayout.LabelField("文本排版与适配配置", EditorStyles.miniBoldLabel);
|
config.font = (Font)EditorGUILayout.ObjectField("Font", config.font, typeof(Font), false);
|
config.fontStyle = (FontStyle)EditorGUILayout.EnumPopup("Font Style", config.fontStyle);
|
config.fontSize = EditorGUILayout.IntField("Font Size", config.fontSize);
|
config.lineSpacing = EditorGUILayout.FloatField("Line Spacing", config.lineSpacing);
|
config.alignment = (TextAnchor)EditorGUILayout.EnumPopup("Alignment", config.alignment);
|
config.alignByGeometry = EditorGUILayout.Toggle("Align By Geometry", config.alignByGeometry);
|
config.horizontalOverflow = (HorizontalWrapMode)EditorGUILayout.EnumPopup("Horizontal Overflow", config.horizontalOverflow);
|
config.verticalOverflow = (VerticalWrapMode)EditorGUILayout.EnumPopup("Vertical Overflow", config.verticalOverflow);
|
config.resizeTextForBestFit = EditorGUILayout.Toggle("Best Fit", config.resizeTextForBestFit);
|
|
if (config.resizeTextForBestFit)
|
{
|
EditorGUI.indentLevel++;
|
config.resizeTextMinSize = EditorGUILayout.IntField("Min Size", config.resizeTextMinSize);
|
config.resizeTextMaxSize = EditorGUILayout.IntField("Max Size", config.resizeTextMaxSize);
|
EditorGUI.indentLevel--;
|
}
|
|
if (EditorGUI.EndChangeCheck())
|
{
|
EditorUtility.SetDirty(target);
|
}
|
}
|
|
private void DrawConfigItemActions(TextLanguageAdapter adapter, string languageId)
|
{
|
EditorGUILayout.BeginHorizontal();
|
GUILayout.Space(EditorGUI.indentLevel * 15f); // 补偿 GUILayout 忽略 indentLevel 的问题
|
|
if (GUILayout.Button("从当前读取", GUILayout.Width(80)))
|
{
|
Undo.RecordObject(adapter, "Read Current Config");
|
adapter.ReadCurrentToConfig(languageId);
|
}
|
|
if (GUILayout.Button("应用", GUILayout.Width(60)))
|
{
|
Undo.RecordObject(adapter, "Apply Config");
|
adapter.ApplyConfig(languageId);
|
}
|
|
bool isDefault = languageId == TextLanguageAdapter.DefaultLangId;
|
|
if (!isDefault)
|
{
|
if (GUILayout.Button("复制到默认", GUILayout.Width(80)))
|
{
|
Undo.RecordObject(adapter, "Copy to Default");
|
adapter.SetConfig(TextLanguageAdapter.DefaultLangId, adapter.LanguageConfigs.Get(languageId)?.Clone());
|
}
|
}
|
|
// Default 不可删除
|
GUI.enabled = !isDefault;
|
if (GUILayout.Button("删除", GUILayout.Width(50)))
|
{
|
Undo.RecordObject(adapter, "Remove Config");
|
adapter.RemoveConfig(languageId);
|
m_FoldoutStates.Remove(languageId);
|
}
|
GUI.enabled = true;
|
|
EditorGUILayout.EndHorizontal();
|
}
|
|
private void DrawAddLanguageConfig(TextLanguageAdapter adapter)
|
{
|
// === 添加预设语言 ===
|
EditorGUILayout.BeginHorizontal();
|
GUILayout.Space(15f);
|
EditorGUILayout.LabelField("添加预设语言:", GUILayout.Width(100));
|
|
// Inspector 面板的可用总宽度 (减去右侧滚动条的大致宽度)
|
float viewWidth = EditorGUIUtility.currentViewWidth - 30f;
|
float currentWidth = 115f; // 起始宽度:15(Space) + 100(LabelWidth)
|
float buttonWidth = 64f; // 按钮宽度 60 + 默认边距大约 4
|
|
for (int i = 0; i < m_PresetLanguageIds.Length; i++)
|
{
|
string langId = m_PresetLanguageIds[i];
|
if (!adapter.HasConfig(langId))
|
{
|
// 检测当前行是否放得下下一个按钮
|
if (currentWidth + buttonWidth > viewWidth)
|
{
|
// 放不下,结束当前行,开启新的一行
|
EditorGUILayout.EndHorizontal();
|
EditorGUILayout.BeginHorizontal();
|
|
// 新行为了美观,缩进对齐上面的按钮
|
GUILayout.Space(115f);
|
currentWidth = 115f;
|
}
|
|
if (GUILayout.Button(m_PresetLanguageNames[i], GUILayout.Width(60)))
|
{
|
CreateNewLanguageConfig(adapter, langId);
|
}
|
|
// 累加当前行的宽度
|
currentWidth += buttonWidth;
|
}
|
}
|
EditorGUILayout.EndHorizontal();
|
|
EditorGUILayout.Space(2f);
|
|
// === 添加自定义语言 ===
|
EditorGUILayout.BeginHorizontal();
|
GUILayout.Space(15f);
|
EditorGUILayout.LabelField("自定义语言ID:", GUILayout.Width(100));
|
m_CopySourceLanguageId = EditorGUILayout.TextField(m_CopySourceLanguageId, GUILayout.Width(80));
|
|
if (GUILayout.Button("添加", GUILayout.Width(50)))
|
{
|
string newLangId = m_CopySourceLanguageId.Trim();
|
if (!string.IsNullOrEmpty(newLangId) && !adapter.HasConfig(newLangId))
|
{
|
CreateNewLanguageConfig(adapter, newLangId);
|
m_CopySourceLanguageId = "";
|
GUI.FocusControl(null);
|
}
|
}
|
EditorGUILayout.EndHorizontal();
|
}
|
|
/// <summary> 辅助方法:封装新建语言配置的复用逻辑 </summary>
|
private void CreateNewLanguageConfig(TextLanguageAdapter adapter, string langId)
|
{
|
Undo.RecordObject(adapter, "Add Language Config");
|
LanguageConfigItem newConfig = adapter.HasConfig(TextLanguageAdapter.DefaultLangId)
|
? adapter.LanguageConfigs.Get(TextLanguageAdapter.DefaultLangId).Clone()
|
: new LanguageConfigItem();
|
|
adapter.SetConfig(langId, newConfig);
|
m_FoldoutStates[langId] = true; // 自动展开新添加的项
|
}
|
}
|