Tanoda
EnumEventTableEditor.cs
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (C) Ultraleap, Inc. 2011-2020. *
3 * *
4 * Use subject to the terms of the Apache License 2.0 available at *
5 * http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
6 * between Ultraleap and you, your company or other organization. *
7 ******************************************************************************/
8
9using System;
10using UnityEngine;
11using UnityEditor;
12using Leap.Unity.Query;
13
14namespace Leap.Unity {
15
16 public class EnumEventTableEditor {
17
18 private SerializedProperty _entries;
19
20 private GUIContent _iconToolbarMinus;
21 private GUIContent _eventIDName;
22 private GUIContent _addButtonContent;
23
24 private GUIContent[] _enumNames;
25 private int[] _enumValues;
26
33 public EnumEventTableEditor(SerializedProperty tableProperty, Type enumType) {
34 _entries = tableProperty.FindPropertyRelative("_entries");
35
36 _addButtonContent = new GUIContent("Add New Event Type");
37 _eventIDName = new GUIContent("");
38 // Have to create a copy since otherwise the tooltip will be overwritten.
39 _iconToolbarMinus = new GUIContent(EditorGUIUtility.IconContent("Toolbar Minus"));
40 _iconToolbarMinus.tooltip = "Remove all events in this list.";
41
42 _enumNames = Enum.GetNames(enumType).Query().Select(s => new GUIContent(s)).ToArray();
43 _enumValues = (int[])Enum.GetValues(enumType);
44 }
45
46 public void DoGuiLayout() {
47 if (_entries.serializedObject.isEditingMultipleObjects) {
48 return;
49 }
50
51 int toBeRemovedEntry = -1;
52
53 EditorGUILayout.Space();
54
55 Vector2 removeButtonSize = GUIStyle.none.CalcSize(_iconToolbarMinus);
56
57 for (int i = 0; i < _entries.arraySize; ++i) {
58 SerializedProperty delegateProperty = _entries.GetArrayElementAtIndex(i);
59 SerializedProperty enumValueProperty = delegateProperty.FindPropertyRelative("enumValue");
60 SerializedProperty callbacksProperty = delegateProperty.FindPropertyRelative("callback");
61
62 int index = Array.IndexOf(_enumValues, enumValueProperty.intValue);
63 if (index < 0) {
64 _eventIDName.text = "Event " + enumValueProperty.intValue;
65 } else {
66 _eventIDName.text = _enumNames[index].text;
67 }
68
69 EditorGUILayout.PropertyField(callbacksProperty, _eventIDName);
70 Rect callbackRect = GUILayoutUtility.GetLastRect();
71
72 Rect removeButtonPos = new Rect(callbackRect.xMax - removeButtonSize.x - 8, callbackRect.y + 1, removeButtonSize.x, removeButtonSize.y);
73 if (GUI.Button(removeButtonPos, _iconToolbarMinus, GUIStyle.none)) {
74 toBeRemovedEntry = i;
75 }
76
77 EditorGUILayout.Space();
78 }
79
80 if (toBeRemovedEntry > -1) {
81 RemoveEntry(toBeRemovedEntry);
82 }
83
84 Rect btPosition = GUILayoutUtility.GetRect(_addButtonContent, GUI.skin.button);
85 const float addButonWidth = 200f;
86 btPosition.x = btPosition.x + (btPosition.width - addButonWidth) / 2;
87 btPosition.width = addButonWidth;
88 if (GUI.Button(btPosition, _addButtonContent)) {
89 showAddEventMenu();
90 }
91
92 _entries.serializedObject.ApplyModifiedProperties();
93 }
94
95 public bool HasAnyCallbacks(int enumValue) {
96 if (_entries == null) return false;
97 for (int i = 0; i < _entries.arraySize; i++) {
98 var entryProperty = _entries.GetArrayElementAtIndex(i);
99 var enumValueProperty = entryProperty.FindPropertyRelative("enumValue");
100 if (enumValueProperty.intValue == enumValue) {
101 return true;
102 }
103 }
104 return false;
105 }
106
107 private void RemoveEntry(int toBeRemovedEntry) {
108 _entries.DeleteArrayElementAtIndex(toBeRemovedEntry);
109 }
110
111 private void showAddEventMenu() {
112 // Now create the menu, add items and show it
113 GenericMenu menu = new GenericMenu();
114 for (int i = 0; i < _enumNames.Length; ++i) {
115 bool active = true;
116
117 // Check if we already have a Entry for the current enum type, if so, disable it
118 for (int p = 0; p < _entries.arraySize; ++p) {
119 SerializedProperty entryProperty = _entries.GetArrayElementAtIndex(p);
120 SerializedProperty enumValueProperty = entryProperty.FindPropertyRelative("enumValue");
121 if (enumValueProperty.intValue == _enumValues[i]) {
122 active = false;
123 }
124 }
125
126 if (active) {
127 menu.AddItem(_enumNames[i], false, OnAddNewSelected, _enumValues[i]);
128 } else {
129 menu.AddDisabledItem(_enumNames[i]);
130 }
131 }
132 menu.ShowAsContext();
133
134 Event.current.Use();
135 }
136
137 private void OnAddNewSelected(object enumValue) {
138 _entries.arraySize += 1;
139 SerializedProperty entryProperty = _entries.GetArrayElementAtIndex(_entries.arraySize - 1);
140 SerializedProperty enumValueProperty = entryProperty.FindPropertyRelative("enumValue");
141 enumValueProperty.intValue = (int)enumValue;
142
143 _entries.serializedObject.ApplyModifiedProperties();
144 }
145 }
146}
EnumEventTableEditor(SerializedProperty tableProperty, Type enumType)
The enum event table is unable to properly display itself in the inspector, it instead must be constr...