162 lines
5.1 KiB
C#
162 lines
5.1 KiB
C#
|
|
#if UNITY_6000_3_OR_NEWER
|
||
|
|
using System;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using System.Linq;
|
||
|
|
using System.Reflection;
|
||
|
|
using AlicizaX.Localization.Editor;
|
||
|
|
using AlicizaX.Localization.Runtime;
|
||
|
|
using UnityEditor;
|
||
|
|
using UnityEditor.SceneManagement;
|
||
|
|
using UnityEditor.Toolbars;
|
||
|
|
using UnityEngine;
|
||
|
|
|
||
|
|
namespace AlicizaX.Editor.Extension
|
||
|
|
{
|
||
|
|
[InitializeOnLoad]
|
||
|
|
public static class LocalizationToolbarDropdown
|
||
|
|
{
|
||
|
|
private const string ElementPath = "AlicizaX/Localization";
|
||
|
|
private const string Tooltip = "Switch editor localization preview language";
|
||
|
|
|
||
|
|
private static readonly Texture2D SettingsIcon;
|
||
|
|
private static string s_LastKnownLanguage;
|
||
|
|
|
||
|
|
static LocalizationToolbarDropdown()
|
||
|
|
{
|
||
|
|
SettingsIcon = GetIcon("Settings");
|
||
|
|
s_LastKnownLanguage = GetSelectedLanguage();
|
||
|
|
EditorApplication.update += RefreshWhenLanguageChanges;
|
||
|
|
}
|
||
|
|
|
||
|
|
[MainToolbarElement(ElementPath, defaultDockPosition = MainToolbarDockPosition.Right, defaultDockIndex = 0)]
|
||
|
|
public static MainToolbarElement CreateElement()
|
||
|
|
{
|
||
|
|
return new MainToolbarDropdown(
|
||
|
|
new MainToolbarContent(GetToolbarLabel(), SettingsIcon, Tooltip),
|
||
|
|
ShowDropdownMenu);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void RefreshWhenLanguageChanges()
|
||
|
|
{
|
||
|
|
var selectedLanguage = GetSelectedLanguage();
|
||
|
|
if (selectedLanguage == s_LastKnownLanguage)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
s_LastKnownLanguage = selectedLanguage;
|
||
|
|
MainToolbar.Refresh(ElementPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void ShowDropdownMenu(Rect dropdownRect)
|
||
|
|
{
|
||
|
|
var selectedLanguage = GetSelectedLanguage();
|
||
|
|
var menu = new GenericMenu();
|
||
|
|
var languageNames = GetLanguageTypeNames();
|
||
|
|
|
||
|
|
if (languageNames.Count == 0)
|
||
|
|
{
|
||
|
|
menu.AddDisabledItem(new GUIContent("No language options"));
|
||
|
|
menu.DropDown(dropdownRect);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
foreach (var languageName in languageNames)
|
||
|
|
{
|
||
|
|
var capturedLanguageName = languageName;
|
||
|
|
menu.AddItem(
|
||
|
|
new GUIContent(capturedLanguageName),
|
||
|
|
string.Equals(selectedLanguage, capturedLanguageName, StringComparison.Ordinal),
|
||
|
|
() => SetSelectedLanguage(capturedLanguageName));
|
||
|
|
}
|
||
|
|
|
||
|
|
menu.DropDown(dropdownRect);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void SetSelectedLanguage(string languageName)
|
||
|
|
{
|
||
|
|
EditorPrefs.SetString(LocalizationComponent.PrefsKey, languageName);
|
||
|
|
s_LastKnownLanguage = languageName;
|
||
|
|
InvokeOnValidateInScene();
|
||
|
|
MainToolbar.Refresh(ElementPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static IReadOnlyList<string> GetLanguageTypeNames()
|
||
|
|
{
|
||
|
|
return LocalizationConfiguration.Instance != null
|
||
|
|
? LocalizationConfiguration.Instance.LanguageTypeNames
|
||
|
|
: Array.Empty<string>();
|
||
|
|
}
|
||
|
|
|
||
|
|
private static string GetSelectedLanguage()
|
||
|
|
{
|
||
|
|
return EditorPrefs.GetString(LocalizationComponent.PrefsKey, "None");
|
||
|
|
}
|
||
|
|
|
||
|
|
private static string GetToolbarLabel()
|
||
|
|
{
|
||
|
|
return GetSelectedLanguage();
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void InvokeOnValidateInScene()
|
||
|
|
{
|
||
|
|
var targetType = FindType("UnityEngine.UI.UXTextMeshPro");
|
||
|
|
if (targetType == null)
|
||
|
|
{
|
||
|
|
Debug.LogWarning("Could not find type UnityEngine.UI.UXTextMeshPro.");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
var onValidateMethod = targetType.GetMethod(
|
||
|
|
"OnValidate",
|
||
|
|
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||
|
|
|
||
|
|
if (onValidateMethod == null)
|
||
|
|
{
|
||
|
|
Debug.LogWarning($"Could not find OnValidate on {targetType.Name}.");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
var components = GameObject.FindObjectsOfType(targetType)
|
||
|
|
.OfType<Component>()
|
||
|
|
.ToList();
|
||
|
|
|
||
|
|
if (components.Count == 0)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
var sceneToMarkDirty = EditorSceneManager.GetActiveScene();
|
||
|
|
|
||
|
|
foreach (var component in components)
|
||
|
|
{
|
||
|
|
Undo.RecordObject(component, "Invoke OnValidate");
|
||
|
|
onValidateMethod.Invoke(component, null);
|
||
|
|
EditorUtility.SetDirty(component);
|
||
|
|
}
|
||
|
|
|
||
|
|
EditorSceneManager.MarkSceneDirty(sceneToMarkDirty);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static Type FindType(string fullName)
|
||
|
|
{
|
||
|
|
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
|
||
|
|
{
|
||
|
|
var type = assembly.GetType(fullName);
|
||
|
|
if (type != null)
|
||
|
|
{
|
||
|
|
return type;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static Texture2D GetIcon(string iconName)
|
||
|
|
{
|
||
|
|
return EditorGUIUtility.IconContent(iconName).image as Texture2D;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endif
|