mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
* Initial plan * Fix Wizard v2 architecture issues - ScrollBar API, event handlers, key bindings Co-authored-by: tig <585482+tig@users.noreply.github.com> * Implement issue #4155 - Put nav buttons in bottom Padding, Help in right Padding Co-authored-by: tig <585482+tig@users.noreply.github.com> * Address code review feedback - Extract helper method, improve null checks Co-authored-by: tig <585482+tig@users.noreply.github.com> * Fix disposal issue - Ensure _helpTextView is always disposed Co-authored-by: tig <585482+tig@users.noreply.github.com> * Refactor & improvements. WIP * Tweaking layout * Wizard tweaks * Added View.GetSubViews that optinoally gets subviews of adornments * Refactor Wizard API: modern events, layout, and design - Replaced custom event args with standard .NET event args (CancelEventArgs, ValueChangingEventArgs, etc.) - Removed Finished event; use Accepting for wizard completion - Updated Cancelled, MovingBack, MovingNext to use CancelEventArgs - Refactored UICatalog scenarios and tests to new event model - Improved WizardStep sizing and wizard auto-resizing to content - Enhanced IDesignable for Wizard and WizardStep with richer design-time UI - Simplified help text padding logic in WizardStep - Removed obsolete code and modernized code style throughout - Improves API consistency, usability, and .NET idiomatic usage * Fixes #4515 - Navigating into and out of Adornments does not work * WIP. QUite broken. * All fixed? * Tweaks. * Exclude Margin subviews from drawing; add shadow tests Update Margin adornment to skip drawing subviews that are themselves Margin views, preventing unsupported nested Margin rendering. Add unit tests to verify that opaque-shadowed buttons in Margin are not drawn, while Border and Padding still support shadow rendering. Update test class to use output helper and assert driver output. * Final code cleanup and test improvements. * Update Margin.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update View.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update View.Hierarchy.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update View.Hierarchy.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Refactor: code style, formatting, and minor logic cleanup - Standardized spacing and formatting for method signatures and object initializations. - Converted simple methods and properties to expression-bodied members for conciseness. - Replaced named arguments with positional arguments for consistency. - Improved XML documentation formatting for readability. - Simplified logic in event handlers (e.g., Wizard Back button). - Removed redundant checks where properties are guaranteed to exist. - Fixed minor bugs related to padding, height calculation, and event handling. - Adopted consistent use of `var` for local variables. - Corrected namespace declarations. - Refactored methods returning constants to use expression-bodied syntax. - General code cleanup for clarity and maintainability; no breaking changes. * api docs --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: tig <585482+tig@users.noreply.github.com> Co-authored-by: Tig <tig@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
using System;
|
||||
#nullable enable
|
||||
// ReSharper disable AccessToDisposedClosure
|
||||
|
||||
// ReSharper disable AssignNullToNotNullAttribute
|
||||
|
||||
namespace UICatalog.Scenarios;
|
||||
|
||||
@@ -10,12 +13,11 @@ public class Adornments : Scenario
|
||||
public override void Main ()
|
||||
{
|
||||
Application.Init ();
|
||||
using IApplication app = Application.Instance;
|
||||
|
||||
Window appWindow = new ()
|
||||
{
|
||||
Title = GetQuitKeyAndName (),
|
||||
BorderStyle = LineStyle.None
|
||||
};
|
||||
using Window appWindow = new ();
|
||||
appWindow.Title = GetQuitKeyAndName ();
|
||||
appWindow.BorderStyle = LineStyle.None;
|
||||
|
||||
var editor = new AdornmentsEditor
|
||||
{
|
||||
@@ -31,7 +33,7 @@ public class Adornments : Scenario
|
||||
|
||||
appWindow.Add (editor);
|
||||
|
||||
var window = new Window
|
||||
Window window = new ()
|
||||
{
|
||||
Title = "The _Window",
|
||||
Arrangement = ViewArrangement.Overlapped | ViewArrangement.Movable,
|
||||
@@ -41,29 +43,29 @@ public class Adornments : Scenario
|
||||
};
|
||||
appWindow.Add (window);
|
||||
|
||||
var tf1 = new TextField { Width = 10, Text = "TextField" };
|
||||
var color = new ColorPicker16 { Title = "BG", BoxHeight = 1, BoxWidth = 1, X = Pos.AnchorEnd () };
|
||||
TextField tf1 = new () { Width = 10, Text = "TextField" };
|
||||
ColorPicker16 color = new () { Title = "BG", BoxHeight = 1, BoxWidth = 1, X = Pos.AnchorEnd () };
|
||||
color.BorderStyle = LineStyle.RoundedDotted;
|
||||
|
||||
color.ColorChanged += (s, e) =>
|
||||
color.ColorChanged += (_, e) =>
|
||||
{
|
||||
color.SuperView!.SetScheme (
|
||||
new (color.SuperView.GetScheme ())
|
||||
{
|
||||
Normal = new (
|
||||
color.SuperView.GetAttributeForRole (VisualRole.Normal).Foreground,
|
||||
e.Result,
|
||||
color.SuperView.GetAttributeForRole (VisualRole.Normal).Style
|
||||
)
|
||||
});
|
||||
new (color.SuperView.GetScheme ())
|
||||
{
|
||||
Normal = new (
|
||||
color.SuperView.GetAttributeForRole (VisualRole.Normal).Foreground,
|
||||
e.Result,
|
||||
color.SuperView.GetAttributeForRole (VisualRole.Normal).Style
|
||||
)
|
||||
});
|
||||
};
|
||||
|
||||
var button = new Button { X = Pos.Center (), Y = Pos.Center (), Text = "Press me!" };
|
||||
Button button = new () { X = Pos.Center (), Y = Pos.Center (), Text = "Press me!" };
|
||||
|
||||
button.Accepting += (s, e) =>
|
||||
MessageBox.Query (appWindow.App, 20, 7, "Hi", $"Am I a {window.GetType ().Name}?", "Yes", "No");
|
||||
button.Accepting += (_, _) =>
|
||||
MessageBox.Query (appWindow.App!, 20, 7, "Hi", $"Am I a {window.GetType ().Name}?", "Yes", "No");
|
||||
|
||||
var label = new TextView
|
||||
TextView label = new ()
|
||||
{
|
||||
X = Pos.Center (),
|
||||
Y = Pos.Bottom (button),
|
||||
@@ -74,9 +76,9 @@ public class Adornments : Scenario
|
||||
};
|
||||
label.Border!.Thickness = new (1, 3, 1, 1);
|
||||
|
||||
var btnButtonInWindow = new Button { X = Pos.AnchorEnd (), Y = Pos.AnchorEnd (), Text = "Button" };
|
||||
Button btnButtonInWindow = new () { X = Pos.AnchorEnd (), Y = Pos.AnchorEnd (), Text = "Button" };
|
||||
|
||||
var labelAnchorEnd = new Label
|
||||
Label labelAnchorEnd = new ()
|
||||
{
|
||||
Y = Pos.AnchorEnd (),
|
||||
Width = 40,
|
||||
@@ -87,68 +89,76 @@ public class Adornments : Scenario
|
||||
|
||||
window.Margin!.Data = "Margin";
|
||||
window.Margin!.Text = "Margin Text";
|
||||
window.Margin!.Thickness = new (0);
|
||||
window.Margin!.Thickness = new (3);
|
||||
|
||||
window.Border!.Data = "Border";
|
||||
window.Border!.Text = "Border Text";
|
||||
window.Border!.Thickness = new (0);
|
||||
window.Border!.Thickness = new (5);
|
||||
window.Border!.SetScheme (SchemeManager.GetScheme (Schemes.Dialog));
|
||||
|
||||
window.Padding.Data = "Padding";
|
||||
window.Padding!.Data = "Padding";
|
||||
window.Padding.Text = "Padding Text line 1\nPadding Text line 3\nPadding Text line 3\nPadding Text line 4\nPadding Text line 5";
|
||||
window.Padding.Thickness = new (3);
|
||||
window.Padding.SchemeName = "Error";
|
||||
window.Padding.Thickness = new (4);
|
||||
window.Padding!.SetScheme (SchemeManager.GetScheme (Schemes.Menu));
|
||||
window.Padding.CanFocus = true;
|
||||
|
||||
var longLabel = new Label
|
||||
Label longLabel = new ()
|
||||
{
|
||||
X = 40, Y = 5, Title = "This is long text (in a label) that should clip."
|
||||
};
|
||||
longLabel.TextFormatter.WordWrap = true;
|
||||
window.Add (tf1, color, button, label, btnButtonInWindow, labelAnchorEnd, longLabel);
|
||||
|
||||
window.Initialized += (s, e) =>
|
||||
window.Initialized += (_, _) =>
|
||||
{
|
||||
editor.ViewToEdit = window;
|
||||
|
||||
editor.ShowViewIdentifier = true;
|
||||
|
||||
var labelInPadding = new Label { X = 0, Y = 1, Title = "_Text:" };
|
||||
window.Padding.Add (labelInPadding);
|
||||
// NOTE: Adding SubViews to Margin is not supported
|
||||
|
||||
var textFieldInPadding = new TextField
|
||||
{
|
||||
X = Pos.Right (labelInPadding) + 1,
|
||||
Y = Pos.Top (labelInPadding), Width = 10,
|
||||
Text = "text (Y = 1)",
|
||||
CanFocus = true
|
||||
};
|
||||
textFieldInPadding.Accepting += (s, e) => MessageBox.Query (appWindow.App, 20, 7, "TextField", textFieldInPadding.Text, "Ok");
|
||||
window.Padding.Add (textFieldInPadding);
|
||||
|
||||
var btnButtonInPadding = new Button
|
||||
Button btnButtonInBorder = new ()
|
||||
{
|
||||
X = Pos.Center (),
|
||||
Y = 1,
|
||||
Text = "_Button in Padding Y = 1",
|
||||
CanFocus = true,
|
||||
HighlightStates = MouseState.None,
|
||||
Text = "_Button in Border Y = 1"
|
||||
};
|
||||
btnButtonInPadding.Accepting += (s, e) => MessageBox.Query (appWindow.App, 20, 7, "Hi", "Button in Padding Pressed!", "Ok");
|
||||
btnButtonInPadding.BorderStyle = LineStyle.Dashed;
|
||||
btnButtonInPadding.Border!.Thickness = new (1, 1, 1, 1);
|
||||
btnButtonInBorder.Accepting += (_, _) => MessageBox.Query (appWindow.App!, 20, 7, "Hi", "Button in Border Pressed!", "Ok");
|
||||
window.Border.Add (btnButtonInBorder);
|
||||
|
||||
Label labelInPadding = new () { X = 0, Y = 1, Title = "_Text:" };
|
||||
window.Padding.Add (labelInPadding);
|
||||
|
||||
TextField textFieldInPadding = new ()
|
||||
{
|
||||
X = Pos.Right (labelInPadding) + 1,
|
||||
Y = Pos.Top (labelInPadding), Width = 10,
|
||||
Text = "text (Y = 1)"
|
||||
};
|
||||
|
||||
textFieldInPadding.Accepting += (_, _) => MessageBox.Query (appWindow.App!, 20, 7, "TextField", textFieldInPadding.Text, "Ok");
|
||||
window.Padding.Add (textFieldInPadding);
|
||||
|
||||
Button btnButtonInPadding = new ()
|
||||
{
|
||||
X = Pos.Center (),
|
||||
Y = 1,
|
||||
Text = "_Button in Padding Y = 1"
|
||||
};
|
||||
btnButtonInPadding.Accepting += (_, _) => MessageBox.Query (appWindow.App!, 20, 7, "Hi", "Button in Padding Pressed!", "Ok");
|
||||
window.Padding.Add (btnButtonInPadding);
|
||||
|
||||
#if SUBVIEW_BASED_BORDER
|
||||
btnButtonInPadding.Border!.CloseButton.Visible = true;
|
||||
|
||||
view.Border!.CloseButton.Visible = true;
|
||||
view.Border!.CloseButton.Accept += (s, e) =>
|
||||
view.Border!.CloseButton.Accept += (_, _) =>
|
||||
{
|
||||
MessageBox.Query (20, 7, "Hi", "Window Close Button Pressed!", "Ok");
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
view.Accept += (s, e) => MessageBox.Query (20, 7, "Hi", "Window Close Button Pressed!", "Ok");
|
||||
view.Accept += (_, _) => MessageBox.Query (20, 7, "Hi", "Window Close Button Pressed!", "Ok");
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -156,9 +166,6 @@ public class Adornments : Scenario
|
||||
editor.AutoSelectSuperView = window;
|
||||
editor.AutoSelectAdornments = true;
|
||||
|
||||
Application.Run (appWindow);
|
||||
appWindow.Dispose ();
|
||||
|
||||
Application.Shutdown ();
|
||||
app.Run (appWindow);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,158 +0,0 @@
|
||||
#nullable enable
|
||||
|
||||
namespace UICatalog.Scenarios;
|
||||
|
||||
[ScenarioMetadata ("WizardAsView", "Shows using the Wizard class in an non-modal way")]
|
||||
[ScenarioCategory ("Wizards")]
|
||||
public class WizardAsView : Scenario
|
||||
{
|
||||
public override void Main ()
|
||||
{
|
||||
Application.Init ();
|
||||
|
||||
// MenuBar
|
||||
MenuBar menu = new ();
|
||||
|
||||
menu.Add (
|
||||
new MenuBarItem (
|
||||
"_File",
|
||||
[
|
||||
new MenuItem
|
||||
{
|
||||
Title = "_Restart Configuration...",
|
||||
Action = () => MessageBox.Query (
|
||||
Application.Instance,
|
||||
"Wizard",
|
||||
"Are you sure you want to reset the Wizard and start over?",
|
||||
"Ok",
|
||||
"Cancel"
|
||||
)
|
||||
},
|
||||
new MenuItem
|
||||
{
|
||||
Title = "Re_boot Server...",
|
||||
Action = () => MessageBox.Query (
|
||||
Application.Instance,
|
||||
"Wizard",
|
||||
"Are you sure you want to reboot the server start over?",
|
||||
"Ok",
|
||||
"Cancel"
|
||||
)
|
||||
},
|
||||
new MenuItem
|
||||
{
|
||||
Title = "_Shutdown Server...",
|
||||
Action = () => MessageBox.Query (
|
||||
Application.Instance,
|
||||
"Wizard",
|
||||
"Are you sure you want to cancel setup and shutdown?",
|
||||
"Ok",
|
||||
"Cancel"
|
||||
)
|
||||
}
|
||||
]
|
||||
)
|
||||
);
|
||||
|
||||
// No need for a Title because the border is disabled
|
||||
Wizard wizard = new ()
|
||||
{
|
||||
X = 0,
|
||||
Y = Pos.Bottom (menu),
|
||||
Width = Dim.Fill (),
|
||||
Height = Dim.Fill (),
|
||||
ShadowStyle = ShadowStyle.None
|
||||
};
|
||||
|
||||
// Set Modal 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 += (s, args) =>
|
||||
{
|
||||
//args.Cancel = true;
|
||||
//actionLabel.Text = "Moving Back";
|
||||
};
|
||||
|
||||
wizard.MovingNext += (s, args) =>
|
||||
{
|
||||
//args.Cancel = true;
|
||||
//actionLabel.Text = "Moving Next";
|
||||
};
|
||||
|
||||
wizard.Finished += (s, args) =>
|
||||
{
|
||||
//args.Cancel = true;
|
||||
MessageBox.Query ((s as View)?.App!, "Setup Wizard", "Finished", "Ok");
|
||||
Application.RequestStop ();
|
||||
};
|
||||
|
||||
wizard.Cancelled += (s, args) =>
|
||||
{
|
||||
int? btn = MessageBox.Query ((s as View)?.App!, "Setup Wizard", "Are you sure you want to cancel?", "Yes", "No");
|
||||
args.Cancel = btn == 1;
|
||||
|
||||
if (btn == 0)
|
||||
{
|
||||
Application.RequestStop ();
|
||||
}
|
||||
};
|
||||
|
||||
// Add 1st step
|
||||
WizardStep firstStep = new () { Title = "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
|
||||
WizardStep secondStep = new () { Title = "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.";
|
||||
|
||||
Label buttonLbl = new () { Text = "Second Step Button: ", X = 0, Y = 0 };
|
||||
|
||||
Button button = new ()
|
||||
{
|
||||
Text = "Press Me to Rename Step",
|
||||
X = Pos.Right (buttonLbl),
|
||||
Y = Pos.Top (buttonLbl)
|
||||
};
|
||||
|
||||
button.Accepting += (s, e) =>
|
||||
{
|
||||
secondStep.Title = "2nd Step";
|
||||
|
||||
MessageBox.Query ((s as View)?.App!,
|
||||
"Wizard Scenario",
|
||||
"This Wizard Step's title was changed to '2nd Step'",
|
||||
"Ok"
|
||||
);
|
||||
};
|
||||
secondStep.Add (buttonLbl, button);
|
||||
|
||||
Label lbl = new () { Text = "First Name: ", X = Pos.Left (buttonLbl), Y = Pos.Bottom (buttonLbl) };
|
||||
TextField firstNameField = new () { Text = "Number", Width = 30, X = Pos.Right (lbl), Y = Pos.Top (lbl) };
|
||||
secondStep.Add (lbl, firstNameField);
|
||||
lbl = new () { Text = "Last Name: ", X = Pos.Left (buttonLbl), Y = Pos.Bottom (lbl) };
|
||||
TextField lastNameField = new () { Text = "Six", Width = 30, X = Pos.Right (lbl), Y = Pos.Top (lbl) };
|
||||
secondStep.Add (lbl, lastNameField);
|
||||
|
||||
// Add last step
|
||||
WizardStep lastStep = new () { Title = "The last step" };
|
||||
wizard.AddStep (lastStep);
|
||||
|
||||
lastStep.HelpText =
|
||||
"The wizard is complete!\n\nPress the Finish button to continue.\n\nPressing Esc will cancel.";
|
||||
|
||||
Window window = new ();
|
||||
window.Add (menu, wizard);
|
||||
|
||||
Application.Run (window);
|
||||
window.Dispose ();
|
||||
Application.Shutdown ();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,9 @@
|
||||
namespace UICatalog.Scenarios;
|
||||
#nullable enable
|
||||
|
||||
// ReSharper disable AccessToDisposedClosure
|
||||
using Terminal.Gui.Views;
|
||||
|
||||
namespace UICatalog.Scenarios;
|
||||
|
||||
[ScenarioMetadata ("Wizards", "Demonstrates the Wizard class")]
|
||||
[ScenarioCategory ("Dialogs")]
|
||||
@@ -6,69 +11,37 @@
|
||||
[ScenarioCategory ("Runnable")]
|
||||
public class Wizards : Scenario
|
||||
{
|
||||
private Wizard? _wizard;
|
||||
private View? _actionLabel;
|
||||
private TextField? _titleEdit;
|
||||
|
||||
public override void Main ()
|
||||
{
|
||||
Application.Init ();
|
||||
var win = new Window { Title = GetQuitKeyAndName () };
|
||||
using IApplication app = Application.Instance;
|
||||
|
||||
var frame = new FrameView
|
||||
using Window win = new ();
|
||||
win.Title = GetQuitKeyAndName ();
|
||||
|
||||
FrameView settingsFrame = new ()
|
||||
{
|
||||
X = Pos.Center (),
|
||||
Y = 0,
|
||||
Width = Dim.Percent (75),
|
||||
SchemeName = "Base",
|
||||
Height = Dim.Auto (),
|
||||
Title = "Wizard Options"
|
||||
};
|
||||
win.Add (frame);
|
||||
win.Add (settingsFrame);
|
||||
|
||||
var label = new Label { X = 0, Y = 0, TextAlignment = Alignment.End, Text = "_Width:", Width = 10 };
|
||||
frame.Add (label);
|
||||
|
||||
var widthEdit = new TextField
|
||||
{
|
||||
X = Pos.Right (label) + 1,
|
||||
Y = Pos.Top (label),
|
||||
Width = 5,
|
||||
Height = 1,
|
||||
Text = "80"
|
||||
};
|
||||
frame.Add (widthEdit);
|
||||
|
||||
label = new ()
|
||||
Label label = new ()
|
||||
{
|
||||
X = 0,
|
||||
Y = Pos.Bottom (label),
|
||||
|
||||
Width = Dim.Width (label),
|
||||
Height = 1,
|
||||
TextAlignment = Alignment.End,
|
||||
Text = "_Height:"
|
||||
};
|
||||
frame.Add (label);
|
||||
|
||||
var heightEdit = new TextField
|
||||
{
|
||||
X = Pos.Right (label) + 1,
|
||||
Y = Pos.Top (label),
|
||||
Width = 5,
|
||||
Height = 1,
|
||||
Text = "20"
|
||||
};
|
||||
frame.Add (heightEdit);
|
||||
|
||||
label = new ()
|
||||
{
|
||||
X = 0,
|
||||
Y = Pos.Bottom (label),
|
||||
|
||||
Width = Dim.Width (label),
|
||||
Height = 1,
|
||||
TextAlignment = Alignment.End,
|
||||
Text = "_Title:"
|
||||
};
|
||||
frame.Add (label);
|
||||
settingsFrame.Add (label);
|
||||
|
||||
var titleEdit = new TextField
|
||||
_titleEdit = new ()
|
||||
{
|
||||
X = Pos.Right (label) + 1,
|
||||
Y = Pos.Top (label),
|
||||
@@ -76,15 +49,26 @@ public class Wizards : Scenario
|
||||
Height = 1,
|
||||
Text = "Gandolf"
|
||||
};
|
||||
frame.Add (titleEdit);
|
||||
settingsFrame.Add (_titleEdit);
|
||||
|
||||
void Win_Loaded (object sender, EventArgs args)
|
||||
CheckBox cbRun = new ()
|
||||
{
|
||||
frame.Height = widthEdit.Frame.Height + heightEdit.Frame.Height + titleEdit.Frame.Height + 2;
|
||||
win.IsModalChanged -= Win_Loaded;
|
||||
}
|
||||
Title = "_Run Wizard as a modal",
|
||||
X = 0,
|
||||
Y = Pos.Bottom (label),
|
||||
CheckedState = CheckState.Checked
|
||||
};
|
||||
settingsFrame.Add (cbRun);
|
||||
|
||||
win.IsModalChanged += Win_Loaded;
|
||||
Button showWizardButton = new ()
|
||||
{
|
||||
X = Pos.Center (),
|
||||
Y = Pos.Bottom (cbRun),
|
||||
IsDefault = true,
|
||||
Text = "_Show Wizard"
|
||||
};
|
||||
|
||||
settingsFrame.Add (showWizardButton);
|
||||
|
||||
label = new ()
|
||||
{
|
||||
@@ -92,295 +76,104 @@ public class Wizards : Scenario
|
||||
};
|
||||
win.Add (label);
|
||||
|
||||
var actionLabel = new Label
|
||||
_actionLabel = new ()
|
||||
{
|
||||
X = Pos.Right (label), Y = Pos.AnchorEnd (1), SchemeName = "Error"
|
||||
X = Pos.Right (label),
|
||||
Y = Pos.AnchorEnd (1),
|
||||
SchemeName = SchemeManager.SchemesToSchemeName (Schemes.Error),
|
||||
Width = Dim.Auto (),
|
||||
Height = Dim.Auto ()
|
||||
};
|
||||
win.Add (actionLabel);
|
||||
win.Add (_actionLabel);
|
||||
|
||||
var showWizardButton = new Button
|
||||
if (cbRun.CheckedState != CheckState.Checked)
|
||||
{
|
||||
X = Pos.Center (), Y = Pos.Bottom (frame) + 2, IsDefault = true, Text = "_Show Wizard"
|
||||
showWizardButton.Enabled = false;
|
||||
_wizard = CreateWizard ();
|
||||
win.Add (_wizard);
|
||||
}
|
||||
|
||||
cbRun.CheckedStateChanged += (_, a) =>
|
||||
{
|
||||
if (a.Value == CheckState.Checked)
|
||||
{
|
||||
showWizardButton.Enabled = true;
|
||||
_wizard!.X = Pos.Center ();
|
||||
_wizard.Y = Pos.Center ();
|
||||
|
||||
win.Remove (_wizard);
|
||||
_wizard.Dispose ();
|
||||
_wizard = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
showWizardButton.Enabled = false;
|
||||
_wizard = CreateWizard ();
|
||||
_wizard.Y = Pos.Bottom (settingsFrame) + 1;
|
||||
win.Add (_wizard);
|
||||
}
|
||||
};
|
||||
|
||||
showWizardButton.Accepting += (s, e) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var width = 0;
|
||||
int.TryParse (widthEdit.Text, out width);
|
||||
var height = 0;
|
||||
int.TryParse (heightEdit.Text, out height);
|
||||
showWizardButton.Accepting += (_, _) =>
|
||||
{
|
||||
_wizard = CreateWizard ();
|
||||
app.Run (_wizard);
|
||||
_wizard.Dispose ();
|
||||
};
|
||||
|
||||
if (width < 1 || height < 1)
|
||||
{
|
||||
MessageBox.ErrorQuery (
|
||||
(s as View)?.App,
|
||||
"Nope",
|
||||
"Height and width must be greater than 0 (much bigger)",
|
||||
"Ok"
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
actionLabel.Text = string.Empty;
|
||||
|
||||
var wizard = new Wizard { Title = titleEdit.Text, Width = width, Height = height };
|
||||
|
||||
wizard.MovingBack += (s, args) =>
|
||||
{
|
||||
//args.Cancel = true;
|
||||
actionLabel.Text = "Moving Back";
|
||||
};
|
||||
|
||||
wizard.MovingNext += (s, args) =>
|
||||
{
|
||||
//args.Cancel = true;
|
||||
actionLabel.Text = "Moving Next";
|
||||
};
|
||||
|
||||
wizard.Finished += (s, args) =>
|
||||
{
|
||||
//args.Cancel = true;
|
||||
actionLabel.Text = "Finished";
|
||||
};
|
||||
|
||||
wizard.Cancelled += (s, args) =>
|
||||
{
|
||||
//args.Cancel = true;
|
||||
actionLabel.Text = "Cancelled";
|
||||
};
|
||||
|
||||
// Add 1st step
|
||||
var firstStep = new WizardStep { Title = "End User License Agreement" };
|
||||
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.";
|
||||
|
||||
OptionSelector optionSelector = new ()
|
||||
{
|
||||
Labels = ["_One", "_Two", "_3"]
|
||||
};
|
||||
firstStep.Add (optionSelector);
|
||||
|
||||
wizard.AddStep (firstStep);
|
||||
|
||||
// Add 2nd step
|
||||
var secondStep = new WizardStep { Title = "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 = 1, Y = 1 };
|
||||
|
||||
var button = new Button
|
||||
{
|
||||
Text = "Press Me to Rename Step", X = Pos.Right (buttonLbl), Y = Pos.Top (buttonLbl)
|
||||
};
|
||||
|
||||
OptionSelector optionSelecor2 = new ()
|
||||
{
|
||||
Labels = ["_A", "_B", "_C"],
|
||||
Orientation = Orientation.Horizontal
|
||||
};
|
||||
secondStep.Add (optionSelecor2);
|
||||
|
||||
button.Accepting += (s, e) =>
|
||||
{
|
||||
secondStep.Title = "2nd Step";
|
||||
|
||||
MessageBox.Query (
|
||||
(s as View)?.App,
|
||||
"Wizard Scenario",
|
||||
"This Wizard Step's title was changed to '2nd Step'"
|
||||
);
|
||||
};
|
||||
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) };
|
||||
secondStep.Add (lbl, firstNameField);
|
||||
lbl = new () { 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) };
|
||||
secondStep.Add (lbl, lastNameField);
|
||||
|
||||
var thirdStepEnabledCeckBox = new CheckBox
|
||||
{
|
||||
Text = "Enable Step _3",
|
||||
CheckedState = CheckState.UnChecked,
|
||||
X = Pos.Left (lastNameField),
|
||||
Y = Pos.Bottom (lastNameField)
|
||||
};
|
||||
secondStep.Add (thirdStepEnabledCeckBox);
|
||||
|
||||
// Add a frame
|
||||
var frame = new FrameView
|
||||
{
|
||||
X = 0,
|
||||
Y = Pos.Bottom (thirdStepEnabledCeckBox) + 2,
|
||||
Width = Dim.Fill (),
|
||||
Height = 4,
|
||||
Title = "A Broken Frame (by Depeche Mode)",
|
||||
TabStop = TabBehavior.NoStop
|
||||
};
|
||||
frame.Add (new TextField { Text = "This is a TextField inside of the frame." });
|
||||
secondStep.Add (frame);
|
||||
|
||||
wizard.StepChanging += (s, args) =>
|
||||
{
|
||||
if (args.OldStep == secondStep && string.IsNullOrEmpty (firstNameField.Text))
|
||||
{
|
||||
args.Cancel = true;
|
||||
|
||||
int? btn = MessageBox.ErrorQuery (
|
||||
(s as View)?.App,
|
||||
"Second Step",
|
||||
"You must enter a First Name to continue",
|
||||
"Ok"
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// Add 3rd (optional) step
|
||||
var thirdStep = new WizardStep { Title = "Third Step (Optional)" };
|
||||
wizard.AddStep (thirdStep);
|
||||
|
||||
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 };
|
||||
thirdStep.Add (step3Label);
|
||||
var progLbl = new Label { Text = "Third Step ProgressBar: ", X = 1, Y = 10 };
|
||||
|
||||
var progressBar = new ProgressBar
|
||||
{
|
||||
X = Pos.Right (progLbl), Y = Pos.Top (progLbl), Width = 40, Fraction = 0.42F
|
||||
};
|
||||
thirdStep.Add (progLbl, progressBar);
|
||||
thirdStep.Enabled = thirdStepEnabledCeckBox.CheckedState == CheckState.Checked;
|
||||
|
||||
thirdStepEnabledCeckBox.CheckedStateChanged += (s, e) =>
|
||||
{
|
||||
thirdStep.Enabled =
|
||||
thirdStepEnabledCeckBox.CheckedState == CheckState.Checked;
|
||||
};
|
||||
|
||||
// Add 4th step
|
||||
var fourthStep = new WizardStep { Title = "Step Four" };
|
||||
wizard.AddStep (fourthStep);
|
||||
|
||||
var someText = new TextView
|
||||
{
|
||||
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 (),
|
||||
WordWrap = true,
|
||||
AllowsTab = false,
|
||||
SchemeName = "Base"
|
||||
};
|
||||
|
||||
someText.Height = Dim.Fill (
|
||||
Dim.Func (v => someText.SuperView is { IsInitialized: true }
|
||||
? someText.SuperView.SubViews
|
||||
.First (view => view.Y.Has<PosAnchorEnd> (out _))
|
||||
.Frame.Height
|
||||
: 1));
|
||||
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 ()
|
||||
};
|
||||
|
||||
hideHelpBtn.Accepting += (s, e) =>
|
||||
{
|
||||
if (fourthStep.HelpText.Length > 0)
|
||||
{
|
||||
fourthStep.HelpText = string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
fourthStep.HelpText = help;
|
||||
}
|
||||
};
|
||||
fourthStep.Add (hideHelpBtn);
|
||||
fourthStep.NextButtonText = "_Go To Last Step";
|
||||
|
||||
//var scrollBar = new ScrollBarView (someText, true);
|
||||
|
||||
//scrollBar.ChangedPosition += (s, e) =>
|
||||
// {
|
||||
// someText.TopRow = scrollBar.Position;
|
||||
|
||||
// if (someText.TopRow != scrollBar.Position)
|
||||
// {
|
||||
// scrollBar.Position = someText.TopRow;
|
||||
// }
|
||||
|
||||
// someText.SetNeedsDraw ();
|
||||
// };
|
||||
|
||||
//someText.DrawingContent += (s, e) =>
|
||||
// {
|
||||
// scrollBar.Size = someText.Lines;
|
||||
// scrollBar.Position = someText.TopRow;
|
||||
|
||||
// if (scrollBar.OtherScrollBarView != null)
|
||||
// {
|
||||
// scrollBar.OtherScrollBarView.Size = someText.Maxlength;
|
||||
// scrollBar.OtherScrollBarView.Position = someText.LeftColumn;
|
||||
// }
|
||||
// };
|
||||
//fourthStep.Add (scrollBar);
|
||||
|
||||
// Add last step
|
||||
var lastStep = new WizardStep { Title = "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.";
|
||||
|
||||
var finalFinalStepEnabledCeckBox =
|
||||
new CheckBox { Text = "Enable _Final Final Step", CheckedState = CheckState.UnChecked, X = 0, Y = 1 };
|
||||
lastStep.Add (finalFinalStepEnabledCeckBox);
|
||||
|
||||
// Add an optional FINAL last step
|
||||
var finalFinalStep = new WizardStep { Title = "The VERY last step" };
|
||||
wizard.AddStep (finalFinalStep);
|
||||
|
||||
finalFinalStep.HelpText =
|
||||
"This step only shows if it was enabled on the other last step.";
|
||||
finalFinalStep.Enabled = thirdStepEnabledCeckBox.CheckedState == CheckState.Checked;
|
||||
|
||||
finalFinalStepEnabledCeckBox.CheckedStateChanged += (s, e) =>
|
||||
{
|
||||
finalFinalStep.Enabled =
|
||||
finalFinalStepEnabledCeckBox.CheckedState
|
||||
== CheckState.Checked;
|
||||
};
|
||||
|
||||
Application.Run (wizard);
|
||||
wizard.Dispose ();
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
actionLabel.Text = "Invalid Options";
|
||||
}
|
||||
};
|
||||
win.Add (showWizardButton);
|
||||
|
||||
Application.Run (win);
|
||||
win.Dispose ();
|
||||
Application.Shutdown ();
|
||||
app.Run (win);
|
||||
}
|
||||
|
||||
private void Wizard_StepChanged (object sender, StepChangeEventArgs e) { throw new NotImplementedException (); }
|
||||
private Wizard CreateWizard ()
|
||||
{
|
||||
Wizard wizard = new ();
|
||||
|
||||
if (_titleEdit is { })
|
||||
{
|
||||
wizard.Title = _titleEdit.Text;
|
||||
}
|
||||
|
||||
wizard.MovingBack += (_, args) =>
|
||||
{
|
||||
// Set Cancel to true to prevent moving back
|
||||
args.Cancel = false;
|
||||
_actionLabel!.Text = "Moving Back";
|
||||
};
|
||||
|
||||
wizard.MovingNext += (_, args) =>
|
||||
{
|
||||
// Set Cancel to true to prevent moving next
|
||||
args.Cancel = false;
|
||||
_actionLabel!.Text = "Moving Next";
|
||||
};
|
||||
|
||||
wizard.Accepting += (s, args) =>
|
||||
{
|
||||
_actionLabel!.Text = "Finished";
|
||||
MessageBox.Query ((s as View)?.App!, "Wizard", "The Wizard has been completed and accepted!", "_Ok");
|
||||
|
||||
if (wizard.IsRunning)
|
||||
{
|
||||
// Don't set args.Handled to true to allow the wizard to close
|
||||
args.Handled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
wizard.App!.RequestStop();
|
||||
args.Handled = true;
|
||||
}
|
||||
};
|
||||
|
||||
wizard.Cancelled += (s, args) =>
|
||||
{
|
||||
_actionLabel!.Text = "Cancelled";
|
||||
|
||||
int? btn = MessageBox.Query ((s as View)?.App!, "Wizard", "Are you sure you want to cancel?", "_Yes", "_No");
|
||||
args.Cancel = btn is not 0;
|
||||
};
|
||||
|
||||
((IDesignable)wizard).EnableForDesign ();
|
||||
|
||||
return wizard;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -663,7 +663,8 @@ public class UICatalog
|
||||
// 'app' closed cleanly.
|
||||
foreach (View? inst in View.Instances)
|
||||
{
|
||||
Debug.Assert (inst.WasDisposed);
|
||||
//Debug.Assert (inst.WasDisposed);
|
||||
Logging.Error ($"View instance not disposed: {inst}");
|
||||
}
|
||||
|
||||
View.Instances.Clear ();
|
||||
|
||||
Reference in New Issue
Block a user