101 lines
3.7 KiB
C#
101 lines
3.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
namespace Jovian.PopupSystem.Editor {
|
|
/// <summary>
|
|
/// Custom PropertyDrawer for <see cref="PopupElementType"/>. Shows a dropdown with
|
|
/// built-in element types plus a "Custom..." option for free-text entry.
|
|
/// </summary>
|
|
[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<string>(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("<id>k__BackingField");
|
|
}
|
|
}
|
|
}
|