Skip to content

Instantly share code, notes, and snippets.

@kalineh
Created February 12, 2019 01:28
Show Gist options
  • Select an option

  • Save kalineh/ad5135946f2009c36f755eea0a880998 to your computer and use it in GitHub Desktop.

Select an option

Save kalineh/ad5135946f2009c36f755eea0a880998 to your computer and use it in GitHub Desktop.

Revisions

  1. kalineh created this gist Feb 12, 2019.
    205 changes: 205 additions & 0 deletions EditorEnumDrawer.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,205 @@
    using System;
    using System.Reflection;
    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;

    #if UNITY_EDITOR
    using UnityEditor;

    public class EnumPickerWindow
    : EditorWindow
    {
    private static GUIStyle regularStyle;
    private static GUIStyle selectedStyle;

    private string enumName;
    private List<string> valuesRaw;
    private List<string> valuesFiltered;
    private string filter;

    private EditorWindow parent;
    private Vector2 scroll;

    private System.Action<string> onSelectCallback;

    public void ShowCustom(string name, List<string> values, Rect rect, System.Action<string> onSelect)
    {
    regularStyle = new GUIStyle(EditorStyles.label);
    regularStyle.active = regularStyle.normal;

    selectedStyle = new GUIStyle(EditorStyles.label);
    selectedStyle.normal = selectedStyle.focused;
    selectedStyle.active = selectedStyle.focused;

    enumName = name;
    valuesRaw = new List<string>(values);
    valuesFiltered = new List<string>(values);
    filter = "";
    onSelectCallback = onSelect;

    parent = focusedWindow;

    var screenRect = rect;
    var screenSize = new Vector2(300, 400);

    screenRect.position = GUIUtility.GUIToScreenPoint(screenRect.position);

    ShowAsDropDown(screenRect, screenSize);
    Focus();

    GUI.FocusControl("filter");
    }

    private void OnGUI()
    {
    GUILayout.Label(string.Format("Enum Type: {0}", enumName));

    GUI.SetNextControlName("filter");
    var filterUpdate = GUILayout.TextField(filter);
    if (filterUpdate != filter)
    FilterValues(filterUpdate);

    // always focused
    GUI.FocusControl("filter");

    scroll = GUILayout.BeginScrollView(scroll);

    for (int i = 0; i < valuesFiltered.Count; ++i)
    {
    var value = valuesFiltered[i];
    var style = i == 0 ? selectedStyle : regularStyle;
    var rect = GUILayoutUtility.GetRect(new GUIContent(value), style);

    var clicked = GUI.Button(rect, value);
    if (clicked)
    {
    GUILayout.EndScrollView();

    onSelectCallback(value);
    Close();
    parent.Repaint();
    parent.Focus();

    return;
    }
    }

    GUILayout.EndScrollView();

    if (Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Return)
    {
    if (valuesFiltered.Count > 0)
    onSelectCallback(valuesFiltered[0]);

    Close();
    parent.Repaint();
    parent.Focus();
    }

    if (Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Escape)
    {
    Close();
    parent.Repaint();
    parent.Focus();
    }

    if (workaroundLostFocusFlag)
    Close();
    }

    private bool workaroundLostFocusFlag;

    public void OnLostFocus()
    {
    // removing this because it crashes unity sometimes
    //Close();

    workaroundLostFocusFlag = true;
    this.Repaint();
    }

    private void FilterValues(string filterUpdate)
    {
    filter = filterUpdate;

    var filterLower = filter.ToLower();

    valuesFiltered.Clear();

    for (int i = 0; i < valuesRaw.Count; ++i)
    {
    var value = valuesRaw[i];
    var lower = value.ToLower();
    if (lower.Contains(filterLower))
    valuesFiltered.Add(value);
    }
    }
    }

    [CustomPropertyDrawer(typeof(IconNames))]
    [CustomPropertyDrawer(typeof(ParticleNames))]
    [CustomPropertyDrawer(typeof(TrickNames))]
    [CustomPropertyDrawer(typeof(InventoryDataNames))]
    [CustomPropertyDrawer(typeof(QuestNames))]
    [CustomPropertyDrawer(typeof(AudioNames))]
    [CustomPropertyDrawer(typeof(PrefabNames))]
    public class WaveBreakEnumDrawers
    : EditorEnumDrawer
    {
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
    base.OnGUI(position, property, label);
    }
    }

    public class EditorEnumDrawer
    : PropertyDrawer
    {
    private EnumPickerWindow window;

    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
    var valuesRaw = Enum.GetValues(fieldInfo.FieldType);
    if (valuesRaw.Length <= 0)
    return;

    var valuesStr = new List<string>();
    for (int i = 0; i < valuesRaw.Length; ++i)
    {
    var raw = valuesRaw.GetValue(i);
    var str = raw.ToString();

    valuesStr.Add(str);
    }

    var enumName = fieldInfo.FieldType.FullName;
    var currentIndex = Mathf.Clamp(property.enumValueIndex, 0, valuesStr.Count);
    var currentName = valuesStr[property.enumValueIndex];

    EditorGUI.PrefixLabel(position, label);

    GUI.SetNextControlName(property.propertyPath);

    var fieldRect = new Rect(position.x + EditorGUIUtility.labelWidth, position.y, position.width - EditorGUIUtility.labelWidth, position.height);

    if (GUI.Button(fieldRect, currentName, EditorStyles.popup))
    {
    window = EditorWindow.GetWindow<EnumPickerWindow>();

    System.Action<string> callback = str =>
    {
    var index = valuesStr.IndexOf(str);

    property.serializedObject.Update();
    property.enumValueIndex = index;
    property.serializedObject.ApplyModifiedProperties();
    };

    window.ShowCustom(enumName, valuesStr, fieldRect, callback);
    window.Focus();
    }
    }
    }

    #endif