|
1 | 1 | using System;
|
| 2 | +using System.Linq; |
2 | 3 | using TNRD.Utilities;
|
3 | 4 | using UnityEditor;
|
4 | 5 | using UnityEditor.IMGUI.Controls;
|
5 | 6 | using UnityEngine;
|
| 7 | +using UnityEngine.Assertions; |
6 | 8 | using UnityEngine.SceneManagement;
|
7 | 9 | using Object = UnityEngine.Object;
|
8 | 10 |
|
9 | 11 | namespace TNRD.Drawers
|
10 | 12 | {
|
11 | 13 | internal abstract class ReferenceDrawer
|
12 | 14 | {
|
| 15 | + private enum DragAndDropMode |
| 16 | + { |
| 17 | + None, |
| 18 | + Raw, |
| 19 | + Unity |
| 20 | + } |
| 21 | + |
| 22 | + private DragAndDropMode dragAndDropMode; |
| 23 | + |
13 | 24 | protected readonly SerializedProperty Property;
|
14 | 25 | protected readonly Type GenericType;
|
15 | 26 | protected readonly CustomObjectDrawer CustomObjectDrawer;
|
@@ -95,5 +106,94 @@ private void OnItemSelected(ReferenceMode mode, object reference)
|
95 | 106 | }
|
96 | 107 |
|
97 | 108 | protected abstract void OnPropertiesClicked();
|
| 109 | + |
| 110 | + protected void HandleDragAndDrop(Rect position) |
| 111 | + { |
| 112 | + if (Event.current.type == EventType.DragPerform) |
| 113 | + { |
| 114 | + HandleDragPerform(); |
| 115 | + } |
| 116 | + else if (Event.current.type == EventType.DragUpdated) |
| 117 | + { |
| 118 | + HandleDragUpdated(position); |
| 119 | + } |
| 120 | + } |
| 121 | + |
| 122 | + private void SetDragAndDropMode(bool success, DragAndDropMode? successMode = null) |
| 123 | + { |
| 124 | + if (success) |
| 125 | + { |
| 126 | + Assert.IsTrue(successMode.HasValue); |
| 127 | + dragAndDropMode = successMode.Value; |
| 128 | + DragAndDrop.visualMode = DragAndDropVisualMode.Link; |
| 129 | + } |
| 130 | + else |
| 131 | + { |
| 132 | + dragAndDropMode = DragAndDropMode.None; |
| 133 | + DragAndDrop.visualMode = DragAndDropVisualMode.Rejected; |
| 134 | + } |
| 135 | + } |
| 136 | + |
| 137 | + private void HandleDragUpdated(Rect position) |
| 138 | + { |
| 139 | + if (!position.Contains(Event.current.mousePosition)) |
| 140 | + return; |
| 141 | + |
| 142 | + if (DragAndDrop.objectReferences.Length > 1) |
| 143 | + { |
| 144 | + SetDragAndDropMode(false); |
| 145 | + return; |
| 146 | + } |
| 147 | + |
| 148 | + Object objectReference = DragAndDrop.objectReferences[0]; |
| 149 | + |
| 150 | + if (objectReference is GameObject gameObject) |
| 151 | + { |
| 152 | + Component component = gameObject.GetComponent(GenericType); |
| 153 | + SetDragAndDropMode(component != null, DragAndDropMode.Unity); |
| 154 | + } |
| 155 | + else if (objectReference is MonoScript monoScript) |
| 156 | + { |
| 157 | + Type scriptType = monoScript.GetClass(); |
| 158 | + |
| 159 | + if (scriptType.IsSubclassOf(typeof(UnityEngine.Object))) |
| 160 | + { |
| 161 | + SetDragAndDropMode(false); |
| 162 | + return; |
| 163 | + } |
| 164 | + |
| 165 | + if (!GenericType.IsAssignableFrom(scriptType)) |
| 166 | + { |
| 167 | + SetDragAndDropMode(false); |
| 168 | + return; |
| 169 | + } |
| 170 | + |
| 171 | + bool isValidDrop = scriptType.GetConstructors().Any(x => x.GetParameters().Length == 0); |
| 172 | + SetDragAndDropMode(isValidDrop, DragAndDropMode.Raw); |
| 173 | + } |
| 174 | + else |
| 175 | + { |
| 176 | + SetDragAndDropMode(GenericType.IsInstanceOfType(objectReference), DragAndDropMode.Unity); |
| 177 | + } |
| 178 | + } |
| 179 | + |
| 180 | + private void HandleDragPerform() |
| 181 | + { |
| 182 | + switch (dragAndDropMode) |
| 183 | + { |
| 184 | + case DragAndDropMode.Raw: |
| 185 | + RawReferenceProperty.managedReferenceValue = |
| 186 | + Activator.CreateInstance(((MonoScript)DragAndDrop.objectReferences[0]).GetClass()); |
| 187 | + ReferenceModeProperty.enumValueIndex = (int)ReferenceMode.Raw; |
| 188 | + break; |
| 189 | + case DragAndDropMode.Unity: |
| 190 | + UnityReferenceProperty.objectReferenceValue = DragAndDrop.objectReferences[0]; |
| 191 | + ReferenceModeProperty.enumValueIndex = (int)ReferenceMode.Unity; |
| 192 | + break; |
| 193 | + case DragAndDropMode.None: |
| 194 | + default: |
| 195 | + throw new ArgumentOutOfRangeException(); |
| 196 | + } |
| 197 | + } |
98 | 198 | }
|
99 | 199 | }
|
0 commit comments