using Jovian.EncounterSystem; using UnityEditor; using UnityEngine; namespace Jovian.EncounterSystem.Editor { /// /// Draws each list element with its /// as the foldout label (falling back to name, then the default element label). /// Children are iterated manually to avoid recursing into this drawer. /// [CustomPropertyDrawer(typeof(Encounter))] public class EncounterDrawer : PropertyDrawer { private const string DefinitionBackingField = "k__BackingField"; public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { var displayLabel = ResolveLabel(property, label); var foldoutRect = new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight); property.isExpanded = EditorGUI.Foldout(foldoutRect, property.isExpanded, displayLabel, true); if(!property.isExpanded) { return; } EditorGUI.indentLevel++; var y = position.y + EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; var iterator = property.Copy(); var end = iterator.GetEndProperty(); if(iterator.NextVisible(true)) { while(!SerializedProperty.EqualContents(iterator, end)) { var h = EditorGUI.GetPropertyHeight(iterator, true); var r = new Rect(position.x, y, position.width, h); EditorGUI.PropertyField(r, iterator, true); y += h + EditorGUIUtility.standardVerticalSpacing; if(!iterator.NextVisible(false)) { break; } } } EditorGUI.indentLevel--; } public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { var height = EditorGUIUtility.singleLineHeight; if(!property.isExpanded) { return height; } var iterator = property.Copy(); var end = iterator.GetEndProperty(); if(iterator.NextVisible(true)) { while(!SerializedProperty.EqualContents(iterator, end)) { height += EditorGUI.GetPropertyHeight(iterator, true) + EditorGUIUtility.standardVerticalSpacing; if(!iterator.NextVisible(false)) { break; } } } return height; } private static GUIContent ResolveLabel(SerializedProperty property, GUIContent fallback) { var definition = property.FindPropertyRelative(DefinitionBackingField); if(definition == null) { return fallback; } var id = definition.FindPropertyRelative("id")?.stringValue; if(!string.IsNullOrEmpty(id)) { return new GUIContent(id); } var name = definition.FindPropertyRelative("name")?.stringValue; if(!string.IsNullOrEmpty(name)) { return new GUIContent(name); } return fallback; } } }