Files
trail-into-darkness/Packages/com.jovian.inspector/Editor/Attributes/RequireArraySizeAttribute.cs
2026-03-29 18:59:24 +02:00

87 lines
3.3 KiB
C#

using System;
using InspectorToolkit.Internal;
using Jovian.Utilities.Editor;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace InspectorToolkit {
public class RequireArraySizeAttribute : ArrayAttribute, IPropertyCondition {
public readonly int size;
public readonly SizeComparison comparison;
public enum SizeComparison {
Equal,
LessThan,
LessThanOrEqual,
GreaterThan,
GreaterThanOrEqual
}
public RequireArraySizeAttribute(int size, SizeComparison comparison = SizeComparison.Equal) {
this.size = size;
this.comparison = comparison;
}
#if UNITY_EDITOR
private bool DoesArraySizeMeetCondition(int arraySize) {
return comparison switch {
SizeComparison.Equal => arraySize == size,
SizeComparison.LessThan => arraySize < size,
SizeComparison.LessThanOrEqual => arraySize <= size,
SizeComparison.GreaterThan => arraySize > size,
SizeComparison.GreaterThanOrEqual => arraySize >= size,
_ => throw new ArgumentOutOfRangeException()
};
}
private string GetConditionString(int arraySize) {
return comparison switch {
SizeComparison.Equal => $"Array.size must be equal to {size} (current={arraySize})",
SizeComparison.LessThan => $"Array.size must be less than {size} (current={arraySize})",
SizeComparison.LessThanOrEqual => $"Array.size must be less than or equal to {size} (current={arraySize})",
SizeComparison.GreaterThan => $"Array.size must be greater than {size} (current={arraySize})",
SizeComparison.GreaterThanOrEqual => $"Array.size must be greater than or equal to {size} (current={arraySize})",
_ => throw new ArgumentOutOfRangeException()
};
}
public bool DoesPropertyMeetCondition(SerializedProperty property, out string description) {
description = string.Empty;
if (!property.isArray && (property.propertyPath.EndsWith(".Array.size") || EditorSerializationUtility.IsPropertyAnArrayElement(property))) {
return true; // don't check array conditions for elements
}
if (!property.isArray) {
description = $"{property.name} must be an array";
return false;
}
if (!(property.isArray && DoesArraySizeMeetCondition(property.arraySize))) {
description = GetConditionString(property.arraySize);
return false;
}
return true;
}
public override void OnPreGUI(ref Rect position, SerializedProperty property, ref GUIContent label) {
if (!DoesPropertyMeetCondition(property, out string description)) {
RequiredUtil.LayoutRequired(ref position, description, indent: true);
}
}
public override void OnPostGUI(ref Rect position, SerializedProperty property, ref GUIContent label) {
if (!DoesPropertyMeetCondition(property, out string description)) {
RequiredUtil.DrawRequired(ref position, description, indent: true);
}
}
#endif
}
}