summaryrefslogtreecommitdiff
path: root/Other/NodeEditorExamples/Assets/xNode-examples/Scripts/Editor/Drawers/NodeEnumDrawer.cs
blob: 8aa748c25b4eadd098ab14ca86ba317b8adc277b (plain)
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
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using XNode;
using XNodeEditor;

namespace XNodeEditor {
	[CustomPropertyDrawer(typeof(NodeEnumAttribute))]
	public class NodeEnumDrawer : PropertyDrawer {
		public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
			EditorGUI.BeginProperty(position, label, property);

			EnumPopup(position, property, label);

			EditorGUI.EndProperty();
		}

		public static void EnumPopup(Rect position, SerializedProperty property, GUIContent label) {
			// Throw error on wrong type
			if (property.propertyType != SerializedPropertyType.Enum) {
				throw new ArgumentException("Parameter selected must be of type System.Enum");
			}

			// Add label
			position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);

			// Get current enum name
			string enumName = "";
			if (property.enumValueIndex >= 0 && property.enumValueIndex < property.enumDisplayNames.Length) enumName = property.enumDisplayNames[property.enumValueIndex];

#if UNITY_2017_1_OR_NEWER
			// Display dropdown
			if (EditorGUI.DropdownButton(position, new GUIContent(enumName), FocusType.Passive)) {
				// Position is all wrong if we show the dropdown during the node draw phase.
				// Instead, add it to onLateGUI to display it later.
				NodeEditorWindow.current.onLateGUI += () => ShowContextMenuAtMouse(property);
			}
#else
			// Display dropdown
			if (GUI.Button(position, new GUIContent(enumName), "MiniPopup")) {
				// Position is all wrong if we show the dropdown during the node draw phase.
				// Instead, add it to onLateGUI to display it later.
				NodeEditorWindow.current.onLateGUI += () => ShowContextMenuAtMouse(property);
			}
#endif
		}

		public static void ShowContextMenuAtMouse(SerializedProperty property) {
			// Initialize menu
			GenericMenu menu = new GenericMenu();

			// Add all enum display names to menu
			for (int i = 0; i < property.enumDisplayNames.Length; i++) {
				int index = i;
				menu.AddItem(new GUIContent(property.enumDisplayNames[i]), false, () => SetEnum(property, index));
			}

			// Display at cursor position
			Rect r = new Rect(Event.current.mousePosition, new Vector2(0, 0));
			menu.DropDown(r);
		}

		private static void SetEnum(SerializedProperty property, int index) {
			property.enumValueIndex = index;
			property.serializedObject.ApplyModifiedProperties();
			property.serializedObject.Update();
		}
	}
}