2
0

WizardStep.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. namespace Terminal.Gui.Views;
  2. /// <summary>
  3. /// Represents a basic step that is displayed in a <see cref="Wizard"/>. The <see cref="WizardStep"/> view is
  4. /// divided horizontally in two. On the left is the content view where <see cref="View"/>s can be added, On the right
  5. /// is the help for the step. Set <see cref="WizardStep.HelpText"/> to set the help text. If the help text is empty the
  6. /// help pane will not be shown. If there are no Views added to the WizardStep the <see cref="HelpText"/> (if not
  7. /// empty) will fill the wizard step.
  8. /// </summary>
  9. /// <remarks>
  10. /// If <see cref="Button"/>s are added, do not set <see cref="Button.IsDefault"/> to true as this will conflict
  11. /// with the Next button of the Wizard. Subscribe to the <see cref="View.VisibleChanged"/> event to be notified when
  12. /// the step is active; see also: <see cref="Wizard.StepChanged"/>. To enable or disable a step from being shown to the
  13. /// user, set <see cref="View.Enabled"/>.
  14. /// </remarks>
  15. public class WizardStep : View
  16. {
  17. // The contentView works like the ContentView in FrameView.
  18. private readonly View _contentView = new ()
  19. {
  20. CanFocus = true,
  21. TabStop = TabBehavior.TabStop,
  22. Id = "WizardStep._contentView"
  23. };
  24. private readonly TextView _helpTextView = new ()
  25. {
  26. CanFocus = true,
  27. TabStop = TabBehavior.TabStop,
  28. ReadOnly = true,
  29. WordWrap = true,
  30. AllowsTab = false,
  31. Id = "WizardStep._helpTextView"
  32. };
  33. /// <summary>
  34. /// Initializes a new instance of the <see cref="Wizard"/> class.
  35. /// </summary>
  36. public WizardStep ()
  37. {
  38. TabStop = TabBehavior.TabStop;
  39. CanFocus = true;
  40. BorderStyle = LineStyle.None;
  41. base.Add (_contentView);
  42. base.Add (_helpTextView);
  43. // BUGBUG: v2 - Disabling scrolling for now
  44. //var scrollBar = new ScrollBarView (helpTextView, true);
  45. //scrollBar.ChangedPosition += (s,e) => {
  46. // helpTextView.TopRow = scrollBar.Position;
  47. // if (helpTextView.TopRow != scrollBar.Position) {
  48. // scrollBar.Position = helpTextView.TopRow;
  49. // }
  50. // helpTextView.SetNeedsDraw ();
  51. //};
  52. //scrollBar.OtherScrollBarView.ChangedPosition += (s,e) => {
  53. // helpTextView.LeftColumn = scrollBar.OtherScrollBarView.Position;
  54. // if (helpTextView.LeftColumn != scrollBar.OtherScrollBarView.Position) {
  55. // scrollBar.OtherScrollBarView.Position = helpTextView.LeftColumn;
  56. // }
  57. // helpTextView.SetNeedsDraw ();
  58. //};
  59. //scrollBar.VisibleChanged += (s,e) => {
  60. // if (scrollBar.Visible && helpTextView.RightOffset == 0) {
  61. // helpTextView.RightOffset = 1;
  62. // } else if (!scrollBar.Visible && helpTextView.RightOffset == 1) {
  63. // helpTextView.RightOffset = 0;
  64. // }
  65. //};
  66. //scrollBar.OtherScrollBarView.VisibleChanged += (s,e) => {
  67. // if (scrollBar.OtherScrollBarView.Visible && helpTextView.BottomOffset == 0) {
  68. // helpTextView.BottomOffset = 1;
  69. // } else if (!scrollBar.OtherScrollBarView.Visible && helpTextView.BottomOffset == 1) {
  70. // helpTextView.BottomOffset = 0;
  71. // }
  72. //};
  73. //helpTextView.DrawContent += (s,e) => {
  74. // scrollBar.Size = helpTextView.Lines;
  75. // scrollBar.Position = helpTextView.TopRow;
  76. // if (scrollBar.OtherScrollBarView is { }) {
  77. // scrollBar.OtherScrollBarView.Size = helpTextView.Maxlength;
  78. // scrollBar.OtherScrollBarView.Position = helpTextView.LeftColumn;
  79. // }
  80. // scrollBar.LayoutSubViews ();
  81. // scrollBar.Refresh ();
  82. //};
  83. //base.Add (scrollBar);
  84. ShowHide ();
  85. }
  86. /// <summary>Sets or gets the text for the back button. The back button will only be visible on steps after the first step.</summary>
  87. /// <remarks>The default text is "Back"</remarks>
  88. public string BackButtonText { get; set; } = string.Empty;
  89. /// <summary>
  90. /// Sets or gets help text for the <see cref="WizardStep"/>.If <see cref="WizardStep.HelpText"/> is empty the help
  91. /// pane will not be visible and the content will fill the entire WizardStep.
  92. /// </summary>
  93. /// <remarks>The help text is displayed using a read-only <see cref="TextView"/>.</remarks>
  94. public string HelpText
  95. {
  96. get => _helpTextView.Text;
  97. set
  98. {
  99. _helpTextView.Text = value;
  100. ShowHide ();
  101. SetNeedsDraw ();
  102. }
  103. }
  104. /// <summary>Sets or gets the text for the next/finish button.</summary>
  105. /// <remarks>The default text is "Next..." if the Pane is not the last pane. Otherwise it is "Finish"</remarks>
  106. public string NextButtonText { get; set; } = string.Empty;
  107. /// <summary>Add the specified <see cref="View"/> to the <see cref="WizardStep"/>.</summary>
  108. /// <param name="view"><see cref="View"/> to add to this container</param>
  109. public override View Add (View? view)
  110. {
  111. _contentView.Add (view);
  112. if (view!.CanFocus)
  113. {
  114. CanFocus = true;
  115. }
  116. ShowHide ();
  117. return view;
  118. }
  119. /// <summary>Removes a <see cref="View"/> from <see cref="WizardStep"/>.</summary>
  120. /// <remarks></remarks>
  121. public override View? Remove (View? view)
  122. {
  123. SetNeedsDraw ();
  124. View? container = view?.SuperView;
  125. if (container == this)
  126. {
  127. base.Remove (view);
  128. }
  129. else
  130. {
  131. container?.Remove (view);
  132. }
  133. if (_contentView.InternalSubViews.Count < 1)
  134. {
  135. CanFocus = false;
  136. }
  137. ShowHide ();
  138. return view;
  139. }
  140. /// <summary>Removes all <see cref="View"/>s from the <see cref="WizardStep"/>.</summary>
  141. /// <remarks></remarks>
  142. public override IReadOnlyCollection<View> RemoveAll ()
  143. {
  144. IReadOnlyCollection<View> removed = _contentView.RemoveAll ();
  145. ShowHide ();
  146. return removed;
  147. }
  148. /// <summary>Does the work to show and hide the contentView and helpView as appropriate</summary>
  149. internal void ShowHide ()
  150. {
  151. _contentView.Height = Dim.Fill ();
  152. _helpTextView.Height = Dim.Height(_contentView);
  153. _helpTextView.Width = Dim.Fill ();
  154. if (_contentView.InternalSubViews?.Count > 0)
  155. {
  156. if (_helpTextView.Text.Length > 0)
  157. {
  158. _contentView.Width = Dim.Percent (70);
  159. _helpTextView.X = Pos.Right (_contentView);
  160. _helpTextView.Width = Dim.Fill ();
  161. }
  162. else
  163. {
  164. _contentView.Width = Dim.Fill ();
  165. }
  166. }
  167. else
  168. {
  169. if (_helpTextView.Text.Length > 0)
  170. {
  171. _helpTextView.X = 0;
  172. }
  173. // Error - no pane shown
  174. }
  175. _contentView.Visible = _contentView.InternalSubViews?.Count > 0;
  176. _helpTextView.Visible = _helpTextView.Text.Length > 0;
  177. }
  178. } // end of WizardStep class