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

226 lines
9.0 KiB
C#
Raw Normal View History

2024-03-07 03:18:00 +08:00
#if UNITY_EDITOR
using DCFApixels.DragonECS.Unity.Internal;
2024-10-05 18:41:23 +08:00
using DCFApixels.DragonECS.Unity.RefRepairer.Editors;
2024-03-07 03:18:00 +08:00
using UnityEditor;
2024-09-27 22:04:00 +08:00
using UnityEditorInternal;
2024-03-07 03:18:00 +08:00
using UnityEngine;
2024-03-03 03:51:49 +08:00
namespace DCFApixels.DragonECS.Unity.Editors
{
2024-10-18 17:22:02 +08:00
internal abstract class EntityTemplateEditorBase : ExtendedEditor<IEntityTemplateInternal>
2024-03-03 03:51:49 +08:00
{
2024-05-16 19:03:03 +08:00
private static readonly Rect HeadIconsRect = new Rect(0f, 0f, 19f, 19f);
2024-03-03 03:51:49 +08:00
2024-09-12 01:35:37 +08:00
private ComponentDropDown _componentDropDown;
2024-03-03 03:51:49 +08:00
2024-09-27 22:04:00 +08:00
private SerializedProperty _componentsProp;
private ReorderableList _reorderableComponentsList;
2024-05-15 00:36:56 +08:00
2025-03-20 11:05:29 +08:00
protected abstract bool IsSO { get; }
2024-10-31 19:13:14 +08:00
//public virtual bool IsStaticData { get { return false; } }
2024-03-03 03:51:49 +08:00
#region Init
2024-09-29 15:59:14 +08:00
protected override bool IsInit { get { return _componentDropDown != null; } }
protected override void OnInit()
2024-03-03 03:51:49 +08:00
{
2024-09-12 01:35:37 +08:00
_componentDropDown = new ComponentDropDown();
2024-09-27 22:04:00 +08:00
_componentsProp = serializedObject.FindProperty(Target.ComponentsPropertyName);
_reorderableComponentsList = new ReorderableList(serializedObject, _componentsProp, true, false, false, false);
_reorderableComponentsList.onAddCallback += OnReorderableComponentsListAdd;
_reorderableComponentsList.onRemoveCallback += OnReorderableListRemove;
_reorderableComponentsList.drawElementCallback += OnReorderableListDrawEmptyElement;
_reorderableComponentsList.drawElementBackgroundCallback += OnReorderableComponentsListDrawElement;
_reorderableComponentsList.drawNoneElementCallback += OnReorderableComponentsListDrawNoneElement;
_reorderableComponentsList.elementHeightCallback += OnReorderableComponentsListElementHeight;
_reorderableComponentsList.onReorderCallback += OnReorderableListReorder;
_reorderableComponentsList.showDefaultBackground = false;
_reorderableComponentsList.footerHeight = 0f;
_reorderableComponentsList.headerHeight = 0f;
_reorderableComponentsList.elementHeight = 0f;
}
#region ReorderableComponentsList
private void OnReorderableComponentsListDrawNoneElement(Rect rect) { }
private void OnReorderableListDrawEmptyElement(Rect rect, int index, bool isActive, bool isFocused) { }
private void OnReorderableListReorder(ReorderableList list)
{
EcsGUI.Changed = true;
}
private SerializedProperty GetTargetProperty(SerializedProperty prop)
{
IComponentTemplate template = prop.managedReferenceValue as IComponentTemplate;
if (template == null || prop.managedReferenceValue == null)
{
//DrawDamagedComponent_Replaced(componentRefProp, index);
return prop;
}
SerializedProperty componentProperty = prop;
2024-10-12 23:00:59 +08:00
if (componentProperty.managedReferenceValue is ComponentTemplateBase customTemplate)
2024-09-27 22:04:00 +08:00
{
2024-10-12 23:00:59 +08:00
componentProperty = prop.FindPropertyRelative("component");
2024-09-27 22:04:00 +08:00
}
2024-10-12 23:00:59 +08:00
return componentProperty == null ? prop : componentProperty;
2024-09-27 22:04:00 +08:00
}
2024-10-12 23:00:59 +08:00
2024-09-27 22:04:00 +08:00
private float OnReorderableComponentsListElementHeight(int index)
{
var componentProperty = GetTargetProperty(_componentsProp.GetArrayElementAtIndex(index));
float result = EditorGUI.GetPropertyHeight(componentProperty);
return EcsGUI.GetTypeMetaBlockHeight(result) + Spacing * 2f;
}
private void OnReorderableComponentsListDrawElement(Rect rect, int index, bool isActive, bool isFocused)
{
if (index < 0 || Event.current.type == EventType.Used) { return; }
rect = rect.AddPadding(OneLineHeight + Spacing, Spacing * 2f, Spacing, Spacing);
using (EcsGUI.CheckChanged())
{
SerializedProperty prop = _componentsProp.GetArrayElementAtIndex(index);
IComponentTemplate template = prop.managedReferenceValue as IComponentTemplate;
if (template == null || prop.managedReferenceValue == null)
{
2024-10-01 18:55:14 +08:00
//DrawDamagedComponent_Replaced(prop, index);
EditorGUI.PropertyField(rect, prop, UnityEditorUtility.GetLabel(prop.displayName), true);
2024-09-27 22:04:00 +08:00
return;
}
var componentProp = GetTargetProperty(prop);
ITypeMeta meta = template is ITypeMeta metaOverride ? metaOverride : template.Type.ToMeta();
if (EcsGUI.DrawTypeMetaElementBlock(ref rect, _componentsProp, index, componentProp, meta))
{
return;
}
GUIContent label = UnityEditorUtility.GetLabel(meta.Name);
if (componentProp.propertyType == SerializedPropertyType.Generic)
{
EditorGUI.PropertyField(rect, componentProp, label, true);
}
else
{
EditorGUI.PropertyField(rect.AddPadding(0, 20f, 0, 0), componentProp, label, true);
}
}
}
private void OnReorderableComponentsListAdd(ReorderableList list)
{
list.serializedProperty.arraySize += 1;
list.serializedProperty.GetArrayElementAtIndex(list.serializedProperty.arraySize - 1).ResetValues();
EcsGUI.Changed = true;
}
private void OnReorderableListRemove(ReorderableList list)
{
if (list.selectedIndices.Count <= 0)
{
if (list.serializedProperty.arraySize > 0)
{
list.serializedProperty.DeleteArrayElementAtIndex(list.serializedProperty.arraySize - 1);
}
return;
}
for (int i = list.selectedIndices.Count - 1; i >= 0; i--)
{
list.serializedProperty.DeleteArrayElementAtIndex(list.selectedIndices[i]);
}
EcsGUI.Changed = true;
2024-03-03 03:51:49 +08:00
}
#endregion
2024-09-27 22:04:00 +08:00
#endregion
2024-03-03 03:51:49 +08:00
#region Add/Remove
private void OnRemoveComponentAt(int index)
{
2024-10-18 17:22:02 +08:00
if (this.target is IEntityTemplateInternal target)
2024-03-03 03:51:49 +08:00
{
SerializedProperty componentsProp = serializedObject.FindProperty(target.ComponentsPropertyName);
componentsProp.DeleteArrayElementAtIndex(index);
serializedObject.ApplyModifiedProperties();
EditorUtility.SetDirty(this.target);
}
}
#endregion
2024-09-27 22:04:00 +08:00
protected override void DrawCustom()
2024-03-03 03:51:49 +08:00
{
Init();
2024-09-27 22:04:00 +08:00
if (_componentsProp == null)
2024-03-05 00:46:47 +08:00
{
2024-03-03 03:51:49 +08:00
return;
2024-03-05 00:46:47 +08:00
}
2024-03-03 03:51:49 +08:00
2025-03-20 11:05:29 +08:00
if (IsSO)
{
EcsGUI.Layout.ManuallySerializeButton(target);
}
2024-10-01 18:04:53 +08:00
if (IsMultipleTargets == false && SerializationUtility.HasManagedReferencesWithMissingTypes(target))
{
using (EcsGUI.Layout.BeginHorizontal(EditorStyles.helpBox))
{
GUILayout.Label(UnityEditorUtility.GetLabel(Icons.Instance.WarningIcon), GUILayout.ExpandWidth(false));
using (EcsGUI.Layout.BeginVertical())
{
GUILayout.Label("This object contains SerializeReference types which are missing.", EditorStyles.miniLabel);
if (GUILayout.Button("Repaire References Tool", EditorStyles.miniButton, GUILayout.MaxWidth(200f)))
{
RefRepairerWindow.Open();
}
}
}
}
2025-03-10 17:56:18 +08:00
using (EcsGUI.Layout.BeginVertical(UnityEditorUtility.GetTransperentBlackBackgrounStyle()))
2024-03-03 03:51:49 +08:00
{
2024-09-27 22:04:00 +08:00
DrawTop(Target, _componentsProp);
_reorderableComponentsList.DoLayoutList();
2024-03-03 03:51:49 +08:00
}
}
2024-10-18 17:22:02 +08:00
private void DrawTop(IEntityTemplateInternal target, SerializedProperty componentsProp)
2024-03-03 03:51:49 +08:00
{
2024-10-12 23:00:59 +08:00
GUILayout.Space(2f);
2024-09-12 01:35:37 +08:00
switch (EcsGUI.Layout.AddClearComponentButtons(out Rect rect))
2024-03-03 03:51:49 +08:00
{
2024-09-16 19:31:01 +08:00
case EcsGUI.AddClearButton.Add:
2024-03-09 03:35:01 +08:00
Init();
2024-09-16 19:31:01 +08:00
_componentDropDown.OpenForArray(rect, componentsProp, true);
2024-03-09 03:35:01 +08:00
break;
2024-09-16 19:31:01 +08:00
case EcsGUI.AddClearButton.Clear:
2024-03-09 03:35:01 +08:00
Init();
2024-09-27 22:04:00 +08:00
componentsProp.ClearArray();
2024-03-09 03:35:01 +08:00
serializedObject.ApplyModifiedProperties();
break;
2024-03-03 03:51:49 +08:00
}
}
}
[CustomEditor(typeof(ScriptableEntityTemplate), true)]
2024-10-31 19:13:14 +08:00
internal class ScriptableEntityTemplateEditor : EntityTemplateEditorBase
{
//public override bool IsStaticData { get { return true; } }
2025-03-20 11:05:29 +08:00
protected override bool IsSO => true;
2024-10-31 19:13:14 +08:00
}
2024-03-03 03:51:49 +08:00
[CustomEditor(typeof(MonoEntityTemplate), true)]
2024-10-31 19:13:14 +08:00
internal class MonoEntityTemplateEditor : EntityTemplateEditorBase
{
//public override bool IsStaticData { get { return false; } }
2025-03-20 11:05:29 +08:00
protected override bool IsSO => false;
2024-10-31 19:13:14 +08:00
}
2024-03-03 03:51:49 +08:00
}
#endif