// Adapted from https://gist.github.com/kalineh/ad5135946f2009c36f755eea0a880998 using System; using System.Collections.Generic; using System.Linq; #if H3VR_IMPORTED using FistVR; #endif using UnityEditor; using UnityEngine; public class EnumPickerWindow : EditorWindow { private static GUIStyle _regularStyle; private static GUIStyle _selectedStyle; private string _enumName; private string _filter; private Action _onSelectCallback; private EditorWindow _parent; private Vector2 _scroll; private List _valuesFiltered; private List _valuesRaw; 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 (var 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(); } } public void OnLostFocus() { Close(); } public void ShowCustom(string enumName, List values, Rect rect, Action onSelect) { _regularStyle = new GUIStyle(EditorStyles.label); _regularStyle.active = _regularStyle.normal; _selectedStyle = new GUIStyle(EditorStyles.label); _selectedStyle.normal = _selectedStyle.focused; _selectedStyle.active = _selectedStyle.focused; _enumName = enumName; _valuesRaw = new List(values); _valuesFiltered = new List(values); _filter = ""; _onSelectCallback = onSelect; _parent = focusedWindow; var screenRect = rect; var screenSize = new Vector2(400, 400); screenRect.position = GUIUtility.GUIToScreenPoint(screenRect.position); ShowAsDropDown(screenRect, screenSize); Focus(); GUI.FocusControl("filter"); } private void FilterValues(string filterUpdate) { _filter = filterUpdate; var filterLower = _filter.ToLower(); _valuesFiltered.Clear(); foreach (var value in from value in _valuesRaw let lower = value.ToLower() where lower.Contains(filterLower) select value) _valuesFiltered.Add(value); } } public class EnumPicker : PropertyDrawer { private EnumPickerWindow _window; public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { Array valuesRaw = null; Type enumType = fieldInfo.FieldType; // Check if the property is an array or a list if (enumType.IsArray) enumType = enumType.GetElementType(); else if (enumType.IsGenericType && enumType.GetGenericTypeDefinition() == typeof(List<>)) enumType = enumType.GetGenericArguments()[0]; if (enumType == null || !enumType.IsEnum) { Debug.LogError("Can't determine how to draw a field for " + fieldInfo.FieldType); return; } valuesRaw = Enum.GetValues(enumType); if (valuesRaw.Length <= 0) return; var valuesStr = new List(); for (var i = 0; i < valuesRaw.Length; ++i) { object raw = valuesRaw.GetValue(i); var str = raw.ToString(); valuesStr.Add(str); } string enumName = enumType.Name; string currentName = Enum.GetName(enumType, property.intValue); 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(); Action callback = str => { var index = (int) Convert.ChangeType(Enum.Parse(enumType, str), enumType); property.serializedObject.Update(); property.intValue = index; property.serializedObject.ApplyModifiedProperties(); }; _window.ShowCustom(enumName, valuesStr, fieldRect, callback); _window.Focus(); } } } #if H3VR_IMPORTED [CustomPropertyDrawer(typeof(FireArmMagazineType))] [CustomPropertyDrawer(typeof(FireArmClipType))] [CustomPropertyDrawer(typeof(FireArmRoundClass))] [CustomPropertyDrawer(typeof(ItemSpawnerObjectDefinition.ItemSpawnerCategory))] [CustomPropertyDrawer(typeof(ItemSpawnerID.EItemCategory))] [CustomPropertyDrawer(typeof(ItemSpawnerID.ESubCategory))] [CustomPropertyDrawer(typeof(FireArmRoundType))] [CustomPropertyDrawer(typeof(SosigEnemyID))] [CustomPropertyDrawer(typeof(FVRFireArmAttachementMountType))] public class EnumDrawers : EnumPicker { } #endif