框架结构优化解耦

This commit is contained in:
陈思海 2025-09-25 11:11:19 +08:00
parent dd0cbf21aa
commit f42f4df718
9 changed files with 134 additions and 138 deletions

View File

@ -8,6 +8,8 @@ namespace AlicizaX.Localization.Editor
[AlicizaX.Editor.Setting.FilePath("ProjectSettings/LocalizationConfiguration.asset")]
public class LocalizationConfiguration : AlicizaX.Editor.Setting.ScriptableSingleton<LocalizationConfiguration>
{
[SerializeField] internal string generateScriptCodeFirstConfig;
[SerializeField] private List<string> LanguageTypes = new List<string>()
{
/// <summary>
@ -34,5 +36,6 @@ namespace AlicizaX.Localization.Editor
[SerializeField] private string _genLangaugeTypePath = "Assets/LanguageTypes.cs";
public IReadOnlyList<string> LanguageTypeNames => LanguageTypes;
public string GenerateScriptCodeFirstConfig => generateScriptCodeFirstConfig;
}
}

View File

@ -1,4 +1,6 @@
using System.Collections.Generic;
using System.Text;
using AlicizaX.Editor;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
@ -12,6 +14,8 @@ namespace AlicizaX.Localization.Editor
private SerializedProperty _languageTypes;
private ReorderableList _languageList;
private SerializedProperty _genLangaugeTypePath;
private SerializedProperty generateScriptCodeFirstConfig;
private List<string> popConfig = new List<string>();
public LocalizationSettingsProvider() : base("Project/Localization Settings", SettingsScope.Project)
{
@ -29,9 +33,10 @@ namespace AlicizaX.Localization.Editor
_serializedObject = new SerializedObject(setting);
_languageTypes = _serializedObject.FindProperty("LanguageTypes");
_genLangaugeTypePath = _serializedObject.FindProperty("_genLangaugeTypePath");
generateScriptCodeFirstConfig = _serializedObject.FindProperty("generateScriptCodeFirstConfig");
// 自定义 ReorderableList
_languageList = new ReorderableList(_serializedObject, _languageTypes,
draggable: false, // 禁止拖拽
draggable: false,
displayHeader: true,
displayAddButton: true,
displayRemoveButton: true);
@ -43,11 +48,36 @@ namespace AlicizaX.Localization.Editor
var element = _languageTypes.GetArrayElementAtIndex(index);
rect.y += 2;
// 只显示可编辑的 string 字段
if (index < 2) // 前两个(中文、英文)禁止修改
{
EditorGUI.BeginDisabledGroup(true);
EditorGUI.TextField(
new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight),
element.stringValue);
EditorGUI.EndDisabledGroup();
}
else
{
element.stringValue = EditorGUI.TextField(
new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight),
element.stringValue);
}
};
// 禁止删除前两个
_languageList.onCanRemoveCallback = list =>
{
return list.index >= 2; // 只有索引 >=2 的项才能删除
};
popConfig.Clear();
if (setting.LanguageTypeNames.Count > 0)
{
foreach (var lang in setting.LanguageTypeNames)
{
string name = lang.Or("Unknown");
popConfig.Add(name);
}
}
}
public override void OnGUI(string searchContext)
@ -59,7 +89,15 @@ namespace AlicizaX.Localization.Editor
_serializedObject.Update();
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(_genLangaugeTypePath);
EditorDrawing.DrawStringSelectPopup(new GUIContent("Gen Lang"), new GUIContent("None"), popConfig.ToArray(), generateScriptCodeFirstConfig.stringValue,
(e) =>
{
generateScriptCodeFirstConfig.stringValue = e;
_serializedObject.ApplyModifiedProperties();
LocalizationConfiguration.Save();
});
if (GUILayout.Button("Generate Language Types"))
{
RegenerateLanguageTypes();
@ -95,15 +133,12 @@ namespace AlicizaX.Localization.Editor
sb.AppendLine("\t};");
sb.AppendLine("");
sb.AppendLine("\tpublic static string IndexToString(int index)");
sb.AppendLine("\t{");
sb.AppendLine("\t\tif (index < 0 || index >= Types.Count) return \"Unknown\";");
sb.AppendLine("\t\treturn Types[index];");
sb.AppendLine("\t}");
sb.AppendLine("");
sb.AppendLine("\tpublic static int StringToIndex(string s)");
sb.AppendLine("\t{");
sb.AppendLine("\t\tint index = -1;");
@ -114,15 +149,13 @@ namespace AlicizaX.Localization.Editor
sb.AppendLine("\t\t\t\tindex = i;");
sb.AppendLine("\t\t\t\tbreak;");
sb.AppendLine("\t\t\t}");
sb.AppendLine("\t\t}");
sb.AppendLine("");
sb.AppendLine("\t\treturn index;");
sb.AppendLine("\t}");
sb.AppendLine("");
sb.AppendLine("}");
System.IO.File.WriteAllText(_genLangaugeTypePath.stringValue, sb.ToString());
AssetDatabase.Refresh();
}

