247 lines
4.6 KiB
C#
247 lines
4.6 KiB
C#
using System.Collections;
|
|
using UnityEngine;
|
|
using UnityEngine.EventSystems;
|
|
using UnityEngine.Events;
|
|
using UnityEngine.UI;
|
|
|
|
namespace UIWidgets
|
|
{
|
|
public abstract class SpinnerBase<T> : InputField, IPointerDownHandler, IEventSystemHandler where T : struct
|
|
{
|
|
[SerializeField]
|
|
protected T _min;
|
|
|
|
[SerializeField]
|
|
protected T _max;
|
|
|
|
[SerializeField]
|
|
protected T _step;
|
|
|
|
[SerializeField]
|
|
protected T _value;
|
|
|
|
[SerializeField]
|
|
public SpinnerValidation Validation;
|
|
|
|
[SerializeField]
|
|
public float HoldStartDelay = 0.5f;
|
|
|
|
[SerializeField]
|
|
public float HoldChangeDelay = 0.1f;
|
|
|
|
[SerializeField]
|
|
protected ButtonAdvanced _plusButton;
|
|
|
|
[SerializeField]
|
|
protected ButtonAdvanced _minusButton;
|
|
|
|
public UnityEvent onPlusClick = new UnityEvent();
|
|
|
|
public UnityEvent onMinusClick = new UnityEvent();
|
|
|
|
private IEnumerator corutine;
|
|
|
|
public T Min
|
|
{
|
|
get
|
|
{
|
|
return _min;
|
|
}
|
|
set
|
|
{
|
|
_min = value;
|
|
}
|
|
}
|
|
|
|
public T Max
|
|
{
|
|
get
|
|
{
|
|
return _max;
|
|
}
|
|
set
|
|
{
|
|
_max = value;
|
|
}
|
|
}
|
|
|
|
public T Step
|
|
{
|
|
get
|
|
{
|
|
return _step;
|
|
}
|
|
set
|
|
{
|
|
_step = value;
|
|
}
|
|
}
|
|
|
|
public T Value
|
|
{
|
|
get
|
|
{
|
|
return _value;
|
|
}
|
|
set
|
|
{
|
|
SetValue(value);
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
public abstract void Plus();
|
|
|
|
public abstract void Minus();
|
|
|
|
protected abstract void SetValue(T newValue);
|
|
|
|
protected override void Start()
|
|
{
|
|
base.Start();
|
|
base.onValidateInput = SpinnerValidate;
|
|
base.onValueChanged.AddListener(ValueChange);
|
|
base.onEndEdit.AddListener(ValueEndEdit);
|
|
PlusButton = _plusButton;
|
|
MinusButton = _minusButton;
|
|
Value = _value;
|
|
}
|
|
|
|
private IEnumerator HoldPlus()
|
|
{
|
|
yield return new WaitForSeconds(HoldStartDelay);
|
|
while (true)
|
|
{
|
|
Plus();
|
|
yield return new WaitForSeconds(HoldChangeDelay);
|
|
}
|
|
}
|
|
|
|
private IEnumerator HoldMinus()
|
|
{
|
|
yield return new WaitForSeconds(HoldStartDelay);
|
|
while (true)
|
|
{
|
|
Minus();
|
|
yield return new WaitForSeconds(HoldChangeDelay);
|
|
}
|
|
}
|
|
|
|
public void OnMinusClick()
|
|
{
|
|
Minus();
|
|
onMinusClick.Invoke();
|
|
}
|
|
|
|
public void OnPlusClick()
|
|
{
|
|
Plus();
|
|
onPlusClick.Invoke();
|
|
}
|
|
|
|
public void OnPlusButtonDown(PointerEventData eventData)
|
|
{
|
|
if (corutine != null)
|
|
{
|
|
StopCoroutine(corutine);
|
|
}
|
|
corutine = HoldPlus();
|
|
StartCoroutine(corutine);
|
|
}
|
|
|
|
public void OnPlusButtonUp(PointerEventData eventData)
|
|
{
|
|
StopCoroutine(corutine);
|
|
}
|
|
|
|
public void OnMinusButtonDown(PointerEventData eventData)
|
|
{
|
|
if (corutine != null)
|
|
{
|
|
StopCoroutine(corutine);
|
|
}
|
|
corutine = HoldMinus();
|
|
StartCoroutine(corutine);
|
|
}
|
|
|
|
public void OnMinusButtonUp(PointerEventData eventData)
|
|
{
|
|
StopCoroutine(corutine);
|
|
}
|
|
|
|
protected virtual void onDestroy()
|
|
{
|
|
base.onValueChanged.RemoveListener(ValueChange);
|
|
base.onEndEdit.RemoveListener(ValueEndEdit);
|
|
PlusButton = null;
|
|
MinusButton = null;
|
|
}
|
|
|
|
protected abstract void ValueChange(string value);
|
|
|
|
protected abstract void ValueEndEdit(string value);
|
|
|
|
private char SpinnerValidate(string validateText, int charIndex, char addedChar)
|
|
{
|
|
if (Validation == SpinnerValidation.OnEndInput)
|
|
{
|
|
return ValidateShort(validateText, charIndex, addedChar);
|
|
}
|
|
return ValidateFull(validateText, charIndex, addedChar);
|
|
}
|
|
|
|
protected abstract char ValidateShort(string validateText, int charIndex, char addedChar);
|
|
|
|
protected abstract char ValidateFull(string validateText, int charIndex, char addedChar);
|
|
|
|
protected abstract T InBounds(T value);
|
|
}
|
|
}
|