using System.Collections; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; namespace UIWidgets { public abstract class SpinnerBase : 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); } }