From e9ccb3f48e99ef2f2a578ff9d8d12d90dfa5c59c Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Thu, 16 May 2024 19:03:03 +0800 Subject: [PATCH] add component template display --- src/Connectors/EcsEntityConnect.cs | 5 +- src/Debug/Editor/SettingsEditor.cs | 1 - .../Monitors/Editor/EntityMonitorEditor.cs | 2 +- .../ComponentTemplateReferenceAttribute.cs | 67 +++++ ...omponentTemplateReferenceAttribute.cs.meta | 11 + .../ComponentTemplateReferenceDrawer.cs | 250 ++++++++++++++++++ .../ComponentTemplateReferenceDrawer.cs.meta | 11 + .../Editor/EntityTemplateEditor.cs | 64 +---- src/Internal/Editor/EcsGUI.cs | 63 ++++- src/Internal/Utils/RectUtility.cs | 38 +-- 10 files changed, 433 insertions(+), 79 deletions(-) create mode 100644 src/EntityTemplate/ComponentTemplateReferenceAttribute.cs create mode 100644 src/EntityTemplate/ComponentTemplateReferenceAttribute.cs.meta create mode 100644 src/EntityTemplate/Editor/ComponentTemplateReferenceDrawer.cs create mode 100644 src/EntityTemplate/Editor/ComponentTemplateReferenceDrawer.cs.meta diff --git a/src/Connectors/EcsEntityConnect.cs b/src/Connectors/EcsEntityConnect.cs index 78db7ff..0f6a22b 100644 --- a/src/Connectors/EcsEntityConnect.cs +++ b/src/Connectors/EcsEntityConnect.cs @@ -1,8 +1,10 @@ using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; -using UnityEditor; using UnityEngine; +#region UNITY_EDITOR +using UnityEditor; +#endregion namespace DCFApixels.DragonECS { @@ -172,6 +174,7 @@ namespace DCFApixels.DragonECS internal void Autoset_Editor() { Autoset(this); + } [ContextMenu("Autoset Cascade")] internal void AutosetCascade_Editor() diff --git a/src/Debug/Editor/SettingsEditor.cs b/src/Debug/Editor/SettingsEditor.cs index e8e0e39..be5310a 100644 --- a/src/Debug/Editor/SettingsEditor.cs +++ b/src/Debug/Editor/SettingsEditor.cs @@ -1,5 +1,4 @@ #if UNITY_EDITOR -using System; using System.Collections.Generic; using System.Linq; using UnityEditor; diff --git a/src/Debug/Monitors/Editor/EntityMonitorEditor.cs b/src/Debug/Monitors/Editor/EntityMonitorEditor.cs index b3f505e..0581d9c 100644 --- a/src/Debug/Monitors/Editor/EntityMonitorEditor.cs +++ b/src/Debug/Monitors/Editor/EntityMonitorEditor.cs @@ -15,7 +15,7 @@ namespace DCFApixels.DragonECS.Unity.Editors bool isAlive = Target.Entity.TryUnpackForUnityEditor(out int id, out short gen, out short worldID, out EcsWorld world); using (new EditorGUI.DisabledScope(!isAlive)) { - if (GUILayout.Button("Delete Entity")) + if (GUILayout.Button("Delete Entity", GUILayout.Height(36f))) { world.DelEntity(id); } diff --git a/src/EntityTemplate/ComponentTemplateReferenceAttribute.cs b/src/EntityTemplate/ComponentTemplateReferenceAttribute.cs new file mode 100644 index 0000000..3a3c372 --- /dev/null +++ b/src/EntityTemplate/ComponentTemplateReferenceAttribute.cs @@ -0,0 +1,67 @@ +using System; +using System.Runtime.CompilerServices; +using UnityEngine; + +namespace DCFApixels.DragonECS +{ + [Serializable] + public struct ComponentTemplateProperty : IEquatable + { + [SerializeReference, ComponentTemplateReference] + private IComponentTemplate _template; + public ComponentTemplateProperty(IComponentTemplate template) + { + _template = template; + } + + public IComponentTemplate Template + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return _template; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + set { _template = value; } + } + public Type Type + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return _template.Type; } + } + public bool IsNull + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return _template == null; } + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Apply(short worldID, int entityID) { _template.Apply(worldID, entityID); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public object GetRaw() { return _template.GetRaw(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void OnGizmos(Transform transform, IComponentTemplate.GizmosMode mode) { _template.OnGizmos(transform, mode); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void OnValidate(UnityEngine.Object obj) { _template.OnValidate(obj); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void SetRaw(object raw) { _template.SetRaw(raw); } + + public bool Equals(ComponentTemplateProperty other) + { + return _template == other._template; + } + public override int GetHashCode() + { + return _template.GetHashCode(); + } + public static bool operator ==(ComponentTemplateProperty a, ComponentTemplateProperty b) { return a._template == b._template; } + public static bool operator !=(ComponentTemplateProperty a, ComponentTemplateProperty b) { return a._template != b._template; } + + public static bool operator ==(ComponentTemplateProperty a, Null? b) { return a.IsNull; } + public static bool operator ==(Null? a, ComponentTemplateProperty b) { return b.IsNull; } + + public static bool operator !=(ComponentTemplateProperty a, Null? b) { return !a.IsNull; } + public static bool operator !=(Null? a, ComponentTemplateProperty b) { return !b.IsNull; } + + public readonly struct Null { } + } + + + public sealed class ComponentTemplateReferenceAttribute : PropertyAttribute { } +} \ No newline at end of file diff --git a/src/EntityTemplate/ComponentTemplateReferenceAttribute.cs.meta b/src/EntityTemplate/ComponentTemplateReferenceAttribute.cs.meta new file mode 100644 index 0000000..92c9ce3 --- /dev/null +++ b/src/EntityTemplate/ComponentTemplateReferenceAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6231d6781930a694696d09c3d55fc2fb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/EntityTemplate/Editor/ComponentTemplateReferenceDrawer.cs b/src/EntityTemplate/Editor/ComponentTemplateReferenceDrawer.cs new file mode 100644 index 0000000..88afa19 --- /dev/null +++ b/src/EntityTemplate/Editor/ComponentTemplateReferenceDrawer.cs @@ -0,0 +1,250 @@ +#if UNITY_EDITOR +using DCFApixels.DragonECS.Unity.Internal; +using System; +using System.Reflection; +using UnityEditor; +using UnityEngine; + +namespace DCFApixels.DragonECS.Unity.Editors +{ + + [CustomPropertyDrawer(typeof(ComponentTemplateReferenceAttribute), true)] + public class ComponentTemplateReferenceDrawer : PropertyDrawer + { + private static readonly Rect HeadIconsRect = new Rect(0f, 0f, 19f, 19f); + + private float Padding => EditorGUIUtility.standardVerticalSpacing; + + private const float DamagedComponentHeight = 18f * 2f; + + private static bool _isInit; + private static GenericMenu _genericMenu; + #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() == 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; + } + + var propsCounter = property.Copy(); + int lastDepth = propsCounter.depth; + bool next = propsCounter.Next(true) && lastDepth < propsCounter.depth; + int propCount = next ? -1 : 0; + while (next) + { + propCount++; + next = propsCounter.Next(false); + } + bool isEmpty = propCount <= 0; + + + return (isEmpty ? EditorGUIUtility.singleLineHeight : EditorGUI.GetPropertyHeight(property, label)) + Padding * 4f; + } + + + + 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; + + int propCount = EcsGUI.GetChildPropertiesCount(componentProperty, componentType, out bool isEmpty); + + Color panelColor = EcsGUI.SelectPanelColor(meta, positionCountr, -1).Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE); + + Color alphaPanelColor = panelColor; + alphaPanelColor.a = EscEditorConsts.COMPONENT_DRAWER_ALPHA; + + + EditorGUI.BeginChangeCheck(); + GUI.Box(position, "", UnityEditorUtility.GetStyle(alphaPanelColor)); + + 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) + { + label.text = $"{label.text} ({name})"; + EditorGUI.LabelField(paddingPosition, label); + Rect emptyPos = paddingPosition; + emptyPos.xMin += EditorGUIUtility.labelWidth; + if (isEmpty) + { + using (new EcsGUI.ContentColorScope(1f, 1f, 1f, 0.4f)) + { + GUI.Label(emptyPos, "empty"); + } + } + EditorGUI.BeginProperty(paddingPosition, label, componentRefProp); + EditorGUI.EndProperty(); + } + else + { + label.text = $"{label.text} ({name})"; + 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); + } + } + 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, 20f, 0f, 0f); + 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 \ No newline at end of file diff --git a/src/EntityTemplate/Editor/ComponentTemplateReferenceDrawer.cs.meta b/src/EntityTemplate/Editor/ComponentTemplateReferenceDrawer.cs.meta new file mode 100644 index 0000000..03dce75 --- /dev/null +++ b/src/EntityTemplate/Editor/ComponentTemplateReferenceDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dbf91ec8124942340b7f095474db92b1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/EntityTemplate/Editor/EntityTemplateEditor.cs b/src/EntityTemplate/Editor/EntityTemplateEditor.cs index ac4e4c1..f5654e8 100644 --- a/src/EntityTemplate/Editor/EntityTemplateEditor.cs +++ b/src/EntityTemplate/Editor/EntityTemplateEditor.cs @@ -9,10 +9,8 @@ namespace DCFApixels.DragonECS.Unity.Editors { internal abstract class EntityTemplateEditorBase : Editor { - private static readonly Rect RemoveButtonRect = new Rect(0f, 0f, 19f, 19f); - private static readonly Rect TooltipIconRect = new Rect(0f, 0f, 19f, 19f); + private static readonly Rect HeadIconsRect = new Rect(0f, 0f, 19f, 19f); - private GUIStyle _removeButtonStyle; private GenericMenu _genericMenu; private bool _isInit = false; @@ -28,21 +26,6 @@ namespace DCFApixels.DragonECS.Unity.Editors if (_genericMenu == null) { _isInit = false; } if (_isInit) { return; } - 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); - - _removeButtonStyle = new GUIStyle(EditorStyles.linkLabel); - _removeButtonStyle.alignment = TextAnchor.MiddleCenter; - - _removeButtonStyle.normal = tmpstylebase.normal; - _removeButtonStyle.hover = tmpStyle.normal; - _removeButtonStyle.active = tmpStyle.normal; - _removeButtonStyle.focused = tmpStyle.normal; - - _removeButtonStyle.padding = new RectOffset(0, 0, 0, 0); - _removeButtonStyle.margin = new RectOffset(0, 0, 0, 0); - _removeButtonStyle.border = new RectOffset(0, 0, 0, 0); - _genericMenu = new GenericMenu(); var componentTemplateDummies = ComponentTemplateTypeCache.Dummies; @@ -187,40 +170,11 @@ namespace DCFApixels.DragonECS.Unity.Editors string name = meta.Name; string description = meta.Description.Text; - bool isEmpty = componentType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length <= 0; - var propsCounter = componentProperty.Copy(); - int lastDepth = propsCounter.depth; - bool next = propsCounter.Next(true) && lastDepth < propsCounter.depth; - int propCount = next ? -1 : 0; - while (next) - { - propCount++; - next = propsCounter.Next(false); - } + int propCount = EcsGUI.GetChildPropertiesCount(componentProperty, componentType, out bool isEmpty); + float padding = EditorGUIUtility.standardVerticalSpacing; - Color panelColor; - if (meta.IsCustomColor) - { - panelColor = meta.Color.ToUnityColor(); - } - else - { - switch (AutoColorMode) - { - case ComponentColorMode.Auto: - panelColor = meta.Color.ToUnityColor().Desaturate(0.48f) / 1.18f; //.Desaturate(0.48f) / 1.18f; - break; - case ComponentColorMode.Rainbow: - Color hsv = Color.HSVToRGB(1f / (Mathf.Max(total, EscEditorConsts.AUTO_COLOR_RAINBOW_MIN_RANGE)) * index, 1, 1); - panelColor = hsv.Desaturate(0.48f) / 1.18f; - break; - default: - panelColor = index % 2 == 0 ? new Color(0.40f, 0.40f, 0.40f) : new Color(0.54f, 0.54f, 0.54f); - break; - } - } - panelColor = panelColor.Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE); + Color panelColor = EcsGUI.SelectPanelColor(meta, index, total).Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE); Color alphaPanelColor = panelColor; alphaPanelColor.a = EscEditorConsts.COMPONENT_DRAWER_ALPHA; @@ -232,8 +186,8 @@ namespace DCFApixels.DragonECS.Unity.Editors #region Draw Component Block removeButtonRect.yMin = removeButtonRect.yMax; - removeButtonRect.yMax += RemoveButtonRect.height; - removeButtonRect.xMin = removeButtonRect.xMax - RemoveButtonRect.width; + removeButtonRect.yMax += HeadIconsRect.height; + removeButtonRect.xMin = removeButtonRect.xMax - HeadIconsRect.width; removeButtonRect.center += Vector2.up * padding * 2f; bool isRemoveComponent = EcsGUI.CloseButton(removeButtonRect); @@ -273,7 +227,7 @@ namespace DCFApixels.DragonECS.Unity.Editors } if (string.IsNullOrEmpty(description) == false) { - Rect tooltipIconRect = TooltipIconRect; + Rect tooltipIconRect = HeadIconsRect; tooltipIconRect.center = removeButtonRect.center; tooltipIconRect.center -= Vector2.right * tooltipIconRect.width; EcsGUI.DescriptionIcon(tooltipIconRect, description); @@ -301,8 +255,8 @@ namespace DCFApixels.DragonECS.Unity.Editors float padding = EditorGUIUtility.standardVerticalSpacing; removeButtonRect.yMin = removeButtonRect.yMax; - removeButtonRect.yMax += RemoveButtonRect.height; - removeButtonRect.xMin = removeButtonRect.xMax - RemoveButtonRect.width; + removeButtonRect.yMax += HeadIconsRect.height; + removeButtonRect.xMin = removeButtonRect.xMax - HeadIconsRect.width; removeButtonRect.center += Vector2.up * padding * 2f; bool isRemoveComponent = EcsGUI.CloseButton(removeButtonRect); diff --git a/src/Internal/Editor/EcsGUI.cs b/src/Internal/Editor/EcsGUI.cs index 0c7a18c..4f5938e 100644 --- a/src/Internal/Editor/EcsGUI.cs +++ b/src/Internal/Editor/EcsGUI.cs @@ -26,6 +26,7 @@ namespace DCFApixels.DragonECS.Unity.Editors public struct ColorScope : IDisposable { private readonly Color _value; + public ColorScope(float r, float g, float b, float a = 1f) : this(new Color(r, g, b, a)) { } public ColorScope(Color value) { _value = GUI.color; @@ -50,7 +51,15 @@ namespace DCFApixels.DragonECS.Unity.Editors GUI.contentColor = _value; } } + 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); #endregion + private static readonly BindingFlags fieldFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; internal readonly static Color GrayColor = new Color32(100, 100, 100, 255); @@ -119,8 +128,11 @@ namespace DCFApixels.DragonECS.Unity.Editors #region small elems public static void DrawIcon(Rect position, Texture icon, float iconPadding, string description) { - GUI.Label(position, UnityEditorUtility.GetLabel(string.Empty, description)); - GUI.DrawTexture(RectUtility.AddPadding(position, iconPadding), icon); + 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); + } } public static (bool, bool) IconButtonGeneric(Rect position) { @@ -259,6 +271,51 @@ namespace DCFApixels.DragonECS.Unity.Editors } #endregion + 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++; + next = propsCounter.Next(false); + } + return result; + } + public static Color SelectPanelColor(ITypeMeta meta, int index, int total) + { + Color panelColor; + if (meta.IsCustomColor) + { + panelColor = meta.Color.ToUnityColor(); + } + else + { + switch (AutoColorMode) + { + case ComponentColorMode.Auto: + panelColor = meta.Color.ToUnityColor().Desaturate(0.48f) / 1.18f; //.Desaturate(0.48f) / 1.18f; + break; + case ComponentColorMode.Rainbow: + int localTotal = Mathf.Max(total, EscEditorConsts.AUTO_COLOR_RAINBOW_MIN_RANGE); + Color hsv = Color.HSVToRGB(1f / localTotal * (index % localTotal), 1, 1); + panelColor = hsv.Desaturate(0.48f) / 1.18f; + break; + default: + panelColor = index % 2 == 0 ? new Color(0.40f, 0.40f, 0.40f) : new Color(0.54f, 0.54f, 0.54f); + break; + } + } + return panelColor; + } public static bool AddComponentButtons(Rect position) { position = RectUtility.AddPadding(position, 20f, 20f, 12f, 2f); @@ -352,7 +409,7 @@ namespace DCFApixels.DragonECS.Unity.Editors } if (isWithFoldout == false || IsShowRuntimeComponents) { - if (EcsGUI.Layout.AddComponentButtons()) + if (AddComponentButtons()) { GenericMenu genericMenu = RuntimeComponentsUtility.GetAddComponentGenericMenu(world); RuntimeComponentsUtility.CurrentEntityID = entityID; diff --git a/src/Internal/Utils/RectUtility.cs b/src/Internal/Utils/RectUtility.cs index e341fbf..82e033e 100644 --- a/src/Internal/Utils/RectUtility.cs +++ b/src/Internal/Utils/RectUtility.cs @@ -4,7 +4,7 @@ namespace DCFApixels.DragonECS.Unity.Internal { internal static class RectUtility { - public static (Rect, Rect) HorizontalSliceLerp(Rect rect, float t) + public static (Rect, Rect) HorizontalSliceLerp(in this Rect rect, float t) { Rect l = rect; Rect r = rect; @@ -12,7 +12,7 @@ namespace DCFApixels.DragonECS.Unity.Internal r.xMin += rect.width * t; return (l, r); } - public static (Rect, Rect) HorizontalSliceLeft(Rect rect, float with) + public static (Rect, Rect) HorizontalSliceLeft(in this Rect rect, float with) { Rect l = rect; Rect r = rect; @@ -20,7 +20,7 @@ namespace DCFApixels.DragonECS.Unity.Internal r.xMin += with; return (l, r); } - public static (Rect, Rect) HorizontalSliceRight(Rect rect, float with) + public static (Rect, Rect) HorizontalSliceRight(in this Rect rect, float with) { Rect l = rect; Rect r = rect; @@ -29,7 +29,7 @@ namespace DCFApixels.DragonECS.Unity.Internal return (l, r); } - public static (Rect, Rect) VerticalSliceTop(Rect rect, float height) + public static (Rect, Rect) VerticalSliceTop(in this Rect rect, float height) { Rect t = rect; Rect b = rect; @@ -37,7 +37,7 @@ namespace DCFApixels.DragonECS.Unity.Internal b.yMin += height; return (t, b); } - public static (Rect, Rect) VerticalSliceBottom(Rect rect, float height) + public static (Rect, Rect) VerticalSliceBottom(in this Rect rect, float height) { Rect t = rect; Rect b = rect; @@ -46,28 +46,30 @@ namespace DCFApixels.DragonECS.Unity.Internal return (t, b); } - public static Rect AddPadding(Rect rect, float verticalHorizontal) + public static Rect AddPadding(in this Rect rect, float verticalHorizontal) { return AddPadding(rect, verticalHorizontal, verticalHorizontal, verticalHorizontal, verticalHorizontal); } - public static Rect AddPadding(Rect rect, float horizontal, float vertical) + public static Rect AddPadding(in this Rect rect, float horizontal, float vertical) { return AddPadding(rect, horizontal, horizontal, vertical, vertical); } - public static Rect AddPadding(Rect rect, float left, float right, float top, float bottom) + public static Rect AddPadding(in this Rect rect, float left, float right, float top, float bottom) { - rect.xMin += left; - rect.xMax -= right; - rect.yMin += top; - rect.yMax -= bottom; + Rect result = rect; + result.xMin += left; + result.xMax -= right; + result.yMin += top; + result.yMax -= bottom; + return result; + } + public static Rect Move(in this Rect rect, Vector2 addVector) + { + Rect result = rect; + result.center += addVector; return rect; } - public static Rect Move(Rect rect, Vector2 addVector) - { - rect.center += addVector; - return rect; - } - public static Rect Move(Rect rect, float addX, float addY) + public static Rect Move(in this Rect rect, float addX, float addY) { return Move(rect, new Vector2(addX, addY)); }