Tri-Inspector/Editor/Elements/TriPropertyElement.cs

168 lines
5.0 KiB
C#

using System;
using TriInspector.Utilities;
using UnityEditor;
using UnityEngine;
namespace TriInspector.Elements
{
public class TriPropertyElement : TriElement
{
private readonly TriProperty _property;
[Serializable]
public struct Props
{
public bool forceInline;
}
public TriPropertyElement(TriProperty property, Props props = default)
{
_property = property;
var element = CreateElement(property, props);
var drawers = property.AllDrawers;
for (var index = drawers.Count - 1; index >= 0; index--)
{
var drawer = drawers[index];
var canDrawMessage = drawer.CanDraw(_property);
if (!string.IsNullOrEmpty(canDrawMessage))
{
AddChild(new TriInfoBoxElement(canDrawMessage, TriMessageType.Error));
continue;
}
element = drawer.CreateElementInternal(property, element);
}
AddChild(element);
}
public override float GetHeight(float width)
{
if (!_property.IsVisible)
{
return 0f;
}
return base.GetHeight(width);
}
public override void OnGUI(Rect position)
{
if (!_property.IsVisible)
{
return;
}
var oldShowMixedValue = EditorGUI.showMixedValue;
var oldEnabled = GUI.enabled;
GUI.enabled &= _property.IsEnabled;
EditorGUI.showMixedValue = _property.IsValueMixed;
using (TriPropertyOverrideContext.BeginProperty())
{
base.OnGUI(position);
}
EditorGUI.showMixedValue = oldShowMixedValue;
GUI.enabled = oldEnabled;
}
private static TriElement CreateElement(TriProperty property, Props props)
{
var isSerializedProperty = property.TryGetSerializedProperty(out var serializedProperty);
var handler = isSerializedProperty
? ScriptAttributeUtilityProxy.GetHandler(serializedProperty)
: default(PropertyHandlerProxy?);
if (!handler.HasValue || !handler.Value.hasPropertyDrawer)
{
var propertyType = property.PropertyType;
switch (propertyType)
{
case TriPropertyType.Array:
{
return CreateArrayElement(property);
}
case TriPropertyType.Reference:
{
return CreateReferenceElement(property, props);
}
case TriPropertyType.Generic:
{
return CreateGenericElement(property, props);
}
}
}
if (isSerializedProperty)
{
return new TriBuiltInPropertyElement(property, serializedProperty, handler.Value);
}
return new TriNoDrawerElement(property);
}
private static TriElement CreateArrayElement(TriProperty property)
{
return new TriListElement(property);
}
private static TriElement CreateReferenceElement(TriProperty property, Props props)
{
if (property.TryGetAttribute(out InlinePropertyAttribute inlineAttribute))
{
return new TriReferenceElement(property, new TriReferenceElement.Props
{
inline = true,
drawPrefixLabel = !props.forceInline,
labelWidth = inlineAttribute.LabelWidth,
});
}
if (props.forceInline)
{
return new TriReferenceElement(property, new TriReferenceElement.Props
{
inline = true,
drawPrefixLabel = false,
});
}
return new TriReferenceElement(property, new TriReferenceElement.Props
{
inline = false,
drawPrefixLabel = false,
});
}
private static TriElement CreateGenericElement(TriProperty property, Props props)
{
if (property.TryGetAttribute(out InlinePropertyAttribute inlineAttribute))
{
return new TriInlineGenericElement(property, new TriInlineGenericElement.Props
{
drawPrefixLabel = !props.forceInline,
labelWidth = inlineAttribute.LabelWidth,
});
}
if (props.forceInline)
{
return new TriInlineGenericElement(property, new TriInlineGenericElement.Props
{
drawPrefixLabel = false,
});
}
return new TriFoldoutElement(property);
}
}
}