ScrollView.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. using System;
  2. namespace Terminal.Gui {
  3. /// <summary>
  4. ///
  5. /// </summary>
  6. /// <remarks>
  7. /// <para>
  8. /// The subviews that are added to this scrollview are offset by the
  9. /// ContentOffset property. The view itself is a window into the
  10. /// space represented by the ContentSize.
  11. /// </para>
  12. /// <para>
  13. ///
  14. /// </para>
  15. /// </remarks>
  16. public class ScrollView : View {
  17. View contentView;
  18. public ScrollView (Rect frame) : base (frame)
  19. {
  20. contentView = new View (frame);
  21. base.Add (contentView);
  22. }
  23. Size contentSize;
  24. Point contentOffset;
  25. bool showHorizontalScrollIndicator;
  26. bool showVerticalScrollIndicator;
  27. /// <summary>
  28. /// Represents the contents of the data shown inside the scrolview
  29. /// </summary>
  30. /// <value>The size of the content.</value>
  31. public Size ContentSize {
  32. get {
  33. return contentSize;
  34. }
  35. set {
  36. contentSize = value;
  37. contentView.Frame = new Rect (contentOffset, value);
  38. }
  39. }
  40. /// <summary>
  41. /// Represents the top left corner coordinate that is displayed by the scrollview
  42. /// </summary>
  43. /// <value>The content offset.</value>
  44. public Point ContentOffset {
  45. get {
  46. return contentOffset;
  47. }
  48. set {
  49. contentOffset = new Point (-value.X, -value.Y);
  50. contentView.Frame = new Rect (contentOffset, contentSize);
  51. }
  52. }
  53. /// <summary>
  54. /// Adds the view to the scrollview.
  55. /// </summary>
  56. /// <param name="view">The view to add to the scrollview.</param>
  57. public override void Add (View view)
  58. {
  59. contentView.Add (view);
  60. }
  61. /// <summary>
  62. /// Gets or sets the visibility for the horizontal scroll indicator.
  63. /// </summary>
  64. /// <value><c>true</c> if show vertical scroll indicator; otherwise, <c>false</c>.</value>
  65. public bool ShowHorizontalScrollIndicator {
  66. get => showHorizontalScrollIndicator;
  67. set {
  68. showHorizontalScrollIndicator = value;
  69. SetNeedsDisplay ();
  70. }
  71. }
  72. /// <summary>
  73. /// /// Gets or sets the visibility for the vertical scroll indicator.
  74. /// </summary>
  75. /// <value><c>true</c> if show vertical scroll indicator; otherwise, <c>false</c>.</value>
  76. public bool ShowVerticalScrollIndicator {
  77. get => showVerticalScrollIndicator;
  78. set {
  79. showVerticalScrollIndicator = value;
  80. SetNeedsDisplay ();
  81. }
  82. }
  83. /// <summary>
  84. /// This event is raised when the contents have scrolled
  85. /// </summary>
  86. public event Action<ScrollView> Scrolled;
  87. public override void Redraw(Rect region)
  88. {
  89. var oldClip = ClipToBounds ();
  90. base.Redraw(region);
  91. Attribute last = ColorScheme.Normal;
  92. Driver.SetAttribute (last);
  93. void SetColor (Attribute a)
  94. {
  95. if (a != last)
  96. Driver.SetAttribute (a);
  97. last = a;
  98. }
  99. Driver.Clip = oldClip;
  100. if (true || ShowVerticalScrollIndicator) {
  101. var bh = Bounds.Height;
  102. var by1 = -contentOffset.Y * bh/ contentSize.Height;
  103. var by2 = (-contentOffset.Y+bh) * bh/ contentSize.Height;
  104. for (int y = 0; y < bh; y++) {
  105. Move (Bounds.Width - 1, y);
  106. SpecialChar special;
  107. if (y < by1 || y > by2)
  108. special = SpecialChar.Stipple;
  109. else {
  110. if (by2 - by1 == 0)
  111. special = SpecialChar.Diamond;
  112. else {
  113. if (y == by1)
  114. special = SpecialChar.TopTee;
  115. else if (y == by2)
  116. special = SpecialChar.BottomTee;
  117. else
  118. special = SpecialChar.VLine;
  119. }
  120. }
  121. Driver.AddSpecial (special);
  122. }
  123. }
  124. if (true || ShowHorizontalScrollIndicator){
  125. var bw = Bounds.Width;
  126. var bx1 = -contentOffset.X * bw / contentSize.Width;
  127. var bx2 = (-contentOffset.X + bw) * bw / contentSize.Width;
  128. Move (0, Bounds.Height - 1);
  129. for (int x = 0; x < bw; x++) {
  130. SpecialChar special;
  131. if (x < bx1 || x > bx2){
  132. special = SpecialChar.Stipple;
  133. } else {
  134. if (bx2 - bx1 == 0)
  135. special = SpecialChar.Diamond;
  136. else {
  137. if (x == bx1)
  138. special = SpecialChar.LeftTee;
  139. else if (x == bx2)
  140. special = SpecialChar.RightTee;
  141. else
  142. special = SpecialChar.HLine;
  143. }
  144. }
  145. Driver.AddSpecial (special);
  146. }
  147. }
  148. }
  149. }
  150. }