using UnityEngine; using UnityEngine.Events; using UnityEngine.EventSystems; using UnityEngine.UI; using System; using System.Collections; namespace UIWidgets { /// /// Spinner validation. /// public enum SpinnerValidation { OnKeyDown = 0, OnEndInput = 1, } /// /// Spinner base class. /// abstract public class SpinnerBase : InputField, IPointerDownHandler where T : struct { /// /// The min. /// [SerializeField] protected T _min; /// /// The max. /// [SerializeField] protected T _max; /// /// The step. /// [SerializeField] protected T _step; /// /// The value. /// [SerializeField] protected T _value; /// /// The validation type. /// [SerializeField] public SpinnerValidation Validation = SpinnerValidation.OnKeyDown; /// /// Delay of hold in seconds for permanent increase/descrease value. /// [SerializeField] public float HoldStartDelay = 0.5f; /// /// Delay of hold in seconds between increase/descrease value. /// [SerializeField] public float HoldChangeDelay = 0.1f; /// /// Gets or sets the minimum. /// /// The minimum. public T Min { get { return _min; } set { _min = value; } } /// /// Gets or sets the maximum. /// /// The maximum. public T Max { get { return _max; } set { _max = value; } } /// /// Gets or sets the step. /// /// The step. public T Step { get { return _step; } set { _step = value; } } /// /// Gets or sets the value. /// /// The value. public T Value { get { return _value; } set { SetValue(value); } } /// /// The plus button. /// [SerializeField] protected ButtonAdvanced _plusButton; /// /// The minus button. /// [SerializeField] protected ButtonAdvanced _minusButton; /// /// Gets or sets the plus button. /// /// The plus button. public ButtonAdvanced PlusButton { get { return _plusButton; } set { if (_plusButton!=null) { _plusButton.onClick.RemoveListener(OnPlusClick); _plusButton.onPointerDown.RemoveListener(OnPlusButtonDown); _plusButton.onPointerUp.RemoveListener(OnPlusButtonUp); } _plusButton = value; if (_plusButton!=null) { _plusButton.onClick.AddListener(OnPlusClick); _plusButton.onPointerDown.AddListener(OnPlusButtonDown); _plusButton.onPointerUp.AddListener(OnPlusButtonUp); } } } /// /// Gets or sets the minus button. /// /// The minus button. public ButtonAdvanced MinusButton { get { return _minusButton; } set { if (_minusButton!=null) { _minusButton.onClick.RemoveListener(OnMinusClick); _minusButton.onPointerDown.RemoveListener(OnMinusButtonDown); _minusButton.onPointerUp.RemoveListener(OnMinusButtonUp); } _minusButton = value; if (_minusButton!=null) { _minusButton.onClick.AddListener(OnMinusClick); _minusButton.onPointerDown.AddListener(OnMinusButtonDown); _minusButton.onPointerUp.AddListener(OnMinusButtonUp); } } } /// /// onPlusClick event. /// public UnityEvent onPlusClick = new UnityEvent(); /// /// onMinusClick event. /// public UnityEvent onMinusClick = new UnityEvent(); /// /// Increase value on step. /// abstract public void Plus(); /// /// Decrease value on step. /// abstract public void Minus(); /// /// Sets the value. /// /// New value. abstract protected void SetValue(T newValue); /// /// Start this instance. /// protected override void Start() { base.Start(); onValidateInput = SpinnerValidate; #if UNITY_4_6 || UNITY_4_7 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2 onValueChange.AddListener(ValueChange); #else onValueChanged.AddListener(ValueChange); #endif onEndEdit.AddListener(ValueEndEdit); PlusButton = _plusButton; MinusButton = _minusButton; Value = _value; } IEnumerator HoldPlus() { yield return new WaitForSeconds(HoldStartDelay); while (true) { Plus(); yield return new WaitForSeconds(HoldChangeDelay); } } IEnumerator HoldMinus() { yield return new WaitForSeconds(HoldStartDelay); while (true) { Minus(); yield return new WaitForSeconds(HoldChangeDelay); } } /// /// Raises the minus click event. /// public void OnMinusClick() { Minus(); onMinusClick.Invoke(); } /// /// Raises the plus click event. /// public void OnPlusClick() { Plus(); onPlusClick.Invoke(); } IEnumerator corutine; /// /// Raises the plus button down event. /// /// Current event data. public void OnPlusButtonDown(PointerEventData eventData) { if (corutine!=null) { StopCoroutine(corutine); } corutine = HoldPlus(); StartCoroutine(corutine); } /// /// Raises the plus button up event. /// /// Current event data. public void OnPlusButtonUp(PointerEventData eventData) { StopCoroutine(corutine); } /// /// Raises the minus button down event. /// /// Current event data. public void OnMinusButtonDown(PointerEventData eventData) { if (corutine!=null) { StopCoroutine(corutine); } corutine = HoldMinus(); StartCoroutine(corutine); } /// /// Raises the minus button up event. /// /// Current event data. public void OnMinusButtonUp(PointerEventData eventData) { StopCoroutine(corutine); } /// /// Ons the destroy. /// protected virtual void onDestroy() { #if UNITY_4_6 || UNITY_4_7 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2 onValueChange.RemoveListener(ValueChange); #else onValueChanged.RemoveListener(ValueChange); #endif onEndEdit.RemoveListener(ValueEndEdit); PlusButton = null; MinusButton = null; } /// /// Called when value changed. /// /// Value. abstract protected void ValueChange(string value); /// /// Called when end edit. /// /// Value. abstract protected void ValueEndEdit(string value); char SpinnerValidate(string validateText, int charIndex, char addedChar) { if (SpinnerValidation.OnEndInput==Validation) { return ValidateShort(validateText, charIndex, addedChar); } else { return ValidateFull(validateText, charIndex, addedChar); } } /// /// Validate when key down for Validation=OnEndInput. /// /// The char. /// Validate text. /// Char index. /// Added char. abstract protected char ValidateShort(string validateText, int charIndex, char addedChar); /// /// Validates when key down for Validation=OnKeyDown. /// /// The char. /// Validate text. /// Char index. /// Added char. abstract protected char ValidateFull(string validateText, int charIndex, char addedChar); /// /// Clamps a value between a minimum and maximum value. /// /// The bounds. /// Value. abstract protected T InBounds(T value); } }