|
@@ -6,23 +6,33 @@ using Terminal.Gui.Resources;
|
|
|
|
|
|
namespace Terminal.Gui {
|
|
namespace Terminal.Gui {
|
|
/// <summary>
|
|
/// <summary>
|
|
- /// Provides a step-based "wizard" UI. The Wizard supports multiple steps. Each step (<see cref="WizardStep"/>) can host
|
|
|
|
|
|
+ /// Provides navigation and a user interface (UI) to collect related data across multiple steps. Each step (<see cref="WizardStep"/>) can host
|
|
/// arbitrary <see cref="View"/>s, much like a <see cref="Dialog"/>. Each step also has a pane for help text. Along the
|
|
/// arbitrary <see cref="View"/>s, much like a <see cref="Dialog"/>. Each step also has a pane for help text. Along the
|
|
/// bottom of the Wizard view are customizable buttons enabling the user to navigate forward and backward through the Wizard.
|
|
/// bottom of the Wizard view are customizable buttons enabling the user to navigate forward and backward through the Wizard.
|
|
/// </summary>
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <remarks>
|
|
- /// The Wizard can be shown either as a modal pop-up (the default) or embedded in a containing <see cref="View"/>. To use a a <see cref="View"/>,
|
|
|
|
- /// set <see cref="Toplevel.Modal"/> to `false`.
|
|
|
|
|
|
+ /// The Wizard can be displayed either as a modal (pop-up) <see cref="Window"/> (like <see cref="Dialog"/>) or as an embedded <see cref="View"/>.
|
|
|
|
+ ///
|
|
|
|
+ /// By default, <see cref="Modal"/> is true; launch the Wizard using `Application.Run(wizard)`.
|
|
|
|
+ ///
|
|
|
|
+ /// Set <see cref="Modal"/> to `false` to use Wizard as an embedded View, and add the Wizard to a containing view with <see cref="View.Add(View)"/>.
|
|
|
|
+ ///
|
|
|
|
+ /// When used as a modal pop-up window, the Esc key will cause the <see cref="Cancelled"/> event to fire and (if the event is not cancelled),
|
|
|
|
+ /// will cause <see cref="Application.RequestStop(Toplevel)"/> to be called, closing the Wizard.
|
|
|
|
+ ///
|
|
|
|
+ /// When used as an embedded View, no frame is drawn around the Wizard. To detect if the user wants to cancel
|
|
|
|
+ /// the Wizard, subscrie to the <see cref="Cancelled"/> event.
|
|
|
|
+ ///
|
|
/// </remarks>
|
|
/// </remarks>
|
|
public class Wizard : Dialog {
|
|
public class Wizard : Dialog {
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
- /// One step for the Wizard. The <see cref="WizardStep"/> view is divided horizontally in two. On the left is the
|
|
|
|
|
|
+ /// 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
|
|
/// content view where <see cref="View"/>s can be added, On the right is the help for the step.
|
|
/// content view where <see cref="View"/>s can be added, On the right is the help for the step.
|
|
/// Set <see cref="WizardStep.HelpText"/> to set the help text. If the help text is empty the help pane will not
|
|
/// Set <see cref="WizardStep.HelpText"/> to set the help text. If the help text is empty the help pane will not
|
|
/// be shown.
|
|
/// be shown.
|
|
- /// If there are no Views added to the WizardStep, and the help text is not empty the help text will
|
|
|
|
- /// fill the wizard step.
|
|
|
|
|
|
+ ///
|
|
|
|
+ /// If there are no Views added to the WizardStep the <see cref="HelpText"/> (if not empty) will fill the wizard step.
|
|
/// </summary>
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <remarks>
|
|
/// If <see cref="Button"/>s are added, do not set <see cref="Button.IsDefault"/> to true as this will conflict
|
|
/// If <see cref="Button"/>s are added, do not set <see cref="Button.IsDefault"/> to true as this will conflict
|
|
@@ -35,8 +45,9 @@ namespace Terminal.Gui {
|
|
/// </remarks>
|
|
/// </remarks>
|
|
public class WizardStep : FrameView {
|
|
public class WizardStep : FrameView {
|
|
/// <summary>
|
|
/// <summary>
|
|
- /// The title of the <see cref="WizardStep"/>.
|
|
|
|
|
|
+ /// The title of the <see cref="WizardStep"/>.
|
|
/// </summary>
|
|
/// </summary>
|
|
|
|
+ /// <remarks>The Title is only displayed when the <see cref="Wizard"/> is used as a modal pop-up.</remarks>
|
|
public new ustring Title {
|
|
public new ustring Title {
|
|
get => title;
|
|
get => title;
|
|
set {
|
|
set {
|
|
@@ -45,6 +56,7 @@ namespace Terminal.Gui {
|
|
title = value;
|
|
title = value;
|
|
OnTitleChanged (old, title);
|
|
OnTitleChanged (old, title);
|
|
}
|
|
}
|
|
|
|
+ base.Title = value;
|
|
SetNeedsDisplay ();
|
|
SetNeedsDisplay ();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -81,6 +93,7 @@ namespace Terminal.Gui {
|
|
NewTitle = newTitle;
|
|
NewTitle = newTitle;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
/// <summary>
|
|
/// <summary>
|
|
/// Called before the <see cref="Title"/> changes. Invokes the <see cref="TitleChanging"/> event, which can be cancelled.
|
|
/// Called before the <see cref="Title"/> changes. Invokes the <see cref="TitleChanging"/> event, which can be cancelled.
|
|
/// </summary>
|
|
/// </summary>
|
|
@@ -116,8 +129,7 @@ namespace Terminal.Gui {
|
|
/// </summary>
|
|
/// </summary>
|
|
public event Action<TitleEventArgs> TitleChanged;
|
|
public event Action<TitleEventArgs> TitleChanged;
|
|
|
|
|
|
- // The controlPane is a separate view, so when devs add controls to the Step and help is visible, Y = Pos.AnchorEnd()
|
|
|
|
- // will work as expected.
|
|
|
|
|
|
+ // The contentView works like the ContentView in FrameView.
|
|
private View contentView = new View ();
|
|
private View contentView = new View ();
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
@@ -125,9 +137,9 @@ namespace Terminal.Gui {
|
|
/// the help pane will not be visible and the content will fill the entire WizardStep.
|
|
/// the help pane will not be visible and the content will fill the entire WizardStep.
|
|
/// </summary>
|
|
/// </summary>
|
|
/// <remarks>The help text is displayed using a read-only <see cref="TextView"/>.</remarks>
|
|
/// <remarks>The help text is displayed using a read-only <see cref="TextView"/>.</remarks>
|
|
- public ustring HelpText {
|
|
|
|
- get => helpTextView.Text;
|
|
|
|
- set {
|
|
|
|
|
|
+ public ustring HelpText {
|
|
|
|
+ get => helpTextView.Text;
|
|
|
|
+ set {
|
|
helpTextView.Text = value;
|
|
helpTextView.Text = value;
|
|
ShowHide ();
|
|
ShowHide ();
|
|
SetNeedsDisplay ();
|
|
SetNeedsDisplay ();
|
|
@@ -141,14 +153,12 @@ namespace Terminal.Gui {
|
|
/// </summary>
|
|
/// </summary>
|
|
/// <remarks>The default text is "Back"</remarks>
|
|
/// <remarks>The default text is "Back"</remarks>
|
|
public ustring BackButtonText { get; set; } = ustring.Empty;
|
|
public ustring BackButtonText { get; set; } = ustring.Empty;
|
|
- // TODO: Update button text of Wizard button when step's button text is changed if step is current - this will require step to slueth it's parent
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
/// Sets or gets the text for the next/finish button.
|
|
/// Sets or gets the text for the next/finish button.
|
|
/// </summary>
|
|
/// </summary>
|
|
/// <remarks>The default text is "Next..." if the Pane is not the last pane. Otherwise it is "Finish"</remarks>
|
|
/// <remarks>The default text is "Next..." if the Pane is not the last pane. Otherwise it is "Finish"</remarks>
|
|
public ustring NextButtonText { get; set; } = ustring.Empty;
|
|
public ustring NextButtonText { get; set; } = ustring.Empty;
|
|
- // TODO: Update button text of Wizard button when step's button text is changed if step is current - this will require step to slueth it's parent
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="Wizard"/> class using <see cref="LayoutStyle.Computed"/> positioning.
|
|
/// Initializes a new instance of the <see cref="Wizard"/> class using <see cref="LayoutStyle.Computed"/> positioning.
|
|
@@ -290,7 +300,7 @@ namespace Terminal.Gui {
|
|
ShowHide ();
|
|
ShowHide ();
|
|
}
|
|
}
|
|
|
|
|
|
- } // WizardStep
|
|
|
|
|
|
+ } // end of WizardStep class
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="Wizard"/> class using <see cref="LayoutStyle.Computed"/> positioning.
|
|
/// Initializes a new instance of the <see cref="Wizard"/> class using <see cref="LayoutStyle.Computed"/> positioning.
|
|
@@ -306,7 +316,7 @@ namespace Terminal.Gui {
|
|
/// <summary>
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="Wizard"/> class using <see cref="LayoutStyle.Computed"/> positioning.
|
|
/// Initializes a new instance of the <see cref="Wizard"/> class using <see cref="LayoutStyle.Computed"/> positioning.
|
|
/// </summary>
|
|
/// </summary>
|
|
- /// <param name="title">Title for the Wizard.</param>
|
|
|
|
|
|
+ /// <param name="title">Sets the <see cref="Title"/> for the Wizard.</param>
|
|
/// <remarks>
|
|
/// <remarks>
|
|
/// The Wizard will be vertically and horizontally centered in the container.
|
|
/// The Wizard will be vertically and horizontally centered in the container.
|
|
/// After initialization use <c>X</c>, <c>Y</c>, <c>Width</c>, and <c>Height</c> change size and position.
|
|
/// After initialization use <c>X</c>, <c>Y</c>, <c>Width</c>, and <c>Height</c> change size and position.
|
|
@@ -339,6 +349,12 @@ namespace Terminal.Gui {
|
|
|
|
|
|
Loaded += Wizard_Loaded;
|
|
Loaded += Wizard_Loaded;
|
|
Closing += Wizard_Closing;
|
|
Closing += Wizard_Closing;
|
|
|
|
+
|
|
|
|
+ if (Modal) {
|
|
|
|
+ ClearKeybinding (Command.QuitToplevel);
|
|
|
|
+ AddKeyBinding (Key.Esc, Command.QuitToplevel);
|
|
|
|
+ }
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
private void Wizard_Loaded ()
|
|
private void Wizard_Loaded ()
|
|
@@ -382,16 +398,19 @@ namespace Terminal.Gui {
|
|
///<inheritdoc/>
|
|
///<inheritdoc/>
|
|
public override bool ProcessKey (KeyEvent kb)
|
|
public override bool ProcessKey (KeyEvent kb)
|
|
{
|
|
{
|
|
- switch (kb.Key) {
|
|
|
|
- case Key.Esc:
|
|
|
|
- // Dialog causes ESC to close/cancel; we dont want that with wizard
|
|
|
|
- // Use QuitKey instead.
|
|
|
|
- return false;
|
|
|
|
|
|
+ if (!Modal) {
|
|
|
|
+ switch (kb.Key) {
|
|
|
|
+ case Key.Esc:
|
|
|
|
+ // Dialog causes ESC to RequestStop; we dont want that with a non-modal wizard
|
|
|
|
+ // Instead, we fire the Cancelled event.
|
|
|
|
+ var args = new WizardButtonEventArgs ();
|
|
|
|
+ Cancelled?.Invoke (args);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
return base.ProcessKey (kb);
|
|
return base.ProcessKey (kb);
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
/// Causes the wizad to move to the next enabled step (or last step if <see cref="CurrentStep"/> is not set).
|
|
/// Causes the wizad to move to the next enabled step (or last step if <see cref="CurrentStep"/> is not set).
|
|
/// If there is no previous step, does nothing.
|
|
/// If there is no previous step, does nothing.
|
|
@@ -548,6 +567,7 @@ namespace Terminal.Gui {
|
|
/// <summary>
|
|
/// <summary>
|
|
/// The title of the Wizard, shown at the top of the Wizard with " - currentStep.Title" appended.
|
|
/// The title of the Wizard, shown at the top of the Wizard with " - currentStep.Title" appended.
|
|
/// </summary>
|
|
/// </summary>
|
|
|
|
+ /// <remarks>The Title is only displayed when the <see cref="Wizard"/> is used as a modal pop-up.</remarks>
|
|
public new ustring Title {
|
|
public new ustring Title {
|
|
get {
|
|
get {
|
|
// The base (Dialog) Title holds the full title ("Wizard Title - Step Title")
|
|
// The base (Dialog) Title holds the full title ("Wizard Title - Step Title")
|
|
@@ -585,9 +605,9 @@ namespace Terminal.Gui {
|
|
public event Action<WizardButtonEventArgs> MovingBack;
|
|
public event Action<WizardButtonEventArgs> MovingBack;
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
- /// This event is raised when the Next/Finish button in the <see cref="Wizard"/> is clicked. The Next/Finish button is always
|
|
|
|
- /// the last button in the array of Buttons passed to the <see cref="Wizard"/> constructor, if any. This event is only
|
|
|
|
- /// raised if the <see cref="CurrentStep"/> is the last Step in the Wizard flow
|
|
|
|
|
|
+ /// This event is raised when the Next/Finish button in the <see cref="Wizard"/> is clicked (or the user presses Enter).
|
|
|
|
+ /// The Next/Finish button is always the last button in the array of Buttons passed to the <see cref="Wizard"/> constructor,
|
|
|
|
+ /// if any. This event is only raised if the <see cref="CurrentStep"/> is the last Step in the Wizard flow
|
|
/// (otherwise the <see cref="Finished"/> event is raised).
|
|
/// (otherwise the <see cref="Finished"/> event is raised).
|
|
/// </summary>
|
|
/// </summary>
|
|
public event Action<WizardButtonEventArgs> MovingNext;
|
|
public event Action<WizardButtonEventArgs> MovingNext;
|
|
@@ -600,9 +620,10 @@ namespace Terminal.Gui {
|
|
/// </summary>
|
|
/// </summary>
|
|
public event Action<WizardButtonEventArgs> Finished;
|
|
public event Action<WizardButtonEventArgs> Finished;
|
|
|
|
|
|
-
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
- /// This event is raised when the user has cancelled the <see cref="Wizard"/> (with Ctrl-Q or ESC).
|
|
|
|
|
|
+ /// This event is raised when the user has cancelled the <see cref="Wizard"/> by pressin the Esc key.
|
|
|
|
+ /// To prevent a <see cref="Modal"/> Wizard from
|
|
|
|
+ /// closing, cancel the event by setting <see cref="WizardButtonEventArgs.Cancel"/> to `true` before returning from the event handler.
|
|
/// </summary>
|
|
/// </summary>
|
|
public event Action<WizardButtonEventArgs> Cancelled;
|
|
public event Action<WizardButtonEventArgs> Cancelled;
|
|
|
|
|
|
@@ -762,7 +783,15 @@ namespace Terminal.Gui {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- /// <inheritdoc/>
|
|
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// Determines whether the <see cref="Wizard"/> is displayed as modal pop-up or not.
|
|
|
|
+ ///
|
|
|
|
+ /// The default is `true`. The Wizard will be shown with a frame with <see cref="Title"/> and will behave like
|
|
|
|
+ /// any <see cref="Toplevel"/> window.
|
|
|
|
+ ///
|
|
|
|
+ /// If set to `false` the Wizard will have no frame and will behave like any embedded <see cref="View"/>.
|
|
|
|
+ ///
|
|
|
|
+ /// </summary>
|
|
public new bool Modal {
|
|
public new bool Modal {
|
|
get => base.Modal;
|
|
get => base.Modal;
|
|
set {
|
|
set {
|