namespace UIWidgets { using System; using System.Collections; using UIWidgets.Attributes; using UIWidgets.Styles; using UnityEngine; using UnityEngine.EventSystems; /// /// Base class for Time widget. /// [DataBindSupport] public class TimeSpinnerBase : TimeBase, IUpgradeable { /// /// The input field for the hours. /// [SerializeField] protected InputFieldAdapter InputHoursAdapter; /// /// The input field for the minutes. /// [SerializeField] protected InputFieldAdapter InputMinutesAdapter; /// /// The input field for the seconds. /// [SerializeField] protected InputFieldAdapter InputSecondsAdapter; /// /// The input field proxy for the hours. /// [Obsolete("Replaced with InputHoursAdapter.")] protected IInputFieldProxy InputProxyHours { get { return InputHoursAdapter; } } /// /// The input field proxy for the minutes. /// [Obsolete("Replaced with InputMinutesAdapter.")] protected IInputFieldProxy InputProxyMinutes { get { return InputMinutesAdapter; } } /// /// The input field proxy for the seconds. /// [Obsolete("Replaced with InputSecondsAdapter.")] protected IInputFieldProxy InputProxySeconds { get { return InputSecondsAdapter; } } /// /// The button to increase hours. /// [SerializeField] protected ButtonAdvanced ButtonHoursIncrease; /// /// The button to decrease hours. /// [SerializeField] protected ButtonAdvanced ButtonHoursDecrease; /// /// The button to increase minutes. /// [SerializeField] protected ButtonAdvanced ButtonMinutesIncrease; /// /// The button to decrease minutes. /// [SerializeField] protected ButtonAdvanced ButtonMinutesDecrease; /// /// The button to increase seconds. /// [SerializeField] protected ButtonAdvanced ButtonSecondsIncrease; /// /// The button to decrease seconds. /// [SerializeField] protected ButtonAdvanced ButtonSecondsDecrease; /// /// Allow changing value during hold. /// [SerializeField] public bool AllowHold = true; /// /// Delay of hold in seconds for permanent increase/decrease value. /// [SerializeField] public float HoldStartDelay = 0.5f; /// /// Delay of hold in seconds between increase/decrease value. /// [SerializeField] public float HoldChangeDelay = 0.1f; /// /// Use unscaled time. /// [SerializeField] public bool UnscaledTime = true; IEnumerator HoldCoroutine; /// /// Init the input. /// protected override void InitInput() { Upgrade(); } /// /// Process interactable change. /// /// Current interactable state. protected override void OnInteractableChange(bool interactableState) { if (InputHoursAdapter != null) { InputHoursAdapter.interactable = interactableState; } if (InputMinutesAdapter != null) { InputMinutesAdapter.interactable = interactableState; } if (InputSecondsAdapter != null) { InputSecondsAdapter.interactable = interactableState; } if (ButtonHoursIncrease != null) { ButtonHoursIncrease.interactable = interactableState; } if (ButtonHoursDecrease != null) { ButtonHoursDecrease.interactable = interactableState; } if (ButtonMinutesIncrease != null) { ButtonMinutesIncrease.interactable = interactableState; } if (ButtonMinutesDecrease != null) { ButtonMinutesDecrease.interactable = interactableState; } if (ButtonSecondsIncrease != null) { ButtonSecondsIncrease.interactable = interactableState; } if (ButtonSecondsDecrease != null) { ButtonSecondsDecrease.interactable = interactableState; } } /// /// Add the listeners. /// protected override void AddListeners() { if (InputHoursAdapter != null) { InputHoursAdapter.onEndEdit.AddListener(UpdateHours); } if (InputMinutesAdapter != null) { InputMinutesAdapter.onEndEdit.AddListener(UpdateMinutes); } if (InputSecondsAdapter != null) { InputSecondsAdapter.onEndEdit.AddListener(UpdateSeconds); } if (ButtonHoursIncrease != null) { ButtonHoursIncrease.onClick.AddListener(HoursIncrease); ButtonHoursIncrease.onPointerDown.AddListener(ButtonHoursIncreaseDown); ButtonHoursIncrease.onPointerUp.AddListener(ButtonUp); } if (ButtonHoursDecrease != null) { ButtonHoursDecrease.onClick.AddListener(HoursDecrease); ButtonHoursDecrease.onPointerDown.AddListener(ButtonHoursDecreaseDown); ButtonHoursDecrease.onPointerUp.AddListener(ButtonUp); } if (ButtonMinutesIncrease != null) { ButtonMinutesIncrease.onClick.AddListener(MinutesIncrease); ButtonMinutesIncrease.onPointerDown.AddListener(ButtonMinutesIncreaseDown); ButtonMinutesIncrease.onPointerUp.AddListener(ButtonUp); } if (ButtonMinutesDecrease != null) { ButtonMinutesDecrease.onClick.AddListener(MinutesDecrease); ButtonMinutesDecrease.onPointerDown.AddListener(ButtonMinutesDecreaseDown); ButtonMinutesDecrease.onPointerUp.AddListener(ButtonUp); } if (ButtonSecondsIncrease != null) { ButtonSecondsIncrease.onClick.AddListener(SecondsIncrease); ButtonSecondsIncrease.onPointerDown.AddListener(ButtonSecondsIncreaseDown); ButtonSecondsIncrease.onPointerUp.AddListener(ButtonUp); } if (ButtonSecondsDecrease != null) { ButtonSecondsDecrease.onClick.AddListener(SecondsDecrease); ButtonSecondsDecrease.onPointerDown.AddListener(ButtonSecondsDecreaseDown); ButtonSecondsDecrease.onPointerUp.AddListener(ButtonUp); } } /// /// Removes the listeners. /// protected override void RemoveListeners() { if (InputHoursAdapter != null) { InputHoursAdapter.onEndEdit.RemoveListener(UpdateHours); } if (InputMinutesAdapter != null) { InputMinutesAdapter.onEndEdit.RemoveListener(UpdateMinutes); } if (InputSecondsAdapter != null) { InputSecondsAdapter.onEndEdit.RemoveListener(UpdateSeconds); } if (ButtonHoursIncrease != null) { ButtonHoursIncrease.onClick.RemoveListener(HoursIncrease); ButtonHoursIncrease.onPointerDown.RemoveListener(ButtonHoursIncreaseDown); ButtonHoursIncrease.onPointerUp.RemoveListener(ButtonUp); } if (ButtonHoursDecrease != null) { ButtonHoursDecrease.onClick.RemoveListener(HoursDecrease); ButtonHoursDecrease.onPointerDown.RemoveListener(ButtonHoursDecreaseDown); ButtonHoursDecrease.onPointerUp.RemoveListener(ButtonUp); } if (ButtonMinutesIncrease != null) { ButtonMinutesIncrease.onClick.RemoveListener(MinutesIncrease); ButtonMinutesIncrease.onPointerDown.RemoveListener(ButtonMinutesIncreaseDown); ButtonMinutesIncrease.onPointerUp.RemoveListener(ButtonUp); } if (ButtonMinutesDecrease != null) { ButtonMinutesDecrease.onClick.RemoveListener(MinutesDecrease); ButtonMinutesDecrease.onPointerDown.RemoveListener(ButtonMinutesDecreaseDown); ButtonMinutesDecrease.onPointerUp.RemoveListener(ButtonUp); } if (ButtonSecondsIncrease != null) { ButtonSecondsIncrease.onClick.RemoveListener(SecondsIncrease); ButtonSecondsIncrease.onPointerDown.RemoveListener(ButtonSecondsIncreaseDown); ButtonSecondsIncrease.onPointerUp.RemoveListener(ButtonUp); } if (ButtonSecondsDecrease != null) { ButtonSecondsDecrease.onClick.RemoveListener(SecondsDecrease); ButtonSecondsDecrease.onPointerDown.RemoveListener(ButtonSecondsDecreaseDown); ButtonSecondsDecrease.onPointerUp.RemoveListener(ButtonUp); } } /// /// Updates the hours. /// /// Hours. protected virtual void UpdateHours(string hours) { int h; if (int.TryParse(hours, out h)) { Time += new TimeSpan(Mathf.Abs(h) - time.Hours, 0, 0); } else { UpdateInputs(); } } /// /// Updates the minutes. /// /// Minutes. protected virtual void UpdateMinutes(string minutes) { int m; if (int.TryParse(minutes, out m)) { Time += new TimeSpan(0, Mathf.Abs(m) - time.Minutes, 0); } else { UpdateInputs(); } } /// /// Updates the seconds. /// /// Seconds. protected virtual void UpdateSeconds(string seconds) { int s; if (int.TryParse(seconds, out s)) { Time += new TimeSpan(0, 0, Mathf.Abs(s) - time.Seconds); } else { UpdateInputs(); } } /// /// Increase the hours. /// public void HoursIncrease() { Time += new TimeSpan(1, 0, 0); } /// /// Decrease the hours. /// public void HoursDecrease() { Time -= new TimeSpan(1, 0, 0); } /// /// Increase the minutes. /// public void MinutesIncrease() { Time += new TimeSpan(0, 1, 0); } /// /// Decrease the minutes. /// public void MinutesDecrease() { Time -= new TimeSpan(0, 1, 0); } /// /// Increase the seconds. /// public void SecondsIncrease() { Time += new TimeSpan(0, 0, 1); } /// /// Decrease the seconds. /// public void SecondsDecrease() { Time -= new TimeSpan(0, 0, 1); } /// /// Process the destroy event. /// protected override void OnDestroy() { RemoveListeners(); } /// /// Updates the inputs. /// public override void UpdateInputs() { if (InputHoursAdapter != null) { InputHoursAdapter.text = Time.Hours.ToString("D2"); } if (InputMinutesAdapter != null) { InputMinutesAdapter.text = Time.Minutes.ToString("D2"); } if (InputSecondsAdapter != null) { InputSecondsAdapter.text = Time.Seconds.ToString("D2"); } } #region Hold /// /// Create hold coroutine. /// /// Action. /// Hold coroutine. [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "HAA0401:Possible allocation of reference type enumerator", Justification = "Enumerator is reusable.")] protected virtual IEnumerator HoldCreateCoroutine(Action action) { if (AllowHold) { yield return UtilitiesTime.Wait(HoldStartDelay, UnscaledTime); while (AllowHold) { action(); yield return UtilitiesTime.Wait(HoldChangeDelay, UnscaledTime); } } } /// /// Start hold process. /// /// Action. protected virtual void HoldStart(Action action) { HoldStop(); HoldCoroutine = HoldCreateCoroutine(action); StartCoroutine(HoldCoroutine); } /// /// Stop hold process. /// protected virtual void HoldStop() { if (HoldCoroutine != null) { StopCoroutine(HoldCoroutine); } } /// /// Process pointer up event on all buttons. /// /// Current event data. public void ButtonUp(PointerEventData eventData) { HoldStop(); } /// /// Process pointer down event on hours increase button. /// /// Current event data. public void ButtonHoursIncreaseDown(PointerEventData eventData) { HoldStart(HoursIncrease); } /// /// Process pointer down event on hours decrease button. /// /// Current event data. public void ButtonHoursDecreaseDown(PointerEventData eventData) { HoldStart(HoursDecrease); } /// /// Process pointer down event on minutes increase button. /// /// Current event data. public void ButtonMinutesIncreaseDown(PointerEventData eventData) { HoldStart(MinutesIncrease); } /// /// Process pointer down event on minutes decrease button. /// /// Current event data. public void ButtonMinutesDecreaseDown(PointerEventData eventData) { HoldStart(MinutesDecrease); } /// /// Process pointer down event on seconds increase button. /// /// Current event data. public void ButtonSecondsIncreaseDown(PointerEventData eventData) { HoldStart(SecondsIncrease); } /// /// Process pointer down event on seconds decrease button. /// /// Current event data. public void ButtonSecondsDecreaseDown(PointerEventData eventData) { HoldStart(SecondsDecrease); } #endregion /// /// Upgrade this instance. /// public virtual void Upgrade() { } #if UNITY_EDITOR /// /// Validate this instance. /// protected override void OnValidate() { Compatibility.Upgrade(this); } #endif #region IStylable implementation /// public override bool SetStyle(Style style) { if (InputHoursAdapter != null) { style.Time.InputBackground.ApplyTo(InputHoursAdapter); if (InputHoursAdapter.textComponent != null) { style.Time.InputText.ApplyTo(InputHoursAdapter.textComponent.gameObject); } } if (InputMinutesAdapter != null) { style.Time.InputBackground.ApplyTo(InputMinutesAdapter); if (InputMinutesAdapter.textComponent != null) { style.Time.InputText.ApplyTo(InputMinutesAdapter.textComponent.gameObject); } } if (InputSecondsAdapter != null) { style.Time.InputBackground.ApplyTo(InputSecondsAdapter); if (InputSecondsAdapter.textComponent != null) { style.Time.InputText.ApplyTo(InputSecondsAdapter.textComponent.gameObject); } } style.Time.ButtonIncrease.ApplyTo(ButtonHoursIncrease); style.Time.ButtonDecrease.ApplyTo(ButtonHoursDecrease); style.Time.ButtonIncrease.ApplyTo(ButtonMinutesIncrease); style.Time.ButtonDecrease.ApplyTo(ButtonMinutesDecrease); style.Time.ButtonIncrease.ApplyTo(ButtonSecondsIncrease); style.Time.ButtonDecrease.ApplyTo(ButtonSecondsDecrease); return true; } /// public override bool GetStyle(Style style) { if (InputHoursAdapter != null) { style.Time.InputBackground.GetFrom(InputHoursAdapter); if (InputHoursAdapter.textComponent != null) { style.Time.InputText.GetFrom(InputHoursAdapter.textComponent.gameObject); } } if (InputMinutesAdapter != null) { style.Time.InputBackground.GetFrom(InputMinutesAdapter); if (InputMinutesAdapter.textComponent != null) { style.Time.InputText.GetFrom(InputMinutesAdapter.textComponent.gameObject); } } if (InputSecondsAdapter != null) { style.Time.InputBackground.GetFrom(InputSecondsAdapter); if (InputSecondsAdapter.textComponent != null) { style.Time.InputText.GetFrom(InputSecondsAdapter.textComponent.gameObject); } } style.Time.ButtonIncrease.GetFrom(ButtonHoursIncrease); style.Time.ButtonDecrease.GetFrom(ButtonHoursDecrease); style.Time.ButtonIncrease.GetFrom(ButtonMinutesIncrease); style.Time.ButtonDecrease.GetFrom(ButtonMinutesDecrease); style.Time.ButtonIncrease.GetFrom(ButtonSecondsIncrease); style.Time.ButtonDecrease.GetFrom(ButtonSecondsDecrease); return true; } #endregion } }