namespace SRF.UI { using System; using Internal; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; [AddComponentMenu(ComponentMenuPaths.NumberSpinner)] public class SRNumberSpinner : InputField { private double _currentValue; private double _dragStartAmount; private double _dragStep; public float DragSensitivity = 0.01f; public double MaxValue = double.MaxValue; public double MinValue = double.MinValue; protected override void Awake() { base.Awake(); if (contentType != ContentType.IntegerNumber && contentType != ContentType.DecimalNumber) { Debug.LogError("[SRNumberSpinner] contentType must be integer or decimal. Defaulting to integer"); contentType = ContentType.DecimalNumber; } } public override void OnPointerClick(PointerEventData eventData) { //Debug.Log("OnPointerClick (isFocused: {0}, isUsed: {1}, isDragging: {2})".Fmt(isFocused, eventData.used, eventData.dragging)); if (!interactable) { return; } if (eventData.dragging) { return; } EventSystem.current.SetSelectedGameObject(gameObject, eventData); base.OnPointerClick(eventData); if ((m_Keyboard == null || !m_Keyboard.active)) { OnSelect(eventData); } else { UpdateLabel(); eventData.Use(); } } public override void OnPointerDown(PointerEventData eventData) { //Debug.Log("OnPointerDown (isFocused: {0}, isUsed: {1})".Fmt(isFocused, eventData.used)); //base.OnPointerDown(eventData); } public override void OnPointerUp(PointerEventData eventData) { //Debug.Log("OnPointerUp (isFocused: {0}, isUsed: {1})".Fmt(isFocused, eventData.used)); //base.OnPointerUp(eventData); } public override void OnBeginDrag(PointerEventData eventData) { if (!interactable) { return; } //Debug.Log("OnBeginDrag (isFocused: {0}, isUsed: {1}, delta: {2})".Fmt(isFocused, eventData.used, eventData.delta)); // Pass event to parent if it is a vertical drag if (Mathf.Abs(eventData.delta.y) > Mathf.Abs(eventData.delta.x)) { //Debug.Log("Passing To Parent"); var parent = transform.parent; if (parent != null) { eventData.pointerDrag = ExecuteEvents.GetEventHandler(parent.gameObject); if (eventData.pointerDrag != null) { ExecuteEvents.Execute(eventData.pointerDrag, eventData, ExecuteEvents.beginDragHandler); } } return; } eventData.Use(); _dragStartAmount = double.Parse(text); _currentValue = _dragStartAmount; var minStep = 1f; // Use a larger minimum step for integer numbers, since there are no fractional values if (contentType == ContentType.IntegerNumber) { minStep *= 10; } _dragStep = Math.Max(minStep, _dragStartAmount*0.05f); if (isFocused) { DeactivateInputField(); } } public override void OnDrag(PointerEventData eventData) { if (!interactable) { return; } //Debug.Log("OnDrag (isFocused: {0}, isUsed: {1})".Fmt(isFocused, eventData.used)); var diff = eventData.delta.x; _currentValue += Math.Abs(_dragStep)*diff*DragSensitivity; _currentValue = Math.Round(_currentValue, 2); if (_currentValue > MaxValue) { _currentValue = MaxValue; } if (_currentValue < MinValue) { _currentValue = MinValue; } if (contentType == ContentType.IntegerNumber) { text = ((int) Math.Round(_currentValue)).ToString(); } else { text = _currentValue.ToString(); } } public override void OnEndDrag(PointerEventData eventData) { if (!interactable) { return; } //Debug.Log("OnEndDrag (isFocused: {0}, isUsed: {1})".Fmt(isFocused, eventData.used)); //base.OnEndDrag(eventData); eventData.Use(); if (_dragStartAmount != _currentValue) { DeactivateInputField(); SendOnSubmit(); } } } }