NodeEnumDrawer.cs 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEditor;
  5. using UnityEngine;
  6. using XNode;
  7. using XNodeEditor;
  8. namespace XNodeEditor {
  9. [CustomPropertyDrawer(typeof(NodeEnumAttribute))]
  10. public class NodeEnumDrawer : PropertyDrawer {
  11. public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
  12. EditorGUI.BeginProperty(position, label, property);
  13. EnumPopup(position, property, label);
  14. EditorGUI.EndProperty();
  15. }
  16. public static void EnumPopup(Rect position, SerializedProperty property, GUIContent label) {
  17. // Throw error on wrong type
  18. if (property.propertyType != SerializedPropertyType.Enum) {
  19. throw new ArgumentException("Parameter selected must be of type System.Enum");
  20. }
  21. // Add label
  22. position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
  23. // Get current enum name
  24. string enumName = "";
  25. if (property.enumValueIndex >= 0 && property.enumValueIndex < property.enumDisplayNames.Length) enumName = property.enumDisplayNames[property.enumValueIndex];
  26. #if UNITY_2017_1_OR_NEWER
  27. // Display dropdown
  28. if (EditorGUI.DropdownButton(position, new GUIContent(enumName), FocusType.Passive)) {
  29. // Position is all wrong if we show the dropdown during the node draw phase.
  30. // Instead, add it to onLateGUI to display it later.
  31. NodeEditorWindow.current.onLateGUI += () => ShowContextMenuAtMouse(property);
  32. }
  33. #else
  34. // Display dropdown
  35. if (GUI.Button(position, new GUIContent(enumName), "MiniPopup")) {
  36. // Position is all wrong if we show the dropdown during the node draw phase.
  37. // Instead, add it to onLateGUI to display it later.
  38. NodeEditorWindow.current.onLateGUI += () => ShowContextMenuAtMouse(property);
  39. }
  40. #endif
  41. }
  42. public static void ShowContextMenuAtMouse(SerializedProperty property) {
  43. // Initialize menu
  44. GenericMenu menu = new GenericMenu();
  45. // Add all enum display names to menu
  46. for (int i = 0; i < property.enumDisplayNames.Length; i++) {
  47. int index = i;
  48. menu.AddItem(new GUIContent(property.enumDisplayNames[i]), false, () => SetEnum(property, index));
  49. }
  50. // Display at cursor position
  51. Rect r = new Rect(Event.current.mousePosition, new Vector2(0, 0));
  52. menu.DropDown(r);
  53. }
  54. private static void SetEnum(SerializedProperty property, int index) {
  55. property.enumValueIndex = index;
  56. property.serializedObject.ApplyModifiedProperties();
  57. property.serializedObject.Update();
  58. }
  59. }
  60. }