1.1.0: Added validate attribute with NotNullField

This commit is contained in:
Anders Ejlersen 2021-12-04 15:04:41 +01:00
parent 18356eb532
commit 41ced8fdb7
15 changed files with 166 additions and 8 deletions

View file

@ -14,6 +14,9 @@ namespace Module.Inspector.Editor
if (accessType == EAccessType.Hidden)
return;
bool prevEnabled = GUI.enabled;
GUI.enabled = accessType == EAccessType.Enabled;
label.tooltip = result.tooltip;
for (var i = 0; i < result.predrawerModifiers.Count; i++)
@ -22,18 +25,39 @@ namespace Module.Inspector.Editor
value.drawer.Modify(value.attribute, property, label);
}
bool prevEnabled = GUI.enabled;
GUI.enabled = accessType == EAccessType.Enabled;
var isValid = true;
var validationError = string.Empty;
for (var i = 0; i < result.validators.Count; i++)
{
EditorPropertyUtility.ResultValue<ValidatePropertyAttribute, ValidatePropertyDrawer> value = result.validators[i];
if (value.drawer.Validate(value.attribute, property))
continue;
validationError += value.drawer.GetValidationError(property);
isValid = false;
}
Color prevColor = GUI.color;
if (!isValid)
{
if (string.IsNullOrEmpty(label.tooltip))
label.tooltip = validationError;
else
label.tooltip += "\n" + validationError;
GUI.color = Color.red;
}
if (result.draw != null)
{
if (!result.draw.drawer.Draw(position, result.draw.attribute, property, label, result))
{
Color prevColor = GUI.color;
GUI.color = Color.red;
var errorContent = new GUIContent(result.draw.drawer.GetErrorMessage(property));
EditorGUI.LabelField(position, label, errorContent);
GUI.color = prevColor;
}
}
else
@ -41,6 +65,7 @@ namespace Module.Inspector.Editor
EditorGUI.PropertyField(position, property, label, true);
}
GUI.color = prevColor;
GUI.enabled = prevEnabled;
for (var i = 0; i < result.valueModifiers.Count; i++)

View file

@ -75,6 +75,7 @@ namespace Module.Inspector.Editor.Utilities
var predrawerModifiers = new List<ResultValue<PredrawerModifierPropertyAttribute, PredrawerModifierPropertyDrawer>>(2);
var valueModifiers = new List<ResultValue<ValueModifierPropertyAttribute, ValueModifierPropertyDrawer>>(2);
var accessModifiers = new List<ResultValue<AccessModifierPropertyAttribute, AccessModifierPropertyDrawer>>(2);
var validators = new List<ResultValue<ValidatePropertyAttribute, ValidatePropertyDrawer>>(2);
object[] attributes = fieldInfo.GetCustomAttributes(false);
string tooltip = null;
var isObsolete = false;
@ -115,6 +116,13 @@ namespace Module.Inspector.Editor.Utilities
if (prop != null)
accessModifiers.Add(new ResultValue<AccessModifierPropertyAttribute, AccessModifierPropertyDrawer>(accessModifier, prop));
}
else if (att is ValidatePropertyAttribute validator)
{
var prop = InternalCreateInstanceOf<ValidatePropertyDrawer>(validator);
if (prop != null)
validators.Add(new ResultValue<ValidatePropertyAttribute, ValidatePropertyDrawer>(validator, prop));
}
else if (att is TooltipAttribute attTooltip)
{
tooltip = attTooltip.tooltip;
@ -144,7 +152,7 @@ namespace Module.Inspector.Editor.Utilities
}
}
return new Result(drawer, predrawerModifiers, valueModifiers, accessModifiers, tooltip, isObsolete);
return new Result(drawer, predrawerModifiers, valueModifiers, accessModifiers, validators, tooltip, isObsolete);
}
private static T InternalCreateInstanceOf<T>(AbstractPropertyAttribute att) where T : AbstractPropertyDrawer
@ -172,6 +180,7 @@ namespace Module.Inspector.Editor.Utilities
public readonly List<ResultValue<PredrawerModifierPropertyAttribute, PredrawerModifierPropertyDrawer>> predrawerModifiers;
public readonly List<ResultValue<ValueModifierPropertyAttribute, ValueModifierPropertyDrawer>> valueModifiers;
public readonly List<ResultValue<AccessModifierPropertyAttribute, AccessModifierPropertyDrawer>> accessModifiers;
public readonly List<ResultValue<ValidatePropertyAttribute, ValidatePropertyDrawer>> validators;
public readonly string tooltip;
public readonly bool isObsolete;
@ -179,6 +188,7 @@ namespace Module.Inspector.Editor.Utilities
List<ResultValue<PredrawerModifierPropertyAttribute, PredrawerModifierPropertyDrawer>> predrawerModifiers,
List<ResultValue<ValueModifierPropertyAttribute, ValueModifierPropertyDrawer>> valueModifiers,
List<ResultValue<AccessModifierPropertyAttribute, AccessModifierPropertyDrawer>> accessModifiers,
List<ResultValue<ValidatePropertyAttribute, ValidatePropertyDrawer>> validators,
string tooltip,
bool isObsolete)
{
@ -186,6 +196,7 @@ namespace Module.Inspector.Editor.Utilities
this.predrawerModifiers = predrawerModifiers;
this.valueModifiers = valueModifiers;
this.accessModifiers = accessModifiers;
this.validators = validators;
this.tooltip = tooltip;
this.isObsolete = isObsolete;
}
@ -222,6 +233,17 @@ namespace Module.Inspector.Editor.Utilities
return null;
}
public T GetValidator<T>() where T : ValidatePropertyAttribute
{
for (var i = 0; i < validators.Count; i++)
{
if (validators[i].attribute is T att)
return att;
}
return null;
}
}
/// <summary>

