245 lines
4.7 KiB
C#
245 lines
4.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using SRF;
|
|
using SRF.UI;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace SRDebugger.UI.Controls.Data
|
|
{
|
|
public class NumberControl : DataBoundControl
|
|
{
|
|
private struct ValueRange
|
|
{
|
|
public double MaxValue;
|
|
|
|
public double MinValue;
|
|
}
|
|
|
|
private static readonly Type[] IntegerTypes = new Type[6]
|
|
{
|
|
typeof(int),
|
|
typeof(short),
|
|
typeof(byte),
|
|
typeof(sbyte),
|
|
typeof(uint),
|
|
typeof(ushort)
|
|
};
|
|
|
|
private static readonly Type[] DecimalTypes = new Type[2]
|
|
{
|
|
typeof(float),
|
|
typeof(double)
|
|
};
|
|
|
|
private static readonly Dictionary<Type, ValueRange> ValueRanges = new Dictionary<Type, ValueRange>
|
|
{
|
|
{
|
|
typeof(int),
|
|
new ValueRange
|
|
{
|
|
MaxValue = 2147483647.0,
|
|
MinValue = -2147483648.0
|
|
}
|
|
},
|
|
{
|
|
typeof(short),
|
|
new ValueRange
|
|
{
|
|
MaxValue = 32767.0,
|
|
MinValue = -32768.0
|
|
}
|
|
},
|
|
{
|
|
typeof(byte),
|
|
new ValueRange
|
|
{
|
|
MaxValue = 255.0,
|
|
MinValue = 0.0
|
|
}
|
|
},
|
|
{
|
|
typeof(sbyte),
|
|
new ValueRange
|
|
{
|
|
MaxValue = 127.0,
|
|
MinValue = -128.0
|
|
}
|
|
},
|
|
{
|
|
typeof(uint),
|
|
new ValueRange
|
|
{
|
|
MaxValue = 4294967295.0,
|
|
MinValue = 0.0
|
|
}
|
|
},
|
|
{
|
|
typeof(ushort),
|
|
new ValueRange
|
|
{
|
|
MaxValue = 65535.0,
|
|
MinValue = 0.0
|
|
}
|
|
},
|
|
{
|
|
typeof(float),
|
|
new ValueRange
|
|
{
|
|
MaxValue = 3.4028234663852886E+38,
|
|
MinValue = -3.4028234663852886E+38
|
|
}
|
|
},
|
|
{
|
|
typeof(double),
|
|
new ValueRange
|
|
{
|
|
MaxValue = double.MaxValue,
|
|
MinValue = double.MinValue
|
|
}
|
|
}
|
|
};
|
|
|
|
private string _lastValue;
|
|
|
|
private Type _type;
|
|
|
|
public GameObject[] DisableOnReadOnly;
|
|
|
|
public SRNumberButton DownNumberButton;
|
|
|
|
[RequiredField]
|
|
public SRNumberSpinner NumberSpinner;
|
|
|
|
[RequiredField]
|
|
public Text Title;
|
|
|
|
public SRNumberButton UpNumberButton;
|
|
|
|
protected override void Start()
|
|
{
|
|
base.Start();
|
|
NumberSpinner.onEndEdit.AddListener(OnValueChanged);
|
|
}
|
|
|
|
private void OnValueChanged(string newValue)
|
|
{
|
|
try
|
|
{
|
|
object newValue2 = Convert.ChangeType(newValue, _type);
|
|
UpdateValue(newValue2);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
NumberSpinner.text = _lastValue;
|
|
}
|
|
}
|
|
|
|
protected override void OnBind(string propertyName, Type t)
|
|
{
|
|
base.OnBind(propertyName, t);
|
|
Title.text = propertyName;
|
|
if (IsIntegerType(t))
|
|
{
|
|
NumberSpinner.contentType = InputField.ContentType.IntegerNumber;
|
|
}
|
|
else
|
|
{
|
|
if (!IsDecimalType(t))
|
|
{
|
|
throw new ArgumentException("Type must be one of expected types", "t");
|
|
}
|
|
NumberSpinner.contentType = InputField.ContentType.DecimalNumber;
|
|
}
|
|
SROptions.NumberRangeAttribute attribute = base.Property.GetAttribute<SROptions.NumberRangeAttribute>();
|
|
NumberSpinner.MaxValue = GetMaxValue(t);
|
|
NumberSpinner.MinValue = GetMinValue(t);
|
|
if (attribute != null)
|
|
{
|
|
NumberSpinner.MaxValue = Math.Min(attribute.Max, NumberSpinner.MaxValue);
|
|
NumberSpinner.MinValue = Math.Max(attribute.Min, NumberSpinner.MinValue);
|
|
}
|
|
SROptions.IncrementAttribute attribute2 = base.Property.GetAttribute<SROptions.IncrementAttribute>();
|
|
if (attribute2 != null)
|
|
{
|
|
if (UpNumberButton != null)
|
|
{
|
|
UpNumberButton.Amount = attribute2.Increment;
|
|
}
|
|
if (DownNumberButton != null)
|
|
{
|
|
DownNumberButton.Amount = 0.0 - attribute2.Increment;
|
|
}
|
|
}
|
|
_type = t;
|
|
NumberSpinner.interactable = !base.IsReadOnly;
|
|
if (DisableOnReadOnly != null)
|
|
{
|
|
GameObject[] disableOnReadOnly = DisableOnReadOnly;
|
|
foreach (GameObject gameObject in disableOnReadOnly)
|
|
{
|
|
gameObject.SetActive(!base.IsReadOnly);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected override void OnValueUpdated(object newValue)
|
|
{
|
|
string text = Convert.ToString(newValue);
|
|
NumberSpinner.text = text;
|
|
_lastValue = text;
|
|
}
|
|
|
|
public override bool CanBind(Type type)
|
|
{
|
|
return IsDecimalType(type) || IsIntegerType(type);
|
|
}
|
|
|
|
protected static bool IsIntegerType(Type t)
|
|
{
|
|
for (int i = 0; i < IntegerTypes.Length; i++)
|
|
{
|
|
if (IntegerTypes[i] == t)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
protected static bool IsDecimalType(Type t)
|
|
{
|
|
for (int i = 0; i < DecimalTypes.Length; i++)
|
|
{
|
|
if (DecimalTypes[i] == t)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
protected double GetMaxValue(Type t)
|
|
{
|
|
ValueRange value;
|
|
if (ValueRanges.TryGetValue(t, out value))
|
|
{
|
|
return value.MaxValue;
|
|
}
|
|
Debug.LogWarning("[NumberControl] No MaxValue stored for type {0}".Fmt(t));
|
|
return double.MaxValue;
|
|
}
|
|
|
|
protected double GetMinValue(Type t)
|
|
{
|
|
ValueRange value;
|
|
if (ValueRanges.TryGetValue(t, out value))
|
|
{
|
|
return value.MinValue;
|
|
}
|
|
Debug.LogWarning("[NumberControl] No MinValue stored for type {0}".Fmt(t));
|
|
return double.MinValue;
|
|
}
|
|
}
|
|
}
|