mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
* trying to make it work * Fixes #1849. Wizard as non-modal doesn't work * Fixes #1855. Window and Frame content view without the margin frame. * Fixing layout of non-modal * WizardSTep is now a FrameView * Now use Modal = false to set visual style automatically * Removed Controls as an explicit construct. Now just Add to WizardStep Co-authored-by: BDisp <bd.bdisp@gmail.com>
This commit is contained in:
@@ -1099,8 +1099,12 @@ namespace Terminal.Gui {
|
||||
{
|
||||
if (_initialized && Driver != null) {
|
||||
var top = new T ();
|
||||
if (top.GetType ().BaseType != typeof (Toplevel)) {
|
||||
throw new ArgumentException (top.GetType ().BaseType.Name);
|
||||
var type = top.GetType ().BaseType;
|
||||
while (type != typeof (Toplevel) && type != typeof (object)) {
|
||||
type = type.BaseType;
|
||||
}
|
||||
if (type != typeof (Toplevel)) {
|
||||
throw new ArgumentException ($"{top.GetType ().Name} must be derived from TopLevel");
|
||||
}
|
||||
Run (top, errorHandler);
|
||||
} else {
|
||||
|
||||
@@ -164,7 +164,7 @@ namespace Terminal.Gui {
|
||||
/// <summary>
|
||||
/// Called from <see cref="Application.Begin(Toplevel)"/> before the <see cref="Toplevel"/> is redraws for the first time.
|
||||
/// </summary>
|
||||
internal virtual void OnLoaded ()
|
||||
virtual public void OnLoaded ()
|
||||
{
|
||||
Loaded?.Invoke ();
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ namespace Terminal.Gui {
|
||||
} else {
|
||||
if (i == 0) {
|
||||
// first (leftmost) button - always hard flush left
|
||||
var left = Bounds.Width - 2;
|
||||
var left = Bounds.Width - ((Border.DrawMarginFrame ? 2 : 0) + Border.BorderThickness.Left + Border.BorderThickness.Right);
|
||||
button.X = Pos.AnchorEnd (left);
|
||||
} else {
|
||||
shiftLeft += button.Frame.Width + (spacing);
|
||||
|
||||
@@ -11,14 +11,18 @@ namespace Terminal.Gui {
|
||||
/// bottom of the Wizard view are customizable buttons enabling the user to navigate forward and backward through the Wizard.
|
||||
/// </summary>
|
||||
/// <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`.
|
||||
/// </remarks>
|
||||
public class Wizard : Dialog {
|
||||
|
||||
/// <summary>
|
||||
/// One step for the Wizard. The <see cref="WizardStep"/> view hosts two sub-views: 1) add <see cref="View"/>s to <see cref="WizardStep.Controls"/>,
|
||||
/// 2) use <see cref="WizardStep.HelpText"/> to set the contents of the <see cref="TextView"/> that shows on the
|
||||
/// right side. Use <see cref="WizardStep.showControls"/> and <see cref="WizardStep.showHelp"/> to
|
||||
/// control wether the control or help pane are shown.
|
||||
/// One step for the 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.
|
||||
/// Set <see cref="WizardStep.HelpText"/> to set the help text. If the help text is empty the help pane will not
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If <see cref="Button"/>s are added, do not set <see cref="Button.IsDefault"/> to true as this will conflict
|
||||
@@ -29,11 +33,11 @@ namespace Terminal.Gui {
|
||||
/// To enable or disable a step from being shown to the user, set <see cref="View.Enabled"/>.
|
||||
///
|
||||
/// </remarks>
|
||||
public class WizardStep : View {
|
||||
public class WizardStep : FrameView {
|
||||
/// <summary>
|
||||
/// The title of the <see cref="WizardStep"/>.
|
||||
/// </summary>
|
||||
public ustring Title {
|
||||
public new ustring Title {
|
||||
get => title;
|
||||
set {
|
||||
if (!OnTitleChanging (title, value)) {
|
||||
@@ -114,23 +118,21 @@ namespace Terminal.Gui {
|
||||
|
||||
// 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.
|
||||
private View controlPane = new FrameView ();
|
||||
private View contentView = new View ();
|
||||
|
||||
/// <summary>
|
||||
/// THe pane that holds the controls for the <see cref="WizardStep"/>. Use <see cref="WizardStep.Controls"/> `Add(View`) to add
|
||||
/// controls. Note that the Controls view is sized to take 70% of the Wizard's width and the <see cref="WizardStep.HelpText"/>
|
||||
/// takes the other 30%. This can be adjusted by setting `Width` from `Dim.Percent(70)` to
|
||||
/// another value. If <see cref="WizardStep.ShowHelp"/> is set to `false` the control pane will fill the entire
|
||||
/// Wizard.
|
||||
/// </summary>
|
||||
public View Controls { get => controlPane; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets or gets help text for the <see cref="WizardStep"/>.If <see cref="WizardStep.ShowHelp"/> is set to
|
||||
/// `false` the control pane will fill the entire wizard.
|
||||
/// Sets or gets help text for the <see cref="WizardStep"/>.If <see cref="WizardStep.HelpText"/> is empty
|
||||
/// the help pane will not be visible and the content will fill the entire WizardStep.
|
||||
/// </summary>
|
||||
/// <remarks>The help text is displayed using a read-only <see cref="TextView"/>.</remarks>
|
||||
public ustring HelpText { get => helpTextView.Text; set => helpTextView.Text = value; }
|
||||
public ustring HelpText {
|
||||
get => helpTextView.Text;
|
||||
set {
|
||||
helpTextView.Text = value;
|
||||
ShowHide ();
|
||||
SetNeedsDisplay ();
|
||||
}
|
||||
}
|
||||
private TextView helpTextView = new TextView ();
|
||||
|
||||
/// <summary>
|
||||
@@ -158,23 +160,14 @@ namespace Terminal.Gui {
|
||||
public WizardStep (ustring title)
|
||||
{
|
||||
this.Title = title; // this.Title holds just the "Wizard Title"; base.Title holds "Wizard Title - Step Title"
|
||||
this.ColorScheme = Colors.Dialog;
|
||||
this.Border.BorderStyle = BorderStyle.Rounded;
|
||||
|
||||
Y = 0;
|
||||
Height = Dim.Fill (1); // for button frame
|
||||
Width = Dim.Fill ();
|
||||
base.Add (contentView);
|
||||
|
||||
Controls.ColorScheme = Colors.Dialog;
|
||||
Controls.Border.BorderStyle = BorderStyle.None;
|
||||
Controls.Border.Padding = new Thickness (0);
|
||||
Controls.Border.BorderThickness = new Thickness (0);
|
||||
this.Add (Controls);
|
||||
|
||||
helpTextView.ColorScheme = Colors.Menu;
|
||||
helpTextView.Y = 0;
|
||||
helpTextView.ColorScheme = Colors.TopLevel;
|
||||
helpTextView.ReadOnly = true;
|
||||
helpTextView.WordWrap = true;
|
||||
this.Add (helpTextView);
|
||||
base.Add (helpTextView);
|
||||
|
||||
ShowHide ();
|
||||
|
||||
@@ -222,70 +215,79 @@ namespace Terminal.Gui {
|
||||
scrollBar.LayoutSubviews ();
|
||||
scrollBar.Refresh ();
|
||||
};
|
||||
this.Add (scrollBar);
|
||||
base.Add (scrollBar);
|
||||
}
|
||||
|
||||
//public override void OnEnabledChanged()
|
||||
//{
|
||||
// if (Enabled) { }
|
||||
// base.OnEnabledChanged ();
|
||||
//}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// If true (the default) the help will be visible. If false, the help will not be shown and the control pane will
|
||||
/// fill the wizard step.
|
||||
/// Does the work to show and hide the contentView and helpView as appropriate
|
||||
/// </summary>
|
||||
public bool ShowHelp {
|
||||
get => showHelp;
|
||||
set {
|
||||
showHelp = value;
|
||||
ShowHide ();
|
||||
}
|
||||
}
|
||||
private bool showHelp = true;
|
||||
|
||||
/// <summary>
|
||||
/// If true (the default) the <see cref="Controls"/> View will be visible. If false, the controls will not be shown and the help will
|
||||
/// fill the wizard step.
|
||||
/// </summary>
|
||||
public bool ShowControls {
|
||||
get => showControls;
|
||||
set {
|
||||
showControls = value;
|
||||
ShowHide ();
|
||||
}
|
||||
}
|
||||
private bool showControls = true;
|
||||
|
||||
/// <summary>
|
||||
/// Does the work to show and hide the controls, help, and buttons as appropriate
|
||||
/// </summary>
|
||||
private void ShowHide ()
|
||||
internal void ShowHide ()
|
||||
{
|
||||
Controls.Height = Dim.Fill (1);
|
||||
helpTextView.Height = Dim.Fill (1);
|
||||
contentView.Height = Dim.Fill ();
|
||||
helpTextView.Height = Dim.Fill ();
|
||||
helpTextView.Width = Dim.Fill ();
|
||||
|
||||
if (showControls) {
|
||||
if (showHelp) {
|
||||
Controls.Width = Dim.Percent (70);
|
||||
helpTextView.X = Pos.Right (Controls);
|
||||
if (contentView.InternalSubviews?.Count > 0) {
|
||||
if (helpTextView.Text.Length > 0) {
|
||||
contentView.Width = Dim.Percent (70);
|
||||
helpTextView.X = Pos.Right (contentView);
|
||||
helpTextView.Width = Dim.Fill ();
|
||||
|
||||
} else {
|
||||
Controls.Width = Dim.Percent (100);
|
||||
contentView.Width = Dim.Percent (100);
|
||||
}
|
||||
} else {
|
||||
if (showHelp) {
|
||||
if (helpTextView.Text.Length > 0) {
|
||||
helpTextView.X = 0;
|
||||
} else {
|
||||
// Error - no pane shown
|
||||
}
|
||||
|
||||
}
|
||||
Controls.Visible = showControls;
|
||||
helpTextView.Visible = showHelp;
|
||||
contentView.Visible = contentView.InternalSubviews?.Count > 0;
|
||||
helpTextView.Visible = helpTextView.Text.Length > 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add the specified <see cref="View"/> to the <see cref="WizardStep"/>.
|
||||
/// </summary>
|
||||
/// <param name="view"><see cref="View"/> to add to this container</param>
|
||||
public override void Add (View view)
|
||||
{
|
||||
contentView.Add (view);
|
||||
if (view.CanFocus)
|
||||
CanFocus = true;
|
||||
ShowHide ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a <see cref="View"/> from <see cref="WizardStep"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// </remarks>
|
||||
public override void Remove (View view)
|
||||
{
|
||||
if (view == null)
|
||||
return;
|
||||
|
||||
SetNeedsDisplay ();
|
||||
var touched = view.Frame;
|
||||
contentView.Remove (view);
|
||||
|
||||
if (contentView.InternalSubviews.Count < 1)
|
||||
this.CanFocus = false;
|
||||
ShowHide ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all <see cref="View"/>s from the <see cref="WizardStep"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// </remarks>
|
||||
public override void RemoveAll ()
|
||||
{
|
||||
contentView.RemoveAll ();
|
||||
ShowHide ();
|
||||
}
|
||||
|
||||
} // WizardStep
|
||||
@@ -316,12 +318,13 @@ namespace Terminal.Gui {
|
||||
// the left and right edge
|
||||
ButtonAlignment = ButtonAlignments.Justify;
|
||||
this.Border.BorderStyle = BorderStyle.Double;
|
||||
this.Border.Padding = new Thickness (0);
|
||||
|
||||
// Add a horiz separator
|
||||
var separator = new LineView (Graphs.Orientation.Horizontal) {
|
||||
Y = Pos.AnchorEnd (2)
|
||||
};
|
||||
Add (separator);
|
||||
//// Add a horiz separator
|
||||
//var separator = new LineView (Graphs.Orientation.Horizontal) {
|
||||
// Y = Pos.AnchorEnd (2)
|
||||
//};
|
||||
//Add (separator);
|
||||
|
||||
// BUGBUG: Space is to work around https://github.com/migueldeicaza/gui.cs/issues/1812
|
||||
backBtn = new Button (Strings.wzBack) { AutoSize = true };
|
||||
@@ -338,6 +341,11 @@ namespace Terminal.Gui {
|
||||
Closing += Wizard_Closing;
|
||||
}
|
||||
|
||||
private void Wizard_Loaded ()
|
||||
{
|
||||
CurrentStep = GetFirstStep (); // gets the first step if CurrentStep == null
|
||||
}
|
||||
|
||||
private bool finishedPressed = false;
|
||||
|
||||
private void Wizard_Closing (ToplevelClosingEventArgs obj)
|
||||
@@ -348,22 +356,19 @@ namespace Terminal.Gui {
|
||||
}
|
||||
}
|
||||
|
||||
private void Wizard_Loaded ()
|
||||
{
|
||||
foreach (var step in steps) {
|
||||
step.Y = 0;
|
||||
}
|
||||
CurrentStep = GetNextStep (); // gets the first step if CurrentStep == null
|
||||
}
|
||||
|
||||
private void NextfinishBtn_Clicked ()
|
||||
{
|
||||
if (CurrentStep == GetLastStep()) {
|
||||
if (CurrentStep == GetLastStep ()) {
|
||||
var args = new WizardButtonEventArgs ();
|
||||
Finished?.Invoke (args);
|
||||
if (!args.Cancel) {
|
||||
finishedPressed = true;
|
||||
Application.RequestStop (this);
|
||||
if (IsCurrentTop) {
|
||||
Application.RequestStop (this);
|
||||
} else {
|
||||
// Wizard was created as a non-modal (just added to another View).
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var args = new WizardButtonEventArgs ();
|
||||
@@ -374,6 +379,19 @@ namespace Terminal.Gui {
|
||||
}
|
||||
}
|
||||
|
||||
///<inheritdoc/>
|
||||
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;
|
||||
}
|
||||
return base.ProcessKey (kb);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
@@ -396,7 +414,7 @@ namespace Terminal.Gui {
|
||||
{
|
||||
LinkedListNode<WizardStep> step = null;
|
||||
if (CurrentStep == null) {
|
||||
// Get last step, assume it is next
|
||||
// Get first step, assume it is next
|
||||
step = steps.First;
|
||||
} else {
|
||||
// Get the step after current
|
||||
@@ -518,10 +536,12 @@ namespace Terminal.Gui {
|
||||
/// <remarks>The "Next..." button of the last step added will read "Finish" (unless changed from default).</remarks>
|
||||
public void AddStep (WizardStep newStep)
|
||||
{
|
||||
steps.AddLast (newStep);
|
||||
this.Add (newStep);
|
||||
SizeStep (newStep);
|
||||
|
||||
newStep.EnabledChanged += UpdateButtonsAndTitle;
|
||||
newStep.TitleChanged += (args) => UpdateButtonsAndTitle ();
|
||||
steps.AddLast (newStep);
|
||||
this.Add (newStep);
|
||||
UpdateButtonsAndTitle ();
|
||||
}
|
||||
|
||||
@@ -679,6 +699,7 @@ namespace Terminal.Gui {
|
||||
// Hide all but the new step
|
||||
foreach (WizardStep step in steps) {
|
||||
step.Visible = (step == newStep);
|
||||
step.ShowHide ();
|
||||
}
|
||||
|
||||
var oldStep = currentStep;
|
||||
@@ -717,9 +738,55 @@ namespace Terminal.Gui {
|
||||
} else {
|
||||
nextfinishBtn.Text = CurrentStep.NextButtonText != ustring.Empty ? CurrentStep.NextButtonText : Strings.wzNext; // "_Next...";
|
||||
}
|
||||
|
||||
SizeStep (CurrentStep);
|
||||
|
||||
SetNeedsLayout ();
|
||||
LayoutSubviews ();
|
||||
Redraw (Bounds);
|
||||
}
|
||||
|
||||
private void SizeStep (WizardStep step)
|
||||
{
|
||||
if (Modal) {
|
||||
// If we're modal, then we expand the WizardStep so that the top and side
|
||||
// borders and not visible. The bottom border is the separator above the buttons.
|
||||
step.X = step.Y = -1;
|
||||
step.Height = Dim.Fill (1); // for button frame
|
||||
step.Width = Dim.Fill (-1);
|
||||
} else {
|
||||
// If we're not a modal, then we show the border around the WizardStep
|
||||
step.X = step.Y = 0;
|
||||
step.Height = Dim.Fill (1); // for button frame
|
||||
step.Width = Dim.Fill (0);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public new bool Modal {
|
||||
get => base.Modal;
|
||||
set {
|
||||
base.Modal = value;
|
||||
foreach (var step in steps) {
|
||||
SizeStep (step);
|
||||
}
|
||||
if (base.Modal) {
|
||||
ColorScheme = Colors.Dialog;
|
||||
Border.BorderStyle = BorderStyle.Rounded;
|
||||
Border.Effect3D = true;
|
||||
Border.DrawMarginFrame = true;
|
||||
} else {
|
||||
if (SuperView != null) {
|
||||
ColorScheme = SuperView.ColorScheme;
|
||||
} else {
|
||||
ColorScheme = Colors.Base;
|
||||
}
|
||||
CanFocus = true;
|
||||
Border.Effect3D = false;
|
||||
Border.BorderStyle = BorderStyle.None;
|
||||
Border.DrawMarginFrame = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,10 @@
|
||||
"Buttons": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "Buttons"
|
||||
},
|
||||
"WizardAsView": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "WizardAsView"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -146,6 +146,8 @@ namespace UICatalog.Scenarios {
|
||||
};
|
||||
showDialogButton.Clicked += () => {
|
||||
try {
|
||||
Dialog dialog = null;
|
||||
|
||||
int width = 0;
|
||||
int.TryParse (widthEdit.Text.ToString (), out width);
|
||||
int height = 0;
|
||||
@@ -182,7 +184,7 @@ namespace UICatalog.Scenarios {
|
||||
|
||||
// This tests dynamically adding buttons; ensuring the dialog resizes if needed and
|
||||
// the buttons are laid out correctly
|
||||
var dialog = new Dialog (titleEdit.Text, width, height,
|
||||
dialog = new Dialog (titleEdit.Text, width, height,
|
||||
buttons.ToArray ()) {
|
||||
ButtonAlignment = (Dialog.ButtonAlignments)styleRadioGroup.SelectedItem
|
||||
};
|
||||
@@ -204,6 +206,7 @@ namespace UICatalog.Scenarios {
|
||||
button.Clicked += () => {
|
||||
clicked = buttonId;
|
||||
Application.RequestStop ();
|
||||
|
||||
};
|
||||
buttons.Add (button);
|
||||
dialog.AddButton (button);
|
||||
@@ -223,10 +226,12 @@ namespace UICatalog.Scenarios {
|
||||
}
|
||||
dialog.LayoutSubviews ();
|
||||
};
|
||||
dialog.Closed += (args) => {
|
||||
buttonPressedLabel.Text = $"{clicked}";
|
||||
};
|
||||
dialog.Add (addChar);
|
||||
|
||||
Application.Run (dialog);
|
||||
buttonPressedLabel.Text = $"{clicked}";
|
||||
|
||||
} catch (FormatException) {
|
||||
buttonPressedLabel.Text = "Invalid Options";
|
||||
|
||||
102
UICatalog/Scenarios/WizardAsView.cs
Normal file
102
UICatalog/Scenarios/WizardAsView.cs
Normal file
@@ -0,0 +1,102 @@
|
||||
using NStack;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Terminal.Gui;
|
||||
|
||||
namespace UICatalog.Scenarios {
|
||||
[ScenarioMetadata (Name: "WizardAsView", Description: "Shows using the Wizard class in an non-modal way")]
|
||||
[ScenarioCategory ("Dialogs")]
|
||||
public class WizardAsView : Scenario {
|
||||
|
||||
public override void Init (Toplevel top, ColorScheme colorScheme)
|
||||
{
|
||||
Top = Application.Top;
|
||||
|
||||
var menu = new MenuBar (new MenuBarItem [] {
|
||||
new MenuBarItem ("_File", new MenuItem [] {
|
||||
new MenuItem ("_Restart Configuration...", "", () => MessageBox.Query ("Wizaard", "Are you sure you want to reset the Wizard and start over?", "Ok", "Cancel")),
|
||||
new MenuItem ("Re_boot Server...", "", () => MessageBox.Query ("Wizaard", "Are you sure you want to reboot the server start over?", "Ok", "Cancel")),
|
||||
new MenuItem ("_Shutdown Server...", "", () => MessageBox.Query ("Wizaard", "Are you sure you want to cancel setup and shutdown?", "Ok", "Cancel")),
|
||||
})
|
||||
});
|
||||
Top.Add (menu);
|
||||
|
||||
// No need for a Title because the border is disabled
|
||||
var wizard = new Wizard () {
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Width = Dim.Fill (),
|
||||
Height = Dim.Fill (),
|
||||
};
|
||||
|
||||
// Set Mdoal to false to cause the Wizard class to render without a frame and
|
||||
// behave like an non-modal View (vs. a modal/pop-up Window).
|
||||
wizard.Modal = false;
|
||||
|
||||
wizard.MovingBack += (args) => {
|
||||
//args.Cancel = true;
|
||||
//actionLabel.Text = "Moving Back";
|
||||
};
|
||||
|
||||
wizard.MovingNext += (args) => {
|
||||
//args.Cancel = true;
|
||||
//actionLabel.Text = "Moving Next";
|
||||
};
|
||||
|
||||
wizard.Finished += (args) => {
|
||||
//args.Cancel = true;
|
||||
MessageBox.Query ("Setup Wizard", "Finished", "Ok");
|
||||
Application.RequestStop ();
|
||||
};
|
||||
|
||||
// Add 1st step
|
||||
var firstStep = new Wizard.WizardStep ("End User License Agreement");
|
||||
wizard.AddStep (firstStep);
|
||||
firstStep.NextButtonText = "Accept!";
|
||||
firstStep.HelpText = "This is the End User License Agreement.\n\n\n\n\n\nThis is a test of the emergency broadcast system. This is a test of the emergency broadcast system.\nThis is a test of the emergency broadcast system.\n\n\nThis is a test of the emergency broadcast system.\n\nThis is a test of the emergency broadcast system.\n\n\n\nThe end of the EULA.";
|
||||
|
||||
// Add 2nd step
|
||||
var secondStep = new Wizard.WizardStep ("Second Step");
|
||||
wizard.AddStep (secondStep);
|
||||
secondStep.HelpText = "This is the help text for the Second Step.\n\nPress the button to change the Title.\n\nIf First Name is empty the step will prevent moving to the next step.";
|
||||
|
||||
var buttonLbl = new Label () { Text = "Second Step Button: ", X = 0, Y = 0 };
|
||||
var button = new Button () {
|
||||
Text = "Press Me to Rename Step",
|
||||
X = Pos.Right (buttonLbl),
|
||||
Y = Pos.Top (buttonLbl)
|
||||
};
|
||||
button.Clicked += () => {
|
||||
secondStep.Title = "2nd Step";
|
||||
MessageBox.Query ("Wizard Scenario", "This Wizard Step's title was changed to '2nd Step'", "Ok");
|
||||
};
|
||||
secondStep.Add (buttonLbl, button);
|
||||
var lbl = new Label () { Text = "First Name: ", X = Pos.Left (buttonLbl), Y = Pos.Bottom (buttonLbl) };
|
||||
var firstNameField = new TextField () { Text = "Number", Width = 30, X = Pos.Right (lbl), Y = Pos.Top (lbl) };
|
||||
secondStep.Add (lbl, firstNameField);
|
||||
lbl = new Label () { Text = "Last Name: ", X = Pos.Left (buttonLbl), Y = Pos.Bottom (lbl) };
|
||||
var lastNameField = new TextField () { Text = "Six", Width = 30, X = Pos.Right (lbl), Y = Pos.Top (lbl) };
|
||||
secondStep.Add (lbl, lastNameField);
|
||||
|
||||
// Add last step
|
||||
var lastStep = new Wizard.WizardStep ("The last step");
|
||||
wizard.AddStep (lastStep);
|
||||
lastStep.HelpText = "The wizard is complete!\n\nPress the Finish button to continue.\n\nPressing ESC will cancel the wizard.";
|
||||
|
||||
// When run as a modal, Wizard gets a Loading event where it sets the
|
||||
// Current Step. But when running non-modal it must be done manually.
|
||||
wizard.CurrentStep = wizard.GetNextStep ();
|
||||
|
||||
Top.Add (wizard);
|
||||
Application.Run (Top);
|
||||
}
|
||||
|
||||
public override void Run ()
|
||||
{
|
||||
// Do nothing in the override because we call Application.Run above
|
||||
// (just to make it clear how the Top is being run and not the Wizard).
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,12 +6,14 @@ using System.Text;
|
||||
using Terminal.Gui;
|
||||
|
||||
namespace UICatalog.Scenarios {
|
||||
[ScenarioMetadata (Name: "Wizards", Description: "Demonstrates how to the Wizard class")]
|
||||
[ScenarioMetadata (Name: "Wizards", Description: "Demonstrates the Wizard class")]
|
||||
[ScenarioCategory ("Dialogs")]
|
||||
public class Wizards : Scenario {
|
||||
public override void Setup ()
|
||||
{
|
||||
// Set the colorschem to Base so the non-modal part of the demo looks right
|
||||
Win.ColorScheme = Colors.Base;
|
||||
|
||||
var frame = new FrameView ("Wizard Options") {
|
||||
X = Pos.Center (),
|
||||
Y = 0,
|
||||
@@ -71,18 +73,9 @@ namespace UICatalog.Scenarios {
|
||||
};
|
||||
frame.Add (titleEdit);
|
||||
|
||||
var useStepView = new CheckBox () {
|
||||
Text = "Add 3rd step controls to WizardStep instead of WizardStep.Controls",
|
||||
Checked = false,
|
||||
X = Pos.Left (titleEdit),
|
||||
Y = Pos.Bottom (titleEdit)
|
||||
};
|
||||
frame.Add (useStepView);
|
||||
|
||||
|
||||
void Top_Loaded ()
|
||||
{
|
||||
frame.Height = Dim.Height (widthEdit) + Dim.Height (heightEdit) + Dim.Height (titleEdit) + Dim.Height (useStepView) + 2;
|
||||
frame.Height = Dim.Height (widthEdit) + Dim.Height (heightEdit) + Dim.Height (titleEdit) + 2;
|
||||
Top.Loaded -= Top_Loaded;
|
||||
}
|
||||
Top.Loaded += Top_Loaded;
|
||||
@@ -93,17 +86,28 @@ namespace UICatalog.Scenarios {
|
||||
TextAlignment = Terminal.Gui.TextAlignment.Right,
|
||||
};
|
||||
Win.Add (label);
|
||||
var actionLabel = new Label (" ") {
|
||||
|
||||
var actionLabel = new Label ("") {
|
||||
X = Pos.Right (label),
|
||||
Y = Pos.AnchorEnd (1),
|
||||
ColorScheme = Colors.Error,
|
||||
};
|
||||
Win.Add (actionLabel);
|
||||
|
||||
var modalCheckBox = new CheckBox ("Modal (pop-up)") {
|
||||
X = Pos.Center (),
|
||||
Y = Pos.Bottom (frame) + 2,
|
||||
AutoSize = true,
|
||||
Checked = true
|
||||
};
|
||||
Win.Add (modalCheckBox);
|
||||
|
||||
var showWizardButton = new Button ("Show Wizard") {
|
||||
X = Pos.Center (),
|
||||
Y = Pos.Bottom (frame) + 2,
|
||||
Y = Pos.Bottom (modalCheckBox) + 1,
|
||||
IsDefault = true,
|
||||
};
|
||||
|
||||
showWizardButton.Clicked += () => {
|
||||
try {
|
||||
int width = 0;
|
||||
@@ -116,6 +120,8 @@ namespace UICatalog.Scenarios {
|
||||
return;
|
||||
}
|
||||
|
||||
actionLabel.Text = ustring.Empty;
|
||||
|
||||
var wizard = new Wizard (titleEdit.Text) {
|
||||
Width = width,
|
||||
Height = height
|
||||
@@ -143,22 +149,14 @@ namespace UICatalog.Scenarios {
|
||||
|
||||
// Add 1st step
|
||||
var firstStep = new Wizard.WizardStep ("End User License Agreement");
|
||||
wizard.AddStep (firstStep);
|
||||
firstStep.ShowControls = false;
|
||||
firstStep.NextButtonText = "Accept!";
|
||||
firstStep.HelpText = "This is the End User License Agreement.\n\n\n\n\n\nThis is a test of the emergency broadcast system. This is a test of the emergency broadcast system.\nThis is a test of the emergency broadcast system.\n\n\nThis is a test of the emergency broadcast system.\n\nThis is a test of the emergency broadcast system.\n\n\n\nThe end of the EULA.";
|
||||
wizard.AddStep (firstStep);
|
||||
|
||||
// Add 2nd step
|
||||
var secondStep = new Wizard.WizardStep ("Second Step");
|
||||
wizard.AddStep (secondStep);
|
||||
secondStep.HelpText = "This is the help text for the Second Step.\n\nPress the button demo changing the Title.\n\nIf First Name is empty the step will prevent moving to the next step.";
|
||||
|
||||
View viewForControls = secondStep.Controls;
|
||||
ustring frameMsg = "Added to WizardStep.Controls";
|
||||
if (useStepView.Checked) {
|
||||
viewForControls = secondStep;
|
||||
frameMsg = "Added to WizardStep directly";
|
||||
}
|
||||
secondStep.HelpText = "This is the help text for the Second Step.\n\nPress the button to change the Title.\n\nIf First Name is empty the step will prevent moving to the next step.";
|
||||
|
||||
var buttonLbl = new Label () { Text = "Second Step Button: ", X = 1, Y = 1 };
|
||||
var button = new Button () {
|
||||
@@ -170,28 +168,25 @@ namespace UICatalog.Scenarios {
|
||||
secondStep.Title = "2nd Step";
|
||||
MessageBox.Query ("Wizard Scenario", "This Wizard Step's title was changed to '2nd Step'");
|
||||
};
|
||||
viewForControls.Add (buttonLbl, button);
|
||||
secondStep.Add (buttonLbl, button);
|
||||
var lbl = new Label () { Text = "First Name: ", X = 1, Y = Pos.Bottom (buttonLbl) };
|
||||
var firstNameField = new TextField () { Text = "Number", Width = 30, X = Pos.Right (lbl), Y = Pos.Top (lbl) };
|
||||
viewForControls.Add (lbl, firstNameField);
|
||||
secondStep.Add (lbl, firstNameField);
|
||||
lbl = new Label () { Text = "Last Name: ", X = 1, Y = Pos.Bottom (lbl) };
|
||||
var lastNameField = new TextField () { Text = "Six", Width = 30, X = Pos.Right (lbl), Y = Pos.Top (lbl) };
|
||||
viewForControls.Add (lbl, lastNameField);
|
||||
secondStep.Add (lbl, lastNameField);
|
||||
var thirdStepEnabledCeckBox = new CheckBox () { Text = "Enable Step _3", Checked = false, X = Pos.Left (lastNameField), Y = Pos.Bottom (lastNameField) };
|
||||
viewForControls.Add (thirdStepEnabledCeckBox);
|
||||
secondStep.Add (thirdStepEnabledCeckBox);
|
||||
|
||||
// Add a frame to demonstrate difference between adding controls to
|
||||
// WizardStep.Controls vs. WizardStep directly. This is here to demonstrate why
|
||||
// adding to .Controls is preferred.
|
||||
var frame = new FrameView ($"A Broken Frame - {frameMsg}") {
|
||||
// Add a frame
|
||||
var frame = new FrameView ($"A Broken Frame (by Depeche Mode)") {
|
||||
X = 0,
|
||||
Y = Pos.Bottom (thirdStepEnabledCeckBox) + 2,
|
||||
Width = Dim.Fill (),
|
||||
Height = 4,
|
||||
//ColorScheme = Colors.Error,
|
||||
Height = 4
|
||||
};
|
||||
frame.Add (new TextField ("This is a TextField inside of the frame."));
|
||||
viewForControls.Add (frame);
|
||||
secondStep.Add (frame);
|
||||
wizard.StepChanging += (args) => {
|
||||
if (args.OldStep == secondStep && firstNameField.Text.IsEmpty) {
|
||||
args.Cancel = true;
|
||||
@@ -208,7 +203,7 @@ namespace UICatalog.Scenarios {
|
||||
X = 0,
|
||||
Y = 0
|
||||
};
|
||||
thirdStep.Controls.Add (step3Label);
|
||||
thirdStep.Add (step3Label);
|
||||
var progLbl = new Label () { Text = "Third Step ProgressBar: ", X = 1, Y = 10 };
|
||||
var progressBar = new ProgressBar () {
|
||||
X = Pos.Right (progLbl),
|
||||
@@ -216,7 +211,7 @@ namespace UICatalog.Scenarios {
|
||||
Width = 40,
|
||||
Fraction = 0.42F
|
||||
};
|
||||
thirdStep.Controls.Add (progLbl, progressBar);
|
||||
thirdStep.Add (progLbl, progressBar);
|
||||
thirdStep.Enabled = thirdStepEnabledCeckBox.Checked;
|
||||
thirdStepEnabledCeckBox.Toggled += (args) => {
|
||||
thirdStep.Enabled = thirdStepEnabledCeckBox.Checked;
|
||||
@@ -225,17 +220,30 @@ namespace UICatalog.Scenarios {
|
||||
// Add 4th step
|
||||
var fourthStep = new Wizard.WizardStep ("Step Four");
|
||||
wizard.AddStep (fourthStep);
|
||||
fourthStep.ShowHelp = false;
|
||||
var someText = new TextView () {
|
||||
Text = "This step (Step Four) shows how to hide the Help pane. The control pane contains this TextView (but it's hard to tell it's a TextView because of Issue #1800).",
|
||||
Text = "This step (Step Four) shows how to show/hide the Help pane. The step contains this TextView (but it's hard to tell it's a TextView because of Issue #1800).",
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Width = Dim.Fill (),
|
||||
Height = Dim.Fill (),
|
||||
Height = Dim.Fill (1),
|
||||
WordWrap = true,
|
||||
AllowsTab = false
|
||||
AllowsTab = false,
|
||||
};
|
||||
fourthStep.Controls.Add (someText);
|
||||
var help = "This is helpful.";
|
||||
fourthStep.Add (someText);
|
||||
var hideHelpBtn = new Button () {
|
||||
Text = "Press me to show/hide help",
|
||||
X = Pos.Center (),
|
||||
Y = Pos.AnchorEnd(1)
|
||||
};
|
||||
hideHelpBtn.Clicked += () => {
|
||||
if (fourthStep.HelpText.Length > 0) {
|
||||
fourthStep.HelpText = ustring.Empty;
|
||||
} else {
|
||||
fourthStep.HelpText = help;
|
||||
}
|
||||
};
|
||||
fourthStep.Add (hideHelpBtn);
|
||||
fourthStep.NextButtonText = "Go To Last Step";
|
||||
var scrollBar = new ScrollBarView (someText, true);
|
||||
|
||||
@@ -265,7 +273,7 @@ namespace UICatalog.Scenarios {
|
||||
scrollBar.LayoutSubviews ();
|
||||
scrollBar.Refresh ();
|
||||
};
|
||||
fourthStep.Controls.Add (scrollBar);
|
||||
fourthStep.Add (scrollBar);
|
||||
|
||||
// Add last step
|
||||
var lastStep = new Wizard.WizardStep ("The last step");
|
||||
@@ -283,15 +291,30 @@ namespace UICatalog.Scenarios {
|
||||
finalFinalStep.Enabled = finalFinalStepEnabledCeckBox.Checked;
|
||||
};
|
||||
|
||||
Application.Run (wizard);
|
||||
if (modalCheckBox.Checked) {
|
||||
Application.Run (wizard);
|
||||
} else {
|
||||
// Disable the Show button so this only happens once
|
||||
showWizardButton.Visible = false;
|
||||
// To use Wizard as a View, you must set Modal = false
|
||||
wizard.Modal = false;
|
||||
|
||||
// When run as a modal, Wizard gets a Loading event where it sets the
|
||||
// Current Step. But when running non-modal it must be done manually.
|
||||
wizard.CurrentStep = wizard.GetNextStep ();
|
||||
|
||||
Win.Add (wizard);
|
||||
|
||||
// Ensure the wizard has focus
|
||||
wizard.SetFocus ();
|
||||
|
||||
}
|
||||
|
||||
} catch (FormatException) {
|
||||
actionLabel.Text = "Invalid Options";
|
||||
}
|
||||
};
|
||||
Win.Add (showWizardButton);
|
||||
|
||||
Win.Add (actionLabel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ namespace Terminal.Gui.Views {
|
||||
var topRow = $"{d.ULDCorner} {title}{stepTitle} {new String (d.HDLine.ToString () [0], width - title.Length - stepTitle.Length - 4)}{d.URDCorner}";
|
||||
var row2 = $"{d.VDLine}{new String (' ', width - 2)}{d.VDLine}";
|
||||
var row3 = row2;
|
||||
var separatorRow = $"{d.VDLine}{new String (d.HLine.ToString () [0], width - 2)}{d.VDLine}";
|
||||
var separatorRow = $"{d.VDLine}{new String (' ', width - 2)}{d.VDLine}";
|
||||
var buttonRow = $"{d.VDLine}{btnBack}{new String (' ', width - btnBack.Length - btnNext.Length - 2)}{btnNext}{d.VDLine}";
|
||||
var bottomRow = $"{d.LLDCorner}{new String (d.HDLine.ToString () [0], width - 2)}{d.LRDCorner}";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user