add component template display

This commit is contained in:
Mikhail 2024-05-16 19:03:03 +08:00
parent 60723a67f6
commit e9ccb3f48e
10 changed files with 433 additions and 79 deletions

View File

@ -1,8 +1,10 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using UnityEditor;
using UnityEngine; using UnityEngine;
#region UNITY_EDITOR
using UnityEditor;
#endregion
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
@ -172,6 +174,7 @@ namespace DCFApixels.DragonECS
internal void Autoset_Editor() internal void Autoset_Editor()
{ {
Autoset(this); Autoset(this);
} }
[ContextMenu("Autoset Cascade")] [ContextMenu("Autoset Cascade")]
internal void AutosetCascade_Editor() internal void AutosetCascade_Editor()

View File

@ -1,5 +1,4 @@
#if UNITY_EDITOR #if UNITY_EDITOR
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using UnityEditor; using UnityEditor;

View File

@ -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); bool isAlive = Target.Entity.TryUnpackForUnityEditor(out int id, out short gen, out short worldID, out EcsWorld world);
using (new EditorGUI.DisabledScope(!isAlive)) using (new EditorGUI.DisabledScope(!isAlive))
{ {
if (GUILayout.Button("Delete Entity")) if (GUILayout.Button("Delete Entity", GUILayout.Height(36f)))
{ {
world.DelEntity(id); world.DelEntity(id);
} }

View File

@ -0,0 +1,67 @@
using System;
using System.Runtime.CompilerServices;
using UnityEngine;
namespace DCFApixels.DragonECS
{
[Serializable]
public struct ComponentTemplateProperty : IEquatable<ComponentTemplateProperty>
{
[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 { }
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6231d6781930a694696d09c3d55fc2fb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<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;
}
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

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: dbf91ec8124942340b7f095474db92b1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -9,10 +9,8 @@ namespace DCFApixels.DragonECS.Unity.Editors
{ {
internal abstract class EntityTemplateEditorBase : Editor internal abstract class EntityTemplateEditorBase : Editor
{ {
private static readonly Rect RemoveButtonRect = new Rect(0f, 0f, 19f, 19f); private static readonly Rect HeadIconsRect = new Rect(0f, 0f, 19f, 19f);
private static readonly Rect TooltipIconRect = new Rect(0f, 0f, 19f, 19f);
private GUIStyle _removeButtonStyle;
private GenericMenu _genericMenu; private GenericMenu _genericMenu;
private bool _isInit = false; private bool _isInit = false;
@ -28,21 +26,6 @@ namespace DCFApixels.DragonECS.Unity.Editors
if (_genericMenu == null) { _isInit = false; } if (_genericMenu == null) { _isInit = false; }
if (_isInit) { return; } 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(); _genericMenu = new GenericMenu();
var componentTemplateDummies = ComponentTemplateTypeCache.Dummies; var componentTemplateDummies = ComponentTemplateTypeCache.Dummies;
@ -187,40 +170,11 @@ namespace DCFApixels.DragonECS.Unity.Editors
string name = meta.Name; string name = meta.Name;
string description = meta.Description.Text; string description = meta.Description.Text;
bool isEmpty = componentType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length <= 0; int propCount = EcsGUI.GetChildPropertiesCount(componentProperty, componentType, out bool isEmpty);
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);
}
float padding = EditorGUIUtility.standardVerticalSpacing; float padding = EditorGUIUtility.standardVerticalSpacing;
Color panelColor; Color panelColor = EcsGUI.SelectPanelColor(meta, index, total).Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE);
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 alphaPanelColor = panelColor; Color alphaPanelColor = panelColor;
alphaPanelColor.a = EscEditorConsts.COMPONENT_DRAWER_ALPHA; alphaPanelColor.a = EscEditorConsts.COMPONENT_DRAWER_ALPHA;
@ -232,8 +186,8 @@ namespace DCFApixels.DragonECS.Unity.Editors
#region Draw Component Block #region Draw Component Block
removeButtonRect.yMin = removeButtonRect.yMax; removeButtonRect.yMin = removeButtonRect.yMax;
removeButtonRect.yMax += RemoveButtonRect.height; removeButtonRect.yMax += HeadIconsRect.height;
removeButtonRect.xMin = removeButtonRect.xMax - RemoveButtonRect.width; removeButtonRect.xMin = removeButtonRect.xMax - HeadIconsRect.width;
removeButtonRect.center += Vector2.up * padding * 2f; removeButtonRect.center += Vector2.up * padding * 2f;
bool isRemoveComponent = EcsGUI.CloseButton(removeButtonRect); bool isRemoveComponent = EcsGUI.CloseButton(removeButtonRect);
@ -273,7 +227,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
if (string.IsNullOrEmpty(description) == false) if (string.IsNullOrEmpty(description) == false)
{ {
Rect tooltipIconRect = TooltipIconRect; Rect tooltipIconRect = HeadIconsRect;
tooltipIconRect.center = removeButtonRect.center; tooltipIconRect.center = removeButtonRect.center;
tooltipIconRect.center -= Vector2.right * tooltipIconRect.width; tooltipIconRect.center -= Vector2.right * tooltipIconRect.width;
EcsGUI.DescriptionIcon(tooltipIconRect, description); EcsGUI.DescriptionIcon(tooltipIconRect, description);
@ -301,8 +255,8 @@ namespace DCFApixels.DragonECS.Unity.Editors
float padding = EditorGUIUtility.standardVerticalSpacing; float padding = EditorGUIUtility.standardVerticalSpacing;
removeButtonRect.yMin = removeButtonRect.yMax; removeButtonRect.yMin = removeButtonRect.yMax;
removeButtonRect.yMax += RemoveButtonRect.height; removeButtonRect.yMax += HeadIconsRect.height;
removeButtonRect.xMin = removeButtonRect.xMax - RemoveButtonRect.width; removeButtonRect.xMin = removeButtonRect.xMax - HeadIconsRect.width;
removeButtonRect.center += Vector2.up * padding * 2f; removeButtonRect.center += Vector2.up * padding * 2f;
bool isRemoveComponent = EcsGUI.CloseButton(removeButtonRect); bool isRemoveComponent = EcsGUI.CloseButton(removeButtonRect);

View File

@ -26,6 +26,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
public struct ColorScope : IDisposable public struct ColorScope : IDisposable
{ {
private readonly Color _value; 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) public ColorScope(Color value)
{ {
_value = GUI.color; _value = GUI.color;
@ -50,7 +51,15 @@ namespace DCFApixels.DragonECS.Unity.Editors
GUI.contentColor = _value; 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 #endregion
private static readonly BindingFlags fieldFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private static readonly BindingFlags fieldFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
internal readonly static Color GrayColor = new Color32(100, 100, 100, 255); internal readonly static Color GrayColor = new Color32(100, 100, 100, 255);
@ -119,8 +128,11 @@ namespace DCFApixels.DragonECS.Unity.Editors
#region small elems #region small elems
public static void DrawIcon(Rect position, Texture icon, float iconPadding, string description) public static void DrawIcon(Rect position, Texture icon, float iconPadding, string description)
{ {
GUI.Label(position, UnityEditorUtility.GetLabel(string.Empty, description)); using (SetColor(GUI.enabled ? GUI.color : GUI.color * new Color(1f, 1f, 1f, 0.4f)))
GUI.DrawTexture(RectUtility.AddPadding(position, iconPadding), icon); {
GUI.Label(position, UnityEditorUtility.GetLabel(string.Empty, description));
GUI.DrawTexture(RectUtility.AddPadding(position, iconPadding), icon);
}
} }
public static (bool, bool) IconButtonGeneric(Rect position) public static (bool, bool) IconButtonGeneric(Rect position)
{ {
@ -259,6 +271,51 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
#endregion #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) public static bool AddComponentButtons(Rect position)
{ {
position = RectUtility.AddPadding(position, 20f, 20f, 12f, 2f); position = RectUtility.AddPadding(position, 20f, 20f, 12f, 2f);
@ -352,7 +409,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
if (isWithFoldout == false || IsShowRuntimeComponents) if (isWithFoldout == false || IsShowRuntimeComponents)
{ {
if (EcsGUI.Layout.AddComponentButtons()) if (AddComponentButtons())
{ {
GenericMenu genericMenu = RuntimeComponentsUtility.GetAddComponentGenericMenu(world); GenericMenu genericMenu = RuntimeComponentsUtility.GetAddComponentGenericMenu(world);
RuntimeComponentsUtility.CurrentEntityID = entityID; RuntimeComponentsUtility.CurrentEntityID = entityID;

View File

@ -4,7 +4,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
{ {
internal static class RectUtility 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 l = rect;
Rect r = rect; Rect r = rect;
@ -12,7 +12,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
r.xMin += rect.width * t; r.xMin += rect.width * t;
return (l, r); 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 l = rect;
Rect r = rect; Rect r = rect;
@ -20,7 +20,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
r.xMin += with; r.xMin += with;
return (l, r); 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 l = rect;
Rect r = rect; Rect r = rect;
@ -29,7 +29,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
return (l, r); 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 t = rect;
Rect b = rect; Rect b = rect;
@ -37,7 +37,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
b.yMin += height; b.yMin += height;
return (t, b); 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 t = rect;
Rect b = rect; Rect b = rect;
@ -46,28 +46,30 @@ namespace DCFApixels.DragonECS.Unity.Internal
return (t, b); 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); 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); 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 result = rect;
rect.xMax -= right; result.xMin += left;
rect.yMin += top; result.xMax -= right;
rect.yMax -= bottom; 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; return rect;
} }
public static Rect Move(Rect rect, Vector2 addVector) public static Rect Move(in this Rect rect, float addX, float addY)
{
rect.center += addVector;
return rect;
}
public static Rect Move(Rect rect, float addX, float addY)
{ {
return Move(rect, new Vector2(addX, addY)); return Move(rect, new Vector2(addX, addY));
} }