2
0

SpinnerView.cs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. using System;
  2. namespace Terminal.Gui {
  3. /// <summary>
  4. /// A 1x1 <see cref="View"/> based on <see cref="Label"/> which displays a spinning
  5. /// line character.
  6. /// </summary>
  7. /// <remarks>
  8. /// By default animation only occurs when you call <see cref="View.SetNeedsDisplay()"/>.
  9. /// Use <see cref="AutoSpin"/> to make the automate calls to <see cref="View.SetNeedsDisplay()"/>.
  10. /// </remarks>
  11. public class SpinnerView : Label {
  12. private Rune [] _runes = new Rune [] { '|', '/', '\u2500', '\\' };
  13. private int _currentIdx = 0;
  14. private DateTime _lastRender = DateTime.MinValue;
  15. private object _timeout;
  16. /// <summary>
  17. /// Gets or sets the number of milliseconds to wait between characters
  18. /// in the spin. Defaults to 250.
  19. /// </summary>
  20. /// <remarks>This is the maximum speed the spinner will rotate at. You still need to
  21. /// call <see cref="View.SetNeedsDisplay()"/> or <see cref="SpinnerView.AutoSpin"/> to
  22. /// advance/start animation.</remarks>
  23. public int SpinDelayInMilliseconds { get; set; } = 250;
  24. /// <summary>
  25. /// Creates a new instance of the <see cref="SpinnerView"/> class.
  26. /// </summary>
  27. public SpinnerView ()
  28. {
  29. Width = 1; Height = 1;
  30. }
  31. /// <inheritdoc/>
  32. public override void Redraw (Rect bounds)
  33. {
  34. if (DateTime.Now - _lastRender > TimeSpan.FromMilliseconds (SpinDelayInMilliseconds)) {
  35. _currentIdx = (_currentIdx + 1) % _runes.Length;
  36. Text = "" + _runes [_currentIdx];
  37. _lastRender = DateTime.Now;
  38. }
  39. base.Redraw (bounds);
  40. }
  41. /// <summary>
  42. /// Automates spinning
  43. /// </summary>
  44. public void AutoSpin ()
  45. {
  46. if (_timeout != null) {
  47. return;
  48. }
  49. _timeout = Application.MainLoop.AddTimeout (
  50. TimeSpan.FromMilliseconds (SpinDelayInMilliseconds), (m) => {
  51. Application.MainLoop.Invoke (this.SetNeedsDisplay);
  52. return true;
  53. });
  54. }
  55. /// <inheritdoc/>
  56. protected override void Dispose (bool disposing)
  57. {
  58. if (_timeout != null) {
  59. Application.MainLoop.RemoveTimeout (_timeout);
  60. _timeout = null;
  61. }
  62. base.Dispose (disposing);
  63. }
  64. }
  65. }