DragonECS-Unity/src/Internal/Editor/EcsGUI.cs

598 lines
25 KiB
C#
Raw Normal View History

2024-03-03 19:59:39 +08:00
#if UNITY_EDITOR
using DCFApixels.DragonECS.Unity.Internal;
using System;
using System.Reflection;
using UnityEditor;
using UnityEngine;
2024-05-16 19:59:57 +08:00
using UnityObject = UnityEngine.Object;
using UnityComponent = UnityEngine.Component;
2024-03-03 19:59:39 +08:00
namespace DCFApixels.DragonECS.Unity.Editors
{
2024-03-04 07:38:38 +08:00
internal static class EcsGUI
2024-03-03 19:59:39 +08:00
{
2024-05-13 19:20:07 +08:00
#region Scores
public struct LabelWidthScore : IDisposable
{
private readonly float _value;
public LabelWidthScore(float value)
{
_value = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = value;
}
public void Dispose()
{
EditorGUIUtility.labelWidth = _value;
}
}
2024-03-09 09:42:04 +08:00
public struct ColorScope : IDisposable
{
2024-05-13 19:20:07 +08:00
private readonly Color _value;
2024-05-16 19:03:03 +08:00
public ColorScope(float r, float g, float b, float a = 1f) : this(new Color(r, g, b, a)) { }
2024-05-13 19:20:07 +08:00
public ColorScope(Color value)
2024-03-09 09:42:04 +08:00
{
2024-05-13 19:20:07 +08:00
_value = GUI.color;
GUI.color = value;
2024-03-09 09:42:04 +08:00
}
public void Dispose()
{
2024-05-13 19:20:07 +08:00
GUI.color = _value;
2024-03-09 09:42:04 +08:00
}
}
2024-03-10 04:56:29 +08:00
public struct ContentColorScope : IDisposable
{
2024-05-13 19:20:07 +08:00
private readonly Color _value;
2024-05-15 00:36:56 +08:00
public ContentColorScope(float r, float g, float b, float a = 1f) : this(new Color(r, g, b, a)) { }
2024-05-13 19:20:07 +08:00
public ContentColorScope(Color value)
2024-03-10 04:56:29 +08:00
{
2024-05-13 19:20:07 +08:00
_value = GUI.contentColor;
GUI.contentColor = value;
2024-03-10 04:56:29 +08:00
}
public void Dispose()
{
2024-05-13 19:20:07 +08:00
GUI.contentColor = _value;
2024-03-10 04:56:29 +08:00
}
}
2024-05-16 19:03:03 +08:00
private static ContentColorScope SetContentColor(Color value) => new ContentColorScope(value);
private static ContentColorScope SetContentColor(float r, float g, float b, float a = 1f) => new ContentColorScope(r, g, b, a);
private static ColorScope SetColor(Color value) => new ColorScope(value);
private static ColorScope SetColor(float r, float g, float b, float a = 1f) => new ColorScope(r, g, b, a);
private static EditorGUI.DisabledScope Enable => new EditorGUI.DisabledScope(false);
private static EditorGUI.DisabledScope Disable => new EditorGUI.DisabledScope(true);
private static EditorGUI.DisabledScope SetEnable(bool value) => new EditorGUI.DisabledScope(!value);
2024-05-13 19:20:07 +08:00
#endregion
2024-05-16 19:03:03 +08:00
2024-05-15 01:06:19 +08:00
private static readonly BindingFlags fieldFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
2024-03-10 04:56:29 +08:00
2024-03-04 07:38:38 +08:00
internal readonly static Color GrayColor = new Color32(100, 100, 100, 255);
internal readonly static Color GreenColor = new Color32(75, 255, 0, 255);
internal readonly static Color RedColor = new Color32(255, 0, 75, 255);
2024-03-03 19:59:39 +08:00
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-09 03:35:01 +08:00
2024-03-09 22:36:35 +08:00
public static float EntityBarHeight => EditorGUIUtility.singleLineHeight + 3f;
2024-05-15 01:06:19 +08:00
#region Properties
private static ComponentColorMode AutoColorMode
{
get { return SettingsPrefs.instance.ComponentColorMode; }
set { SettingsPrefs.instance.ComponentColorMode = value; }
}
2024-03-09 03:35:01 +08:00
private static bool IsShowHidden
{
2024-03-10 09:29:21 +08:00
get { return SettingsPrefs.instance.IsShowHidden; }
set { SettingsPrefs.instance.IsShowHidden = value; }
2024-03-09 03:35:01 +08:00
}
private static bool IsShowRuntimeComponents
{
2024-03-10 09:29:21 +08:00
get { return SettingsPrefs.instance.IsShowRuntimeComponents; }
set { SettingsPrefs.instance.IsShowRuntimeComponents = value; }
2024-03-09 03:35:01 +08:00
}
2024-05-15 01:06:19 +08:00
#endregion
2024-03-09 03:35:01 +08:00
2024-05-15 01:06:19 +08:00
#region enums
2024-03-09 03:35:01 +08:00
public enum AddClearComponentButton : byte
{
None = 0,
AddComponent,
Clear,
}
2024-03-09 09:42:04 +08:00
[Flags]
public enum EntityStatus
{
NotAlive = 0,
Alive = 1 << 0,
Undefined = 1 << 1,
}
2024-05-15 01:06:19 +08:00
#endregion
2024-03-09 03:35:01 +08:00
2024-05-15 01:06:19 +08:00
#region HitTest
2024-03-10 09:18:40 +08:00
internal static bool HitTest(Rect rect)
{
return HitTest(rect, Event.current.mousePosition);
}
2024-03-09 09:42:04 +08:00
internal static bool HitTest(Rect rect, Event evt)
{
return HitTest(rect, evt.mousePosition);
}
internal static bool HitTest(Rect rect, Vector2 point)
{
int offset = 0;
return HitTest(rect, point, offset);
}
internal static bool HitTest(Rect rect, Vector2 point, int offset)
{
return point.x >= rect.xMin - (float)offset && point.x < rect.xMax + (float)offset && point.y >= rect.yMin - (float)offset && point.y < rect.yMax + (float)offset;
}
2024-05-15 01:06:19 +08:00
#endregion
2024-03-09 09:42:04 +08:00
2024-05-15 01:06:19 +08:00
#region small elems
2024-05-03 21:21:21 +08:00
public static void DrawIcon(Rect position, Texture icon, float iconPadding, string description)
{
2024-05-16 19:03:03 +08:00
using (SetColor(GUI.enabled ? GUI.color : GUI.color * new Color(1f, 1f, 1f, 0.4f)))
{
GUI.Label(position, UnityEditorUtility.GetLabel(string.Empty, description));
GUI.DrawTexture(RectUtility.AddPadding(position, iconPadding), icon);
}
2024-05-03 21:21:21 +08:00
}
2024-03-09 22:36:35 +08:00
public static (bool, bool) IconButtonGeneric(Rect position)
2024-03-09 09:42:04 +08:00
{
Color dc = GUI.color;
GUI.color = Color.clear; //Хак чтобы сделать реакцию от курсора мыши без лага
bool result = GUI.Button(position, "", EditorStyles.miniButtonMid);
GUI.color = dc;
var current = Event.current;
return (GUI.enabled && HitTest(position, current), result);
}
2024-03-09 22:36:35 +08:00
public static bool IconButton(Rect position, Texture icon, float iconPadding, string description)
2024-03-09 09:42:04 +08:00
{
2024-03-09 22:36:35 +08:00
bool result = GUI.Button(position, UnityEditorUtility.GetLabel(string.Empty));
2024-05-03 21:21:21 +08:00
DrawIcon(position, icon, iconPadding, description);
2024-03-09 22:36:35 +08:00
return result;
2024-03-09 09:42:04 +08:00
}
public static void DescriptionIcon(Rect position, string description)
{
using (new ColorScope(new Color(1f, 1f, 1f, 0.8f)))
{
2024-05-03 23:19:04 +08:00
DrawIcon(position, Icons.Instance.HelpIcon, 0, description);
2024-03-09 09:42:04 +08:00
}
}
public static bool CloseButton(Rect position)
{
using (new ColorScope(new Color(1f, 1f, 1f, 0.8f)))
{
2024-03-09 22:36:35 +08:00
var (hover, click) = IconButtonGeneric(position);
2024-03-09 09:42:04 +08:00
if (hover)
{
2024-05-03 23:19:04 +08:00
DrawIcon(position, Icons.Instance.CloseIconOn, -4f, null);
2024-03-09 09:42:04 +08:00
}
else
{
2024-05-03 23:19:04 +08:00
DrawIcon(position, Icons.Instance.CloseIcon, 0, null);
2024-03-09 09:42:04 +08:00
}
return click;
}
}
2024-03-09 22:36:35 +08:00
public static bool AutosetCascadeButton(Rect position)
{
2024-05-03 23:19:04 +08:00
return IconButton(position, Icons.Instance.AutosetCascadeIcon, 0f, "Autoset Cascade");
2024-03-09 22:36:35 +08:00
}
public static bool AutosetButton(Rect position)
{
2024-05-03 23:19:04 +08:00
return IconButton(position, Icons.Instance.AuotsetIcon, 1f, "Autoset");
2024-03-09 22:36:35 +08:00
}
2024-03-09 09:42:04 +08:00
public static bool UnlinkButton(Rect position)
{
2024-05-03 23:19:04 +08:00
return IconButton(position, Icons.Instance.UnlinkIcon, 1f, "Unlink Entity");
2024-03-09 09:42:04 +08:00
}
public static bool DelEntityButton(Rect position)
{
2024-05-03 23:19:04 +08:00
return IconButton(position, Icons.Instance.CloseIcon, 0f, "Delete Entity");
2024-03-09 09:42:04 +08:00
}
2024-05-15 01:06:19 +08:00
#endregion
2024-03-09 09:42:04 +08:00
2024-05-15 01:06:19 +08:00
#region entity bar
2024-05-13 19:20:07 +08:00
public static void EntityBarForAlive(Rect position, EntityStatus status, int id, short gen, short world)
{
EntityBar(position, status != EntityStatus.Alive, status, id, gen, world);
}
public static void EntityBar(Rect position, int id, short gen, short world)
{
EntityBar_Internal(position, false, id, gen, world);
}
public static void EntityBar(Rect position)
{
EntityBar_Internal(position, true);
}
public static void EntityBar(Rect position, bool isPlaceholder, EntityStatus status, int id = 0, short gen = 0, short world = 0)
{
using (new LabelWidthScore(0f))
{
var (entityInfoRect, statusRect) = RectUtility.VerticalSliceBottom(position, 3f);
2024-03-09 09:42:04 +08:00
2024-05-13 19:20:07 +08:00
Color statusColor;
switch (status)
{
case EntityStatus.NotAlive:
statusColor = EcsGUI.RedColor;
break;
case EntityStatus.Alive:
statusColor = EcsGUI.GreenColor;
break;
default:
statusColor = new Color32(200, 200, 200, 255);
break;
}
2024-03-09 09:42:04 +08:00
statusColor.a = 0.6f;
EditorGUI.DrawRect(statusRect, statusColor);
2024-05-13 19:20:07 +08:00
EntityBar_Internal(entityInfoRect, isPlaceholder, id, gen, world);
2024-03-09 09:42:04 +08:00
}
2024-05-13 19:20:07 +08:00
}
private static void EntityBar_Internal(Rect position, bool isPlaceHolder, int id = 0, short gen = 0, short world = 0)
{
using (new LabelWidthScore(0f))
2024-03-09 09:42:04 +08:00
{
2024-05-13 19:20:07 +08:00
Color w = Color.gray;
w.a = 0.6f;
Color b = Color.black;
b.a = 0.55f;
EditorGUI.DrawRect(position, w);
var (idRect, genWorldRect) = RectUtility.HorizontalSliceLerp(position, 0.4f);
var (genRect, worldRect) = RectUtility.HorizontalSliceLerp(genWorldRect, 0.5f);
idRect = RectUtility.AddPadding(idRect, 2, 1, 0, 0);
genRect = RectUtility.AddPadding(genRect, 1, 1, 0, 0);
worldRect = RectUtility.AddPadding(worldRect, 1, 2, 0, 0);
EditorGUI.DrawRect(idRect, b);
EditorGUI.DrawRect(genRect, b);
EditorGUI.DrawRect(worldRect, b);
GUIStyle style = UnityEditorUtility.GetInputFieldCenterAnhor();
2024-03-09 09:42:04 +08:00
2024-05-13 19:20:07 +08:00
if (isPlaceHolder)
2024-03-09 09:42:04 +08:00
{
2024-05-13 19:20:07 +08:00
using (new EditorGUI.DisabledScope(true))
{
GUI.Label(idRect, "Entity ID", style);
GUI.Label(genRect, "Generation", style);
GUI.Label(worldRect, "World ID", style);
}
}
else
{
EditorGUI.IntField(idRect, id, style);
EditorGUI.IntField(genRect, gen, style);
EditorGUI.IntField(worldRect, world, style);
2024-03-09 09:42:04 +08:00
}
}
}
2024-05-15 01:06:19 +08:00
#endregion
2024-03-09 09:42:04 +08:00
2024-05-16 19:03:03 +08:00
internal static int GetChildPropertiesCount(SerializedProperty property, Type type, out bool isEmpty)
{
int result = GetChildPropertiesCount(property);
isEmpty = result <= 0 && type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length <= 0;
return result;
}
internal static int GetChildPropertiesCount(SerializedProperty property)
{
var propsCounter = property.Copy();
int lastDepth = propsCounter.depth;
bool next = propsCounter.Next(true) && lastDepth < propsCounter.depth;
int result = next ? -1 : 0;
while (next)
{
result++;
2024-05-18 16:15:47 +08:00
next = propsCounter.Next(true);
2024-05-16 19:03:03 +08:00
}
return result;
}
public static Color SelectPanelColor(ITypeMeta meta, int index, int total)
{
2024-05-16 20:31:06 +08:00
var trueMeta = meta.Type.ToMeta();
if (trueMeta.IsCustomColor || meta.Color != trueMeta.Color)
2024-05-16 19:03:03 +08:00
{
2024-05-16 20:31:06 +08:00
return meta.Color.ToUnityColor();
2024-05-16 19:03:03 +08:00
}
else
{
switch (AutoColorMode)
{
case ComponentColorMode.Auto:
2024-05-16 20:31:06 +08:00
return meta.Color.ToUnityColor().Desaturate(0.48f) / 1.18f; //.Desaturate(0.48f) / 1.18f;
2024-05-16 19:03:03 +08:00
case ComponentColorMode.Rainbow:
int localTotal = Mathf.Max(total, EscEditorConsts.AUTO_COLOR_RAINBOW_MIN_RANGE);
Color hsv = Color.HSVToRGB(1f / localTotal * (index % localTotal), 1, 1);
2024-05-16 20:31:06 +08:00
return hsv.Desaturate(0.48f) / 1.18f;
2024-05-16 19:03:03 +08:00
default:
2024-05-16 20:31:06 +08:00
return index % 2 == 0 ? new Color(0.40f, 0.40f, 0.40f) : new Color(0.54f, 0.54f, 0.54f);
2024-05-16 19:03:03 +08:00
}
}
}
2024-03-09 09:42:04 +08:00
public static bool AddComponentButtons(Rect position)
{
position = RectUtility.AddPadding(position, 20f, 20f, 12f, 2f);
return GUI.Button(position, "Add Component");
}
2024-03-09 03:35:01 +08:00
public static AddClearComponentButton AddClearComponentButtons(Rect position)
2024-03-03 19:59:39 +08:00
{
2024-03-09 03:35:01 +08:00
position = RectUtility.AddPadding(position, 20f, 20f, 12f, 2f);
var (left, right) = RectUtility.HorizontalSliceLerp(position, 0.75f);
if (GUI.Button(left, "Add Component"))
{
return AddClearComponentButton.AddComponent;
}
if (GUI.Button(right, "Clear"))
2024-03-04 08:01:49 +08:00
{
2024-03-09 03:35:01 +08:00
return AddClearComponentButton.Clear;
2024-03-04 08:01:49 +08:00
}
2024-03-09 03:35:01 +08:00
return AddClearComponentButton.None;
}
2024-05-16 23:27:45 +08:00
public static void DrawEmptyComponentProperty(Rect position, SerializedProperty property, string name, bool isDisplayEmpty)
{
DrawEmptyComponentProperty(position, property, UnityEditorUtility.GetLabel(name), isDisplayEmpty);
}
public static void DrawEmptyComponentProperty(Rect position, SerializedProperty property, GUIContent label, bool isDisplayEmpty)
2024-03-09 03:35:01 +08:00
{
2024-05-16 23:27:45 +08:00
EditorGUI.LabelField(position, label);
if (isDisplayEmpty)
2024-05-16 19:59:57 +08:00
{
2024-05-16 23:27:45 +08:00
using (SetContentColor(1f, 1f, 1f, 0.4f))
{
GUI.Label(position.AddPadding(EditorGUIUtility.labelWidth, 0, 0, 0), "empty");
}
}
EditorGUI.BeginProperty(position, label, property);
EditorGUI.EndProperty();
}
2024-05-16 19:59:57 +08:00
2024-05-16 23:27:45 +08:00
public static class Layout
{
public static void DrawEmptyComponentProperty(SerializedProperty property, string name, bool isDisplayEmpty)
{
EcsGUI.DrawEmptyComponentProperty(GUILayoutUtility.GetRect(UnityEditorUtility.GetLabel(name), EditorStyles.label), property, name, isDisplayEmpty);
}
public static void DrawEmptyComponentProperty(SerializedProperty property, GUIContent label, bool isDisplayEmpty)
{
EcsGUI.DrawEmptyComponentProperty(GUILayoutUtility.GetRect(label, EditorStyles.label), property, label, isDisplayEmpty);
2024-05-16 19:59:57 +08:00
}
2024-03-10 04:56:29 +08:00
public static void DrawWorldBaseInfo(EcsWorld world)
{
2024-03-28 23:24:39 +08:00
bool isNull = world == null || world.IsDestroyed || world.id == 0;
2024-03-10 04:56:29 +08:00
int entitesCount = isNull ? 0 : world.Count;
int capacity = isNull ? 0 : world.Capacity;
int leakedEntitesCount = isNull ? 0 : world.CountLeakedEntitesDebug();
EditorGUILayout.IntField("Entities", entitesCount, EditorStyles.boldLabel);
EditorGUILayout.IntField("Capacity", capacity, EditorStyles.boldLabel);
Color color = leakedEntitesCount > 0 ? Color.yellow : GUI.contentColor;
using (new ContentColorScope(color))
{
EditorGUILayout.IntField("Leaked Entites", leakedEntitesCount, EditorStyles.boldLabel);
}
}
2024-05-15 01:06:19 +08:00
#region entity bar
2024-05-13 19:20:07 +08:00
public static void EntityBarForAlive(EntityStatus status, int id, short gen, short world)
{
float width = EditorGUIUtility.currentViewWidth;
float height = EntityBarHeight;
EcsGUI.EntityBarForAlive(GUILayoutUtility.GetRect(width, height), status, id, gen, world);
}
public static void EntityBar(EntityStatus status, bool isPlaceholder, int id, short gen, short world)
{
float width = EditorGUIUtility.currentViewWidth;
float height = EntityBarHeight;
EcsGUI.EntityBar(GUILayoutUtility.GetRect(width, height), isPlaceholder, status, id, gen, world);
}
public static void EntityBar(int id, short gen, short world)
2024-03-09 09:42:04 +08:00
{
float width = EditorGUIUtility.currentViewWidth;
2024-03-09 22:36:35 +08:00
float height = EntityBarHeight;
2024-05-13 19:20:07 +08:00
EcsGUI.EntityBar(GUILayoutUtility.GetRect(width, height), id, gen, world);
2024-03-09 09:42:04 +08:00
}
2024-05-13 19:20:07 +08:00
public static void EntityBar()
{
float width = EditorGUIUtility.currentViewWidth;
float height = EntityBarHeight;
EcsGUI.EntityBar(GUILayoutUtility.GetRect(width, height));
}
2024-05-15 01:06:19 +08:00
#endregion
2024-05-13 19:20:07 +08:00
2024-03-09 09:42:04 +08:00
public static bool AddComponentButtons()
{
return EcsGUI.AddComponentButtons(GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, 36f));
}
2024-03-09 03:35:01 +08:00
public static AddClearComponentButton AddClearComponentButtons()
2024-03-04 08:21:01 +08:00
{
2024-03-09 03:35:01 +08:00
return EcsGUI.AddClearComponentButtons(GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, 36f));
2024-03-04 08:21:01 +08:00
}
2024-03-07 03:18:00 +08:00
public static void DrawRuntimeComponents(entlong entity, bool isWithFoldout = true)
2024-03-03 19:59:39 +08:00
{
2024-03-28 23:24:39 +08:00
if (entity.TryUnpackForUnityEditor(out int entityID, out _, out _, out EcsWorld world))
2024-03-03 19:59:39 +08:00
{
2024-03-07 03:18:00 +08:00
DrawRuntimeComponents(entityID, world, isWithFoldout);
2024-03-03 19:59:39 +08:00
}
}
2024-03-07 03:18:00 +08:00
public static void DrawRuntimeComponents(int entityID, EcsWorld world, bool isWithFoldout = true)
2024-03-03 19:59:39 +08:00
{
2024-03-07 03:24:02 +08:00
var componentTypeIDs = world.GetComponentTypeIDsFor(entityID);
2024-03-04 08:01:49 +08:00
2024-03-07 03:18:00 +08:00
GUILayout.BeginVertical(UnityEditorUtility.GetStyle(Color.black, 0.2f));
2024-03-04 08:01:49 +08:00
2024-03-07 03:18:00 +08:00
if (isWithFoldout)
{
IsShowRuntimeComponents = EditorGUILayout.BeginFoldoutHeaderGroup(IsShowRuntimeComponents, "RUNTIME COMPONENTS", EditorStyles.foldout);
EditorGUILayout.EndFoldoutHeaderGroup();
}
if (isWithFoldout == false || IsShowRuntimeComponents)
2024-03-03 19:59:39 +08:00
{
2024-05-16 19:03:03 +08:00
if (AddComponentButtons())
2024-03-09 03:35:01 +08:00
{
2024-03-09 09:42:04 +08:00
GenericMenu genericMenu = RuntimeComponentsUtility.GetAddComponentGenericMenu(world);
RuntimeComponentsUtility.CurrentEntityID = entityID;
genericMenu.ShowAsContext();
2024-03-09 03:35:01 +08:00
}
2024-03-07 03:18:00 +08:00
GUILayout.Box("", UnityEditorUtility.GetStyle(GUI.color, 0.16f), GUILayout.ExpandWidth(true));
2024-03-05 00:46:47 +08:00
IsShowHidden = EditorGUI.Toggle(GUILayoutUtility.GetLastRect(), "Show Hidden", IsShowHidden);
2024-03-09 03:35:01 +08:00
2024-05-15 01:06:19 +08:00
int i = 0;
2024-03-04 08:21:01 +08:00
foreach (var componentTypeID in componentTypeIDs)
2024-03-03 19:59:39 +08:00
{
2024-03-07 03:24:02 +08:00
var pool = world.GetPoolInstance(componentTypeID);
2024-03-04 08:21:01 +08:00
{
2024-05-15 01:06:19 +08:00
DrawRuntimeComponent(componentTypeIDs.Length, i++, entityID, pool);
2024-03-04 08:21:01 +08:00
}
2024-03-03 19:59:39 +08:00
}
}
2024-03-04 07:38:38 +08:00
GUILayout.EndVertical();
2024-03-03 19:59:39 +08:00
}
2024-05-15 01:06:19 +08:00
private static void DrawRuntimeComponent(int total, int index, int entityID, IEcsPool pool)
2024-03-03 19:59:39 +08:00
{
2024-03-04 08:01:49 +08:00
var meta = pool.ComponentType.ToMeta();
if (meta.IsHidden == false || IsShowHidden)
2024-03-03 19:59:39 +08:00
{
2024-03-04 08:01:49 +08:00
object data = pool.GetRaw(entityID);
2024-05-15 01:06:19 +08:00
2024-05-16 19:59:57 +08:00
Color panelColor = SelectPanelColor(meta, index, total).Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE);
2024-03-07 21:22:48 +08:00
float padding = EditorGUIUtility.standardVerticalSpacing;
Rect removeButtonRect = GUILayoutUtility.GetLastRect();
2024-03-07 03:18:00 +08:00
GUILayout.BeginVertical(UnityEditorUtility.GetStyle(panelColor, EscEditorConsts.COMPONENT_DRAWER_ALPHA));
2024-03-04 08:01:49 +08:00
EditorGUI.BeginChangeCheck();
2024-03-07 21:22:48 +08:00
bool isRemoveComponent = false;
removeButtonRect.yMin = removeButtonRect.yMax;
removeButtonRect.yMax += RemoveButtonRect.height;
removeButtonRect.xMin = removeButtonRect.xMax - RemoveButtonRect.width;
removeButtonRect.center += Vector2.up * padding * 2f;
2024-05-16 19:59:57 +08:00
if (CloseButton(removeButtonRect))
2024-03-07 21:22:48 +08:00
{
isRemoveComponent = true;
}
2024-03-04 08:01:49 +08:00
Type componentType = pool.ComponentType;
ExpandMatrix expandMatrix = ExpandMatrix.Take(componentType);
2024-03-07 03:18:00 +08:00
bool changed = DrawRuntimeData(componentType, UnityEditorUtility.GetLabel(meta.Name), expandMatrix, data, out object resultData);
2024-03-07 21:22:48 +08:00
if (changed || isRemoveComponent)
2024-03-04 08:01:49 +08:00
{
2024-03-07 21:22:48 +08:00
if (isRemoveComponent)
{
pool.Del(entityID);
}
else
{
pool.SetRaw(entityID, resultData);
}
2024-03-04 08:01:49 +08:00
}
2024-03-03 19:59:39 +08:00
2024-05-01 15:02:54 +08:00
if (string.IsNullOrEmpty(meta.Description.Text) == false)
2024-03-09 09:42:04 +08:00
{
Rect tooltipIconRect = TooltipIconRect;
tooltipIconRect.center = removeButtonRect.center;
tooltipIconRect.center -= Vector2.right * tooltipIconRect.width;
2024-05-16 19:59:57 +08:00
DescriptionIcon(tooltipIconRect, meta.Description.Text);
2024-03-09 09:42:04 +08:00
}
2024-03-04 08:01:49 +08:00
GUILayout.EndVertical();
}
2024-03-03 19:59:39 +08:00
}
2024-03-04 08:21:01 +08:00
private static bool DrawRuntimeData(Type fieldType, GUIContent label, ExpandMatrix expandMatrix, object data, out object outData)
2024-03-09 09:42:04 +08:00
{
2024-03-09 03:35:01 +08:00
outData = data;
Type type = data == null ? typeof(void) : data.GetType();
2024-03-09 09:42:04 +08:00
2024-05-16 19:59:57 +08:00
bool isUnityObject = typeof(UnityObject).IsAssignableFrom(fieldType);
2024-03-09 03:35:01 +08:00
if (isUnityObject == false && data == null)
{
EditorGUILayout.TextField(label, "Null");
return false;
}
2024-03-04 03:00:45 +08:00
ref bool isExpanded = ref expandMatrix.Down();
2024-03-04 07:38:38 +08:00
bool changed = false;
outData = data;
2024-03-03 22:46:26 +08:00
2024-03-05 03:35:38 +08:00
if (isUnityObject == false && (type.IsGenericType || !type.IsSerializable))
2024-03-03 19:59:39 +08:00
{
2024-03-05 00:46:47 +08:00
isExpanded = EditorGUILayout.BeginFoldoutHeaderGroup(isExpanded, label, EditorStyles.foldout);
EditorGUILayout.EndFoldoutHeaderGroup();
2024-03-04 03:00:45 +08:00
if (isExpanded)
2024-03-03 19:59:39 +08:00
{
2024-03-03 22:46:26 +08:00
EditorGUI.indentLevel++;
foreach (var field in type.GetFields(fieldFlags))
2024-03-03 19:59:39 +08:00
{
2024-03-07 03:18:00 +08:00
GUIContent subLabel = UnityEditorUtility.GetLabel(UnityEditorUtility.TransformFieldName(field.Name));
2024-03-04 08:21:01 +08:00
if (DrawRuntimeData(field.FieldType, subLabel, expandMatrix, field.GetValue(data), out object fieldData))
2024-03-03 22:46:26 +08:00
{
field.SetValue(data, fieldData);
2024-03-07 03:18:00 +08:00
outData = data;
2024-03-04 07:38:38 +08:00
changed = true;
2024-03-03 22:46:26 +08:00
}
2024-03-03 19:59:39 +08:00
}
2024-03-03 22:46:26 +08:00
EditorGUI.indentLevel--;
2024-03-03 19:59:39 +08:00
}
}
else
{
2024-03-05 03:35:38 +08:00
if (isUnityObject)
{
EditorGUI.BeginChangeCheck();
2024-05-16 19:59:57 +08:00
var uobj = (UnityObject)data;
2024-03-07 03:18:00 +08:00
2024-05-16 19:59:57 +08:00
bool isComponent = typeof(UnityComponent).IsAssignableFrom(fieldType);
2024-03-07 03:18:00 +08:00
if (isComponent)
{
2024-05-16 19:59:57 +08:00
uobj = EditorGUILayout.ObjectField(label, uobj, typeof(UnityObject), true);
2024-03-07 03:18:00 +08:00
}
else
{
uobj = EditorGUILayout.ObjectField(label, uobj, fieldType, true);
}
if (isComponent && uobj is GameObject go)
{
uobj = go.GetComponent(fieldType);
}
2024-03-05 03:35:38 +08:00
if (EditorGUI.EndChangeCheck())
{
outData = uobj;
changed = true;
}
}
else
{
EditorGUI.BeginChangeCheck();
WrapperBase w = RefEditorWrapper.Take(data);
2024-03-03 19:59:39 +08:00
2024-03-05 03:35:38 +08:00
w.IsExpanded = isExpanded;
EditorGUILayout.PropertyField(w.Property, label, true);
isExpanded = w.IsExpanded;
2024-03-04 03:00:45 +08:00
2024-03-05 03:35:38 +08:00
if (EditorGUI.EndChangeCheck())
{
w.SO.ApplyModifiedProperties();
outData = w.Data;
changed = true;
}
2024-03-07 03:18:00 +08:00
w.Release();
2024-03-03 19:59:39 +08:00
}
}
2024-03-06 21:37:21 +08:00
2024-03-04 07:38:38 +08:00
expandMatrix.Up();
return changed;
2024-03-03 19:59:39 +08:00
}
}
}
}
#endif