1+ using System ;
2+ using System . Collections . Generic ;
3+ using System . Linq ;
4+ using UnityEditor ;
5+ using UnityEngine ;
6+
7+ namespace FishingCactus . CommonCode
8+ {
9+ [ CustomPropertyDrawer ( typeof ( SubClassPicker ) ) ]
10+ public class SubClassPickerDrawer : PropertyDrawer
11+ {
12+ private const string DefaultDisplay = "Pick a type" ;
13+
14+ private IEnumerable < Type > GetSubClasses (
15+ Type base_type
16+ )
17+ {
18+ if ( ReflectionUtils . IsCollectionType ( base_type )
19+ && ! ReflectionUtils . TryGetEnumerableElementType ( base_type , out base_type )
20+ )
21+ {
22+ return Enumerable . Empty < Type > ( ) ;
23+ }
24+
25+ return TypeCache . GetTypesDerivedFrom ( base_type )
26+ . Where ( type => type . IsClass && ! type . IsAbstract ) ;
27+ }
28+
29+ public override float GetPropertyHeight (
30+ SerializedProperty property ,
31+ GUIContent label
32+ )
33+ {
34+ return EditorGUI . GetPropertyHeight ( property , label ) ;
35+ }
36+
37+ public override void OnGUI (
38+ Rect position ,
39+ SerializedProperty property ,
40+ GUIContent label
41+ )
42+ {
43+ Type field_type = fieldInfo . FieldType ;
44+
45+ string type_name = property . managedReferenceValue ? . GetType ( ) . Name ?? DefaultDisplay ;
46+
47+ Rect drop_down_rect = position ;
48+
49+ drop_down_rect . x += EditorGUIUtility . labelWidth + 2 ;
50+ drop_down_rect . width -= EditorGUIUtility . labelWidth + 2 ;
51+ drop_down_rect . height = EditorGUIUtility . singleLineHeight ;
52+
53+ bool previous_show_mixed_values = EditorGUI . showMixedValue ;
54+ EditorGUI . showMixedValue = property . hasMultipleDifferentValues ;
55+
56+ using ( new EditorGUI . DisabledGroupScope ( property . hasMultipleDifferentValues ) )
57+ {
58+ if ( EditorGUI . DropdownButton ( drop_down_rect , new ( type_name ) , FocusType . Keyboard ) )
59+ {
60+ GenericMenu menu = new GenericMenu ( ) ;
61+ menu . AddItem ( new GUIContent ( "None" ) , property . managedReferenceValue == null , ( ) =>
62+ {
63+ property . managedReferenceValue = null ;
64+ property . serializedObject . ApplyModifiedProperties ( ) ;
65+ } ) ;
66+
67+ foreach ( Type type in GetSubClasses ( field_type ) )
68+ {
69+ menu . AddItem ( new GUIContent ( type . Name ) , type_name == type . Name , ( ) =>
70+ {
71+ property . managedReferenceValue = type . GetConstructor ( Type . EmptyTypes ) . Invoke ( null ) ;
72+ property . serializedObject . ApplyModifiedProperties ( ) ;
73+ } ) ;
74+ }
75+
76+ menu . ShowAsContext ( ) ;
77+ }
78+ }
79+
80+ EditorGUI . PropertyField ( position , property , label , true ) ;
81+
82+ EditorGUI . showMixedValue = previous_show_mixed_values ;
83+ }
84+ }
85+ }
0 commit comments