View File

@ -20,6 +20,15 @@ namespace AlicizaX.Localization.Editor
private const float k_LanguagesWidth = 200f;
private const float k_TableSheetWidth = 200f;
// 原本是 const现在改成可调的字段
[SerializeField] private float languagesWidth = 200f;
[SerializeField] private float tableSheetWidth = 200f;
private const float SplitterWidth = 3f; // 拖拽条的宽度
private bool isResizingLeft, isResizingMiddle;
private float Spacing => EditorGUIUtility.standardVerticalSpacing * 2;
private GUIStyle miniLabelButton => new GUIStyle(EditorStyles.miniButton)
@ -185,14 +194,13 @@ namespace AlicizaX.Localization.Editor
private void OnGUI()
{
// 顶部工具栏
Rect toolbarRect = new(0, 0, position.width, 20f);
GUI.Box(toolbarRect, GUIContent.none, EditorStyles.toolbar);
float buttonWidth = 100f;
float spacing = 5f;
Rect leftTitle = new(toolbarRect.xMin, 0, 40, 20f);
Rect leftPop = new(leftTitle.xMin + 40, 0, 200, 20f);
Rect saveBtn = new(toolbarRect.xMax - buttonWidth - spacing, 0, buttonWidth, 20f);
@ -210,14 +218,12 @@ namespace AlicizaX.Localization.Editor
if (currentTable == null) return;
if (GUI.Button(exportBtn, "Export CSV", EditorStyles.toolbarButton))
{
string path = EditorUtility.SaveFilePanel("Export CSV", "", "Localization", "csv");
LocalizationExporter.ExportLocalizationToCSV(windowData, path);
}
if (GUI.Button(importBtn, "Import CSV", EditorStyles.toolbarButton))
{
string path = EditorUtility.OpenFilePanel("Export CSV", "", "csv");
@ -236,69 +242,77 @@ namespace AlicizaX.Localization.Editor
AssetDatabase.SaveAssets();
}
// ---------------- 这里开始是 SplitView ----------------
Rect fullRect = new Rect(0, 20f, position.width, position.height - 20f);
Rect languagesRect = new Rect(5f, 25f, k_LanguagesWidth, position.height - 35f);
languagesTreeView.OnGUI(languagesRect);
// 左侧 Languages
Rect languagesRect = new Rect(fullRect.x, fullRect.y, languagesWidth, fullRect.height);
languagesTreeView?.OnGUI(languagesRect);
// 左侧拖拽条
Rect leftSplitter = new Rect(languagesRect.xMax, fullRect.y, SplitterWidth, fullRect.height);
EditorGUIUtility.AddCursorRect(leftSplitter, MouseCursor.ResizeHorizontal);
HandleResize(ref languagesWidth, leftSplitter, ref isResizingLeft);
float tableSheetStartX = languagesRect.xMax + 5f;
Rect tableSheetRect = new Rect(tableSheetStartX, 25f, k_TableSheetWidth, position.height - 35f);
tableSheetTreeView.OnGUI(tableSheetRect);
// 中间 TableSheet
Rect tableSheetRect = new Rect(leftSplitter.xMax, fullRect.y, tableSheetWidth, fullRect.height);
tableSheetTreeView?.OnGUI(tableSheetRect);
// 中间拖拽条
Rect midSplitter = new Rect(tableSheetRect.xMax, fullRect.y, SplitterWidth, fullRect.height);
EditorGUIUtility.AddCursorRect(midSplitter, MouseCursor.ResizeHorizontal);
HandleResize(ref tableSheetWidth, midSplitter, ref isResizingMiddle);
// 右侧 Inspector剩余空间
float inspectorWidth = fullRect.width - (languagesWidth + tableSheetWidth + SplitterWidth * 2);
Rect inspectorRect = new Rect(midSplitter.xMax, fullRect.y, inspectorWidth, fullRect.height);
if (selection != null)
{
float inspectorStartX = tableSheetRect.xMax + 5f;
Rect inspectorRect = new Rect(inspectorStartX, 25f, position.width - inspectorStartX - 5f, position.height - 30f);
if (selection is LanguageSelect language)
GUILayout.BeginArea(inspectorRect);
{
string title = language.Language.Entry.LanguageName;
GUIContent inspectorTitle = EditorGUIUtility.TrTextContentWithIcon($" INSPECTOR ({title})", "PrefabVariant On Icon");
EditorDrawing.DrawHeaderWithBorder(ref inspectorRect, inspectorTitle, 20f, false);
Rect inspectorViewRect = inspectorRect;
inspectorViewRect.y += Spacing;
inspectorViewRect.yMax -= Spacing;
inspectorViewRect.xMin += Spacing;
inspectorViewRect.xMax -= Spacing;
GUILayout.BeginArea(inspectorViewRect);
OnDrawLanguageInspector(language);
if (selection is LanguageSelect lang) OnDrawLanguageInspector(lang);
else if (selection is SectionSelect sec) OnDrawSectionInspector(sec);
else if (selection is ItemSelect item) OnDrawSectionItemInspector(item);
}
GUILayout.EndArea();
}
else if (selection is SectionSelect section)
{
string title = section.Section.Name;
GUIContent inspectorTitle = EditorGUIUtility.TrTextContentWithIcon($" INSPECTOR ({title})", "PrefabVariant On Icon");
EditorDrawing.DrawHeaderWithBorder(ref inspectorRect, inspectorTitle, 20f, false);
Rect inspectorViewRect = inspectorRect;
inspectorViewRect.y += Spacing;
inspectorViewRect.yMax -= Spacing;
inspectorViewRect.xMin += Spacing;
inspectorViewRect.xMax -= Spacing;
GUILayout.BeginArea(inspectorViewRect);
OnDrawSectionInspector(section);
GUILayout.EndArea();
}
else if (selection is ItemSelect item)
private void HandleResize(ref float targetWidth, Rect splitterRect, ref bool isResizing)
{
string title = item.Item.Key;
GUIContent inspectorTitle = EditorGUIUtility.TrTextContentWithIcon($" INSPECTOR ({title})", "PrefabVariant On Icon");
EditorDrawing.DrawHeaderWithBorder(ref inspectorRect, inspectorTitle, 20f, false);
Event e = Event.current;
Rect inspectorViewRect = inspectorRect;
inspectorViewRect.y += Spacing;
inspectorViewRect.yMax -= Spacing;
inspectorViewRect.xMin += Spacing;
inspectorViewRect.xMax -= Spacing;
GUILayout.BeginArea(inspectorViewRect);
OnDrawSectionItemInspector(item);
GUILayout.EndArea();
switch (e.type)
{
case EventType.MouseDown:
if (splitterRect.Contains(e.mousePosition))
{
isResizing = true;
e.Use();
}
break;
case EventType.MouseDrag:
if (isResizing)
{
targetWidth += e.delta.x;
targetWidth = Mathf.Max(100f, targetWidth); // 设置最小宽度
e.Use();
Repaint();
}
break;
case EventType.MouseUp:
if (isResizing)
{
isResizing = false;
e.Use();
}
break;
}
}

View File

@ -591,9 +591,9 @@ namespace AlicizaX.Localization.Editor
public static void GenerateCode(GameLocaizationTable table)
{
string filePath = table.GenerateScriptCodePath;
string nameSpace = table.GenerateScriptCodeFirstConfig;
List<LocalizationLanguage.LocalizationString> strings = new List<LocalizationLanguage.LocalizationString>();
var localizationLanguage = table.Languages.Find(t => t.LanguageName == table.GenerateScriptCodeFirstConfig);
Debug.Log(LocalizationConfiguration.Instance.GenerateScriptCodeFirstConfig);
var localizationLanguage = table.Languages.Find(t => t.LanguageName == LocalizationConfiguration.Instance.GenerateScriptCodeFirstConfig);
StringBuilder sb = new StringBuilder();
sb.AppendLine("/// <summary>");
@ -612,7 +612,7 @@ namespace AlicizaX.Localization.Editor
var item = v.SectionSheet[j];
if (!item.IsGen) continue;
string keyValue = item.Key;
string combineKey=v.SectionName+"."+item.Key;
string combineKey = v.SectionName + "." + item.Key;
if (localizationLanguage != null)
{

View File

@ -11,7 +11,6 @@ namespace AlicizaX.Localization.Editor
[CustomEditor(typeof(GameLocaizationTable))]
internal class GameLocaizationTableEditor : InspectorEditor<GameLocaizationTable>
{
private List<string> popConfig = new List<string>();
[OnOpenAsset]
public static bool OnOpenAsset(int instanceId, int line)
@ -31,15 +30,6 @@ namespace AlicizaX.Localization.Editor
public override void OnEnable()
{
base.OnEnable();
popConfig.Clear();
if (Target.Languages.Count > 0)
{
foreach (var lang in Target.Languages)
{
string name = lang.LanguageName.Or("Unknown");
popConfig.Add(name);
}
}
}
public override void OnInspectorGUI()
@ -54,7 +44,6 @@ namespace AlicizaX.Localization.Editor
using (new EditorDrawing.BorderBoxScope(new GUIContent("GenCode"), roundedBox: false))
{
Properties.Draw("GenerateScriptCodePath", new GUIContent("File Path"));
EditorDrawing.DrawStringSelectPopup(new GUIContent("Gen Lang"), new GUIContent("None"), popConfig.ToArray(), Target.GenerateScriptCodeFirstConfig, (e) => { Target.GenerateScriptCodeFirstConfig = e; });
}
}
serializedObject.ApplyModifiedProperties();
@ -108,6 +97,13 @@ namespace AlicizaX.Localization.Editor
window.Show();
}
[MenuItem("Tools/AlicizaX/Localization/Open Localization ProjectSetting")]
public static void OpenSettings()
{
SettingsService.OpenProjectSettings("Project/Localization Settings");
}
[MenuItem("Tools/AlicizaX/Localization/Create Localization Table")]
private static void CreateLocalizationTable()
{

View File

@ -6,7 +6,6 @@
"GUID:b4c00b967a932af48b2e067403eecbe2",
"GUID:f51ebe6a0ceec4240a699833d6309b23",
"GUID:e34a5702dd353724aa315fb8011f08c3",
"GUID:760f1778adc613f49a4394fb41ff0bbc",
"GUID:189d55e03d78888459720d730f4d2424"
],
"includePlatforms": [],
@ -17,11 +16,6 @@
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [
{
"name": "com.alicizax.unity.ui.extension",
"expression": "",
"define": "ALICIZAX_UI_EXTENSION_SUPPORT"
},
{
"name": "com.alicizax.unity.animationflow",
"expression": "",

View File

@ -10,7 +10,6 @@ namespace AlicizaX.Localization
{
#if UNITY_EDITOR
[SerializeField] internal string GenerateScriptCodePath = string.Empty;
[SerializeField] internal string GenerateScriptCodeFirstConfig;
[Serializable]
public struct SheetItem

View File

@ -206,6 +206,7 @@ namespace AlicizaX.UI.Runtime
internal async UniTask InternalInitlized()
{
_state = UIState.Initialized;
Holder.OnWindowInitEvent?.Invoke();
await OnInitializeAsync();
OnRegisterEvent(EventListenerProxy);
}
@ -214,9 +215,7 @@ namespace AlicizaX.UI.Runtime
{
_state = UIState.Opened;
Visible = true;
#if ALICIZAX_UI_EXTENSION_SUPPORT
Holder.BindHotKeys();
#endif
Holder.OnWindowShowEvent?.Invoke();
await OnOpenAsync();
}
@ -224,9 +223,7 @@ namespace AlicizaX.UI.Runtime
{
if (_state == UIState.Opened)
{
#if ALICIZAX_UI_EXTENSION_SUPPORT
Holder.UnBindHotKeys();
#endif
Holder.OnWindowClosedEvent?.Invoke();
await OnCloseAsync();
_state = UIState.Closed;
Visible = false;
@ -243,6 +240,7 @@ namespace AlicizaX.UI.Runtime
internal async UniTask InternalDestroy()
{
_state = UIState.Destroying;
Holder.OnWindowDestroyEvent?.Invoke();
await DestroyAllChildren();
OnDestroy();
ReleaseEventListenerProxy();

View File

@ -12,6 +12,11 @@ namespace AlicizaX.UI.Runtime
[HideMonoScript]
public abstract class UIHolderObjectBase : UnityEngine.MonoBehaviour
{
public Action OnWindowInitEvent;
public Action OnWindowShowEvent;
public Action OnWindowClosedEvent;
public Action OnWindowDestroyEvent;
#if UNITY_EDITOR && ALICIZAX_UI_ANIMATION_SUPPORT
private void SetAnimtionFlow()
{
@ -20,52 +25,6 @@ namespace AlicizaX.UI.Runtime
}
#endif
#if UNITY_EDITOR && ALICIZAX_UI_EXTENSION_SUPPORT
private void SetHotKeyButtons()
{
var btns = transform.GetComponentsInChildren<UXButton>(true);
var hotBtnList = new List<UXButton>();
for (int i = 0; i < btns.Length; i++)
{
if (btns[i].HasHotKeyRefrenced())
{
hotBtnList.Add(btns[i]);
}
}
hotButtons = hotBtnList.ToArray();
}
#endif
#if ALICIZAX_UI_EXTENSION_SUPPORT
#if UNITY_EDITOR
[InlineButton("SetHotKeyButtons")]
#endif
[SerializeField]
[HideLabel]
private UXButton[] hotButtons;
internal void BindHotKeys()
{
for (int i = 0; i < hotButtons.Length; i++)
{
hotButtons[i].BindHotKey();
}
}
internal void UnBindHotKeys()
{
for (int i = 0; i < hotButtons.Length; i++)
{
hotButtons[i].UnBindHotKey();
}
}
#endif
#if ALICIZAX_UI_ANIMATION_SUPPORT
public async UniTask PlayAnimtion(string name)
{