using System; using System.Linq; using System.Reflection; using Module.Inspector.Editor.Utilities; using UnityEditor; using UnityEngine; namespace Module.Inspector.Editor { [CustomPropertyDrawer(typeof(PopupFromConstAttribute))] internal sealed class PopupFromConstAttributeDrawer : DrawerPropertyDrawer { private GUIContent[] names; private string[] values; public override bool Draw(Rect position, DrawerPropertyAttribute attribute, SerializedProperty property, GUIContent label, EditorPropertyUtility.Result result) { if (property.propertyType != SerializedPropertyType.String) return false; var att = (PopupFromConstAttribute)attribute; FetchConstArray(att); EditorGUI.BeginChangeCheck(); EditorGUI.BeginProperty(position, label, property); { int index = Array.IndexOf(values, property.stringValue); int newIndex = EditorGUI.Popup(position, label, index, names); if (newIndex != -1 && index != newIndex) property.stringValue = values[newIndex]; } EditorGUI.EndProperty(); bool changed = EditorGUI.EndChangeCheck(); if (changed) property.serializedObject.ApplyModifiedProperties(); return true; } public override string GetErrorMessage(SerializedProperty property) { return "Only supports integers"; } private void FetchConstArray(PopupFromConstAttribute attribute) { if (names != null) return; FieldInfo[] fields = attribute.type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy) .Where(fi => fi.IsLiteral && !fi.IsInitOnly && fi.FieldType == typeof(string)) .ToArray(); names = new GUIContent[fields.Length + 1]; values = new string[fields.Length + 1]; names[0] = new GUIContent("-- Empty --"); values[0] = string.Empty; for (var i = 0; i < fields.Length; i++) { FieldInfo fi = fields[i]; var value = (string)fi.GetValue(null); names[i + 1] = new GUIContent(value); values[i + 1] = value; } } } }