You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
CrowdControl/Assets/3rd/StompyRobot/SRDebugger/Scripts/UI/Controls/Data/NumberControl.cs

199 lines
5.9 KiB
C#

3 months ago
using System.Globalization;
namespace SRDebugger.UI.Controls.Data
{
using System;
using System.Collections.Generic;
using SRF;
using SRF.UI;
using UnityEngine;
using UnityEngine.UI;
public class NumberControl : DataBoundControl
{
private static readonly Type[] IntegerTypes =
{
typeof (int), typeof (short), typeof (byte), typeof (sbyte), typeof (uint), typeof (ushort)
};
private static readonly Type[] DecimalTypes =
{
typeof (float), typeof (double)
};
public static readonly Dictionary<Type, ValueRange> ValueRanges = new Dictionary<Type, ValueRange>
{
{typeof (int), new ValueRange {MaxValue = int.MaxValue, MinValue = int.MinValue}},
{typeof (short), new ValueRange {MaxValue = short.MaxValue, MinValue = short.MinValue}},
{typeof (byte), new ValueRange {MaxValue = byte.MaxValue, MinValue = byte.MinValue}},
{typeof (sbyte), new ValueRange {MaxValue = sbyte.MaxValue, MinValue = sbyte.MinValue}},
{typeof (uint), new ValueRange {MaxValue = uint.MaxValue, MinValue = uint.MinValue}},
{typeof (ushort), new ValueRange {MaxValue = ushort.MaxValue, MinValue = ushort.MinValue}},
{typeof (float), new ValueRange {MaxValue = float.MaxValue, MinValue = float.MinValue}},
{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
{
var num = Convert.ChangeType(newValue, _type, CultureInfo.InvariantCulture);
UpdateValue(num);
}
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))
{
NumberSpinner.contentType = InputField.ContentType.DecimalNumber;
}
else
{
throw new ArgumentException("Type must be one of expected types", "t");
}
var rangeAttrib = Property.GetAttribute<NumberRangeAttribute>();
NumberSpinner.MaxValue = GetMaxValue(t);
NumberSpinner.MinValue = GetMinValue(t);
if (rangeAttrib != null)
{
NumberSpinner.MaxValue = Math.Min(rangeAttrib.Max, NumberSpinner.MaxValue);
NumberSpinner.MinValue = Math.Max(rangeAttrib.Min, NumberSpinner.MinValue);
}
var incrementAttribute = Property.GetAttribute<IncrementAttribute>();
if (incrementAttribute != null)
{
if (UpNumberButton != null)
{
UpNumberButton.Amount = incrementAttribute.Increment;
}
if (DownNumberButton != null)
{
DownNumberButton.Amount = -incrementAttribute.Increment;
}
}
_type = t;
NumberSpinner.interactable = !IsReadOnly;
if (DisableOnReadOnly != null)
{
foreach (var childControl in DisableOnReadOnly)
{
childControl.SetActive(!IsReadOnly);
}
}
}
protected override void OnValueUpdated(object newValue)
{
var value = Convert.ToDecimal(newValue, CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture);
if (value != _lastValue)
{
NumberSpinner.text = value;
}
_lastValue = value;
}
public override bool CanBind(Type type, bool isReadOnly)
{
return IsDecimalType(type) || IsIntegerType(type);
}
protected static bool IsIntegerType(Type t)
{
for (var i = 0; i < IntegerTypes.Length; i++)
{
if (IntegerTypes[i] == t)
{
return true;
}
}
return false;
}
protected static bool IsDecimalType(Type t)
{
for (var 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;
}
public struct ValueRange
{
public double MaxValue;
public double MinValue;
}
}
}