using System; using System.Collections.Generic; using UnityEngine; using System.Reflection; using System.Runtime.Serialization; using Object = UnityEngine.Object; #if UNITY_2019_1_OR_NEWER using UnityEngine.UIElements; #else using UnityEngine.Experimental.UIElements; #endif namespace Game.NavigationTool.Editor.Toolbar { internal static class ToolbarUtility { public static void AddGuiListener(Action action) { Assembly assembly = typeof(UnityEditor.Editor).Assembly; Type typeToolbar = assembly.GetType("UnityEditor.Toolbar"); Object[] toolbars = Resources.FindObjectsOfTypeAll(typeToolbar); ScriptableObject so = toolbars.Length > 0 ? (ScriptableObject)toolbars[0] : null; if (so == null) return; Type typeGuiView = assembly.GetType("UnityEditor.GUIView"); #if UNITY_2020_1_OR_NEWER Type typeWindowBackend = assembly.GetType("UnityEditor.IWindowBackend"); PropertyInfo piWindowBackend = typeGuiView.GetProperty("windowBackend", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); PropertyInfo piVisualTree = typeWindowBackend.GetProperty("visualTree", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); #else PropertyInfo piVisualTree = typeGuiView.GetProperty("visualTree", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); #endif if (piVisualTree == null) return; FieldInfo fiImguiContainer = typeof(IMGUIContainer).GetField("m_OnGUIHandler", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); if (fiImguiContainer == null) return; #if UNITY_2020_1_OR_NEWER var windowBackend = piWindowBackend.GetValue(so); var visualTree = (VisualElement)piVisualTree.GetValue(windowBackend, null); #else var visualTree = (VisualElement)piVisualTree.GetValue(so, null); #endif var container = (IMGUIContainer)visualTree[0]; var handler = (Action)fiImguiContainer.GetValue(container); handler -= action; handler += action; fiImguiContainer.SetValue(container, handler); } public static IToolbarDrawer[] GetAllDrawers() { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); Type iType = typeof(IToolbarDrawer); var list = new List(8); for (var i = 0; i < assemblies.Length; i++) { Assembly assembly = assemblies[i]; Type[] types = assembly.GetTypes(); for (var j = 0; j < types.Length; j++) { Type type = types[j]; if (!type.IsAbstract && iType.IsAssignableFrom(type)) list.Add((IToolbarDrawer)FormatterServices.GetUninitializedObject(type)); } } return list.ToArray(); } } }