diff options
Diffstat (limited to 'Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Utils/WindowHelper.cs')
-rw-r--r-- | Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Utils/WindowHelper.cs | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Utils/WindowHelper.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Utils/WindowHelper.cs new file mode 100644 index 00000000..7b8972b4 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Utils/WindowHelper.cs @@ -0,0 +1,250 @@ +#if UNITY_EDITOR +using System; +using System.Reflection; +using UnityEditor; +using UnityEngine; + +public static class WindowHelper +{ + private class R_EditorWindow + { + private EditorWindow m_instance; + private System.Type m_type; + + public R_EditorWindow( EditorWindow instance ) + { + m_instance = instance; + m_type = instance.GetType(); + } + + public object Parent + { + get + { + var field = m_type.GetField( "m_Parent", BindingFlags.Instance | BindingFlags.NonPublic ); + return field.GetValue( m_instance ); + } + } + + public object Docked + { + get + { + var property = m_type.GetProperty( "docked", BindingFlags.Instance | BindingFlags.NonPublic ); + return property.GetValue( m_instance, null ); + } + } + } + + private class R_DockArea + { + private object m_instance; + private System.Type m_type; + + public R_DockArea( object instance ) + { + m_instance = instance; + m_type = instance.GetType(); + } + + public object Window + { + get + { + var property = m_type.GetProperty( "window", BindingFlags.Instance | BindingFlags.Public ); + return property.GetValue( m_instance, null ); + } + } + + public object ActualView + { + get + { + var field = m_type.GetField( "m_ActualView", BindingFlags.Instance | BindingFlags.NonPublic ); + return field.GetValue( m_instance ); + } + } + + public object OriginalDragSource + { + set + { + var field = m_type.GetField( "s_OriginalDragSource", BindingFlags.Static | BindingFlags.NonPublic ); + field.SetValue( null, value ); + } + } + + + public void AddTab( EditorWindow pane ) + { +#if UNITY_2018_3_OR_NEWER + var method = m_type.GetMethod( "AddTab", BindingFlags.Instance | BindingFlags.Public, null, new System.Type[] { typeof( EditorWindow ), typeof( bool ) }, null ); + method.Invoke( m_instance, new object[] { pane, true } ); +#else + var method = m_type.GetMethod( "AddTab", BindingFlags.Instance | BindingFlags.Public, null, new System.Type[] { typeof( EditorWindow ) }, null ); + method.Invoke( m_instance, new object[] { pane } ); +#endif + } + + public void RemoveTab( EditorWindow pane ) + { + var method = m_type.GetMethod( "RemoveTab", BindingFlags.Instance | BindingFlags.Public, null, new System.Type[] { typeof( EditorWindow ) }, null ); + method.Invoke( m_instance, new object[] { pane } ); + } + } + + private class R_ContainerWindow + { + private object m_instance; + private System.Type m_type; + + public R_ContainerWindow( object instance ) + { + m_instance = instance; + m_type = instance.GetType(); + } + + public object RootSplitView + { + get + { + var property = m_type.GetProperty( "rootSplitView", BindingFlags.Instance | BindingFlags.Public ); + return property.GetValue( m_instance, null ); + } + } + + public object RootView + { + get + { + var property = m_type.GetProperty( "rootView", BindingFlags.Instance | BindingFlags.Public ); + return property.GetValue( m_instance, null ); + } + } + + public object WindowPtr + { + get + { + var all = m_type.GetNestedTypes(); + foreach( var item in all ) + { + Debug.Log( item.Name ); + } + var property = m_type.GetField( "m_WindowPtr", BindingFlags.Instance | BindingFlags.NonPublic ); + return property.GetValue( m_instance ); + } + } + } + + private class R_SplitView + { + private object m_instance; + private System.Type m_type; + + public R_SplitView( object instance ) + { + m_instance = instance; + m_type = instance.GetType(); + } + + public object DragOver( EditorWindow child, Vector2 screenPoint ) + { + var method = m_type.GetMethod( "DragOver", BindingFlags.Instance | BindingFlags.Public ); + return method.Invoke( m_instance, new object[] { child, screenPoint } ); + } + + public void PerformDrop( EditorWindow child, object dropInfo, Vector2 screenPoint ) + { + var method = m_type.GetMethod( "PerformDrop", BindingFlags.Instance | BindingFlags.Public ); + method.Invoke( m_instance, new object[] { child, dropInfo, screenPoint } ); + } + } + + public enum DockPosition + { + Left, + Top, + Right, + Bottom + } + + public static bool IsDocked( this EditorWindow wnd ) + { + var parent = new R_EditorWindow( wnd ); + return (bool)parent.Docked; + } + + public static void Undock( this EditorWindow wnd ) + { + var parent = new R_EditorWindow( wnd ); + var dockArea = new R_DockArea( parent.Parent ); + dockArea.RemoveTab( wnd ); + wnd.Show( true ); + } + + public static void RemoveTab( this EditorWindow wnd ) + { + var parent = new R_EditorWindow( wnd ); + var dockArea = new R_DockArea( parent.Parent ); + dockArea.RemoveTab( wnd ); + } + + /// <summary> + /// Docks the second window to the first window at the given position + /// </summary> + public static void Dock( this EditorWindow wnd, EditorWindow other, DockPosition position ) + { + var mousePosition = GetFakeMousePosition( wnd, position ); + + var parent = new R_EditorWindow( wnd ); + var child = new R_EditorWindow( other ); + var dockArea = new R_DockArea( parent.Parent ); + var containerWindow = new R_ContainerWindow( dockArea.Window ); + var splitView = new R_SplitView( containerWindow.RootSplitView ); + var dropInfo = splitView.DragOver( other, mousePosition ); + dockArea.OriginalDragSource = child.Parent; + splitView.PerformDrop( other, dropInfo, mousePosition ); + } + + + /// <summary> + /// Adds the the second window as a tab at the end of the first window tab list + /// </summary> + /// <param name="existingWindow"></param> + /// <param name="newWindow"></param> + public static void AddTab( this EditorWindow existingWindow, EditorWindow newWindow ) + { + var parent = new R_EditorWindow( existingWindow ); + var child = new R_EditorWindow( newWindow ); + var dockArea = new R_DockArea( parent.Parent ); + dockArea.OriginalDragSource = child.Parent; + dockArea.AddTab( newWindow ); + } + + private static Vector2 GetFakeMousePosition( EditorWindow wnd, DockPosition position ) + { + Vector2 mousePosition = Vector2.zero; + + // The 20 is required to make the docking work. + // Smaller values might not work when faking the mouse position. + switch ( position ) + { + case DockPosition.Left: + mousePosition = new Vector2( 20, wnd.position.size.y / 2 ); + break; + case DockPosition.Top: + mousePosition = new Vector2( wnd.position.size.x / 2, 20 ); + break; + case DockPosition.Right: + mousePosition = new Vector2( wnd.position.size.x - 20, wnd.position.size.y / 2 ); + break; + case DockPosition.Bottom: + mousePosition = new Vector2( wnd.position.size.x / 2, wnd.position.size.y - 20 ); + break; + } + + return GUIUtility.GUIToScreenPoint( mousePosition ); + } +} +#endif |