module-inspector/Editor/AbstractPropertyDrawer.cs
Anders Ejlersen c87dd743f6 1.9.2: Added OpenPropertyEditor and fixed some issues regarding using multiple drawers with EditorGUI.PropertyField
- Property: `OpenPropertyEditor` adds a "show"-button next to a `ScriptableObject` or `Component` to open a property window
- Property: Fixed issue, where x PropertyDrawers would invoke each other x times
2024-03-10 14:11:49 +01:00

140 lines
5.3 KiB
C#

using System;
using Module.Inspector.Editor.Utilities;
using UnityEditor;
using UnityEngine;
namespace Module.Inspector.Editor
{
public abstract class AbstractPropertyDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorPropertyUtility.Result result = null;
int propertyHash = EditorPropertyUtility.CalculateHash(property);
bool isRootDrawer = false;
try
{
result = EditorPropertyUtility.Query(fieldInfo);
EAccessType accessType = GetAccessType(property, result);
if (accessType == EAccessType.Hidden)
return;
if (result.IsUsedBy(propertyHash))
{
EditorGUI.PropertyField(position, property, label);
return;
}
isRootDrawer = true;
result.AddUsedBy(propertyHash);
bool prevEnabled = GUI.enabled;
GUI.enabled = prevEnabled && accessType == EAccessType.Enabled;
if (Event.current.type == EventType.Repaint)
{
for (var i = 0; i < result.handleDrawers.Count; i++)
{
EditorPropertyUtility.ResultValue<HandleDrawerPropertyAttribute, HandlePropertyDrawer> value =
result.handleDrawers[i];
HandleDrawerEditor.Add(value.attribute, property, value.drawer);
}
}
label.tooltip = result.tooltip;
for (var i = 0; i < result.predrawerModifiers.Count; i++)
{
EditorPropertyUtility.ResultValue<PredrawerModifierPropertyAttribute,
PredrawerModifierPropertyDrawer> value = result.predrawerModifiers[i];
value.drawer.Modify(value.attribute, property, label);
}
var isValid = true;
var validationError = string.Empty;
for (var i = 0; i < result.validators.Count; i++)
{
EditorPropertyUtility.ResultValue<ValidatePropertyAttribute, ValidatePropertyDrawer> value =
result.validators[i];
if (value.drawer.Validate(value.attribute, property))
continue;
validationError += value.drawer.GetValidationError(value.attribute, property);
isValid = false;
}
Color prevColor = GUI.color;
if (!isValid)
{
if (string.IsNullOrEmpty(label.tooltip))
label.tooltip = validationError;
else
label.tooltip += "\n" + validationError;
EditorIcons.SetErrorIcon(label);
}
if (result.draw != null)
{
if (!result.draw.drawer.Draw(position, result.draw.attribute, property, label, result))
{
GUI.color = Color.red;
var errorContent = new GUIContent(result.draw.drawer.GetErrorMessage(property));
EditorGUI.LabelField(position, label, errorContent);
}
}
else
{
EditorGUI.PropertyField(position, property, label, true);
}
GUI.color = prevColor;
GUI.enabled = prevEnabled;
for (var i = 0; i < result.valueModifiers.Count; i++)
{
EditorPropertyUtility.ResultValue<ValueModifierPropertyAttribute, ValueModifierPropertyDrawer>
value = result.valueModifiers[i];
value.drawer.Modify(value.attribute, property);
}
}
catch (Exception)
{
// Ignore
}
finally
{
if (isRootDrawer && result != null)
result.RemoveUsedBy(propertyHash);
}
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
EditorPropertyUtility.Result result = EditorPropertyUtility.Query(fieldInfo);
EAccessType accessType = GetAccessType(property, result);
return accessType != EAccessType.Hidden ? EditorGUI.GetPropertyHeight(property, label) : 0.0f;
}
private static EAccessType GetAccessType(SerializedProperty property, EditorPropertyUtility.Result result)
{
if (result.accessModifiers.Count == 0)
return EAccessType.Enabled;
EAccessType accessType = 0;
for (var i = 0; i < result.accessModifiers.Count; i++)
{
EditorPropertyUtility.ResultValue<AccessModifierPropertyAttribute, AccessModifierPropertyDrawer> value =
result.accessModifiers[i];
accessType = value.drawer.GetAccessType(value.attribute, property, accessType);
}
return accessType;
}
}
}