View file

@ -0,0 +1,10 @@
using UnityEditor;
namespace Module.Inspector.Editor
{
public abstract class ValidatePropertyDrawer : AbstractPropertyDrawer
{
public abstract bool Validate(ValidatePropertyAttribute attribute, SerializedProperty property);
public abstract string GetValidationError(SerializedProperty property);
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 28e84b42c2e449159f7f6da42e61d926
timeCreated: 1638625447

3
Editor/Validators.meta Normal file
View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9fb7568d40b24228ad7e6988dc114052
timeCreated: 1638625429

View file

@ -0,0 +1,50 @@
using UnityEditor;
namespace Module.Inspector.Editor
{
[CustomPropertyDrawer(typeof(NotNullFieldAttribute))]
internal sealed class NotNullFieldAttributeDrawer : ValidatePropertyDrawer
{
public override bool Validate(ValidatePropertyAttribute attribute, SerializedProperty property)
{
switch (property.propertyType)
{
case SerializedPropertyType.Integer:
case SerializedPropertyType.Boolean:
case SerializedPropertyType.Float:
case SerializedPropertyType.String:
case SerializedPropertyType.Color:
case SerializedPropertyType.LayerMask:
case SerializedPropertyType.Enum:
case SerializedPropertyType.Vector2:
case SerializedPropertyType.Vector3:
case SerializedPropertyType.Vector4:
case SerializedPropertyType.Rect:
case SerializedPropertyType.ArraySize:
case SerializedPropertyType.Character:
case SerializedPropertyType.Bounds:
case SerializedPropertyType.Quaternion:
case SerializedPropertyType.Vector2Int:
case SerializedPropertyType.Vector3Int:
case SerializedPropertyType.RectInt:
case SerializedPropertyType.BoundsInt:
return true;
case SerializedPropertyType.ObjectReference:
case SerializedPropertyType.Gradient:
case SerializedPropertyType.ExposedReference:
case SerializedPropertyType.ManagedReference:
case SerializedPropertyType.FixedBufferSize:
return property.objectReferenceValue != null;
case SerializedPropertyType.AnimationCurve:
return property.animationCurveValue != null;
}
return true;
}
public override string GetValidationError(SerializedProperty property)
{
return "NotNullField: Value is null";
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5e97d0a1ad0c4cc48034e3e60ef3d18f
timeCreated: 1638625437

View file

@ -6,7 +6,7 @@ These attributes have different categories and some can be combined to create th
# Base
There are five different kinds of attributes:
There are six different kinds of attributes:
* Access
* Modify access to drawer or value change (E.g. Hide/Show, Disable/Enable input)
@ -16,6 +16,8 @@ There are five different kinds of attributes:
* Custom drawing of the field/method
* Value
* Modify value before setting final result (E.g. clamp value)
* Validate
* Validate field (if invalid, draws as red)
* Decorator
* Adds additional information or styling to a field/method (E.g. Header displays a title/category to fields after attribute)
@ -121,6 +123,15 @@ List of all value attributes:
* If value is less than other fields value, then set value to other fields value
## Validate
list of all validate attributes
* `NotNullField`
* Checks if field is null
## Decorators
List of all decorator attributes:

View file

@ -5,6 +5,7 @@
PredrawerModifier,
Drawer,
ValueModifier,
AccessModifier
AccessModifier,
Validate
}
}

View file

@ -0,0 +1,7 @@
namespace Module.Inspector
{
public abstract class ValidatePropertyAttribute : AbstractPropertyAttribute
{
public override EPropertyType Type => EPropertyType.Validate;
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8b9e492ca9c74144ab913bc4d44a3cb6
timeCreated: 1638625294

3
Runtime/Validators.meta Normal file
View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ae50d6f9a5924095b1622fdce766030b
timeCreated: 1638625321

View file

@ -0,0 +1,14 @@
using System;
using UnityEngine.Scripting;
namespace Module.Inspector
{
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class NotNullFieldAttribute : ValidatePropertyAttribute
{
[Preserve]
public NotNullFieldAttribute()
{
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 869816e3d1fa460dbcb80195c70e8af4
timeCreated: 1638625328

View file

@ -1,6 +1,6 @@
{
"name": "com.module.inspector",
"version": "1.0.0",
"version": "1.1.0",
"displayName": "Module.Inspector",
"description": "Custom inspector with various useful property drawers",
"unity": "2019.2",