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

257 lines
9.8 KiB
C#
Raw Normal View History

2024-03-07 03:18:00 +08:00
#if UNITY_EDITOR
using DCFApixels.DragonECS.Unity.Internal;
2024-03-03 03:51:49 +08:00
using System;
using System.Reflection;
2024-03-07 03:18:00 +08:00
using UnityEditor;
using UnityEngine;
2024-03-03 03:51:49 +08:00
namespace DCFApixels.DragonECS.Unity.Editors
{
public abstract class EntityTemplateEditorBase : Editor
{
2024-03-09 09:42:04 +08:00
private static readonly Rect RemoveButtonRect = new Rect(0f, 0f, 19f, 19f);
private static readonly Rect TooltipIconRect = new Rect(0f, 0f, 19f, 19f);
2024-03-03 03:51:49 +08:00
2024-03-07 21:22:48 +08:00
private GUIStyle _removeButtonStyle;
private GenericMenu _genericMenu;
2024-03-03 03:51:49 +08:00
private bool _isInit = false;
#region Init
private void Init()
{
2024-03-07 21:22:48 +08:00
if (_genericMenu == null) { _isInit = false; }
2024-03-07 03:18:00 +08:00
if (_isInit) { return; }
2024-03-03 03:51:49 +08:00
2024-03-07 03:18:00 +08:00
var tmpstylebase = UnityEditorUtility.GetStyle(new Color(0.9f, 0f, 0.22f), 0.5f);
var tmpStyle = UnityEditorUtility.GetStyle(new Color(1f, 0.5f, 0.7f), 0.5f);
2024-03-03 03:51:49 +08:00
2024-03-07 21:22:48 +08:00
_removeButtonStyle = new GUIStyle(EditorStyles.linkLabel);
_removeButtonStyle.alignment = TextAnchor.MiddleCenter;
2024-03-03 03:51:49 +08:00
2024-03-07 21:22:48 +08:00
_removeButtonStyle.normal = tmpstylebase.normal;
_removeButtonStyle.hover = tmpStyle.normal;
_removeButtonStyle.active = tmpStyle.normal;
_removeButtonStyle.focused = tmpStyle.normal;
2024-03-03 03:51:49 +08:00
2024-03-07 21:22:48 +08:00
_removeButtonStyle.padding = new RectOffset(0, 0, 0, 0);
_removeButtonStyle.margin = new RectOffset(0, 0, 0, 0);
_removeButtonStyle.border = new RectOffset(0, 0, 0, 0);
2024-03-03 03:51:49 +08:00
2024-03-07 21:22:48 +08:00
_genericMenu = new GenericMenu();
2024-03-03 03:51:49 +08:00
2024-03-06 23:29:54 +08:00
var componentTemplateDummies = ComponentTemplateTypeCache.Dummies;
foreach (var dummy in componentTemplateDummies)
2024-03-03 03:51:49 +08:00
{
2024-03-06 23:29:54 +08:00
ITypeMeta meta = dummy is ITypeMeta metaOverride ? metaOverride : dummy.Type.ToMeta();
string name = meta.Name;
string description = meta.Description;
MetaGroup group = meta.Group;
2024-03-07 03:18:00 +08:00
if (group.Name.Length > 0)
2024-03-06 23:29:54 +08:00
{
name = group.Name + name;
}
2024-03-03 03:51:49 +08:00
if (string.IsNullOrEmpty(description) == false)
{
2024-03-10 23:34:00 +08:00
name = $"{name} [i]";
2024-03-03 03:51:49 +08:00
}
2024-03-07 21:22:48 +08:00
_genericMenu.AddItem(new GUIContent(name, description), false, OnAddComponent, dummy);
2024-03-03 03:51:49 +08:00
}
_isInit = true;
}
#endregion
#region Add/Remove
private void OnAddComponent(object obj)
{
Type componentType = obj.GetType();
if (this.target is ITemplateInternal target)
{
SerializedProperty componentsProp = serializedObject.FindProperty(target.ComponentsPropertyName);
for (int i = 0; i < componentsProp.arraySize; i++)
{
if (componentsProp.GetArrayElementAtIndex(i).managedReferenceValue.GetType() == componentType)
2024-03-06 21:37:21 +08:00
{
2024-03-03 03:51:49 +08:00
return;
2024-03-06 21:37:21 +08:00
}
2024-03-03 03:51:49 +08:00
}
componentsProp.InsertArrayElementAtIndex(0);
componentsProp.GetArrayElementAtIndex(0).managedReferenceValue = ((IComponentTemplate)obj).Clone();
serializedObject.ApplyModifiedProperties();
EditorUtility.SetDirty(this.target);
}
}
private void OnRemoveComponentAt(int index)
{
if (this.target is ITemplateInternal target)
{
SerializedProperty componentsProp = serializedObject.FindProperty(target.ComponentsPropertyName);
componentsProp.DeleteArrayElementAtIndex(index);
serializedObject.ApplyModifiedProperties();
EditorUtility.SetDirty(this.target);
}
}
#endregion
protected void Draw(ITemplateInternal target)
{
Init();
SerializedProperty componentsProp = serializedObject.FindProperty(target.ComponentsPropertyName);
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
2024-03-07 03:18:00 +08:00
GUILayout.BeginVertical(UnityEditorUtility.GetStyle(Color.black, 0.2f));
2024-03-09 03:35:01 +08:00
DrawTop(target);
2024-03-06 21:37:21 +08:00
GUILayout.Label("", GUILayout.Height(0), GUILayout.ExpandWidth(true));
2024-03-03 03:51:49 +08:00
for (int i = 0; i < componentsProp.arraySize; i++)
{
DrawComponentData(componentsProp.GetArrayElementAtIndex(i), i);
}
2024-03-04 07:38:38 +08:00
GUILayout.EndVertical();
2024-03-03 03:51:49 +08:00
}
private void DrawTop(ITemplateInternal target)
{
2024-03-09 03:35:01 +08:00
switch (EcsGUI.Layout.AddClearComponentButtons())
2024-03-03 03:51:49 +08:00
{
2024-03-09 03:35:01 +08:00
case EcsGUI.AddClearComponentButton.AddComponent:
Init();
_genericMenu.ShowAsContext();
break;
case EcsGUI.AddClearComponentButton.Clear:
Init();
serializedObject.FindProperty(target.ComponentsPropertyName).ClearArray();
serializedObject.ApplyModifiedProperties();
break;
2024-03-03 03:51:49 +08:00
}
}
2024-03-09 03:35:01 +08:00
2024-03-03 03:51:49 +08:00
private void DrawComponentData(SerializedProperty componentRefProp, int index)
{
IComponentTemplate template = componentRefProp.managedReferenceValue as IComponentTemplate;
2024-03-09 03:35:01 +08:00
if (template == null || componentRefProp.managedReferenceValue == null)
2024-03-03 03:51:49 +08:00
{
DrawDamagedComponent(componentRefProp, index);
return;
}
2024-03-09 09:42:04 +08:00
2024-03-03 03:51:49 +08:00
Type componentType;
SerializedProperty componentProperty = componentRefProp;
ComponentTemplateBase customInitializer = componentProperty.managedReferenceValue as ComponentTemplateBase;
if (customInitializer != null)
{
componentProperty = componentRefProp.FindPropertyRelative("component");
componentType = customInitializer.GetType().GetField("component", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FieldType;
}
else
{
2024-03-05 00:46:47 +08:00
componentType = componentProperty.managedReferenceValue.GetType(); ;
2024-03-03 03:51:49 +08:00
}
2024-03-07 03:18:00 +08:00
2024-03-06 23:29:54 +08:00
ITypeMeta meta = template is ITypeMeta metaOverride ? metaOverride : template.Type.ToMeta();
string name = meta.Name;
string description = meta.Description;
Color panelColor = meta.Color.ToUnityColor().Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE);
2024-03-03 03:51:49 +08:00
2024-03-07 03:18:00 +08:00
//GUIContent label = new GUIContent(name);
GUIContent label = UnityEditorUtility.GetLabel(name);
2024-03-05 00:46:47 +08:00
bool isEmpty = componentType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length <= 0;
float padding = EditorGUIUtility.standardVerticalSpacing;
Color alphaPanelColor = panelColor;
alphaPanelColor.a = EscEditorConsts.COMPONENT_DRAWER_ALPHA;
2024-03-07 21:22:48 +08:00
Rect removeButtonRect = GUILayoutUtility.GetLastRect();
2024-03-06 21:37:21 +08:00
EditorGUI.BeginChangeCheck();
2024-03-07 03:18:00 +08:00
GUILayout.BeginVertical(UnityEditorUtility.GetStyle(alphaPanelColor));
2024-03-05 00:46:47 +08:00
#region Draw Component Block
2024-03-05 03:35:38 +08:00
bool isRemoveComponent = false;
2024-03-06 21:37:21 +08:00
removeButtonRect.yMin = removeButtonRect.yMax;
removeButtonRect.yMax += RemoveButtonRect.height;
removeButtonRect.xMin = removeButtonRect.xMax - RemoveButtonRect.width;
removeButtonRect.center += Vector2.up * padding * 2f;
2024-03-09 09:42:04 +08:00
if (EcsGUI.CloseButton(removeButtonRect))
2024-03-05 03:35:38 +08:00
{
isRemoveComponent = true;
}
2024-03-05 00:46:47 +08:00
if (isEmpty)
2024-03-03 03:51:49 +08:00
{
2024-03-06 21:37:21 +08:00
GUILayout.Label(label);
2024-03-11 03:57:56 +08:00
EditorGUI.BeginProperty(GUILayoutUtility.GetLastRect(), label, componentRefProp);
EditorGUI.EndProperty();
2024-03-03 03:51:49 +08:00
}
else
{
2024-03-06 21:37:21 +08:00
EditorGUILayout.PropertyField(componentProperty, label, true);
2024-03-03 03:51:49 +08:00
}
2024-03-05 03:35:38 +08:00
if (isRemoveComponent)
2024-03-03 19:59:39 +08:00
{
2024-03-03 03:51:49 +08:00
OnRemoveComponentAt(index);
2024-03-03 19:59:39 +08:00
}
2024-03-07 03:18:00 +08:00
if (string.IsNullOrEmpty(description) == false)
2024-03-03 03:51:49 +08:00
{
Rect tooltipIconRect = TooltipIconRect;
2024-03-06 21:37:21 +08:00
tooltipIconRect.center = removeButtonRect.center;
tooltipIconRect.center -= Vector2.right * tooltipIconRect.width;
2024-03-09 09:42:04 +08:00
EcsGUI.DescriptionIcon(tooltipIconRect, description);
2024-03-03 03:51:49 +08:00
}
2024-03-06 21:37:21 +08:00
#endregion
2024-03-05 00:46:47 +08:00
2024-03-06 21:37:21 +08:00
GUILayout.EndVertical();
2024-03-09 09:42:04 +08:00
2024-03-05 00:46:47 +08:00
if (EditorGUI.EndChangeCheck())
{
componentProperty.serializedObject.ApplyModifiedProperties();
2024-03-06 21:37:21 +08:00
EditorUtility.SetDirty(componentProperty.serializedObject.targetObject);
2024-03-05 00:46:47 +08:00
}
2024-03-03 03:51:49 +08:00
}
private void DrawDamagedComponent(SerializedProperty componentRefProp, int index)
{
GUILayout.BeginHorizontal();
EditorGUILayout.HelpBox($"Damaged component. If the problem occurred after renaming a component or initializer. use MovedFromAttrubute", MessageType.Warning);
Rect lastrect = GUILayoutUtility.GetLastRect();
Rect removeButtonRect = RemoveButtonRect;
removeButtonRect.center = new Vector2(lastrect.xMax + removeButtonRect.width, lastrect.yMin + removeButtonRect.height / 2f);
GUILayout.Label("", GUILayout.Width(removeButtonRect.width));
2024-03-07 21:22:48 +08:00
if (GUI.Button(removeButtonRect, "x", _removeButtonStyle))
2024-03-06 21:37:21 +08:00
{
2024-03-03 03:51:49 +08:00
OnRemoveComponentAt(index);
2024-03-06 21:37:21 +08:00
}
2024-03-03 03:51:49 +08:00
GUILayout.EndHorizontal();
}
}
[CustomEditor(typeof(ScriptableEntityTemplate), true)]
public class EntityTemplatePresetEditor : EntityTemplateEditorBase
{
public override void OnInspectorGUI()
{
Draw((ITemplateInternal)target);
}
}
[CustomEditor(typeof(MonoEntityTemplate), true)]
public class EntityTemplateEditor : EntityTemplateEditorBase
{
public override void OnInspectorGUI()
{
Draw((ITemplateInternal)target);
}
}
}
#endif