using System; using System.Collections.Generic; using System.Linq; using UnityEditor; using UnityEngine; using VContainer.Unity; namespace VContainer.Editor { [CustomPropertyDrawer(typeof(ParentReference))] public sealed class ParentReferencePropertyDrawer : PropertyDrawer { static string[] GetAllTypeNames() { return new List { "None" } .Concat(TypeCache.GetTypesDerivedFrom() .Where(x => !x.IsAbstract) .Select(type => type.FullName)) .ToArray(); } static string GetLabel(Type type) => $"{type.Namespace}/{type.Name}"; string[] names; public override void OnGUI(Rect rect, SerializedProperty prop, GUIContent label) { if (names == null) { names = GetAllTypeNames(); if (prop.serializedObject.targetObject is LifetimeScope lifetimeScope) { var lifetimeScopeName = lifetimeScope.GetType().FullName; names = names.Where(name => name != lifetimeScopeName).ToArray(); } } var typeNameProp = prop.FindPropertyRelative("TypeName"); using (new EditorGUI.PropertyScope(rect, label, prop)) { var labelRect = new Rect(rect.x, rect.y, rect.width, 18f); var popupRect = new Rect(rect.x, rect.y + labelRect.height, rect.width , 18f); var index = Array.IndexOf(names, typeNameProp.stringValue); if (index < 0) index = 0; EditorGUI.LabelField(labelRect, "Parent"); using (var check = new EditorGUI.ChangeCheckScope()) { index = EditorGUI.Popup(popupRect, index, names); if (check.changed) { typeNameProp.stringValue = names[index]; } } } } public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { return 18f + 18f + 4f; } } }