Files
Terminal.Gui/Examples/UICatalog/Scenarios/Wizards.cs
Copilot 4145b984ba Fixes #2485 ++ - Wizard v2 architecture modernization with Padding-based layout (#4510)
* 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>
2025-12-21 07:42:04 -07:00

180 lines
5.2 KiB
C#

#nullable enable
// ReSharper disable AccessToDisposedClosure
using Terminal.Gui.Views;
namespace UICatalog.Scenarios;
[ScenarioMetadata ("Wizards", "Demonstrates the Wizard class")]
[ScenarioCategory ("Dialogs")]
[ScenarioCategory ("Wizards")]
[ScenarioCategory ("Runnable")]
public class Wizards : Scenario
{
private Wizard? _wizard;
private View? _actionLabel;
private TextField? _titleEdit;
public override void Main ()
{
Application.Init ();
using IApplication app = Application.Instance;
using Window win = new ();
win.Title = GetQuitKeyAndName ();
FrameView settingsFrame = new ()
{
X = Pos.Center (),
Y = 0,
Width = Dim.Percent (75),
Height = Dim.Auto (),
Title = "Wizard Options"
};
win.Add (settingsFrame);
Label label = new ()
{
X = 0,
TextAlignment = Alignment.End,
Text = "_Title:"
};
settingsFrame.Add (label);
_titleEdit = new ()
{
X = Pos.Right (label) + 1,
Y = Pos.Top (label),
Width = Dim.Fill (),
Height = 1,
Text = "Gandolf"
};
settingsFrame.Add (_titleEdit);
CheckBox cbRun = new ()
{
Title = "_Run Wizard as a modal",
X = 0,
Y = Pos.Bottom (label),
CheckedState = CheckState.Checked
};
settingsFrame.Add (cbRun);
Button showWizardButton = new ()
{
X = Pos.Center (),
Y = Pos.Bottom (cbRun),
IsDefault = true,
Text = "_Show Wizard"
};
settingsFrame.Add (showWizardButton);
label = new ()
{
X = Pos.Center (), Y = Pos.AnchorEnd (1), TextAlignment = Alignment.End, Text = "Action:"
};
win.Add (label);
_actionLabel = new ()
{
X = Pos.Right (label),
Y = Pos.AnchorEnd (1),
SchemeName = SchemeManager.SchemesToSchemeName (Schemes.Error),
Width = Dim.Auto (),
Height = Dim.Auto ()
};
win.Add (_actionLabel);
if (cbRun.CheckedState != CheckState.Checked)
{
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 += (_, _) =>
{
_wizard = CreateWizard ();
app.Run (_wizard);
_wizard.Dispose ();
};
app.Run (win);
}
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;
}
}