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

167 lines
5.9 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
{
private ComponentTemplateReferenceDrawer _drawer = new ComponentTemplateReferenceDrawer();
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;
private static ComponentTemplatesDropDown _componentDropDown;
2024-05-16 19:59:57 +08:00
2024-10-02 14:01:18 +08:00
#region Properties
private float SingleLineWithPadding => OneLineHeight + Padding * 4f;
private float Padding => Spacing;
2024-10-02 14:01:18 +08:00
protected override bool IsStaticInit => _componentDropDown != null;
#endregion
2024-05-16 19:03:03 +08:00
#region Init
protected override void OnStaticInit()
2024-05-16 19:03:03 +08:00
{
_componentDropDown = new ComponentTemplatesDropDown();
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;
2024-09-12 01:35:37 +08:00
currentProperty.managedReferenceValue = item.Obj.Clone();
2024-05-16 19:03:03 +08:00
currentProperty.isExpanded = false;
currentProperty.serializedObject.ApplyModifiedProperties();
}
2024-09-12 01:35:37 +08:00
2024-05-16 19:03:03 +08:00
#endregion
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
2024-10-02 14:01:18 +08:00
#region No SerializeReference
if (property.propertyType != SerializedPropertyType.ManagedReference)
2024-05-17 00:50:05 +08:00
{
return EditorGUI.GetPropertyHeight(property, label);
}
2024-10-02 14:01:18 +08:00
#endregion
var instance = property.managedReferenceValue;
IComponentTemplate template = instance as IComponentTemplate;
if (template == null || instance == null)
2024-05-16 19:03:03 +08:00
{
return EditorGUIUtility.singleLineHeight + Padding * 2f;
}
try
{
2024-10-02 14:01:18 +08:00
if (instance is ComponentTemplateBase customTemplate)
2024-05-16 19:03:03 +08:00
{
property = property.FindPropertyRelative("component");
}
}
2024-10-02 14:01:18 +08:00
catch
2024-05-16 19:03:03 +08:00
{
property = null;
}
if (property == null)
{
return DamagedComponentHeight;
}
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 position, SerializedProperty rootProperty, SerializedProperty property, GUIContent label)
2024-05-16 19:03:03 +08:00
{
2024-10-02 14:01:18 +08:00
#region No SerializeReference
if (property.propertyType != SerializedPropertyType.ManagedReference)
2024-05-17 00:50:05 +08:00
{
2024-10-02 14:01:18 +08:00
EditorGUI.PropertyField(position, property, label, true);
2024-05-17 00:50:05 +08:00
return;
}
2024-10-02 14:01:18 +08:00
#endregion
2024-05-17 00:50:05 +08:00
2024-10-02 14:01:18 +08:00
var instance = property.managedReferenceValue;
IComponentTemplate template = instance as IComponentTemplate;
2024-05-16 19:03:03 +08:00
2024-10-02 14:01:18 +08:00
if (template == null || instance == null)
2024-05-16 19:03:03 +08:00
{
2024-10-02 14:01:18 +08:00
DrawSelectionPopup(position, property, label);
2024-05-16 19:03:03 +08:00
return;
}
2024-10-02 14:01:18 +08:00
SerializedProperty componentProp = property;
if (componentProp.managedReferenceValue is ComponentTemplateBase customTemplate)
2024-05-16 19:03:03 +08:00
{
2024-10-02 14:01:18 +08:00
componentProp = property.FindPropertyRelative("component");
2024-05-16 19:03:03 +08:00
}
2024-10-02 14:01:18 +08:00
if (componentProp == null)
2024-05-16 19:03:03 +08:00
{
DrawDamagedComponent(position, "Damaged component template.");
return;
}
ITypeMeta meta = template is ITypeMeta metaOverride ? metaOverride : template.Type.ToMeta();
2024-10-02 14:01:18 +08:00
Rect rect = position;
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