|
|
|
|
using UnityEngine;
|
|
|
|
|
using UnityEditor;
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
|
|
|
|
|
namespace NaughtyAttributes.Editor
|
|
|
|
|
{
|
|
|
|
|
[CustomPropertyDrawer(typeof(ProgressBarAttribute))]
|
|
|
|
|
public class ProgressBarPropertyDrawer : PropertyDrawerBase
|
|
|
|
|
{
|
|
|
|
|
protected override float GetPropertyHeight_Internal(SerializedProperty property, GUIContent label)
|
|
|
|
|
{
|
|
|
|
|
ProgressBarAttribute progressBarAttribute = PropertyUtility.GetAttribute<ProgressBarAttribute>(property);
|
|
|
|
|
var maxValue = GetMaxValue(property, progressBarAttribute);
|
|
|
|
|
|
|
|
|
|
return IsNumber(property) && IsNumber(maxValue)
|
|
|
|
|
? GetPropertyHeight(property)
|
|
|
|
|
: GetPropertyHeight(property) + GetHelpBoxHeight();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void OnGUI_Internal(Rect rect, SerializedProperty property, GUIContent label)
|
|
|
|
|
{
|
|
|
|
|
EditorGUI.BeginProperty(rect, label, property);
|
|
|
|
|
|
|
|
|
|
if (!IsNumber(property))
|
|
|
|
|
{
|
|
|
|
|
string message = string.Format("Field {0} is not a number", property.name);
|
|
|
|
|
DrawDefaultPropertyAndHelpBox(rect, property, message, MessageType.Warning);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ProgressBarAttribute progressBarAttribute = PropertyUtility.GetAttribute<ProgressBarAttribute>(property);
|
|
|
|
|
var value = property.propertyType == SerializedPropertyType.Integer ? property.intValue : property.floatValue;
|
|
|
|
|
var valueFormatted = property.propertyType == SerializedPropertyType.Integer ? value.ToString() : string.Format("{0:0.00}", value);
|
|
|
|
|
var maxValue = GetMaxValue(property, progressBarAttribute);
|
|
|
|
|
|
|
|
|
|
if (maxValue != null && IsNumber(maxValue))
|
|
|
|
|
{
|
|
|
|
|
var fillPercentage = value / CastToFloat(maxValue);
|
|
|
|
|
var barLabel = (!string.IsNullOrEmpty(progressBarAttribute.Name) ? "[" + progressBarAttribute.Name + "] " : "") + valueFormatted + "/" + maxValue;
|
|
|
|
|
var barColor = progressBarAttribute.Color.GetColor();
|
|
|
|
|
var labelColor = Color.white;
|
|
|
|
|
|
|
|
|
|
var indentLength = NaughtyEditorGUI.GetIndentLength(rect);
|
|
|
|
|
Rect barRect = new Rect()
|
|
|
|
|
{
|
|
|
|
|
x = rect.x + indentLength,
|
|
|
|
|
y = rect.y,
|
|
|
|
|
width = rect.width - indentLength,
|
|
|
|
|
height = EditorGUIUtility.singleLineHeight
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
DrawBar(barRect, Mathf.Clamp01(fillPercentage), barLabel, barColor, labelColor);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
string message = string.Format(
|
|
|
|
|
"The provided dynamic max value for the progress bar is not correct. Please check if the '{0}' is correct, or the return type is float/int",
|
|
|
|
|
nameof(progressBarAttribute.MaxValueName));
|
|
|
|
|
|
|
|
|
|
DrawDefaultPropertyAndHelpBox(rect, property, message, MessageType.Warning);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EditorGUI.EndProperty();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private object GetMaxValue(SerializedProperty property, ProgressBarAttribute progressBarAttribute)
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrEmpty(progressBarAttribute.MaxValueName))
|
|
|
|
|
{
|
|
|
|
|
return progressBarAttribute.MaxValue;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
object target = PropertyUtility.GetTargetObjectWithProperty(property);
|
|
|
|
|
|
|
|
|
|
FieldInfo valuesFieldInfo = ReflectionUtility.GetField(target, progressBarAttribute.MaxValueName);
|
|
|
|
|
if (valuesFieldInfo != null)
|
|
|
|
|
{
|
|
|
|
|
return valuesFieldInfo.GetValue(target);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PropertyInfo valuesPropertyInfo = ReflectionUtility.GetProperty(target, progressBarAttribute.MaxValueName);
|
|
|
|
|
if (valuesPropertyInfo != null)
|
|
|
|
|
{
|
|
|
|
|
return valuesPropertyInfo.GetValue(target);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MethodInfo methodValuesInfo = ReflectionUtility.GetMethod(target, progressBarAttribute.MaxValueName);
|
|
|
|
|
if (methodValuesInfo != null &&
|
|
|
|
|
(methodValuesInfo.ReturnType == typeof(float) || methodValuesInfo.ReturnType == typeof(int)) &&
|
|
|
|
|
methodValuesInfo.GetParameters().Length == 0)
|
|
|
|
|
{
|
|
|
|
|
return methodValuesInfo.Invoke(target, null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DrawBar(Rect rect, float fillPercent, string label, Color barColor, Color labelColor)
|
|
|
|
|
{
|
|
|
|
|
if (Event.current.type != EventType.Repaint)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var fillRect = new Rect(rect.x, rect.y, rect.width * fillPercent, rect.height);
|
|
|
|
|
|
|
|
|
|
EditorGUI.DrawRect(rect, new Color(0.13f, 0.13f, 0.13f));
|
|
|
|
|
EditorGUI.DrawRect(fillRect, barColor);
|
|
|
|
|
|
|
|
|
|
// set alignment and cache the default
|
|
|
|
|
var align = GUI.skin.label.alignment;
|
|
|
|
|
GUI.skin.label.alignment = TextAnchor.UpperCenter;
|
|
|
|
|
|
|
|
|
|
// set the color and cache the default
|
|
|
|
|
var c = GUI.contentColor;
|
|
|
|
|
GUI.contentColor = labelColor;
|
|
|
|
|
|
|
|
|
|
// calculate the position
|
|
|
|
|
var labelRect = new Rect(rect.x, rect.y - 2, rect.width, rect.height);
|
|
|
|
|
|
|
|
|
|
// draw~
|
|
|
|
|
EditorGUI.DropShadowLabel(labelRect, label);
|
|
|
|
|
|
|
|
|
|
// reset color and alignment
|
|
|
|
|
GUI.contentColor = c;
|
|
|
|
|
GUI.skin.label.alignment = align;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool IsNumber(SerializedProperty property)
|
|
|
|
|
{
|
|
|
|
|
bool isNumber = property.propertyType == SerializedPropertyType.Float || property.propertyType == SerializedPropertyType.Integer;
|
|
|
|
|
return isNumber;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool IsNumber(object obj)
|
|
|
|
|
{
|
|
|
|
|
return (obj is float) || (obj is int);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private float CastToFloat(object obj)
|
|
|
|
|
{
|
|
|
|
|
if (obj is int)
|
|
|
|
|
{
|
|
|
|
|
return (int)obj;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return (float)obj;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|