module-inspector/Editor/Drawers/SliderAttributeDrawer.cs

134 lines
5.8 KiB
C#

using Module.Inspector.Editor.Utilities;
using UnityEditor;
using UnityEngine;
namespace Module.Inspector.Editor
{
[CustomPropertyDrawer(typeof(SliderAttribute))]
internal sealed class SliderAttributeDrawer : DrawerPropertyDrawer
{
public override bool Draw(Rect position, DrawerPropertyAttribute attribute, SerializedProperty property, GUIContent label, EditorPropertyUtility.Result result)
{
var min = result.GetValueModifier<MinValueAttribute>();
var max = result.GetValueModifier<MaxValueAttribute>();
if (min == null || max == null)
return false;
switch (property.propertyType)
{
case SerializedPropertyType.Integer:
case SerializedPropertyType.Float:
DrawRange(position, property, label, min, max);
break;
case SerializedPropertyType.Vector2:
case SerializedPropertyType.Vector2Int:
DrawerMinMax(position, property, label, min, max);
break;
default:
return false;
}
return true;
}
public override string GetErrorMessage(SerializedProperty property)
{
switch (property.propertyType)
{
case SerializedPropertyType.Integer:
case SerializedPropertyType.Float:
case SerializedPropertyType.Vector2:
case SerializedPropertyType.Vector2Int:
return "Requires MinValue and MaxValue";
}
return "Only supports integer, float, vector2 and vector2int";
}
private void DrawRange(Rect position, SerializedProperty property, GUIContent label, MinValueAttribute minValueAttribute, MaxValueAttribute maxValueAttribute)
{
int indentLevel = EditorGUI.indentLevel;
float indentSpacing = indentLevel * 15.0f;
EditorGUI.indentLevel = 0;
EditorGUI.BeginProperty(position, label, property);
{
float xMin = position.x + indentSpacing;
var r0 = new Rect(xMin, position.y, EditorGUIUtility.labelWidth - indentSpacing + 2.0f, position.height);
var r1 = new Rect(r0.xMax, r0.y, position.width - r0.width - indentSpacing, r0.height);
EditorGUI.LabelField(r0, label);
switch (property.propertyType)
{
case SerializedPropertyType.Integer:
property.intValue = EditorGUI.IntSlider(r1, property.intValue, minValueAttribute.intValue, maxValueAttribute.intValue);
break;
case SerializedPropertyType.Float:
property.floatValue = EditorGUI.Slider(r1, property.floatValue, minValueAttribute.floatValue, maxValueAttribute.floatValue);
break;
}
}
EditorGUI.EndProperty();
EditorGUI.indentLevel = indentLevel;
}
private void DrawerMinMax(Rect position, SerializedProperty property, GUIContent label, MinValueAttribute min, MaxValueAttribute max)
{
const float FLOAT_WIDTH = 50.0f;
const float FLOAT_SPACING = 8.0f;
int indentLevel = EditorGUI.indentLevel;
float indentSpacing = indentLevel * 15.0f;
EditorGUI.indentLevel = 0;
EditorGUI.BeginProperty(position, label, property);
{
float xMin = position.x + indentSpacing;
float width = position.width - indentSpacing;
var r0 = new Rect(xMin, position.y, EditorGUIUtility.labelWidth - indentSpacing + 2.0f, position.height);
var r1 = new Rect(r0.xMax, r0.y, FLOAT_WIDTH, r0.height);
var r2 = new Rect(r1.xMax + FLOAT_SPACING, r1.y, width - r0.width - (FLOAT_WIDTH + FLOAT_SPACING) * 2, r1.height);
var r3 = new Rect(r2.xMax + FLOAT_SPACING, r2.y, FLOAT_WIDTH, r2.height);
EditorGUI.LabelField(r0, label);
switch (property.propertyType)
{
case SerializedPropertyType.Vector2:
Vector2 v = property.vector2Value;
float minValue = v.x;
float maxValue = v.y;
minValue = EditorGUI.FloatField(r1, minValue);
maxValue = EditorGUI.FloatField(r3, maxValue);
EditorGUI.MinMaxSlider(r2, ref minValue, ref maxValue, min.floatValue, max.floatValue);
v.x = minValue;
v.y = maxValue;
property.vector2Value = v;
break;
case SerializedPropertyType.Vector2Int:
Vector2Int v2Int = property.vector2IntValue;
float minIntValue = v2Int.x;
float maxIntValue = v2Int.y;
minIntValue = EditorGUI.IntField(r1, Mathf.RoundToInt(minIntValue));
maxIntValue = EditorGUI.IntField(r3, Mathf.RoundToInt(maxIntValue));
EditorGUI.MinMaxSlider(r2, ref minIntValue, ref maxIntValue, min.floatValue, max.floatValue);
v2Int.x = Mathf.RoundToInt(minIntValue);
v2Int.y = Mathf.RoundToInt(maxIntValue);
property.vector2IntValue = v2Int;
break;
}
}
EditorGUI.EndProperty();
EditorGUI.indentLevel = indentLevel;
}
}
}