View.ScrollBars.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. #nullable enable
  2. namespace Terminal.Gui;
  3. public partial class View
  4. {
  5. private Lazy<ScrollBar> _horizontalScrollBar;
  6. private Lazy<ScrollBar> _verticalScrollBar;
  7. /// <summary>
  8. /// Initializes the ScrollBars of the View. Called by the constructor.
  9. /// </summary>
  10. private void SetupScrollBars ()
  11. {
  12. _horizontalScrollBar = new (
  13. () =>
  14. {
  15. var scrollBar = new ScrollBar
  16. {
  17. Orientation = Orientation.Horizontal,
  18. X = 0,
  19. Y = Pos.AnchorEnd (),
  20. Width = Dim.Fill (
  21. Dim.Func (
  22. () =>
  23. {
  24. if (_verticalScrollBar.IsValueCreated)
  25. {
  26. return _verticalScrollBar.Value.Visible ? 1 : 0;
  27. }
  28. return 0;
  29. })),
  30. Size = GetContentSize ().Width,
  31. Visible = false
  32. };
  33. Padding?.Add (scrollBar);
  34. scrollBar.Initialized += (_, _) =>
  35. {
  36. Padding!.Thickness = Padding.Thickness with
  37. {
  38. Bottom = scrollBar.Visible ? Padding.Thickness.Bottom + 1 : 0
  39. };
  40. scrollBar.ContentPositionChanged += (_, args) =>
  41. {
  42. Viewport = Viewport with
  43. {
  44. X = Math.Min (
  45. args.CurrentValue,
  46. GetContentSize ().Width - (Viewport.Width))
  47. };
  48. };
  49. scrollBar.VisibleChanged += (_, _) =>
  50. {
  51. Padding.Thickness = Padding.Thickness with
  52. {
  53. Bottom = scrollBar.Visible
  54. ? Padding.Thickness.Bottom + 1
  55. : Padding.Thickness.Bottom - 1
  56. };
  57. };
  58. };
  59. return scrollBar;
  60. });
  61. _verticalScrollBar = new (
  62. () =>
  63. {
  64. var scrollBar = new ScrollBar
  65. {
  66. Orientation = Orientation.Vertical,
  67. X = Pos.AnchorEnd (),
  68. Y = Pos.Func (() => Padding.Thickness.Top),
  69. Height = Dim.Fill (
  70. Dim.Func (
  71. () =>
  72. {
  73. if (_horizontalScrollBar.IsValueCreated)
  74. {
  75. return _horizontalScrollBar.Value.Visible ? 1 : 0;
  76. }
  77. return 0;
  78. })),
  79. Size = GetContentSize ().Height,
  80. Visible = false
  81. };
  82. Padding?.Add (scrollBar);
  83. scrollBar.Initialized += (_, _) =>
  84. {
  85. if (Padding is { })
  86. {
  87. Padding.Thickness = Padding.Thickness with
  88. {
  89. Right = scrollBar.Visible ? Padding.Thickness.Right + 1 : 0
  90. };
  91. scrollBar.ContentPositionChanged += (_, args) =>
  92. {
  93. Viewport = Viewport with
  94. {
  95. Y = Math.Min (
  96. args.CurrentValue,
  97. GetContentSize ().Height - (Viewport.Height))
  98. };
  99. };
  100. scrollBar.VisibleChanged += (_, _) =>
  101. {
  102. Padding.Thickness = Padding.Thickness with
  103. {
  104. Right = scrollBar.Visible
  105. ? Padding.Thickness.Right + 1
  106. : Padding.Thickness.Right - 1
  107. };
  108. };
  109. }
  110. };
  111. return scrollBar;
  112. });
  113. ViewportChanged += (_, _) =>
  114. {
  115. if (_verticalScrollBar.IsValueCreated)
  116. {
  117. _verticalScrollBar.Value.ContentPosition = Viewport.Y;
  118. }
  119. if (_horizontalScrollBar.IsValueCreated)
  120. {
  121. _horizontalScrollBar.Value.ContentPosition = Viewport.X;
  122. }
  123. };
  124. ContentSizeChanged += (_, _) =>
  125. {
  126. if (_verticalScrollBar.IsValueCreated)
  127. {
  128. _verticalScrollBar.Value.Size = GetContentSize ().Height;
  129. }
  130. if (_horizontalScrollBar.IsValueCreated)
  131. {
  132. _horizontalScrollBar.Value.Size = GetContentSize ().Width;
  133. }
  134. };
  135. }
  136. /// <summary>
  137. /// </summary>
  138. public ScrollBar HorizontalScrollBar => _horizontalScrollBar.Value;
  139. /// <summary>
  140. /// </summary>
  141. public ScrollBar VerticalScrollBar => _verticalScrollBar.Value;
  142. /// <summary>
  143. /// Clean up the ScrollBars of the View. Called by View.Dispose.
  144. /// </summary>
  145. private void DisposeScrollBars ()
  146. {
  147. if (_horizontalScrollBar.IsValueCreated)
  148. {
  149. Padding?.Remove (_horizontalScrollBar.Value);
  150. _horizontalScrollBar.Value.Dispose ();
  151. }
  152. if (_verticalScrollBar.IsValueCreated)
  153. {
  154. Padding?.Remove (_verticalScrollBar.Value);
  155. _verticalScrollBar.Value.Dispose ();
  156. }
  157. }
  158. private void SetScrollBarsKeepContentInAllViewport (ViewportSettings viewportSettings)
  159. {
  160. if (viewportSettings == ViewportSettings.None)
  161. {
  162. _horizontalScrollBar.Value.KeepContentInAllViewport = true;
  163. _verticalScrollBar.Value.KeepContentInAllViewport = true;
  164. }
  165. else if (viewportSettings.HasFlag (ViewportSettings.AllowNegativeX))
  166. {
  167. _horizontalScrollBar.Value.AutoHide = false;
  168. }
  169. else if (viewportSettings.HasFlag (ViewportSettings.AllowNegativeY))
  170. {
  171. _verticalScrollBar.Value.AutoHide = false;
  172. }
  173. else if (viewportSettings.HasFlag (ViewportSettings.AllowNegativeLocation))
  174. {
  175. _horizontalScrollBar.Value.AutoHide = false;
  176. _verticalScrollBar.Value.AutoHide = false;
  177. }
  178. else if (viewportSettings.HasFlag (ViewportSettings.AllowXGreaterThanContentWidth))
  179. {
  180. _horizontalScrollBar.Value.KeepContentInAllViewport = false;
  181. }
  182. else if (viewportSettings.HasFlag (ViewportSettings.AllowYGreaterThanContentHeight))
  183. {
  184. _verticalScrollBar.Value.KeepContentInAllViewport = false;
  185. }
  186. else if (viewportSettings.HasFlag (ViewportSettings.AllowLocationGreaterThanContentSize))
  187. {
  188. _horizontalScrollBar.Value.KeepContentInAllViewport = false;
  189. _verticalScrollBar.Value.KeepContentInAllViewport = false;
  190. }
  191. }
  192. }