mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
Wizard fixes (#1802)
* Fixes #1791. Added Pos/Dim Function feature to automate layout. * Added PosFunc/DimFunc class. and some more features. * Fixes #1793. ScrollBarView is hiding if the host fit the available space. * Fixes #1791. View not turn off AutoSize if TextFormatter.Size fit the Anchor. * Done requested changes. * Addressing feedback * Added more AutoSize unit tests. * wip * Refactored and enhanced API * Fixed test Co-authored-by: BDisp <bd.bdisp@gmail.com>
This commit is contained in:
@@ -571,7 +571,6 @@ namespace Terminal.Gui {
|
||||
if (autoSize && value.Anchor (0) != TextFormatter.Size.Width
|
||||
- (TextFormatter.IsHorizontalDirection (TextDirection)
|
||||
&& TextFormatter.Text.Contains (HotKeySpecifier) ? 1 : 0)) {
|
||||
|
||||
autoSize = false;
|
||||
}
|
||||
SetMinWidthHeight ();
|
||||
@@ -600,7 +599,6 @@ namespace Terminal.Gui {
|
||||
if (autoSize && value.Anchor (0) != TextFormatter.Size.Height
|
||||
- (TextFormatter.IsVerticalDirection (TextDirection)
|
||||
&& TextFormatter.Text.Contains (HotKeySpecifier) ? 1 : 0)) {
|
||||
|
||||
autoSize = false;
|
||||
}
|
||||
SetMinWidthHeight ();
|
||||
|
||||
@@ -1659,8 +1659,10 @@ namespace Terminal.Gui {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether pressing the TAB key in a <see cref="TextView"/>
|
||||
/// types a TAB character in the view instead of moving the focus to the next view in the tab order.
|
||||
/// Gets or sets whether the <see cref="TextView"/> inserts a tab character into the text or ignores
|
||||
/// tab input. If set to `false` and the user presses the tab key (or shift-tab) the focus will move to the
|
||||
/// next view (or previous with shift-tab). The default is `true`; if the user presses the tab key, a tab
|
||||
/// character will be inserted into the text.
|
||||
/// </summary>
|
||||
public bool AllowsTab {
|
||||
get => allowsTab;
|
||||
|
||||
@@ -30,6 +30,8 @@ namespace Terminal.Gui {
|
||||
// TODO: Update Wizard title when step title is changed if step is current - this will require step to slueth it's parent
|
||||
private ustring title;
|
||||
|
||||
// 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 ();
|
||||
|
||||
/// <summary>
|
||||
@@ -74,8 +76,8 @@ 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.Menu;
|
||||
|
||||
this.ColorScheme = Colors.Dialog;
|
||||
|
||||
Y = 0;
|
||||
Height = Dim.Fill (1); // for button frame
|
||||
Width = Dim.Fill ();
|
||||
@@ -178,7 +180,7 @@ namespace Terminal.Gui {
|
||||
if (showControls) {
|
||||
if (showHelp) {
|
||||
Controls.Width = Dim.Percent (70);
|
||||
helpTextView.X = Pos.Right (Controls) ;
|
||||
helpTextView.X = Pos.Right (Controls);
|
||||
helpTextView.Width = Dim.Fill ();
|
||||
|
||||
} else {
|
||||
@@ -195,29 +197,7 @@ namespace Terminal.Gui {
|
||||
Controls.Visible = showControls;
|
||||
helpTextView.Visible = showHelp;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the <see cref="CurrentStep"/> is not the first step in the wizard, this button causes
|
||||
/// the <see cref="MovingBack"/> event to be fired and the wizard moves to the previous step.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Use the <see cref="MovingBack"></see> event to be notified when the user attempts to go back.
|
||||
/// </remarks>
|
||||
public Button BackButton { get => backBtn; }
|
||||
private Button backBtn;
|
||||
|
||||
/// <summary>
|
||||
/// If the <see cref="CurrentStep"/> is the last step in the wizard, this button causes
|
||||
/// the <see cref="Finished"/> event to be fired and the wizard to close. If the step is not the last step,
|
||||
/// the <see cref="MovingNext"/> event will be fired and the wizard will move next step.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Use the <see cref="MovingNext"></see> and <see cref="Finished"></see> events to be notified
|
||||
/// when the user attempts go to the next step or finish the wizard.
|
||||
/// </remarks>
|
||||
public Button NextFinishButton { get => nextfinishBtn; }
|
||||
private Button nextfinishBtn;
|
||||
} // WizardStep
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Wizard"/> class using <see cref="LayoutStyle.Computed"/> positioning.
|
||||
@@ -259,46 +239,90 @@ namespace Terminal.Gui {
|
||||
nextfinishBtn.IsDefault = true;
|
||||
AddButton (nextfinishBtn);
|
||||
|
||||
backBtn.Clicked += () => {
|
||||
var args = new WizardStepEventArgs ();
|
||||
MovingBack?.Invoke (args);
|
||||
if (!args.Cancel) {
|
||||
if (currentStep > 0) {
|
||||
CurrentStep--;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
nextfinishBtn.Clicked += () => {
|
||||
if (currentStep == steps.Count - 1) {
|
||||
var args = new WizardStepEventArgs ();
|
||||
Finished?.Invoke (args);
|
||||
if (!args.Cancel) {
|
||||
Application.RequestStop (this);
|
||||
}
|
||||
} else {
|
||||
var args = new WizardStepEventArgs ();
|
||||
MovingNext?.Invoke (args);
|
||||
if (!args.Cancel) {
|
||||
CurrentStep++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Loaded += () => {
|
||||
foreach (var step in steps) {
|
||||
step.Y = 0;
|
||||
}
|
||||
if (steps.Count > 0) {
|
||||
|
||||
CurrentStep = 0;
|
||||
}
|
||||
};
|
||||
backBtn.Clicked += BackBtn_Clicked;
|
||||
nextfinishBtn.Clicked += NextfinishBtn_Clicked;
|
||||
|
||||
Loaded += Wizard_Loaded;
|
||||
Closing += Wizard_Closing;
|
||||
}
|
||||
|
||||
private List<WizardStep> steps = new List<WizardStep> ();
|
||||
private int currentStep = 0;
|
||||
private bool finishedPressed = false;
|
||||
|
||||
private void Wizard_Closing (ToplevelClosingEventArgs obj)
|
||||
{
|
||||
if (!finishedPressed) {
|
||||
var args = new WizardButtonEventArgs ();
|
||||
Cancelled?.Invoke (args);
|
||||
}
|
||||
}
|
||||
|
||||
private void Wizard_Loaded ()
|
||||
{
|
||||
foreach (var step in steps) {
|
||||
step.Y = 0;
|
||||
}
|
||||
if (steps.Count > 0) {
|
||||
CurrentStep = steps.First.Value;
|
||||
}
|
||||
}
|
||||
|
||||
private void NextfinishBtn_Clicked ()
|
||||
{
|
||||
if (CurrentStep == steps.Last.Value) {
|
||||
var args = new WizardButtonEventArgs ();
|
||||
Finished?.Invoke (args);
|
||||
if (!args.Cancel) {
|
||||
finishedPressed = true;
|
||||
Application.RequestStop (this);
|
||||
}
|
||||
} else {
|
||||
var args = new WizardButtonEventArgs ();
|
||||
MovingNext?.Invoke (args);
|
||||
if (!args.Cancel) {
|
||||
var current = steps.Find (CurrentStep);
|
||||
if (current != null && current.Next != null) {
|
||||
GotoStep (current.Next.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void BackBtn_Clicked ()
|
||||
{
|
||||
var args = new WizardButtonEventArgs ();
|
||||
MovingBack?.Invoke (args);
|
||||
if (!args.Cancel) {
|
||||
var current = steps.Find (CurrentStep);
|
||||
if (current != null && current.Previous != null) {
|
||||
GotoStep (current.Previous.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private LinkedList<WizardStep> steps = new LinkedList<WizardStep> ();
|
||||
private WizardStep currentStep = null;
|
||||
|
||||
/// <summary>
|
||||
/// If the <see cref="CurrentStep"/> is not the first step in the wizard, this button causes
|
||||
/// the <see cref="MovingBack"/> event to be fired and the wizard moves to the previous step.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Use the <see cref="MovingBack"></see> event to be notified when the user attempts to go back.
|
||||
/// </remarks>
|
||||
public Button BackButton { get => backBtn; }
|
||||
private Button backBtn;
|
||||
|
||||
/// <summary>
|
||||
/// If the <see cref="CurrentStep"/> is the last step in the wizard, this button causes
|
||||
/// the <see cref="Finished"/> event to be fired and the wizard to close. If the step is not the last step,
|
||||
/// the <see cref="MovingNext"/> event will be fired and the wizard will move next step.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Use the <see cref="MovingNext"></see> and <see cref="Finished"></see> events to be notified
|
||||
/// when the user attempts go to the next step or finish the wizard.
|
||||
/// </remarks>
|
||||
public Button NextFinishButton { get => nextfinishBtn; }
|
||||
private Button nextfinishBtn;
|
||||
|
||||
/// <summary>
|
||||
/// Adds a step to the wizard. The Next and Back buttons navigate through the added steps in the
|
||||
@@ -308,8 +332,9 @@ 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.Add (newStep);
|
||||
steps.AddLast (newStep);
|
||||
this.Add (newStep);
|
||||
SetNeedsLayout ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -322,7 +347,7 @@ namespace Terminal.Gui {
|
||||
}
|
||||
set {
|
||||
wizardTitle = value;
|
||||
base.Title = $"{wizardTitle}{(steps.Count > 0 ? " - " + steps [currentStep].Title : string.Empty)}";
|
||||
base.Title = $"{wizardTitle}{(steps.Count > 0 ? " - " + currentStep.Title : string.Empty)}";
|
||||
}
|
||||
}
|
||||
private ustring wizardTitle = ustring.Empty;
|
||||
@@ -330,16 +355,16 @@ namespace Terminal.Gui {
|
||||
/// <summary>
|
||||
/// <see cref="EventArgs"/> for <see cref="WizardStep"/> transition events.
|
||||
/// </summary>
|
||||
public class WizardStepEventArgs : EventArgs {
|
||||
public class WizardButtonEventArgs : EventArgs {
|
||||
/// <summary>
|
||||
/// Set to true to cancel the transition to the next step.
|
||||
/// </summary>
|
||||
public bool Cancel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="WizardStepEventArgs"/>
|
||||
/// Initializes a new instance of <see cref="WizardButtonEventArgs"/>
|
||||
/// </summary>
|
||||
public WizardStepEventArgs ()
|
||||
public WizardButtonEventArgs ()
|
||||
{
|
||||
Cancel = false;
|
||||
}
|
||||
@@ -349,7 +374,7 @@ namespace Terminal.Gui {
|
||||
/// This event is raised when the Back button in the <see cref="Wizard"/> is clicked. The Back button is always
|
||||
/// the first button in the array of Buttons passed to the <see cref="Wizard"/> constructor, if any.
|
||||
/// </summary>
|
||||
public event Action<WizardStepEventArgs> MovingBack;
|
||||
public event Action<WizardButtonEventArgs> MovingBack;
|
||||
|
||||
/// <summary>
|
||||
/// This event is raised when the Next/Finish button in the <see cref="Wizard"/> is clicked. The Next/Finish button is always
|
||||
@@ -357,7 +382,7 @@ namespace Terminal.Gui {
|
||||
/// raised if the <see cref="CurrentStep"/> is the last Step in the Wizard flow
|
||||
/// (otherwise the <see cref="Finished"/> event is raised).
|
||||
/// </summary>
|
||||
public event Action<WizardStepEventArgs> MovingNext;
|
||||
public event Action<WizardButtonEventArgs> MovingNext;
|
||||
|
||||
/// <summary>
|
||||
/// This event is raised when the Next/Finish button in the <see cref="Wizard"/> is clicked. The Next/Finish button is always
|
||||
@@ -365,69 +390,143 @@ namespace Terminal.Gui {
|
||||
/// raised if the <see cref="CurrentStep"/> is the last Step in the Wizard flow
|
||||
/// (otherwise the <see cref="Finished"/> event is raised).
|
||||
/// </summary>
|
||||
public event Action<WizardStepEventArgs> Finished;
|
||||
public event Action<WizardButtonEventArgs> Finished;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// This event is raised when the current step )<see cref="CurrentStep"/>) in the <see cref="Wizard"/> changes.
|
||||
/// This event is raised when the user has cancelled the <see cref="Wizard"/> (with Ctrl-Q or ESC).
|
||||
/// </summary>
|
||||
public event Action<CurrentStepChangedEventArgs> CurrentStepChanged;
|
||||
public event Action<WizardButtonEventArgs> Cancelled;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="EventArgs"/> for <see cref="WizardStep"/> events.
|
||||
/// </summary>
|
||||
public class CurrentStepChangedEventArgs : EventArgs {
|
||||
public class StepChangeEventArgs : EventArgs {
|
||||
/// <summary>
|
||||
/// The new current <see cref="WizardStep"/>.
|
||||
/// The current (or previous) <see cref="WizardStep"/>.
|
||||
/// </summary>
|
||||
public int CurrentStepIndex { get; }
|
||||
public WizardStep OldStep { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="CurrentStepChangedEventArgs"/>
|
||||
/// The <see cref="WizardStep"/> the <see cref="Wizard"/> is changing to or has changed to.
|
||||
/// </summary>
|
||||
/// <param name="currentStepIndex">The new current <see cref="WizardStep"/>.</param>
|
||||
public CurrentStepChangedEventArgs (int currentStepIndex)
|
||||
public WizardStep NewStep { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Event handlers can set to true before returning to cancel the step transition.
|
||||
/// </summary>
|
||||
public bool Cancel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="StepChangeEventArgs"/>
|
||||
/// </summary>
|
||||
/// <param name="oldStep">The current <see cref="WizardStep"/>.</param>
|
||||
/// <param name="newStep">The new <see cref="WizardStep"/>.</param>
|
||||
public StepChangeEventArgs (WizardStep oldStep, WizardStep newStep)
|
||||
{
|
||||
CurrentStepIndex = currentStepIndex;
|
||||
OldStep = oldStep;
|
||||
NewStep = newStep;
|
||||
Cancel = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This event is raised when the current <see cref="CurrentStep"/>) is about to change. Use <see cref="StepChangeEventArgs.Cancel"/>
|
||||
/// to abort the transition.
|
||||
/// </summary>
|
||||
public event Action<StepChangeEventArgs> StepChanging;
|
||||
|
||||
/// <summary>
|
||||
/// This event is raised after the <see cref="Wizard"/> has changed the <see cref="CurrentStep"/>.
|
||||
/// </summary>
|
||||
public event Action<StepChangeEventArgs> StepChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the currently active <see cref="WizardStep"/>.
|
||||
/// </summary>
|
||||
public int CurrentStep {
|
||||
public WizardStep CurrentStep {
|
||||
get => currentStep;
|
||||
set {
|
||||
currentStep = value;
|
||||
OnCurrentStepChanged ();
|
||||
GotoStep (value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the current <see cref="WizardStep"/> has changed (<see cref="CurrentStep"/>).
|
||||
/// Called when the <see cref="Wizard"/> is about to transition to another <see cref="WizardStep"/>. Fires the <see cref="StepChanging"/> event.
|
||||
/// </summary>
|
||||
public virtual void OnCurrentStepChanged ()
|
||||
/// <param name="oldStep">The step the Wizard is about to change from</param>
|
||||
/// <param name="newStep">The step the Wizard is about to change to</param>
|
||||
/// <returns>True if the change is to be cancelled.</returns>
|
||||
public virtual bool OnStepChanging (WizardStep oldStep, WizardStep newStep)
|
||||
{
|
||||
CurrentStepChanged?.Invoke (new CurrentStepChangedEventArgs (currentStep));
|
||||
// Hide all but the first step
|
||||
var args = new StepChangeEventArgs (oldStep, newStep);
|
||||
StepChanging?.Invoke (args);
|
||||
return args.Cancel;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Called when the <see cref="Wizard"/> has completed transition to a new <see cref="WizardStep"/>. Fires the <see cref="StepChanged"/> event.
|
||||
/// </summary>
|
||||
/// <param name="oldStep">The step the Wizard changed from</param>
|
||||
/// <param name="newStep">The step the Wizard has changed to</param>
|
||||
/// <returns>True if the change is to be cancelled.</returns>
|
||||
public virtual bool OnStepChanged (WizardStep oldStep, WizardStep newStep)
|
||||
{
|
||||
var args = new StepChangeEventArgs (oldStep, newStep);
|
||||
StepChanged?.Invoke (args);
|
||||
return args.Cancel;
|
||||
}
|
||||
/// <summary>
|
||||
/// Changes to the specified <see cref="WizardStep"/>.
|
||||
/// </summary>
|
||||
/// <param name="newStep">The step to go to.</param>
|
||||
/// <returns>True if the transition to the step succeeded. False if the step was not found or the operation was cancelled.</returns>
|
||||
public bool GotoStep (WizardStep newStep)
|
||||
{
|
||||
if (OnStepChanging (currentStep, newStep)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Hide all but the new step
|
||||
foreach (WizardStep step in steps) {
|
||||
step.Visible = (steps [currentStep] == step);
|
||||
step.Visible = (step == newStep);
|
||||
}
|
||||
|
||||
// TODO: Add support for "Wizard Title - Step Title"
|
||||
base.Title = $"{wizardTitle}{(steps.Count > 0 ? " - " + steps [currentStep].Title : string.Empty)}";
|
||||
base.Title = $"{wizardTitle}{(steps.Count > 0 ? " - " + newStep.Title : string.Empty)}";
|
||||
|
||||
backBtn.Text = steps [currentStep].BackButtonText != ustring.Empty ? steps [currentStep].BackButtonText : "_Back";
|
||||
if (currentStep == 0) {
|
||||
backBtn.Visible = false;
|
||||
// TODO: Move strings to loc
|
||||
|
||||
// Configure the Back button
|
||||
backBtn.Text = newStep.BackButtonText != ustring.Empty ? newStep.BackButtonText : "_Back";
|
||||
backBtn.Visible = (newStep != steps.First.Value);
|
||||
|
||||
// Configure the Next/Finished button
|
||||
if (newStep == steps.Last.Value) {
|
||||
nextfinishBtn.Text = newStep.NextButtonText != ustring.Empty ? newStep.NextButtonText : "Fi_nish";
|
||||
} else {
|
||||
backBtn.Visible = true;
|
||||
nextfinishBtn.Text = newStep.NextButtonText != ustring.Empty ? newStep.NextButtonText : "_Next...";
|
||||
}
|
||||
|
||||
if (currentStep == steps.Count - 1) {
|
||||
nextfinishBtn.Text = steps [currentStep].NextButtonText != ustring.Empty ? steps [currentStep].NextButtonText : "Fi_nish";
|
||||
// Set focus to the nav buttons
|
||||
if (backBtn.HasFocus) {
|
||||
backBtn.SetFocus ();
|
||||
} else {
|
||||
nextfinishBtn.Text = steps [currentStep].NextButtonText != ustring.Empty ? steps [currentStep].NextButtonText : "_Next...";
|
||||
nextfinishBtn.SetFocus ();
|
||||
}
|
||||
|
||||
var oldStep = currentStep;
|
||||
currentStep = newStep;
|
||||
|
||||
LayoutSubviews ();
|
||||
Redraw (this.Bounds);
|
||||
|
||||
if (OnStepChanged (oldStep, currentStep)) {
|
||||
// For correctness we do this, but it's meaningless because there's nothing to cancel
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -215,6 +215,18 @@ namespace UICatalog.Scenarios {
|
||||
};
|
||||
dialog.Add (add);
|
||||
|
||||
var addChar = new Button ($"Add a {Char.ConvertFromUtf32(CODE_POINT)} to each button") {
|
||||
X = Pos.Center (),
|
||||
Y = Pos.Center () + 1
|
||||
};
|
||||
addChar.Clicked += () => {
|
||||
foreach (var button in buttons) {
|
||||
button.Text += Char.ConvertFromUtf32 (CODE_POINT);
|
||||
}
|
||||
dialog.LayoutSubviews ();
|
||||
};
|
||||
dialog.Add (addChar);
|
||||
|
||||
Application.Run (dialog);
|
||||
buttonPressedLabel.Text = $"{clicked}";
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ namespace UICatalog.Scenarios {
|
||||
X = Pos.Center (),
|
||||
Y = 0,
|
||||
Width = Dim.Percent (75),
|
||||
Height = 10,
|
||||
ColorScheme = Colors.Base,
|
||||
};
|
||||
Win.Add (frame);
|
||||
@@ -69,9 +68,18 @@ 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) + 2;
|
||||
frame.Height = Dim.Height (widthEdit) + Dim.Height (heightEdit) + Dim.Height (titleEdit) + Dim.Height (useStepView) + 2;
|
||||
Top.Loaded -= Top_Loaded;
|
||||
}
|
||||
Top.Loaded += Top_Loaded;
|
||||
@@ -127,6 +135,11 @@ namespace UICatalog.Scenarios {
|
||||
actionLabel.Text = "Finished";
|
||||
};
|
||||
|
||||
wizard.Cancelled += (args) => {
|
||||
//args.Cancel = true;
|
||||
actionLabel.Text = "Cancelled";
|
||||
};
|
||||
|
||||
// Add 1st step
|
||||
var firstStep = new Wizard.WizardStep ("End User License Agreement");
|
||||
wizard.AddStep (firstStep);
|
||||
@@ -138,6 +151,15 @@ namespace UICatalog.Scenarios {
|
||||
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 see a message box.\n\nEnter name too.";
|
||||
|
||||
|
||||
View viewForControls = secondStep.Controls;
|
||||
ustring frameMsg = "Added to WizardStep.Controls";
|
||||
if (useStepView.Checked) {
|
||||
viewForControls = secondStep;
|
||||
frameMsg = "Added to WizardStep directly";
|
||||
}
|
||||
|
||||
var buttonLbl = new Label () { Text = "Second Step Button: ", AutoSize = true, X = 1, Y = 1 };
|
||||
var button = new Button () {
|
||||
Text = "Press Me",
|
||||
@@ -147,13 +169,28 @@ namespace UICatalog.Scenarios {
|
||||
button.Clicked += () => {
|
||||
MessageBox.Query ("Wizard Scenario", "The Second Step Button was pressed.");
|
||||
};
|
||||
secondStep.Controls.Add (buttonLbl, button);
|
||||
viewForControls.Add (buttonLbl, button);
|
||||
var lbl = new Label () { Text = "First Name: ", AutoSize = true, X = 1, Y = Pos.Bottom (buttonLbl) };
|
||||
var firstNameField = new TextField () { Width = 30, X = Pos.Right (lbl), Y = Pos.Top (lbl) };
|
||||
secondStep.Controls.Add (lbl, firstNameField);
|
||||
viewForControls.Add (lbl, firstNameField);
|
||||
lbl = new Label () { Text = "Last Name: ", AutoSize = true, X = 1, Y = Pos.Bottom (lbl) };
|
||||
var lastNameField = new TextField () { Width = 30, X = Pos.Right (lbl), Y = Pos.Top (lbl) };
|
||||
secondStep.Controls.Add (lbl, lastNameField);
|
||||
viewForControls.Add (lbl, lastNameField);
|
||||
var checkBox = new CheckBox () { Text = "Un-check me!", Checked = true, X = Pos.Left (lastNameField), Y = Pos.Bottom (lastNameField) };
|
||||
viewForControls.Add (checkBox);
|
||||
|
||||
// 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}") {
|
||||
X = 0,
|
||||
Y = Pos.Bottom (checkBox) + 2,
|
||||
Width = Dim.Fill (),
|
||||
Height = 4,
|
||||
//ColorScheme = Colors.Error,
|
||||
};
|
||||
frame.Add (new TextField ("This is a TextField inside of the frame."));
|
||||
viewForControls.Add (frame);
|
||||
|
||||
// Add 3rd step
|
||||
var thirdStep = new Wizard.WizardStep ("Third Step");
|
||||
@@ -169,20 +206,35 @@ namespace UICatalog.Scenarios {
|
||||
thirdStep.Controls.Add (progLbl, progressBar);
|
||||
|
||||
// Add 4th step
|
||||
var fourthStep = new Wizard.WizardStep ("Hidden Help pane");
|
||||
var fourthStep = new Wizard.WizardStep ("Step Four");
|
||||
wizard.AddStep (fourthStep);
|
||||
fourthStep.ShowHelp = false;
|
||||
var someText = new TextView () {
|
||||
Text = "This step shows how to hide the Help pane. The control pane contains this 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).",
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Width = Dim.Fill (),
|
||||
Height = Dim.Fill (),
|
||||
WordWrap = true,
|
||||
AllowsTab = false
|
||||
};
|
||||
fourthStep.Controls.Add (someText);
|
||||
//fourthStep.NextButtonText = "4";
|
||||
var scrollBar = new ScrollBarView (someText, true);
|
||||
|
||||
wizard.StepChanging += (args) => {
|
||||
if (args.NewStep == fourthStep) {
|
||||
var btn = MessageBox.ErrorQuery ("Wizards", "Move to Step Four?", "Yes", "No");
|
||||
args.Cancel = btn == 1;
|
||||
}
|
||||
};
|
||||
|
||||
wizard.StepChanged += (args) => {
|
||||
if (args.NewStep == fourthStep) {
|
||||
var btn = MessageBox.ErrorQuery ("Wizards", "Yay. Moved to Step Four", "Ok");
|
||||
}
|
||||
};
|
||||
|
||||
scrollBar.ChangedPosition += () => {
|
||||
someText.TopRow = scrollBar.Position;
|
||||
if (someText.TopRow != scrollBar.Position) {
|
||||
@@ -216,13 +268,8 @@ namespace UICatalog.Scenarios {
|
||||
wizard.AddStep (lastStep);
|
||||
lastStep.HelpText = "The wizard is complete! Press the Finish button to continue. Pressing ESC will cancel the wizard.";
|
||||
|
||||
|
||||
// TODO: Demo setting initial Pane
|
||||
|
||||
wizard.Finished += (args) => {
|
||||
Application.RequestStop (wizard);
|
||||
};
|
||||
|
||||
Application.Run (wizard);
|
||||
|
||||
} catch (FormatException) {
|
||||
|
||||
@@ -93,6 +93,37 @@ namespace Terminal.Gui.Views {
|
||||
// and that the title is correct
|
||||
public void OneStepWizard_Shows ()
|
||||
{
|
||||
var d = ((FakeDriver)Application.Driver);
|
||||
|
||||
var title = "1234";
|
||||
var stepTitle = "ABCD";
|
||||
|
||||
int width = 30;
|
||||
int height = 7;
|
||||
d.SetBufferSize (width, height);
|
||||
|
||||
var btnBackText = "Back";
|
||||
var btnBack = string.Empty; // $"{d.LeftBracket} {btnBackText} {d.RightBracket}";
|
||||
var btnNextText = "Finish"; // "Next";
|
||||
var btnNext = $"{d.LeftBracket}{d.LeftDefaultIndicator} {btnNextText} {d.RightDefaultIndicator}{d.RightBracket}";
|
||||
|
||||
var topRow = $"{d.ULDCorner} {title} - {stepTitle} {new String (d.HDLine.ToString () [0], width - title.Length - stepTitle.Length - 7)}{d.URDCorner}";
|
||||
var row2 = $"{d.VDLine}{new String (' ', width - 2)}{d.VDLine}";
|
||||
var row3 = row2;
|
||||
var row4 = row3;
|
||||
var separatorRow = $"{d.VDLine}{new String (d.HLine.ToString () [0], 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}";
|
||||
|
||||
var wizard = new Wizard (title) { Width = width, Height = height };
|
||||
wizard.AddStep (new Wizard.WizardStep (stepTitle));
|
||||
//wizard.LayoutSubviews ();
|
||||
var firstIteration = false;
|
||||
var runstate = Application.Begin (wizard);
|
||||
Application.RunMainLoopIteration (ref runstate, true, ref firstIteration);
|
||||
|
||||
GraphViewTests.AssertDriverContentsWithFrameAre ($"{topRow}\n{row2}\n{row3}\n{row4}\n{separatorRow}\n{buttonRow}\n{bottomRow}", output);
|
||||
Application.End (runstate);
|
||||
}
|
||||
|
||||
[Fact, AutoInitShutdown]
|
||||
@@ -150,7 +181,7 @@ namespace Terminal.Gui.Views {
|
||||
var separatorRow = $"{d.VDLine}{new String (d.HLine.ToString () [0], width - 2)}{d.VDLine}";
|
||||
|
||||
// Once this is fixed, revert to commented out line: https://github.com/migueldeicaza/gui.cs/issues/1791
|
||||
var buttonRow = $"{d.VDLine}{new String (' ', width - btnNext.Length - 3)}{btnNext} {d.VDLine}";
|
||||
var buttonRow = $"{d.VDLine}{new String (' ', width - btnNext.Length - 2)}{btnNext}{d.VDLine}";
|
||||
//var buttonRow = $"{d.VDLine}{new String (' ', width - 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