ProgressBar.cs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. using System;
  2. namespace Terminal.Gui {
  3. /// <summary>
  4. /// A Progress Bar view that can indicate progress of an activity visually.
  5. /// </summary>
  6. /// <remarks>
  7. /// <para>
  8. /// <see cref="ProgressBar"/> can operate in two modes, percentage mode, or
  9. /// activity mode. The progress bar starts in percentage mode and
  10. /// setting the Fraction property will reflect on the UI the progress
  11. /// made so far. Activity mode is used when the application has no
  12. /// way of knowing how much time is left, and is started when the <see cref="Pulse"/> method is called.
  13. /// Call <see cref="Pulse"/> repeatedly as progress is made.
  14. /// </para>
  15. /// </remarks>
  16. public class ProgressBar : View {
  17. bool isActivity;
  18. int activityPos, delta;
  19. /// <summary>
  20. /// Initializes a new instance of the <see cref="ProgressBar"/> class, starts in percentage mode with an absolute position and size.
  21. /// </summary>
  22. /// <param name="rect">Rect.</param>
  23. public ProgressBar (Rect rect) : base (rect)
  24. {
  25. CanFocus = false;
  26. fraction = 0;
  27. }
  28. /// <summary>
  29. /// Initializes a new instance of the <see cref="ProgressBar"/> class, starts in percentage mode and uses relative layout.
  30. /// </summary>
  31. public ProgressBar () : base ()
  32. {
  33. CanFocus = false;
  34. fraction = 0;
  35. }
  36. float fraction;
  37. /// <summary>
  38. /// Gets or sets the <see cref="ProgressBar"/> fraction to display, must be a value between 0 and 1.
  39. /// </summary>
  40. /// <value>The fraction representing the progress.</value>
  41. public float Fraction {
  42. get => fraction;
  43. set {
  44. fraction = value;
  45. isActivity = false;
  46. SetNeedsDisplay ();
  47. }
  48. }
  49. /// <summary>
  50. /// Notifies the <see cref="ProgressBar"/> that some progress has taken place.
  51. /// </summary>
  52. /// <remarks>
  53. /// If the <see cref="ProgressBar"/> is is percentage mode, it switches to activity
  54. /// mode. If is in activity mode, the marker is moved.
  55. /// </remarks>
  56. public void Pulse ()
  57. {
  58. if (!isActivity) {
  59. isActivity = true;
  60. activityPos = 0;
  61. delta = 1;
  62. } else {
  63. activityPos += delta;
  64. if (activityPos < 0) {
  65. activityPos = 1;
  66. delta = 1;
  67. } else if (activityPos >= Frame.Width) {
  68. activityPos = Frame.Width - 2;
  69. delta = -1;
  70. }
  71. }
  72. SetNeedsDisplay ();
  73. }
  74. ///<inheritdoc cref="Redraw"/>
  75. public override void Redraw(Rect region)
  76. {
  77. Driver.SetAttribute (ColorScheme.Normal);
  78. int top = Frame.Width;
  79. if (isActivity) {
  80. Move (0, 0);
  81. for (int i = 0; i < top; i++)
  82. if (i == activityPos)
  83. Driver.AddRune (Driver.Stipple);
  84. else
  85. Driver.AddRune (' ');
  86. } else {
  87. Move (0, 0);
  88. int mid = (int)(fraction * top);
  89. int i;
  90. for (i = 0; i < mid; i++)
  91. Driver.AddRune (Driver.Stipple);
  92. for (; i < top; i++)
  93. Driver.AddRune (' ');
  94. }
  95. }
  96. }
  97. }