using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace Jovian.PopupSystem.Editor {
///
/// Custom PropertyDrawer for . Shows a dropdown with
/// built-in element types plus a "Custom..." option for free-text entry.
///
[CustomPropertyDrawer(typeof(PopupElementType))]
public sealed class PopupElementTypeDrawer : PropertyDrawer {
private static readonly string[] builtInIds = {
"header",
"text",
"label_value_text",
"image",
"separator"
};
private const string customLabel = "Custom...";
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) {
var idProp = FindIdProperty(property);
if(idProp == null) {
return EditorGUIUtility.singleLineHeight;
}
var currentValue = idProp.stringValue ?? "";
var isCustom = Array.IndexOf(builtInIds, currentValue) < 0 && !string.IsNullOrEmpty(currentValue);
return isCustom
? EditorGUIUtility.singleLineHeight * 2 + 2
: EditorGUIUtility.singleLineHeight;
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
EditorGUI.BeginProperty(position, label, property);
var idProp = FindIdProperty(property);
if(idProp == null) {
EditorGUI.LabelField(position, label.text, "Cannot resolve PopupElementType id field");
EditorGUI.EndProperty();
return;
}
var currentValue = idProp.stringValue ?? "";
var builtInIndex = Array.IndexOf(builtInIds, currentValue);
var isCustom = builtInIndex < 0 && !string.IsNullOrEmpty(currentValue);
var options = new List(builtInIds);
options.Add(customLabel);
int selectedIndex;
if(builtInIndex >= 0) {
selectedIndex = builtInIndex;
}
else {
selectedIndex = options.Count - 1;
}
var dropdownRect = new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight);
var newIndex = EditorGUI.Popup(dropdownRect, label.text, selectedIndex, options.ToArray());
if(newIndex != selectedIndex) {
if(newIndex < builtInIds.Length) {
idProp.stringValue = builtInIds[newIndex];
}
else {
if(!isCustom) {
idProp.stringValue = "custom_element";
}
}
}
var finalIsCustom = newIndex >= builtInIds.Length || (newIndex == selectedIndex && isCustom);
if(finalIsCustom) {
var textRect = new Rect(
position.x + EditorGUIUtility.labelWidth + 2,
position.y + EditorGUIUtility.singleLineHeight + 2,
position.width - EditorGUIUtility.labelWidth - 2,
EditorGUIUtility.singleLineHeight);
var newValue = EditorGUI.TextField(textRect, idProp.stringValue);
if(newValue != idProp.stringValue) {
idProp.stringValue = newValue;
}
}
EditorGUI.EndProperty();
}
private static SerializedProperty FindIdProperty(SerializedProperty property) {
var prop = property.FindPropertyRelative("id");
if(prop != null) {
return prop;
}
return property.FindPropertyRelative("k__BackingField");
}
}
}