123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- using System;
- using System.Reflection;
-
- using UnityEditor;
- using UnityEngine;
-
- namespace Unity.PlasticSCM.Editor.UI
- {
- internal static class RunModal
- {
- static RunModal()
- {
- InitializeInfo();
- }
-
- internal static bool IsAvailable()
- {
- return mShowWithModeMethod != null
- && mCreateSavedGUIState != null
- && mApplyAndForgetMethod != null
- && mParentField != null
- && mParentWindowProp != null
- && mMakeModalMethod != null;
- }
-
- internal static void Dialog(EditorWindow window)
- {
- ShowAsUtility(window);
-
- object savedGUIState = CreateSavedGUIState();
- PushDispatcherContext(window);
-
- MakeModal(window);
-
- PopDispatcherContext(window);
- ApplySavedGUIState(savedGUIState);
- }
-
- static void MakeModal(EditorWindow window)
- {
- // MakeModal(m_Parent.window);
- var hostView = mParentField.GetValue(window);
- var parentWindow = mParentWindowProp.GetValue(hostView, null);
-
- mMakeModalMethod.Invoke(
- mMakeModalMethod.IsStatic ? null : window,
- new object[] { parentWindow });
- }
-
- static void ShowAsUtility(EditorWindow window)
- {
- // ShowWithMode(ShowMode.Utility);
- mShowWithModeMethod.Invoke(window, new object[] { 2 });
- }
-
- static object CreateSavedGUIState()
- {
- // SavedGUIState guiState = SavedGUIState.Create();
- return mCreateSavedGUIState.Invoke(null, null);
- }
-
- static void ApplySavedGUIState(object savedGUIState)
- {
- // guiState.ApplyAndForget();
- mApplyAndForgetMethod.Invoke(savedGUIState, null);
- }
-
- static void PopDispatcherContext(EditorWindow window)
- {
- #if UNITY_2020_1_OR_NEWER
- //UnityEngine.UIElements.EventDispatcher.editorDispatcher.PopDispatcherContext();
-
- object editorDispatcher = mEditorDispatcherProp2020.GetValue(null);
- mPopContextMethod2020.Invoke(editorDispatcher, null);
- #else
- // m_Parent.visualTree.panel.dispatcher?.PopDispatcherContext();
-
- object dispatcher = GetDispatcher(window);
-
- if (dispatcher != null)
- mPopContextMethod.Invoke(dispatcher, null);
- #endif
- }
-
- static void PushDispatcherContext(EditorWindow window)
- {
- #if UNITY_2020_1_OR_NEWER
- //UnityEngine.UIElements.EventDispatcher.editorDispatcher.PushDispatcherContext();
-
- object editorDispatcher = mEditorDispatcherProp2020.GetValue(null);
- mPushContextMethod2020.Invoke(editorDispatcher, null);
- #else
- // m_Parent.visualTree.panel.dispatcher?.PushDispatcherContext();
-
- object dispatcher = GetDispatcher(window);
-
- if (dispatcher != null)
- mPushContextMethod.Invoke(dispatcher, null);
- #endif
- }
-
- static object GetDispatcher(EditorWindow window)
- {
- object dispatcher = null;
- if (MayHaveDispatcher())
- {
- var parent = mParentField.GetValue(window);
- if (parent != null)
- {
- var visualTree = mVisualTreeProp.GetValue(parent, null);
- if (visualTree != null)
- {
- var panel = mPanelProp.GetValue(visualTree, null);
- if (panel != null)
- {
- dispatcher = mDispatcherProp.GetValue(panel, null);
- }
- }
- }
- }
-
- return dispatcher;
- }
-
- static bool MayHaveDispatcher()
- {
- return mDispatcherType != null
- && mPushContextMethod != null
- && mPopContextMethod != null;
- }
-
- static void InitializeInfo()
- {
- var flags = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static;
- mMakeModalMethod = BuildMakeModalMethodInfo(flags);
- mShowWithModeMethod = typeof(EditorWindow).GetMethod("ShowWithMode", flags);
- mParentField = typeof(EditorWindow).GetField("m_Parent", flags);
- var hostViewType = mParentField.FieldType;
- mParentWindowProp = hostViewType.GetProperty("window", flags);
-
- var savedGUIStateType = typeof(EditorWindow).Assembly.GetType("UnityEditor.SavedGUIState");
- mCreateSavedGUIState = savedGUIStateType.GetMethod("Create", flags);
- mApplyAndForgetMethod = savedGUIStateType.GetMethod("ApplyAndForget", flags);
-
- #if UNITY_2020_1_OR_NEWER
- mEditorDispatcherProp2020 = typeof(UnityEngine.UIElements.EventDispatcher).GetProperty("editorDispatcher", flags);
- mPushContextMethod2020 = mEditorDispatcherProp2020.PropertyType.GetMethod("PushDispatcherContext", flags);
- mPopContextMethod2020 = mEditorDispatcherProp2020.PropertyType.GetMethod("PopDispatcherContext", flags);
- #endif
- flags = BindingFlags.NonPublic
- | BindingFlags.Instance
- | BindingFlags.Public;
-
- mParentField = typeof(EditorWindow).GetField("m_Parent", flags);
- if (mParentField != null)
- hostViewType = mParentField.FieldType;
- if (hostViewType != null)
- mVisualTreeProp = hostViewType.GetProperty("visualTree");
- if (mVisualTreeProp != null)
- {
- var visualTreeType = mVisualTreeProp.PropertyType;
- if (visualTreeType != null)
- {
- mPanelProp = visualTreeType.GetProperty("panel");
- if (mPanelProp != null)
- {
- var panelType = mPanelProp.PropertyType;
- if (panelType != null)
- {
- mDispatcherProp = panelType.GetProperty("dispatcher");
- if (mDispatcherProp != null)
- {
- mDispatcherType = mDispatcherProp.PropertyType;
- if (mDispatcherType != null)
- {
- mPushContextMethod = mDispatcherType.GetMethod("PushDispatcherContext", flags);
- mPopContextMethod = mDispatcherType.GetMethod("PopDispatcherContext", flags);
- }
- }
- }
- }
- }
- }
- }
-
- static MethodInfo BuildMakeModalMethodInfo(BindingFlags flags)
- {
- if (EditorVersion.IsCurrentEditorOlderThan("2019.3.10f1"))
- return typeof(EditorWindow).GetMethod("MakeModal", flags);
-
- return typeof(EditorWindow).GetMethod("Internal_MakeModal", flags);
- }
-
- static FieldInfo mParentField;
- static PropertyInfo mParentWindowProp;
- static MethodInfo mMakeModalMethod;
- static MethodInfo mShowWithModeMethod;
- static MethodInfo mCreateSavedGUIState;
- static MethodInfo mApplyAndForgetMethod;
- static PropertyInfo mVisualTreeProp;
- static Type mDispatcherType;
- static MethodInfo mPushContextMethod;
- static MethodInfo mPopContextMethod;
- static PropertyInfo mPanelProp;
- static PropertyInfo mDispatcherProp;
-
- #if UNITY_2020_1_OR_NEWER
- static PropertyInfo mEditorDispatcherProp2020;
- static MethodInfo mPushContextMethod2020;
- static MethodInfo mPopContextMethod2020;
- #endif
-
- // // How ContainerWindows are visualized. Used with ContainerWindow.Show
- // internal enum ShowMode
- // {
- // // Show as a normal window with max, min & close buttons.
- // NormalWindow = 0,
- // // Used for a popup menu. On mac this means light shadow and no titlebar.
- // PopupMenu = 1,
- // // Utility window - floats above the app. Disappears when app loses focus.
- // Utility = 2,
- // // Window has no shadow or decorations. Used internally for dragging stuff around.
- // NoShadow = 3,
- // // The Unity main window. On mac, this is the same as NormalWindow, except window doesn't have a close button.
- // MainWindow = 4,
- // // Aux windows. The ones that close the moment you move the mouse out of them.
- // AuxWindow = 5,
- // // Like PopupMenu, but without keyboard focus
- // Tooltip = 6
- // }
- }
- }
|