Files
2026-02-21 16:45:37 +08:00

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