// // /*=============================================================================== // // Copyright (C) 2025 PhantomsXR Ltd. All Rights Reserved. // // // // This file is part of the Phantom.XRMOD.XRMODLocalization.Editor. // // // // The XR-MOD cannot be copied, distributed, or made available to // // third-parties for commercial purposes without written permission of PhantomsXR Ltd. // // // // Contact nswell@phantomsxr.com for licensing requests. // // ===============================================================================*/ using System; using System.Collections.Generic; using System.Linq; using Phantom.XRMOD.Localization.Runtime; using Phantom.XRMOD.XRMODUtilites.Runtime; using UnityEditor; using UnityEditor.UIElements; using UnityEngine; using UnityEngine.UIElements; using Object = UnityEngine.Object; namespace Phantom.XRMOD.Localization.Editor { public class LocalizationEditorWindow : EditorWindow { internal static LocalizationEditorWindow _WINDOW; private VisualElement tableDetailContainer; private IEditorDraw leftPane; private IEditorDraw rightPane; private IEditorDraw settingsButton; // private IEditorDraw addTableButton; private IEditorDraw aiTranslationButton; private IEditorDraw syncContentToAllTableButton; private const string _CONST_PREF_KEY = "LocalizationEditor_LastDbPath"; [MenuItem("Tools/XR-MOD/Tools/Localization/Database Editor")] public static void ShowWindow() { if (_WINDOW != null) return; _WINDOW = GetWindow(); _WINDOW.titleContent = new GUIContent("Localization Editor"); } public static void OpenWithDatabase(LocalizationDatabase _db) { if (SharedData.Instance.Database != null && SharedData.Instance.Database == _db) return; SharedData.Instance.Table = null; SharedData.Instance.Database = _db; ShowWindow(); _WINDOW.RefreshTableList(); } private void OnEnable() { ReloadDb(); } private void OnDisable() { SharedData.Instance.Table = null; SharedData.Instance.Database = null; } private void ReloadDb() { if (SharedData.Instance.Database != null) return; string tmp_Path = EditorPrefs.GetString($"{Application.productName}_{_CONST_PREF_KEY}", ""); if (string.IsNullOrEmpty(tmp_Path)) return; var tmp_DB = AssetDatabase.LoadAssetAtPath(tmp_Path); if (tmp_DB == null) return; SharedData.Instance.Database = tmp_DB; if (SharedData.Instance.Database.LocalizatoinSettings == null) { var tmp_SupportLanguageSettings = CreateInstance(); tmp_SupportLanguageSettings.name = nameof(LocalizatoinSettings); Utilities.CreateAndAttachTable(SharedData.Instance.Database, tmp_SupportLanguageSettings); } RefreshTableList(); } private static void PersistenceEditingDb() { if (SharedData.Instance.Database == null) return; string tmp_SavePath = AssetDatabase.GetAssetPath(SharedData.Instance.Database); EditorPrefs.SetString($"{Application.productName}_{_CONST_PREF_KEY}", tmp_SavePath); } private void CreateGUI() { ReloadDb(); var tmp_Root = rootVisualElement; tmp_Root.styleSheets.Add( AssetDatabase.LoadAssetAtPath( "Packages/com.phantomsxr.xrmodlocalization/Editor/Assets/LocalizationEditorWindow.uss")); Toolbar(tmp_Root); // ==== Split View ==== var tmp_SplitView = new TwoPaneSplitView(0, 200, TwoPaneSplitViewOrientation.Horizontal); tmp_Root.Add(tmp_SplitView); // ==== Left Panel: Table List ==== DrawLeftPane(tmp_SplitView); // ==== Right Panel: Table Details ==== DrawRightPane(tmp_SplitView); RefreshTableList(); } private void DrawRightPane(TwoPaneSplitView _splitView) { var tmp_RightPane = new VisualElement { name = "RightPane", style = { flexGrow = 1 } }; rightPane = new RightEditorPanel(tmp_RightPane, this); rightPane.Draw(); _splitView.Add(tmp_RightPane); rightPane.ReBuild(); } private void DrawLeftPane(TwoPaneSplitView _splitView) { var tmp_LeftPane = new VisualElement { name = "LeftPane", style = { flexGrow = 1 } }; leftPane = new LeftEditorPane(tmp_LeftPane, this); leftPane.Draw(); _splitView.Add(tmp_LeftPane); } private void Toolbar(VisualElement _root) { // === Toolbar === var tmp_Toolbar = new Toolbar(); tmp_Toolbar.Clear(); var tmp_ToolbarMenuButton = new ToolbarMenu() {text = "File"}; tmp_ToolbarMenuButton.menu.AppendAction("Open", _data => { string tmp_Path = EditorUtility.OpenFilePanel("Select LocalizationDatabase", "Assets", "asset"); if (string.IsNullOrEmpty(tmp_Path) || !tmp_Path.StartsWith(Application.dataPath)) return; string tmp_RelativePath = "Assets" + tmp_Path.Substring(Application.dataPath.Length); var tmp_LoadedDb = AssetDatabase.LoadAssetAtPath(tmp_RelativePath); if (tmp_LoadedDb != null) { SharedData.Instance.Database = tmp_LoadedDb; RefreshTableList(); tableDetailContainer?.Clear(); } else { Debug.LogWarning("Selected file is not a LocalizationDatabase."); } var tmp_WorldPos = tmp_ToolbarMenuButton.worldBound.position; var tmp_ScreenPos = GUIUtility.GUIToScreenPoint(tmp_WorldPos); }); tmp_ToolbarMenuButton.menu.AppendSeparator(); tmp_ToolbarMenuButton.menu.AppendAction("Import CSV", _data => { if (SharedData.Instance.Table == null) return; var tmp_FilePath = EditorUtility.OpenFilePanel("Select LocalizationDatabase", "Assets", "csv"); Utilities.ImportFromCsv(tmp_FilePath, SharedData.Instance.Table); RefreshEntryList(); }, _action => SharedData.Instance.Table != null ? DropdownMenuAction.Status.Normal : DropdownMenuAction.Status.Disabled); tmp_Toolbar.Add(tmp_ToolbarMenuButton); tmp_ToolbarMenuButton.menu.AppendAction("Export CSV", _data => { if (SharedData.Instance.Table == null) return; var tmp_Path = EditorUtility.SaveFilePanel("Save CSV", "", $"{SharedData.Instance.Table.Scope}_{SharedData.Instance.Table.Platform}.csv", "csv"); Utilities.ExportToCsv(SharedData.Instance.Table, tmp_Path); }, _action => SharedData.Instance.Table != null ? DropdownMenuAction.Status.Normal : DropdownMenuAction.Status.Disabled); tmp_Toolbar.Add(tmp_ToolbarMenuButton); tmp_Toolbar.Add(new ToolbarSpacer()); settingsButton ??= new SettingsButton(tmp_Toolbar, this); settingsButton.Draw(); var tmp_Spacer = new VisualElement { style = { flexGrow = 1 } }; tmp_Toolbar.Add(tmp_Spacer); aiTranslationButton ??= new AITranslationButton(tmp_Toolbar, this); aiTranslationButton.Draw(); syncContentToAllTableButton ??= new SyncToOtherTableButton(tmp_Toolbar, this); syncContentToAllTableButton.Draw(); _root.Add(tmp_Toolbar); } internal void RefreshTableList() { leftPane?.ReBuild(); rightPane?.ReBuild(); aiTranslationButton?.ReBuild(); syncContentToAllTableButton?.ReBuild(); PersistenceEditingDb(); } internal void RefreshEntryList() { rightPane?.ReBuild(); } internal void SetSelectedTable(LocalizationTable _table) { SharedData.Instance.Table = _table; rightPane?.ReBuild(); aiTranslationButton?.ReBuild(); syncContentToAllTableButton?.ReBuild(); } } }