WizardStep.cs 6.4 KB

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