2024-05-16 19:03:03 +08:00
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
using DCFApixels.DragonECS.Unity.Internal;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
using UnityEditor;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
|
|
|
|
namespace DCFApixels.DragonECS.Unity.Editors
|
|
|
|
|
{
|
2024-05-16 19:59:57 +08:00
|
|
|
|
[CustomPropertyDrawer(typeof(ComponentTemplateProperty), true)]
|
|
|
|
|
internal class ComponentTemplatePropertyDrawer : PropertyDrawer
|
|
|
|
|
{
|
|
|
|
|
private ComponentTemplateReferenceDrawer _drawer = new ComponentTemplateReferenceDrawer();
|
|
|
|
|
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
|
|
|
|
{
|
|
|
|
|
property.Next(true);
|
|
|
|
|
return _drawer.GetPropertyHeight(property, label);
|
|
|
|
|
}
|
|
|
|
|
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
|
|
|
|
{
|
|
|
|
|
property.Next(true);
|
|
|
|
|
_drawer.OnGUI(position, property, label);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-16 19:03:03 +08:00
|
|
|
|
[CustomPropertyDrawer(typeof(ComponentTemplateReferenceAttribute), true)]
|
2024-05-16 19:59:57 +08:00
|
|
|
|
internal class ComponentTemplateReferenceDrawer : PropertyDrawer
|
2024-05-16 19:03:03 +08:00
|
|
|
|
{
|
|
|
|
|
private static readonly Rect HeadIconsRect = new Rect(0f, 0f, 19f, 19f);
|
|
|
|
|
|
|
|
|
|
private float Padding => EditorGUIUtility.standardVerticalSpacing;
|
2024-05-17 00:18:44 +08:00
|
|
|
|
private float SingleLineWithPadding => EditorGUIUtility.singleLineHeight + Padding * 4f;
|
2024-05-16 19:03:03 +08:00
|
|
|
|
|
|
|
|
|
private const float DamagedComponentHeight = 18f * 2f;
|
|
|
|
|
|
|
|
|
|
private static bool _isInit;
|
|
|
|
|
private static GenericMenu _genericMenu;
|
2024-05-16 19:59:57 +08:00
|
|
|
|
|
2024-05-16 19:03:03 +08:00
|
|
|
|
#region Init
|
|
|
|
|
private static void Init()
|
|
|
|
|
{
|
|
|
|
|
if (_genericMenu == null) { _isInit = false; }
|
|
|
|
|
if (_isInit) { return; }
|
|
|
|
|
|
|
|
|
|
_genericMenu = new GenericMenu();
|
|
|
|
|
|
|
|
|
|
var componentTemplateDummies = ComponentTemplateTypeCache.Dummies;
|
|
|
|
|
foreach (var dummy in componentTemplateDummies)
|
|
|
|
|
{
|
|
|
|
|
if (dummy.Type.GetCustomAttribute<SerializableAttribute>() == null)
|
|
|
|
|
{
|
|
|
|
|
Debug.LogWarning($"Type {dummy.Type.Name} does not have the [Serializable] attribute");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
ITypeMeta meta = dummy is ITypeMeta metaOverride ? metaOverride : dummy.Type.ToMeta();
|
|
|
|
|
string name = meta.Name;
|
|
|
|
|
string description = meta.Description.Text;
|
|
|
|
|
MetaGroup group = meta.Group;
|
|
|
|
|
|
|
|
|
|
if (group.Name.Length > 0)
|
|
|
|
|
{
|
|
|
|
|
name = group.Name + name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(description) == false)
|
|
|
|
|
{
|
|
|
|
|
name = $"{name} [i]";
|
|
|
|
|
}
|
|
|
|
|
_genericMenu.AddItem(new GUIContent(name, description), false, SelectComponent, dummy);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_isInit = true;
|
|
|
|
|
}
|
|
|
|
|
[ThreadStatic]
|
|
|
|
|
private static SerializedProperty currentProperty;
|
|
|
|
|
private static void SelectComponent(object dummy)
|
|
|
|
|
{
|
|
|
|
|
currentProperty.managedReferenceValue = ((IComponentTemplate)dummy).Clone();
|
|
|
|
|
currentProperty.isExpanded = false;
|
|
|
|
|
currentProperty.serializedObject.ApplyModifiedProperties();
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
|
|
|
|
{
|
|
|
|
|
IComponentTemplate template = property.managedReferenceValue as IComponentTemplate;
|
|
|
|
|
if (template == null || property.managedReferenceValue == null)
|
|
|
|
|
{
|
|
|
|
|
return EditorGUIUtility.singleLineHeight + Padding * 2f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
ComponentTemplateBase customTemplate = property.managedReferenceValue as ComponentTemplateBase;
|
|
|
|
|
if (customTemplate != null)
|
|
|
|
|
{
|
|
|
|
|
property = property.FindPropertyRelative("component");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception)
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public override void OnGUI(Rect position, SerializedProperty componentRefProp, GUIContent label)
|
|
|
|
|
{
|
|
|
|
|
Init();
|
|
|
|
|
var counter = componentRefProp.Copy();
|
|
|
|
|
|
|
|
|
|
int positionCountr = int.MaxValue;
|
|
|
|
|
while (counter.NextVisible(false))
|
|
|
|
|
{
|
|
|
|
|
positionCountr--;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IComponentTemplate template = componentRefProp.managedReferenceValue as IComponentTemplate;
|
|
|
|
|
if (template == null || componentRefProp.managedReferenceValue == null)
|
|
|
|
|
{
|
|
|
|
|
DrawSelectionPopup(position, componentRefProp, label);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Type componentType;
|
|
|
|
|
SerializedProperty componentProperty = componentRefProp;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
ComponentTemplateBase customTemplate = componentProperty.managedReferenceValue as ComponentTemplateBase;
|
|
|
|
|
if (customTemplate != null)
|
|
|
|
|
{
|
|
|
|
|
componentProperty = componentRefProp.FindPropertyRelative("component");
|
|
|
|
|
componentType = customTemplate.GetType().GetField("component", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FieldType;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
componentType = componentProperty.managedReferenceValue.GetType();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (componentType == null || componentProperty == null)
|
|
|
|
|
{
|
|
|
|
|
throw new NullReferenceException();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
|
|
|
|
Debug.LogException(e, componentRefProp.serializedObject.targetObject);
|
|
|
|
|
DrawDamagedComponent(position, "Damaged component template.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//сюда попадают уже валидные компоненты
|
|
|
|
|
|
|
|
|
|
ITypeMeta meta = template is ITypeMeta metaOverride ? metaOverride : template.Type.ToMeta();
|
|
|
|
|
string name = meta.Name;
|
|
|
|
|
string description = meta.Description.Text;
|
|
|
|
|
|
2024-05-17 00:18:44 +08:00
|
|
|
|
int propCount = EcsGUI.GetChildPropertiesCount(componentProperty);
|
2024-05-16 19:03:03 +08:00
|
|
|
|
|
|
|
|
|
Color panelColor = EcsGUI.SelectPanelColor(meta, positionCountr, -1).Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE);
|
|
|
|
|
|
|
|
|
|
Color alphaPanelColor = panelColor;
|
|
|
|
|
alphaPanelColor.a = EscEditorConsts.COMPONENT_DRAWER_ALPHA;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUI.BeginChangeCheck();
|
2024-05-16 19:59:57 +08:00
|
|
|
|
EditorGUI.DrawRect(position, alphaPanelColor);
|
2024-05-16 19:03:03 +08:00
|
|
|
|
|
|
|
|
|
Rect paddingPosition = RectUtility.AddPadding(position, Padding * 2f);
|
|
|
|
|
|
|
|
|
|
#region Draw Component Block
|
|
|
|
|
Rect removeButtonRect = position;
|
|
|
|
|
removeButtonRect.center -= new Vector2(0, removeButtonRect.height);
|
|
|
|
|
removeButtonRect.yMin = removeButtonRect.yMax;
|
|
|
|
|
removeButtonRect.yMax += HeadIconsRect.height;
|
|
|
|
|
removeButtonRect.xMin = removeButtonRect.xMax - HeadIconsRect.width;
|
|
|
|
|
removeButtonRect.center += Vector2.up * Padding * 1f;
|
|
|
|
|
|
|
|
|
|
bool isRemoveComponent = EcsGUI.CloseButton(removeButtonRect);
|
|
|
|
|
|
|
|
|
|
if (propCount <= 0)
|
|
|
|
|
{
|
2024-05-17 00:18:44 +08:00
|
|
|
|
EcsGUI.DrawEmptyComponentProperty(paddingPosition, componentRefProp, label, false);
|
2024-05-16 19:03:03 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (componentProperty.propertyType == SerializedPropertyType.Generic)
|
|
|
|
|
{
|
|
|
|
|
EditorGUI.PropertyField(paddingPosition, componentProperty, label, true);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Rect r = RectUtility.AddPadding(paddingPosition, 0, 20f, 0, 0);
|
|
|
|
|
EditorGUI.PropertyField(r, componentProperty, label, true);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-17 00:18:44 +08:00
|
|
|
|
if (string.IsNullOrEmpty(label.text))
|
|
|
|
|
{
|
|
|
|
|
EditorGUI.indentLevel++;
|
|
|
|
|
EditorGUI.PrefixLabel(position.AddPadding(0, 0, 0, position.height - SingleLineWithPadding), UnityEditorUtility.GetLabel(name));
|
|
|
|
|
EditorGUI.indentLevel--;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
GUI.Label(position.AddPadding(EditorGUIUtility.labelWidth, 0, 0, position.height - SingleLineWithPadding), name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2024-05-16 19:03:03 +08:00
|
|
|
|
if (isRemoveComponent)
|
|
|
|
|
{
|
|
|
|
|
componentRefProp.managedReferenceValue = null;
|
|
|
|
|
}
|
|
|
|
|
if (string.IsNullOrEmpty(description) == false)
|
|
|
|
|
{
|
|
|
|
|
Rect tooltipIconRect = HeadIconsRect;
|
|
|
|
|
tooltipIconRect.center = removeButtonRect.center;
|
|
|
|
|
tooltipIconRect.center -= Vector2.right * tooltipIconRect.width;
|
|
|
|
|
EcsGUI.DescriptionIcon(tooltipIconRect, description);
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
if (EditorGUI.EndChangeCheck())
|
|
|
|
|
{
|
|
|
|
|
componentProperty.serializedObject.ApplyModifiedProperties();
|
|
|
|
|
EditorUtility.SetDirty(componentProperty.serializedObject.targetObject);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DrawSelectionPopup(Rect position, SerializedProperty componentRefProp, GUIContent label)
|
|
|
|
|
{
|
|
|
|
|
EditorGUI.LabelField(position, label);
|
|
|
|
|
Rect buttonRect = RectUtility.AddPadding(position, EditorGUIUtility.labelWidth, 0f, 0f, 0f);
|
|
|
|
|
if (GUI.Button(buttonRect, "Select"))
|
|
|
|
|
{
|
|
|
|
|
currentProperty = componentRefProp;
|
|
|
|
|
_genericMenu.ShowAsContext();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private void DrawDamagedComponent(Rect position, string message)
|
|
|
|
|
{
|
|
|
|
|
EditorGUI.HelpBox(position, message, MessageType.Warning);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|