-
Notifications
You must be signed in to change notification settings - Fork 322
/
DockUtilities.cs
88 lines (62 loc) · 2.62 KB
/
DockUtilities.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEditor;
using UnityEngine;
public static class DockUtilities
{
public enum DockPosition
{
Left,
Top,
Right,
Bottom
}
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 new Vector2(wnd.position.x + mousePosition.x, wnd.position.y + mousePosition.y);
}
/// <summary>
/// Docks the "docked" window to the "anchor" window at the given position
/// </summary>
public static void DockWindow(this EditorWindow anchor, EditorWindow docked, DockPosition position)
{
var anchorParent = GetParentOf(anchor);
SetDragSource(anchorParent, GetParentOf(docked));
PerformDrop(GetWindowOf(anchorParent), docked, GetFakeMousePosition(anchor, position));
}
static object GetParentOf(object target)
{
var field = target.GetType().GetField("m_Parent", BindingFlags.Instance | BindingFlags.NonPublic);
return field.GetValue(target);
}
static object GetWindowOf(object target)
{
var property = target.GetType().GetProperty("window", BindingFlags.Instance | BindingFlags.Public);
return property.GetValue(target, null);
}
static void SetDragSource(object target, object source)
{
var field = target.GetType().GetField("s_OriginalDragSource", BindingFlags.Static | BindingFlags.NonPublic);
field.SetValue(null, source);
}
static void PerformDrop(object window, EditorWindow child, Vector2 screenPoint)
{
var rootSplitViewProperty = window.GetType().GetProperty("rootSplitView", BindingFlags.Instance | BindingFlags.Public);
object rootSplitView = rootSplitViewProperty.GetValue(window, null);
var dragMethod = rootSplitView.GetType().GetMethod("DragOver", BindingFlags.Instance | BindingFlags.Public);
var dropMethod = rootSplitView.GetType().GetMethod("PerformDrop", BindingFlags.Instance | BindingFlags.Public);
var dropInfo = dragMethod.Invoke(rootSplitView, new object[] { child, screenPoint });
dropMethod.Invoke(rootSplitView, new object[] { child, dropInfo, screenPoint });
}
}