YIUIToolbarCallback.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. using System;
  2. using UnityEngine;
  3. using UnityEditor;
  4. using System.Reflection;
  5. #if UNITY_2019_1_OR_NEWER
  6. using UnityEngine.UIElements;
  7. #else
  8. using UnityEngine.Experimental.UIElements;
  9. #endif
  10. namespace YIUIFramework.Editor
  11. {
  12. public static class YIUIToolbarCallback
  13. {
  14. static Type m_toolbarType = typeof(UnityEditor.Editor).Assembly.GetType("UnityEditor.Toolbar");
  15. static Type m_guiViewType = typeof(UnityEditor.Editor).Assembly.GetType("UnityEditor.GUIView");
  16. #if UNITY_2020_1_OR_NEWER
  17. static Type m_iWindowBackendType = typeof(UnityEditor.Editor).Assembly.GetType("UnityEditor.IWindowBackend");
  18. static PropertyInfo m_windowBackend = m_guiViewType.GetProperty("windowBackend",
  19. BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
  20. static PropertyInfo m_viewVisualTree = m_iWindowBackendType.GetProperty("visualTree",
  21. BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
  22. #else
  23. static PropertyInfo m_viewVisualTree = m_guiViewType.GetProperty("visualTree",
  24. BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
  25. #endif
  26. static FieldInfo m_imguiContainerOnGui = typeof(IMGUIContainer).GetField("m_OnGUIHandler",
  27. BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
  28. static ScriptableObject m_currentToolbar;
  29. public static Action OnToolbarGUI;
  30. public static Action OnToolbarGUILeft;
  31. public static Action OnToolbarGUIRight;
  32. static YIUIToolbarCallback()
  33. {
  34. EditorApplication.update -= OnUpdate;
  35. EditorApplication.update += OnUpdate;
  36. }
  37. static void OnUpdate()
  38. {
  39. if (m_currentToolbar == null)
  40. {
  41. var toolbars = Resources.FindObjectsOfTypeAll(m_toolbarType);
  42. m_currentToolbar = toolbars.Length > 0 ? (ScriptableObject)toolbars[0] : null;
  43. if (m_currentToolbar != null)
  44. {
  45. #if UNITY_2021_1_OR_NEWER
  46. var root = m_currentToolbar.GetType().GetField("m_Root", BindingFlags.NonPublic | BindingFlags.Instance);
  47. var rawRoot = root.GetValue(m_currentToolbar);
  48. var mRoot = rawRoot as VisualElement;
  49. RegisterCallback("ToolbarZoneLeftAlign", OnToolbarGUILeft);
  50. RegisterCallback("ToolbarZoneRightAlign", OnToolbarGUIRight);
  51. void RegisterCallback(string root, Action cb)
  52. {
  53. var toolbarZone = mRoot.Q(root);
  54. var parent = new VisualElement()
  55. {
  56. style =
  57. {
  58. flexGrow = 1,
  59. flexDirection = FlexDirection.Row,
  60. }
  61. };
  62. var container = new IMGUIContainer();
  63. container.style.flexGrow = 1;
  64. container.onGUIHandler += () => { cb?.Invoke(); };
  65. parent.Add(container);
  66. toolbarZone.Add(parent);
  67. }
  68. #else
  69. #if UNITY_2020_1_OR_NEWER
  70. var windowBackend = m_windowBackend.GetValue(m_currentToolbar);
  71. // Get it's visual tree
  72. var visualTree = (VisualElement) m_viewVisualTree.GetValue(windowBackend, null);
  73. #else
  74. // Get it's visual tree
  75. var visualTree = (VisualElement) m_viewVisualTree.GetValue(m_currentToolbar, null);
  76. #endif
  77. // Get first child which 'happens' to be toolbar IMGUIContainer
  78. var container = (IMGUIContainer) visualTree[0];
  79. // (Re)attach handler
  80. var handler = (Action) m_imguiContainerOnGui.GetValue(container);
  81. handler -= OnGUI;
  82. handler += OnGUI;
  83. m_imguiContainerOnGui.SetValue(container, handler);
  84. #endif
  85. }
  86. }
  87. }
  88. static void OnGUI()
  89. {
  90. OnToolbarGUI?.Invoke();
  91. }
  92. }
  93. }