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);
}
}