diff --git a/Editor/Localization/LocalizationConfiguration.cs b/Editor/Localization/LocalizationConfiguration.cs index 8be21d5..c5a5689 100644 --- a/Editor/Localization/LocalizationConfiguration.cs +++ b/Editor/Localization/LocalizationConfiguration.cs @@ -8,6 +8,8 @@ namespace AlicizaX.Localization.Editor [AlicizaX.Editor.Setting.FilePath("ProjectSettings/LocalizationConfiguration.asset")] public class LocalizationConfiguration : AlicizaX.Editor.Setting.ScriptableSingleton { + [SerializeField] internal string generateScriptCodeFirstConfig; + [SerializeField] private List LanguageTypes = new List() { /// @@ -34,5 +36,6 @@ namespace AlicizaX.Localization.Editor [SerializeField] private string _genLangaugeTypePath = "Assets/LanguageTypes.cs"; public IReadOnlyList LanguageTypeNames => LanguageTypes; + public string GenerateScriptCodeFirstConfig => generateScriptCodeFirstConfig; } } diff --git a/Editor/Localization/LocalizationSettingsProvider.cs b/Editor/Localization/LocalizationSettingsProvider.cs index 762724f..3754967 100644 --- a/Editor/Localization/LocalizationSettingsProvider.cs +++ b/Editor/Localization/LocalizationSettingsProvider.cs @@ -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 popConfig = new List(); 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 字段 - element.stringValue = EditorGUI.TextField( - new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight), - element.stringValue); + 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(); } diff --git a/Editor/Localization/LocalizationTableWindow/LocalizationTableWindow.cs b/Editor/Localization/LocalizationTableWindow/LocalizationTableWindow.cs index 34ae13d..4cce690 100644 --- a/Editor/Localization/LocalizationTableWindow/LocalizationTableWindow.cs +++ b/Editor/Localization/LocalizationTableWindow/LocalizationTableWindow.cs @@ -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); - GUILayout.EndArea(); + if (selection is LanguageSelect lang) OnDrawLanguageInspector(lang); + else if (selection is SectionSelect sec) OnDrawSectionInspector(sec); + else if (selection is ItemSelect item) OnDrawSectionItemInspector(item); } - 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); + GUILayout.EndArea(); + } + } - Rect inspectorViewRect = inspectorRect; - inspectorViewRect.y += Spacing; - inspectorViewRect.yMax -= Spacing; - inspectorViewRect.xMin += Spacing; - inspectorViewRect.xMax -= Spacing; + private void HandleResize(ref float targetWidth, Rect splitterRect, ref bool isResizing) + { + Event e = Event.current; - GUILayout.BeginArea(inspectorViewRect); - OnDrawSectionInspector(section); - GUILayout.EndArea(); - } - else if (selection is ItemSelect item) - { - string title = item.Item.Key; - GUIContent inspectorTitle = EditorGUIUtility.TrTextContentWithIcon($" INSPECTOR ({title})", "PrefabVariant On Icon"); - EditorDrawing.DrawHeaderWithBorder(ref inspectorRect, inspectorTitle, 20f, false); + switch (e.type) + { + case EventType.MouseDown: + if (splitterRect.Contains(e.mousePosition)) + { + isResizing = true; + e.Use(); + } - Rect inspectorViewRect = inspectorRect; - inspectorViewRect.y += Spacing; - inspectorViewRect.yMax -= Spacing; - inspectorViewRect.xMin += Spacing; - inspectorViewRect.xMax -= Spacing; + break; - GUILayout.BeginArea(inspectorViewRect); - OnDrawSectionItemInspector(item); - GUILayout.EndArea(); - } + 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; } } diff --git a/Editor/Localization/LocalizationTableWindow/LocalizationWindowUtility.cs b/Editor/Localization/LocalizationTableWindow/LocalizationWindowUtility.cs index dcf6bcb..04a5bed 100644 --- a/Editor/Localization/LocalizationTableWindow/LocalizationWindowUtility.cs +++ b/Editor/Localization/LocalizationTableWindow/LocalizationWindowUtility.cs @@ -591,9 +591,9 @@ namespace AlicizaX.Localization.Editor public static void GenerateCode(GameLocaizationTable table) { string filePath = table.GenerateScriptCodePath; - string nameSpace = table.GenerateScriptCodeFirstConfig; List strings = new List(); - 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("/// "); @@ -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) { diff --git a/Editor/Localization/LocalizationTableWindow/Scriptable/GameLocaizationTableEditor.cs b/Editor/Localization/LocalizationTableWindow/Scriptable/GameLocaizationTableEditor.cs index c3822d6..259364e 100644 --- a/Editor/Localization/LocalizationTableWindow/Scriptable/GameLocaizationTableEditor.cs +++ b/Editor/Localization/LocalizationTableWindow/Scriptable/GameLocaizationTableEditor.cs @@ -11,7 +11,6 @@ namespace AlicizaX.Localization.Editor [CustomEditor(typeof(GameLocaizationTable))] internal class GameLocaizationTableEditor : InspectorEditor { - private List popConfig = new List(); [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() { diff --git a/Runtime/AlicizaX.Framework.Runtime.asmdef b/Runtime/AlicizaX.Framework.Runtime.asmdef index 013ed76..8669906 100644 --- a/Runtime/AlicizaX.Framework.Runtime.asmdef +++ b/Runtime/AlicizaX.Framework.Runtime.asmdef @@ -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": "", diff --git a/Runtime/Localization/ScriptableObject/GameLocaizationTable.cs b/Runtime/Localization/ScriptableObject/GameLocaizationTable.cs index d21acd7..fd8e0a2 100644 --- a/Runtime/Localization/ScriptableObject/GameLocaizationTable.cs +++ b/Runtime/Localization/ScriptableObject/GameLocaizationTable.cs @@ -10,7 +10,6 @@ namespace AlicizaX.Localization { #if UNITY_EDITOR [SerializeField] internal string GenerateScriptCodePath = string.Empty; - [SerializeField] internal string GenerateScriptCodeFirstConfig; [Serializable] public struct SheetItem diff --git a/Runtime/UI/UIBase/UIBase.cs b/Runtime/UI/UIBase/UIBase.cs index e3f4138..9036178 100644 --- a/Runtime/UI/UIBase/UIBase.cs +++ b/Runtime/UI/UIBase/UIBase.cs @@ -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(); diff --git a/Runtime/UI/UIBase/UIHolderObjectBase.cs b/Runtime/UI/UIBase/UIHolderObjectBase.cs index 92e5092..f81c129 100644 --- a/Runtime/UI/UIBase/UIHolderObjectBase.cs +++ b/Runtime/UI/UIBase/UIHolderObjectBase.cs @@ -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(true); - var hotBtnList = new List(); - 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) {