mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
Progress on refactoring nav
This commit is contained in:
committed by
Tig Kindel
parent
76542360ad
commit
1bc2c79938
@@ -2399,7 +2399,7 @@ namespace Terminal.Gui {
|
||||
}
|
||||
}
|
||||
|
||||
bool oldEnabled;
|
||||
bool oldEnabled = true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Enabled {
|
||||
|
||||
@@ -22,6 +22,11 @@ namespace Terminal.Gui {
|
||||
/// <remarks>
|
||||
/// If <see cref="Button"/>s are added, do not set <see cref="Button.IsDefault"/> to true as this will conflict
|
||||
/// with the Next button of the Wizard.
|
||||
///
|
||||
/// Subscribe to the <see cref="View.VisibleChanged"/> event to be notified when the step is active; see also: <see cref="Wizard.StepChanged"/>.
|
||||
///
|
||||
/// To enable or disable a step from being shown to the user, set <see cref="View.Enabled"/>.
|
||||
///
|
||||
/// </remarks>
|
||||
public class WizardStep : View {
|
||||
/// <summary>
|
||||
@@ -94,6 +99,7 @@ namespace Terminal.Gui {
|
||||
helpTextView.ReadOnly = true;
|
||||
helpTextView.WordWrap = true;
|
||||
this.Add (helpTextView);
|
||||
|
||||
ShowHide ();
|
||||
|
||||
var scrollBar = new ScrollBarView (helpTextView, true);
|
||||
@@ -143,6 +149,13 @@ namespace Terminal.Gui {
|
||||
this.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.
|
||||
@@ -281,24 +294,102 @@ namespace Terminal.Gui {
|
||||
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);
|
||||
}
|
||||
GoNext ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <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.
|
||||
/// </summary>
|
||||
public void GoNext ()
|
||||
{
|
||||
var nextStep = GetNextStep ();
|
||||
if (nextStep != null) {
|
||||
GoToStep (nextStep);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the next enabled <see cref="WizardStep"/> after the current step. Takes into account steps which
|
||||
/// are disabled. If <see cref="CurrentStep"/> is `null` returns the first enabled step.
|
||||
/// </summary>
|
||||
/// <returns>The next step after the current step, if there is one; otherwise returns `null`, which
|
||||
/// indicates either there are no enabled steps or the current step is the last enabled step.</returns>
|
||||
public WizardStep GetNextStep ()
|
||||
{
|
||||
LinkedListNode<WizardStep> step = null;
|
||||
if (CurrentStep == null) {
|
||||
// Get last step, assume it is next
|
||||
step = steps.First;
|
||||
} else {
|
||||
// Get the step after current
|
||||
step = steps.Find (CurrentStep);
|
||||
if (step != null) {
|
||||
step = step.Next;
|
||||
}
|
||||
}
|
||||
|
||||
// step now points to the potential next step
|
||||
while (step != null) {
|
||||
if (step.Value.Enabled) {
|
||||
return step.Value;
|
||||
}
|
||||
step = step.Next;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
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);
|
||||
GoBack ();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Causes the wizad to move to the previous enabled step (or first step if <see cref="CurrentStep"/> is not set).
|
||||
/// If there is no previous step, does nothing.
|
||||
/// </summary>
|
||||
public void GoBack ()
|
||||
{
|
||||
var previous = GetPreviousStep ();
|
||||
if (previous != null) {
|
||||
GoToStep (previous);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the first enabled <see cref="WizardStep"/> before the current step. Takes into account steps which
|
||||
/// are disabled. If <see cref="CurrentStep"/> is `null` returns the last enabled step.
|
||||
/// </summary>
|
||||
/// <returns>The first step ahead of the current step, if there is one; otherwise returns `null`, which
|
||||
/// indicates either there are no enabled steps or the current step is the first enabled step.</returns>
|
||||
public WizardStep GetPreviousStep ()
|
||||
{
|
||||
LinkedListNode<WizardStep> step = null;
|
||||
if (CurrentStep == null) {
|
||||
// Get last step, assume it is previous
|
||||
step = steps.Last;
|
||||
} else {
|
||||
// Get the step before current
|
||||
step = steps.Find (CurrentStep);
|
||||
if (step != null) {
|
||||
step = step.Previous;
|
||||
}
|
||||
}
|
||||
|
||||
// step now points to the potential previous step
|
||||
while (step != null) {
|
||||
if (step.Value.Enabled) {
|
||||
return step.Value;
|
||||
}
|
||||
step = step.Previous;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private LinkedList<WizardStep> steps = new LinkedList<WizardStep> ();
|
||||
@@ -449,7 +540,7 @@ namespace Terminal.Gui {
|
||||
public WizardStep CurrentStep {
|
||||
get => currentStep;
|
||||
set {
|
||||
GotoStep (value);
|
||||
GoToStep (value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -484,9 +575,9 @@ namespace Terminal.Gui {
|
||||
/// </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)
|
||||
public bool GoToStep (WizardStep newStep)
|
||||
{
|
||||
if (OnStepChanging (currentStep, newStep)) {
|
||||
if (OnStepChanging (currentStep, newStep) || (newStep != null && !newStep.Enabled)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -495,17 +586,20 @@ namespace Terminal.Gui {
|
||||
step.Visible = (step == newStep);
|
||||
}
|
||||
|
||||
base.Title = $"{wizardTitle}{(steps.Count > 0 ? " - " + newStep.Title : string.Empty)}";
|
||||
if (newStep != null) {
|
||||
|
||||
// Configure the Back button
|
||||
backBtn.Text = newStep.BackButtonText != ustring.Empty ? newStep.BackButtonText : Strings.wzBack; // "_Back";
|
||||
backBtn.Visible = (newStep != steps.First.Value);
|
||||
base.Title = $"{wizardTitle}{(steps.Count > 0 ? " - " + newStep.Title : string.Empty)}";
|
||||
|
||||
// Configure the Next/Finished button
|
||||
if (newStep == steps.Last.Value) {
|
||||
nextfinishBtn.Text = newStep.NextButtonText != ustring.Empty ? newStep.NextButtonText : Strings.wzFinish; // "Fi_nish";
|
||||
} else {
|
||||
nextfinishBtn.Text = newStep.NextButtonText != ustring.Empty ? newStep.NextButtonText : Strings.wzNext; // "_Next...";
|
||||
// Configure the Back button
|
||||
backBtn.Text = newStep.BackButtonText != ustring.Empty ? newStep.BackButtonText : Strings.wzBack; // "_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 : Strings.wzFinish; // "Fi_nish";
|
||||
} else {
|
||||
nextfinishBtn.Text = newStep.NextButtonText != ustring.Empty ? newStep.NextButtonText : Strings.wzNext; // "_Next...";
|
||||
}
|
||||
}
|
||||
|
||||
// Set focus to the nav buttons
|
||||
@@ -515,7 +609,7 @@ namespace Terminal.Gui {
|
||||
nextfinishBtn.SetFocus ();
|
||||
}
|
||||
|
||||
var oldStep = currentStep;
|
||||
var oldStep = currentStep;
|
||||
currentStep = newStep;
|
||||
|
||||
LayoutSubviews ();
|
||||
|
||||
@@ -176,15 +176,15 @@ namespace UICatalog.Scenarios {
|
||||
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) };
|
||||
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);
|
||||
var thirdStepEnabledCeckBox = new CheckBox () { Text = "Enable Step _3", Checked = false, X = Pos.Left (lastNameField), Y = Pos.Bottom (lastNameField) };
|
||||
viewForControls.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}") {
|
||||
X = 0,
|
||||
Y = Pos.Bottom (checkBox) + 2,
|
||||
Y = Pos.Bottom (thirdStepEnabledCeckBox) + 2,
|
||||
Width = Dim.Fill (),
|
||||
Height = 4,
|
||||
//ColorScheme = Colors.Error,
|
||||
@@ -192,10 +192,23 @@ namespace UICatalog.Scenarios {
|
||||
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");
|
||||
// Add 3rd (optional) step
|
||||
var thirdStep = new Wizard.WizardStep ("Third Step (Optional)");
|
||||
|
||||
thirdStep.Enabled = thirdStepEnabledCeckBox.Checked;
|
||||
thirdStepEnabledCeckBox.Toggled += (args) => {
|
||||
thirdStep.Enabled = thirdStepEnabledCeckBox.Checked;
|
||||
};
|
||||
|
||||
wizard.AddStep (thirdStep);
|
||||
thirdStep.HelpText = "This is the help text for the Third Step.";
|
||||
thirdStep.HelpText = "This is step is optional (WizardStep.Enabled = false). Enable it with the checkbox in Step 2.";
|
||||
var step3Label = new Label () {
|
||||
Text = "This step is optional.",
|
||||
X = 0,
|
||||
Y = 0,
|
||||
AutoSize = true
|
||||
};
|
||||
thirdStep.Controls.Add (step3Label);
|
||||
var progLbl = new Label () { Text = "Third Step ProgressBar: ", AutoSize = true, X = 1, Y = 10 };
|
||||
var progressBar = new ProgressBar () {
|
||||
X = Pos.Right (progLbl),
|
||||
@@ -222,18 +235,18 @@ namespace UICatalog.Scenarios {
|
||||
//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.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");
|
||||
}
|
||||
};
|
||||
//wizard.StepChanged += (args) => {
|
||||
// if (args.NewStep == fourthStep) {
|
||||
// var btn = MessageBox.ErrorQuery ("Wizards", "Yay. Moved to Step Four", "Ok");
|
||||
// }
|
||||
//};
|
||||
|
||||
scrollBar.ChangedPosition += () => {
|
||||
someText.TopRow = scrollBar.Position;
|
||||
|
||||
@@ -191,5 +191,220 @@ namespace Terminal.Gui.Views {
|
||||
Application.End (Application.Begin (wizard));
|
||||
GraphViewTests.AssertDriverContentsWithFrameAre ($"{topRow}\n{separatorRow}\n{buttonRow}\n{bottomRow}", output);
|
||||
}
|
||||
|
||||
[Fact, AutoInitShutdown]
|
||||
public void Navigate_GetPreviousStep_Correct ()
|
||||
{
|
||||
var wizard = new Wizard ();
|
||||
|
||||
// If no steps should be null
|
||||
Assert.Null (wizard.GetPreviousStep ());
|
||||
|
||||
var step1 = new Wizard.WizardStep ("step1");
|
||||
wizard.AddStep (step1);
|
||||
|
||||
// If no current step, should be last step
|
||||
Assert.Equal (step1.Title.ToString(), wizard.GetPreviousStep ().Title.ToString());
|
||||
|
||||
wizard.CurrentStep = step1;
|
||||
// If there is 1 step it's current step should be null
|
||||
Assert.Null (wizard.GetPreviousStep ());
|
||||
|
||||
// If one disabled step should be null
|
||||
step1.Enabled = false;
|
||||
Assert.Null (wizard.GetPreviousStep ());
|
||||
|
||||
// If two steps and at 2 and step 1 is `Enabled = true`should be step1
|
||||
var step2 = new Wizard.WizardStep ("step2");
|
||||
wizard.AddStep (step2);
|
||||
wizard.CurrentStep = step2;
|
||||
step1.Enabled = true;
|
||||
Assert.Equal (step1.Title.ToString(), wizard.GetPreviousStep ().Title.ToString());
|
||||
|
||||
// If two steps and at 2 and step 1 is `Enabled = false` should be null
|
||||
step1.Enabled = false;
|
||||
Assert.Null (wizard.GetPreviousStep ());
|
||||
|
||||
// If three steps with Step2.Enabled = true
|
||||
// At step 1 should be null
|
||||
// At step 2 should be step 1
|
||||
// At step 3 should be step 2
|
||||
var step3 = new Wizard.WizardStep ("step3");
|
||||
wizard.AddStep (step3);
|
||||
step1.Enabled = true;
|
||||
wizard.CurrentStep = step1;
|
||||
step2.Enabled = true;
|
||||
step3.Enabled = true;
|
||||
Assert.Null (wizard.GetPreviousStep ());
|
||||
wizard.CurrentStep = step2;
|
||||
Assert.Equal (step1.Title.ToString(), wizard.GetPreviousStep ().Title.ToString());
|
||||
wizard.CurrentStep = step3;
|
||||
Assert.Equal (step2.Title.ToString(), wizard.GetPreviousStep ().Title.ToString());
|
||||
|
||||
// If three steps with Step2.Enabled = false
|
||||
// At step 1 should be null
|
||||
// At step 3 should be step1
|
||||
step1.Enabled = true;
|
||||
step2.Enabled = false;
|
||||
step3.Enabled = true;
|
||||
wizard.CurrentStep = step1;
|
||||
Assert.Null (wizard.GetPreviousStep ());
|
||||
wizard.CurrentStep = step3;
|
||||
Assert.Equal (step1.Title.ToString(), wizard.GetPreviousStep ().Title.ToString());
|
||||
|
||||
// If three steps with Step1.Enabled = false & Step2.Enabled = false
|
||||
// At step 3 should be null
|
||||
|
||||
// If no current step, GetPreviousStep provides equivalent to GetLastStep
|
||||
wizard.CurrentStep = null;
|
||||
step1.Enabled = true;
|
||||
step2.Enabled = true;
|
||||
step3.Enabled = true;
|
||||
Assert.Equal (step3.Title.ToString(), wizard.GetPreviousStep ().Title.ToString());
|
||||
|
||||
step1.Enabled = false;
|
||||
step2.Enabled = true;
|
||||
step3.Enabled = true;
|
||||
Assert.Equal (step3.Title.ToString(), wizard.GetPreviousStep ().Title.ToString());
|
||||
|
||||
step1.Enabled = false;
|
||||
step2.Enabled = false;
|
||||
step3.Enabled = true;
|
||||
Assert.Equal (step3.Title.ToString(), wizard.GetPreviousStep ().Title.ToString());
|
||||
|
||||
step1.Enabled = false;
|
||||
step2.Enabled = true;
|
||||
step3.Enabled = false;
|
||||
Assert.Equal (step2.Title.ToString(), wizard.GetPreviousStep ().Title.ToString());
|
||||
|
||||
step1.Enabled = true;
|
||||
step2.Enabled = false;
|
||||
step3.Enabled = false;
|
||||
Assert.Equal (step1.Title.ToString(), wizard.GetPreviousStep ().Title.ToString());
|
||||
}
|
||||
|
||||
[Fact, AutoInitShutdown]
|
||||
public void Navigate_GetNextStep_Correct ()
|
||||
{
|
||||
var wizard = new Wizard ();
|
||||
|
||||
// If no steps should be null
|
||||
Assert.Null (wizard.GetNextStep ());
|
||||
|
||||
var step1 = new Wizard.WizardStep ("step1");
|
||||
wizard.AddStep (step1);
|
||||
|
||||
// If no current step, should be first step
|
||||
Assert.Equal (step1.Title.ToString(), wizard.GetNextStep ().Title.ToString());
|
||||
|
||||
wizard.CurrentStep = step1;
|
||||
// If there is 1 step it's current step should be null
|
||||
Assert.Null (wizard.GetNextStep ());
|
||||
|
||||
// If one disabled step should be null
|
||||
step1.Enabled = false;
|
||||
Assert.Null (wizard.GetNextStep ());
|
||||
|
||||
// If two steps and at 1 and step 2 is `Enabled = true`should be step 2
|
||||
var step2 = new Wizard.WizardStep ("step2");
|
||||
wizard.AddStep (step2);
|
||||
Assert.Equal (step2.Title.ToString(), wizard.GetNextStep ().Title.ToString());
|
||||
|
||||
// If two steps and at 1 and step 2 is `Enabled = false` should be null
|
||||
step1.Enabled = true;
|
||||
wizard.CurrentStep = step1;
|
||||
step2.Enabled = false;
|
||||
Assert.Null (wizard.GetNextStep ());
|
||||
|
||||
// If three steps with Step2.Enabled = true
|
||||
// At step 1 should be step 2
|
||||
// At step 2 should be step 3
|
||||
// At step 3 should be null
|
||||
var step3 = new Wizard.WizardStep ("step3");
|
||||
wizard.AddStep (step3);
|
||||
step1.Enabled = true;
|
||||
wizard.CurrentStep = step1;
|
||||
step2.Enabled = true;
|
||||
step3.Enabled = true;
|
||||
Assert.Equal (step2.Title.ToString(), wizard.GetNextStep ().Title.ToString());
|
||||
wizard.CurrentStep = step2;
|
||||
Assert.Equal (step3.Title.ToString(), wizard.GetNextStep ().Title.ToString());
|
||||
wizard.CurrentStep = step3;
|
||||
Assert.Null (wizard.GetNextStep ());
|
||||
|
||||
// If three steps with Step2.Enabled = false
|
||||
// At step 1 should be step 3
|
||||
// At step 3 should be null
|
||||
step1.Enabled = true;
|
||||
wizard.CurrentStep = step1;
|
||||
step2.Enabled = false;
|
||||
step3.Enabled = true;
|
||||
Assert.Equal (step3.Title.ToString(), wizard.GetNextStep ().Title.ToString());
|
||||
wizard.CurrentStep = step3;
|
||||
Assert.Null (wizard.GetNextStep ());
|
||||
|
||||
// If three steps with Step2.Enabled = false & Step3.Enabled = false
|
||||
// At step 1 should be null
|
||||
step1.Enabled = true;
|
||||
wizard.CurrentStep = step1;
|
||||
step2.Enabled = false;
|
||||
step3.Enabled = false;
|
||||
Assert.Null (wizard.GetNextStep ());
|
||||
|
||||
// If no current step, GetNextStep provides equivalent to GetFirstStep
|
||||
wizard.CurrentStep = null;
|
||||
step1.Enabled = true;
|
||||
step2.Enabled = true;
|
||||
step3.Enabled = true;
|
||||
Assert.Equal (step1.Title.ToString(), wizard.GetNextStep ().Title.ToString());
|
||||
|
||||
step1.Enabled = false;
|
||||
step2.Enabled = true;
|
||||
step3.Enabled = true;
|
||||
Assert.Equal (step2.Title.ToString(), wizard.GetNextStep ().Title.ToString());
|
||||
|
||||
step1.Enabled = false;
|
||||
step2.Enabled = false;
|
||||
step3.Enabled = true;
|
||||
Assert.Equal (step3.Title.ToString(), wizard.GetNextStep ().Title.ToString());
|
||||
|
||||
step1.Enabled = false;
|
||||
step2.Enabled = true;
|
||||
step3.Enabled = false;
|
||||
Assert.Equal (step2.Title.ToString(), wizard.GetNextStep ().Title.ToString());
|
||||
|
||||
step1.Enabled = true;
|
||||
step2.Enabled = false;
|
||||
step3.Enabled = false;
|
||||
Assert.Equal (step1.Title.ToString(), wizard.GetNextStep ().Title.ToString());
|
||||
}
|
||||
|
||||
[Fact, AutoInitShutdown]
|
||||
public void Navigate_GoNext_Works ()
|
||||
{
|
||||
// If zero steps do nothing
|
||||
|
||||
// If one step do nothing (enabled or disabled)
|
||||
|
||||
// If two steps
|
||||
// If current is 1
|
||||
// If 2 is enabled 2 becomes current
|
||||
// If 2 is disabled 1 stays current
|
||||
// If current is 2 does nothing
|
||||
}
|
||||
|
||||
[Fact, AutoInitShutdown]
|
||||
public void Navigate_GoBack_Works ()
|
||||
{
|
||||
// If zero steps do nothing
|
||||
|
||||
// If one step do nothing (enabled or disabled)
|
||||
|
||||
// If two steps
|
||||
// If current is 1 does nothing
|
||||
// If current is 2 does nothing
|
||||
// If 1 is enabled 2 becomes current
|
||||
// If 1 is disabled 1 stays current
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user