DragonECS-Unity/src/Templates/EntityTemplate/Editor/ComponentTemplatePropertyDrawer.cs

208 lines
7.7 KiB
C#
Raw Normal View History

2024-05-16 19:03:03 +08:00
#if UNITY_EDITOR
using DCFApixels.DragonECS.Unity.Internal;
using System;
using UnityEditor;
using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Editors
{
2024-05-16 19:59:57 +08:00
[CustomPropertyDrawer(typeof(ComponentTemplateProperty), true)]
2024-10-02 14:01:18 +08:00
internal class ComponentTemplatePropertyDrawer : ExtendedPropertyDrawer
2024-05-16 19:59:57 +08:00
{
2026-03-30 20:11:16 +08:00
private ComponentTemplateReferenceDrawer _drawer = new ComponentTemplateReferenceDrawer(new PredicateTypesKey(new Type[] { typeof(ITemplateNode) }));
2024-05-16 19:59:57 +08:00
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
property.Next(true);
2024-10-02 14:01:18 +08:00
_drawer.StaticInit();
_drawer.Init();
2024-05-16 19:59:57 +08:00
return _drawer.GetPropertyHeight(property, label);
}
2024-10-02 14:01:18 +08:00
protected override void DrawCustom(Rect position, SerializedProperty property, GUIContent label)
2024-05-16 19:59:57 +08:00
{
2024-10-02 14:01:18 +08:00
var root = property.Copy();
2024-05-16 19:59:57 +08:00
property.Next(true);
2024-10-02 14:01:18 +08:00
_drawer.StaticInit();
_drawer.Init();
_drawer.Draw(position, root, property, label);
2024-05-16 19:59:57 +08:00
}
}
2024-05-16 19:03:03 +08:00
[CustomPropertyDrawer(typeof(ComponentTemplateReferenceAttribute), true)]
internal class ComponentTemplateReferenceDrawer : ExtendedPropertyDrawer<ComponentTemplateReferenceAttribute>
2024-05-16 19:03:03 +08:00
{
private const float DamagedComponentHeight = 18f * 2f;
2026-03-30 20:11:16 +08:00
private ComponentTemplatesDropDown _componentDropDown;
private PredicateTypesKey? _predicateOverride;
2024-05-16 19:59:57 +08:00
2024-10-02 14:01:18 +08:00
#region Properties
private float Padding => Spacing;
2026-03-30 20:11:16 +08:00
protected override bool IsInit => _componentDropDown != null;
2024-10-02 14:01:18 +08:00
#endregion
2026-03-30 20:11:16 +08:00
public ComponentTemplateReferenceDrawer() { }
public ComponentTemplateReferenceDrawer(PredicateTypesKey key)
{
_predicateOverride = key;
}
2024-05-16 19:03:03 +08:00
#region Init
2026-03-30 20:11:16 +08:00
protected override void OnInit()
2024-05-16 19:03:03 +08:00
{
2026-03-30 20:11:16 +08:00
PredicateTypesKey key;
if(_predicateOverride == null)
{
Type[] withOutTypes = Type.EmptyTypes;
if (fieldInfo != null)
{
withOutTypes = fieldInfo.TryGetAttribute(out ReferenceButtonWithOutAttribute a) ? a.PredicateTypes : Array.Empty<Type>();
}
if (Attribute != null)
{
var types = Attribute.PredicateTypes;
if(types == null || types.Length == 0)
{
types = new Type[] { typeof(ITemplateNode) };
}
key = new PredicateTypesKey(types, withOutTypes);
}
else
{
key = new PredicateTypesKey(new Type[] { typeof(object) }, withOutTypes);
}
_predicateOverride = key;
}
_componentDropDown = ComponentTemplatesDropDown.Get(_predicateOverride.Value);
2024-09-12 01:35:37 +08:00
_componentDropDown.OnSelected += SelectComponent;
2024-05-16 19:03:03 +08:00
}
2024-05-16 19:03:03 +08:00
[ThreadStatic]
private static SerializedProperty currentProperty;
private static void SelectComponent(ComponentTemplatesDropDown.Item item)
2024-05-16 19:03:03 +08:00
{
//EcsGUI.Changed = true;
2026-03-30 20:11:16 +08:00
object inst = item.Obj.CreateInstance();
currentProperty.managedReferenceValue = inst;
2024-05-16 19:03:03 +08:00
currentProperty.isExpanded = false;
currentProperty.serializedObject.ApplyModifiedProperties();
}
#endregion
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
bool isSerializeReference = property.propertyType == SerializedPropertyType.ManagedReference;
//#region No SerializeReference
//if (property.propertyType != SerializedPropertyType.ManagedReference)
//{
// return EditorGUI.GetPropertyHeight(property, label);
//}
//#endregion
if (isSerializeReference)
2024-05-17 00:50:05 +08:00
{
var instance = property.managedReferenceValue;
IComponentTemplate template = instance as IComponentTemplate;
if (instance == null)
{
return EditorGUIUtility.singleLineHeight + Padding * 2f;
}
2024-05-16 19:03:03 +08:00
try
2024-05-16 19:03:03 +08:00
{
if (instance is ComponentTemplateBase customTemplate)
{
property = property.FindPropertyRelative("component");
}
}
catch
{
property = null;
}
if (property == null)
{
return DamagedComponentHeight;
2024-05-16 19:03:03 +08:00
}
}
2024-05-16 19:59:57 +08:00
int propCount = EcsGUI.GetChildPropertiesCount(property);
2024-05-16 19:03:03 +08:00
2024-05-16 19:59:57 +08:00
return (propCount <= 0 ? EditorGUIUtility.singleLineHeight : EditorGUI.GetPropertyHeight(property, label)) + Padding * 4f;
2024-05-16 19:03:03 +08:00
}
2024-10-02 14:01:18 +08:00
protected override void DrawCustom(Rect position, SerializedProperty property, GUIContent label)
{
Draw(position, property, property, label);
}
public void Draw(Rect rect, SerializedProperty rootProperty, SerializedProperty property, GUIContent label)
2024-05-16 19:03:03 +08:00
{
bool isSerializeReference = property.propertyType == SerializedPropertyType.ManagedReference;
//#region No SerializeReference
//if (isSerializeReference == false)
//{
// EditorGUI.PropertyField(position, property, label, true);
// return;
//}
//#endregion
ITypeMeta meta = null;
SerializedProperty componentProp = property;
if (isSerializeReference)
2024-05-17 00:50:05 +08:00
{
var instance = property.managedReferenceValue;
if (instance == null)
{
DrawSelectionPopup(rect, property, label);
return;
}
2024-05-16 19:03:03 +08:00
IComponentTemplate template = instance as IComponentTemplate;
if (componentProp.managedReferenceValue is ComponentTemplateBase customTemplate)
{
componentProp = property.FindPropertyRelative("component");
}
if (componentProp == null)
{
DrawDamagedComponent(rect, "Damaged component template.");
return;
}
2024-05-16 19:03:03 +08:00
2026-03-30 20:11:16 +08:00
meta = template is ITypeMeta metaOverride ? metaOverride : _predicateOverride.Value.Types[0].GetMeta();
2024-05-16 19:03:03 +08:00
}
else
2024-05-16 19:03:03 +08:00
{
meta = fieldInfo.FieldType.GetMeta();
2024-05-16 19:03:03 +08:00
}
2024-10-02 14:01:18 +08:00
if (EcsGUI.DrawTypeMetaBlock(ref rect, rootProperty, meta))
2024-06-15 18:43:29 +08:00
{
2024-06-15 19:18:28 +08:00
return;
2024-06-15 18:43:29 +08:00
}
2024-06-15 19:30:59 +08:00
2024-10-02 14:01:18 +08:00
label.text = meta.Name;
if (componentProp.propertyType == SerializedPropertyType.Generic)
2024-05-16 19:03:03 +08:00
{
2024-10-02 14:01:18 +08:00
EditorGUI.PropertyField(rect, componentProp, label, true);
2024-05-17 00:18:44 +08:00
}
else
{
2024-10-02 14:01:18 +08:00
EditorGUI.PropertyField(rect.AddPadding(0, 20f, 0, 0), componentProp, label, true);
2024-05-16 19:03:03 +08:00
}
}
2024-10-02 14:01:18 +08:00
private void DrawSelectionPopup(Rect position, SerializedProperty property, GUIContent label)
2024-05-16 19:03:03 +08:00
{
EditorGUI.LabelField(position, label);
Rect buttonRect = RectUtility.AddPadding(position, EditorGUIUtility.labelWidth, 0f, 0f, 0f);
if (GUI.Button(buttonRect, "Select"))
{
2024-10-02 14:01:18 +08:00
currentProperty = property;
2024-09-12 01:35:37 +08:00
_componentDropDown.Show(buttonRect);
2024-05-16 19:03:03 +08:00
}
}
private void DrawDamagedComponent(Rect position, string message)
{
EditorGUI.HelpBox(position, message, MessageType.Warning);
}
}
}
#endif