瀏覽代碼

Merged with v2_develop

Tig 1 年之前
父節點
當前提交
36503921ca
共有 100 個文件被更改,包括 1113 次插入939 次删除
  1. 2 2
      .github/workflows/api-docs.yml
  2. 1 1
      .github/workflows/publish.yml
  3. 5 5
      CONTRIBUTING.md
  4. 0 6
      Directory.Build.props
  5. 0 5
      Directory.Build.targets
  6. 21 20
      Example/Example.cs
  7. 3 0
      FSharpExample/FSharpExample.fsproj
  8. 36 442
      FSharpExample/Program.fs
  9. 122 17
      README.md
  10. 2 2
      Release.ps1
  11. 89 0
      SelfContained/Program.cs
  12. 16 0
      SelfContained/Properties/PublishProfiles/FolderProfile_net8.0_linux-x64_Debug.pubxml
  13. 16 0
      SelfContained/Properties/PublishProfiles/FolderProfile_net8.0_linux-x64_Release.pubxml
  14. 16 0
      SelfContained/Properties/PublishProfiles/FolderProfile_net8.0_osx-x64_Debug.pubxml
  15. 16 0
      SelfContained/Properties/PublishProfiles/FolderProfile_net8.0_osx-x64_Release.pubxml
  16. 17 0
      SelfContained/Properties/PublishProfiles/FolderProfile_net8.0_win-x64_Debug.pubxml
  17. 17 0
      SelfContained/Properties/PublishProfiles/FolderProfile_net8.0_win-x64_Release.pubxml
  18. 9 0
      SelfContained/README.md
  19. 25 0
      SelfContained/SelfContained.csproj
  20. 31 0
      Showcase.md
  21. 11 1
      Terminal.Gui/Application/Application.cs
  22. 3 3
      Terminal.Gui/Configuration/AttributeJsonConverter.cs
  23. 1 1
      Terminal.Gui/Configuration/ColorSchemeJsonConverter.cs
  24. 22 4
      Terminal.Gui/Configuration/ConfigurationManager.cs
  25. 3 3
      Terminal.Gui/Configuration/DictionaryJsonConverter.cs
  26. 1 1
      Terminal.Gui/Configuration/KeyCodeJsonConverter.cs
  27. 13 5
      Terminal.Gui/Configuration/ScopeJsonConverter.cs
  28. 10 1
      Terminal.Gui/Configuration/SettingsScope.cs
  29. 23 0
      Terminal.Gui/Configuration/SourceGenerationContext.cs
  30. 113 0
      Terminal.Gui/Configuration/ThemeManager.cs
  31. 2 0
      Terminal.Gui/ConsoleDrivers/CursesDriver/UnmanagedLibrary.cs
  32. 3 0
      Terminal.Gui/ConsoleDrivers/NetDriver.cs
  33. 3 3
      Terminal.Gui/ConsoleDrivers/WindowsDriver.cs
  34. 3 1
      Terminal.Gui/FileServices/FileDialogStyle.cs
  35. 2 4
      Terminal.Gui/README.md
  36. 5 7
      Terminal.Gui/Terminal.Gui.csproj
  37. 1 1
      Terminal.Gui/Views/Button.cs
  38. 4 4
      Terminal.Gui/Views/Dialog.cs
  39. 1 1
      Terminal.Gui/Views/FrameView.cs
  40. 1 1
      Terminal.Gui/Views/MessageBox.cs
  41. 1 1
      Terminal.Gui/Views/Window.cs
  42. 6 0
      Terminal.sln
  43. 4 80
      UICatalog/Scenario.cs
  44. 1 1
      UICatalog/Scenarios/ASCIICustomButton.cs
  45. 1 1
      UICatalog/Scenarios/Adornments.cs
  46. 1 1
      UICatalog/Scenarios/AllViewsTester.cs
  47. 1 1
      UICatalog/Scenarios/AnimationScenario.cs
  48. 1 1
      UICatalog/Scenarios/Bars.cs
  49. 1 1
      UICatalog/Scenarios/BasicColors.cs
  50. 1 1
      UICatalog/Scenarios/Buttons.cs
  51. 1 1
      UICatalog/Scenarios/ChineseUI.cs
  52. 19 9
      UICatalog/Scenarios/ClassExplorer.cs
  53. 8 12
      UICatalog/Scenarios/Clipping.cs
  54. 13 12
      UICatalog/Scenarios/CollectionNavigatorTester.cs
  55. 1 1
      UICatalog/Scenarios/ColorPicker.cs
  56. 24 24
      UICatalog/Scenarios/CombiningMarks.cs
  57. 13 7
      UICatalog/Scenarios/ComboBoxIteration.cs
  58. 1 1
      UICatalog/Scenarios/ComputedLayout.cs
  59. 1 1
      UICatalog/Scenarios/ContentScrolling.cs
  60. 1 1
      UICatalog/Scenarios/ContextMenus.cs
  61. 1 1
      UICatalog/Scenarios/DatePickers.cs
  62. 1 1
      UICatalog/Scenarios/Dialogs.cs
  63. 1 1
      UICatalog/Scenarios/DimAutoDemo.cs
  64. 1 1
      UICatalog/Scenarios/DynamicMenuBar.cs
  65. 1 1
      UICatalog/Scenarios/DynamicStatusBar.cs
  66. 1 1
      UICatalog/Scenarios/Editor.cs
  67. 36 30
      UICatalog/Scenarios/FileDialogExamples.cs
  68. 1 1
      UICatalog/Scenarios/Generic.cs
  69. 1 1
      UICatalog/Scenarios/HotKeys.cs
  70. 58 52
      UICatalog/Scenarios/Images.cs
  71. 13 4
      UICatalog/Scenarios/InvertColors.cs
  72. 1 1
      UICatalog/Scenarios/KeyBindings.cs
  73. 19 13
      UICatalog/Scenarios/Keys.cs
  74. 1 1
      UICatalog/Scenarios/LineCanvasExperiment.cs
  75. 10 4
      UICatalog/Scenarios/LineDrawing.cs
  76. 7 5
      UICatalog/Scenarios/LineViewExample.cs
  77. 10 9
      UICatalog/Scenarios/ListColumns.cs
  78. 1 1
      UICatalog/Scenarios/ListViewWithSelection.cs
  79. 10 4
      UICatalog/Scenarios/ListsAndCombos.cs
  80. 20 13
      UICatalog/Scenarios/Localization.cs
  81. 1 1
      UICatalog/Scenarios/MenuBarScenario.cs
  82. 1 1
      UICatalog/Scenarios/MessageBoxes.cs
  83. 1 1
      UICatalog/Scenarios/Mouse.cs
  84. 1 1
      UICatalog/Scenarios/MultiColouredTable.cs
  85. 13 5
      UICatalog/Scenarios/ProcessTable.cs
  86. 12 5
      UICatalog/Scenarios/Progress.cs
  87. 1 1
      UICatalog/Scenarios/ProgressBarStyles.cs
  88. 1 1
      UICatalog/Scenarios/Scrolling.cs
  89. 18 12
      UICatalog/Scenarios/SendKeys.cs
  90. 1 1
      UICatalog/Scenarios/ShadowStyles.cs
  91. 1 1
      UICatalog/Scenarios/Shortcuts.cs
  92. 1 1
      UICatalog/Scenarios/Sliders.cs
  93. 8 3
      UICatalog/Scenarios/Snake.cs
  94. 1 1
      UICatalog/Scenarios/SpinnerStyles.cs
  95. 33 27
      UICatalog/Scenarios/Text.cs
  96. 1 1
      UICatalog/Scenarios/TextAlignmentAndDirection.cs
  97. 1 1
      UICatalog/Scenarios/TextFormatterDemo.cs
  98. 13 7
      UICatalog/Scenarios/Threading.cs
  99. 22 12
      UICatalog/Scenarios/TileViewNesting.cs
  100. 19 13
      UICatalog/Scenarios/TimeAndDate.cs

+ 2 - 2
.github/workflows/api-docs.yml

@@ -32,7 +32,7 @@ jobs:
 
 
     - name: Setup Pages
     - name: Setup Pages
       if: github.ref_name == 'v1_release' ||  github.ref_name == 'v1_develop'
       if: github.ref_name == 'v1_release' ||  github.ref_name == 'v1_develop'
-      uses: actions/configure-pages@v4
+      uses: actions/configure-pages@v5
       
       
     - name: Upload artifact
     - name: Upload artifact
       if: github.ref_name == 'v1_release' ||  github.ref_name == 'v1_develop'
       if: github.ref_name == 'v1_release' ||  github.ref_name == 'v1_develop'
@@ -49,7 +49,7 @@ jobs:
 
 
     - name: v2_develop Repository Dispatch ${{ github.ref_name }}
     - name: v2_develop Repository Dispatch ${{ github.ref_name }}
       if: github.ref_name == 'v2_develop'
       if: github.ref_name == 'v2_develop'
-      uses: peter-evans/repository-dispatch@v2
+      uses: peter-evans/repository-dispatch@v3
       with:
       with:
         token: ${{ secrets.V2DOCS_TOKEN }}
         token: ${{ secrets.V2DOCS_TOKEN }}
         repository: gui-cs/Terminal.GuiV2Docs
         repository: gui-cs/Terminal.GuiV2Docs

+ 1 - 1
.github/workflows/publish.yml

@@ -19,7 +19,7 @@ jobs:
         fetch-depth: 0 # fetch-depth is needed for GitVersion
         fetch-depth: 0 # fetch-depth is needed for GitVersion
 
 
     - name: Install GitVersion 
     - name: Install GitVersion 
-      uses: gittools/actions/gitversion/setup@v0
+      uses: gittools/actions/gitversion/setup@v1
       with:
       with:
           versionSpec: '5.x'
           versionSpec: '5.x'
           includePrerelease: true
           includePrerelease: true

+ 5 - 5
CONTRIBUTING.md

@@ -10,8 +10,8 @@ We welcome contributions from the community. See [Issues](https://github.com/gui
 
 
 Terminal.Gui uses the [GitFlow](https://nvie.com/posts/a-successful-git-branching-model/) branching model. 
 Terminal.Gui uses the [GitFlow](https://nvie.com/posts/a-successful-git-branching-model/) branching model. 
 
 
-* The `main` branch is always stable, and always matches the most recently released Nuget package.
-* The `develop` branch is where new development and bug-fixes happen. It is the default branch.
+* The `v1_release_` and `v2_release` branches are always stable, and always matches the most recently released Nuget package.
+* The `v1__develop` and `v2_develop` branches are where new development and bug-fixes happen. `v2_develop` is the default Github branch.
 
 
 ### Forking Terminal.Gui
 ### Forking Terminal.Gui
 
 
@@ -33,11 +33,11 @@ You now have your own fork and a local repo that references it as `origin`. Your
 
 
 ### Starting to Make a Change
 ### Starting to Make a Change
 
 
-Ensure your local `develop` (for v1) or `v2_develop` (for v2) branch is up-to-date with `upstream` (`github.com/gui-cs/Terminal.Gui`):
+Ensure your local `v1_develop` (for v1) or `v2_develop` (for v2) branch is up-to-date with `upstream` (`github.com/gui-cs/Terminal.Gui`):
 ```powershell
 ```powershell
 cd ./Terminal.Gui
 cd ./Terminal.Gui
-git checkout develop
-git pull upstream develop
+git checkout v2_develop
+git pull upstream v2_develop
 ```
 ```
 
 
 Create a new local branch:
 Create a new local branch:

+ 0 - 6
Directory.Build.props

@@ -1,6 +0,0 @@
-<Project>
-  <ItemGroup>
-    <PackageReference Include="JetBrains.Annotations" Version="[2024,)" PrivateAssets="all" />
-    <PackageReference Include="JetBrains.ExternalAnnotations" Version="[10.2.149,)" PrivateAssets="all" />
-  </ItemGroup>
-</Project>

+ 0 - 5
Directory.Build.targets

@@ -1,5 +0,0 @@
-<Project>
-  <PropertyGroup>
-    <DefineConstants>$(DefineConstants);DIMAUTO</DefineConstants>
-  </PropertyGroup>
-</Project>

+ 21 - 20
Example/Example.cs

@@ -6,19 +6,19 @@
 using System;
 using System;
 using Terminal.Gui;
 using Terminal.Gui;
 
 
-var app = Application.Run<ExampleWindow> ();
-
-Console.WriteLine ($"Username: {app.UserNameText.Text}");
-
-app.Dispose ();
+Application.Run<ExampleWindow> ().Dispose ();
 
 
 // Before the application exits, reset Terminal.Gui for clean shutdown
 // Before the application exits, reset Terminal.Gui for clean shutdown
 Application.Shutdown ();
 Application.Shutdown ();
 
 
+// To see this output on the screen it must be done after shutdown,
+// which restores the previous screen.
+Console.WriteLine ($@"Username: {ExampleWindow.UserName}");
+
 // Defines a top-level window with border and title
 // Defines a top-level window with border and title
 public class ExampleWindow : Window
 public class ExampleWindow : Window
 {
 {
-    public TextField UserNameText;
+    public static string UserName;
 
 
     public ExampleWindow ()
     public ExampleWindow ()
     {
     {
@@ -27,7 +27,7 @@ public class ExampleWindow : Window
         // Create input components and labels
         // Create input components and labels
         var usernameLabel = new Label { Text = "Username:" };
         var usernameLabel = new Label { Text = "Username:" };
 
 
-        UserNameText = new TextField
+        var userNameText = new TextField
         {
         {
             // Position text field adjacent to the label
             // Position text field adjacent to the label
             X = Pos.Right (usernameLabel) + 1,
             X = Pos.Right (usernameLabel) + 1,
@@ -46,7 +46,7 @@ public class ExampleWindow : Window
             Secret = true,
             Secret = true,
 
 
             // align with the text box above
             // align with the text box above
-            X = Pos.Left (UserNameText),
+            X = Pos.Left (userNameText),
             Y = Pos.Top (passwordLabel),
             Y = Pos.Top (passwordLabel),
             Width = Dim.Fill ()
             Width = Dim.Fill ()
         };
         };
@@ -64,19 +64,20 @@ public class ExampleWindow : Window
 
 
         // When login button is clicked display a message popup
         // When login button is clicked display a message popup
         btnLogin.Accept += (s, e) =>
         btnLogin.Accept += (s, e) =>
-                            {
-                                if (UserNameText.Text == "admin" && passwordText.Text == "password")
-                                {
-                                    MessageBox.Query ("Logging In", "Login Successful", "Ok");
-                                    Application.RequestStop ();
-                                }
-                                else
-                                {
-                                    MessageBox.ErrorQuery ("Logging In", "Incorrect username or password", "Ok");
-                                }
-                            };
+                           {
+                               if (userNameText.Text == "admin" && passwordText.Text == "password")
+                               {
+                                   MessageBox.Query ("Logging In", "Login Successful", "Ok");
+                                   UserName = userNameText.Text;
+                                   Application.RequestStop ();
+                               }
+                               else
+                               {
+                                   MessageBox.ErrorQuery ("Logging In", "Incorrect username or password", "Ok");
+                               }
+                           };
 
 
         // Add the views to the Window
         // Add the views to the Window
-        Add (usernameLabel, UserNameText, passwordLabel, passwordText, btnLogin);
+        Add (usernameLabel, userNameText, passwordLabel, passwordText, btnLogin);
     }
     }
 }
 }

+ 3 - 0
FSharpExample/FSharpExample.fsproj

@@ -13,4 +13,7 @@
   <ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\Terminal.Gui\Terminal.Gui.csproj" />
     <ProjectReference Include="..\Terminal.Gui\Terminal.Gui.csproj" />
   </ItemGroup>
   </ItemGroup>
+  <ItemGroup>
+    <PackageReference Update="FSharp.Core" Version="8.0.300" />
+  </ItemGroup>
 </Project>
 </Project>

+ 36 - 442
FSharpExample/Program.fs

@@ -1,454 +1,48 @@
-open System
-open System.Diagnostics
-open System.Globalization
-open System.IO
-open NStack
-open Terminal.Gui
+open Terminal.Gui
 
 
-let ustr (x: string) = ustring.Make(x)
-let mutable ml2 = Unchecked.defaultof<Label>
-let mutable ml = Unchecked.defaultof<Label>
-let mutable menu = Unchecked.defaultof<MenuBar>
-let mutable menuKeysStyle = Unchecked.defaultof<CheckBox>
-let mutable menuAutoMouseNav = Unchecked.defaultof<CheckBox>
-
-type Box10x (x: int, y: int) =
-    inherit View (Rect(x, y, 20, 10))
-    let w = 40
-    let h = 50
-
-    new () =
-        new Box10x ()
-
-    member _.GetContentSize () =
-        Size (w, h)
-
-    member _.SetCursorPosition (_ : Point) =
-        raise (NotImplementedException())
-
-    override this.Redraw (_: Rect) =
-        Application.Driver.SetAttribute this.ColorScheme.Focus
-        do
-        let mutable y = 0
-        while y < h do
-        this.Move (0, y)
-        Application.Driver.AddStr (ustr (string y))
-        do
-        let mutable x = 0
-        while x < w - (y.ToString ()).Length do
-            if (string y).Length < w
-            then Application.Driver.AddStr (ustr " ")
-            x <- x + 1
-        y <- y + 1
-
-type Filler (rect: Rect) =
-    inherit View(rect)
-    new () =
-        new Filler ()
-
-    override this.Redraw (_: Rect) =
-        Application.Driver.SetAttribute this.ColorScheme.Focus
-        let mutable f = this.Frame
-        do
-        let mutable y = 0
-        while y < f.Width do
-        this.Move (0, y)
-        do
-        let mutable x = 0
-        while x < f.Height do
-            let r =
-                match x % 3 with
-                | 0 ->
-                    Application.Driver.AddRune ((Rune ((string y).ToCharArray (0, 1)).[0]))
-                    if y > 9 then
-                        Application.Driver.AddRune ((Rune ((string y).ToCharArray (1, 1)).[0]))
-                    Rune '.'
-                | 1 -> Rune 'o'
-                | _ -> Rune 'O'
-            Application.Driver.AddRune r
-            x <- x + 1
-        y <- y + 1
-
-let ShowTextAlignments () =
-    let okButton = new Button (ustr "Ok", true)
-    okButton.add_Clicked (Action (Application.RequestStop))
-    let cancelButton = new Button (ustr "Cancel", true)
-    cancelButton.add_Clicked (Action (Application.RequestStop))
-
-    let container = new Dialog (ustr "Text Alignments", 50, 20, okButton, cancelButton)
-    let txt = "Hello world, how are you doing today"
-    container.Add (
-        new Label (Rect(0, 1, 40, 3), ustr ((sprintf "%O-%O" 1) txt), TextAlignment = TextAlignment.Left),
-        new Label (Rect(0, 3, 40, 3), ustr ((sprintf "%O-%O" 2) txt), TextAlignment = TextAlignment.Right),
-        new Label (Rect(0, 5, 40, 3), ustr ((sprintf "%O-%O" 3) txt), TextAlignment = TextAlignment.Centered),
-        new Label (Rect(0, 7, 40, 3), ustr ((sprintf "%O-%O" 4) txt), TextAlignment = TextAlignment.Justified))
-    Application.Run container
-
-let ShowEntries (container: View) =
-    let scrollView = 
-        new ScrollView (Rect (50, 10, 20, 8),
-            ContentSize = Size (20, 50),
-            ShowVerticalScrollIndicator = true,
-            ShowHorizontalScrollIndicator = true)
-    scrollView.Add (new Filler (Rect (0, 0, 40, 40)))
-    let scrollView2 = 
-        new ScrollView (Rect (72, 10, 3, 3),
-            ContentSize = Size (100, 100),
-            ShowVerticalScrollIndicator = true,
-            ShowHorizontalScrollIndicator = true)
-    scrollView2.Add (new Box10x (0, 0))
-    let progress = new ProgressBar (Rect(68, 1, 10, 1))
-    let timer = Func<MainLoop, bool> (fun _ ->
-        progress.Pulse ()
-        true)
-
-    Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (300.), timer) |> ignore
-
-    let login =
-        new Label (ustr "Login: ",
-            X = Pos.At 3,
-            Y = Pos.At 6)
-    let password =
-        new Label (ustr "Password: ",
-            X = Pos.Left login,
-            Y = Pos.Bottom login + Pos.At 1)
-    let loginText =
-        new TextField (ustr "",
-            X = Pos.Right password,
-            Y = Pos.Top login,
-            Width = Dim.op_Implicit 40)
-    let passText =
-        new TextField (ustr "",
-            Secret = true,
-            X = Pos.Left loginText,
-            Y = Pos.Top password,
-            Width = Dim.Width loginText)
-    let tf = new Button (3, 19, ustr "Ok")
-    container.Add (login, loginText, password, passText,
-        new FrameView (Rect (3, 10, 25, 6), ustr "Options",
-            [| new CheckBox (1, 0, ustr "Remember me")
-               new RadioGroup (1, 2, 
-                [| ustr "_Personal"; ustr "_Company"|])|]),
-        new ListView (Rect (59, 6, 16, 4),
-                [| "First row"
-                   "<>"
-                   "This is a very long row that should overflow what is shown"
-                   "4th"
-                   "There is an empty slot on the second row"
-                   "Whoa"
-                   "This is so cool" |]),
-        scrollView, scrollView2, tf,
-        new Button (10, 19, ustr "Cancel"),
-        new TimeField (3, 20, DateTime.Now.TimeOfDay),
-        new TimeField (23, 20, DateTime.Now.TimeOfDay, true),
-        new DateField (3, 22, DateTime.Now),
-        new DateField (23, 22, DateTime.Now, true),
-        progress,
-        new Label (3, 24, ustr "Press F9 (on Unix, ESC+9 is an alias) to activate the menubar"),
-        menuKeysStyle,
-        menuAutoMouseNav)
-    container.SendSubviewToBack tf
-
-let NewFile () =
-    let okButton = new Button (ustr "Ok", true)
-    okButton.add_Clicked (Action (Application.RequestStop))
-    let cancelButton = new Button (ustr "Cancel", true)
-    cancelButton.add_Clicked (Action (Application.RequestStop))
-
-    let d = new Dialog (ustr "New File", 50, 20, okButton, cancelButton)
-    ml2 <- new Label (1, 1, ustr "Mouse Debug Line")
-    d.Add ml2
-    Application.Run d
-
-let GetFileName () =
-    let mutable fname = Unchecked.defaultof<_>
-    for s in [| "/etc/passwd"; "c:\\windows\\win.ini" |] do
-        if File.Exists s
-        then fname <- s
-    fname
-
-let Editor (top: Toplevel) =
-    let tframe = top.Frame
-    let ntop = new Toplevel(tframe)
-    let menu = 
-        new MenuBar(
-            [| MenuBarItem (ustr "_File",
-                 [| MenuItem (ustr "_Close", ustring.Empty, (fun () -> Application.RequestStop ())) |]);
-                    MenuBarItem (ustr "_Edit",
-                        [| MenuItem (ustr "_Copy", ustring.Empty, Unchecked.defaultof<_>)
-                           MenuItem (ustr "C_ut", ustring.Empty, Unchecked.defaultof<_>)
-                           MenuItem (ustr "_Paste", ustring.Empty, Unchecked.defaultof<_>) |]) |])
-    ntop.Add menu
-    let fname = GetFileName ()
-    let win = 
-        new Window (
-            ustr (if not (isNull fname) then fname else "Untitled"),
-            X = Pos.At 0,
-            Y = Pos.At 1,
-            Width = Dim.Fill (),
-            Height = Dim.Fill ())
-    ntop.Add win
-    let text = new TextView (Rect(0, 0, (tframe.Width - 2), (tframe.Height - 3)))
-    if fname <> Unchecked.defaultof<_>
-    then text.Text <- ustr (File.ReadAllText fname)
-    win.Add text
-    Application.Run ntop
-
-let Quit () =
-    MessageBox.Query (50, 7, ustr "Quit Demo", ustr "Are you sure you want to quit this demo?", ustr "Yes", ustr "No") = 0
-
-let Close () =
-    MessageBox.ErrorQuery (50, 7, ustr "Error", ustr "There is nothing to close", ustr "Ok")
-    |> ignore
-
-let Open () =
-    let d = new OpenDialog (ustr "Open", ustr "Open a file", AllowsMultipleSelection = true)
-    Application.Run d
-    if not d.Canceled
-        then MessageBox.Query (50, 7, ustr "Selected File", ustr (String.Join (", ", d.FilePaths)), ustr "Ok") |> ignore
-
-let ShowHex (top: Toplevel) =
-    let tframe = top.Frame
-    let ntop = new Toplevel (tframe)
-    let menu = 
-        new MenuBar (
-            [| MenuBarItem (ustr "_File",
-                 [| MenuItem (ustr "_Close", ustring.Empty, (fun () -> Application.RequestStop ())) |]) |])
-    ntop.Add menu
-    let win =
-        new Window (ustr "/etc/passwd",
-            X = Pos.At 0,
-            Y = Pos.At 1,
-            Width = Dim.Fill (),
-            Height = Dim.Fill ())
-    ntop.Add win
-    let fname = GetFileName ()
-    let source = File.OpenRead fname
-    let hex = 
-        new HexView (source,
-            X = Pos.At 0,
-            Y = Pos.At 0,
-            Width = Dim.Fill (),
-            Height = Dim.Fill ())
-    win.Add hex
-    Application.Run ntop
-
-type MenuItemDetails () =
-    inherit MenuItem ()
-    new (title: ustring, help: ustring, action: Action) as this =
-        MenuItemDetails ()
-        then
-            this.Title <- title
-            this.Help <- help
-            this.Action <- action
-
-    static member Instance (mi: MenuItem) =
-        (mi.GetMenuItem ()) :?> MenuItemDetails
-
-type MenuItemDelegate = delegate of MenuItemDetails -> MenuItem
-
-let ShowMenuItem (mi: MenuItemDetails) =
-    MessageBox.Query (70, 7, ustr (mi.Title.ToString ()),
-        ustr ((sprintf "%O selected. Is from submenu: %O" (mi.Title.ToString ())) (mi.GetMenuBarItem ())), ustr "Ok")
-    |> ignore
-
-let MenuKeysStyleToggled (_: bool) =
-    menu.UseKeysUpDownAsKeysLeftRight <- menuKeysStyle.Checked
-
-let MenuAutoMouseNavToggled (_: bool) =
-    menu.WantMousePositionReports <- menuAutoMouseNav.Checked
-
-let Copy () =
-    let textField = menu.LastFocused :?> TextField
-    if textField <> Unchecked.defaultof<_> && textField.SelectedLength <> 0
-    then textField.Copy ()
+type ExampleWindow() as this =
+    inherit Window()
+    
+    do
+        this.Title <- sprintf "Example App (%O to quit)" Application.QuitKey
 
 
-let Cut () =
-    let textField = menu.LastFocused :?> TextField
-    if textField <> Unchecked.defaultof<_> && textField.SelectedLength <> 0
-    then textField.Cut ()
+        // Create input components and labels
+        let usernameLabel = new Label(Text = "Username:")
 
 
-let Paste () =
-    let textField = menu.LastFocused :?> TextField
-    if textField <> Unchecked.defaultof<_>
-    then textField.Paste ()
+        let userNameText = new TextField(X = Pos.Right(usernameLabel) + Pos.op_Implicit(1), Width = Dim.Fill())
 
 
-let Help () =
-    MessageBox.Query (50, 7, ustr "Help", ustr "This is a small help\nBe kind.", ustr "Ok")
-    |> ignore
+        let passwordLabel = new Label(Text = "Password:", X = Pos.Left(usernameLabel), Y = Pos.Bottom(usernameLabel) +  Pos.op_Implicit(1))
 
 
-let Load () =
-    MessageBox.Query (50, 7, ustr "Load", ustr "This is a small load\nBe kind.", ustr "Ok")
-    |> ignore
+        let passwordText = new TextField(Secret = true, X = Pos.Left(userNameText), Y = Pos.Top(passwordLabel), Width = Dim.Fill())
 
 
-let Save () =
-    MessageBox.Query (50, 7, ustr "Save ", ustr "This is a small save\nBe kind.", ustr "Ok")
-    |> ignore
+        // Create login button
+        let btnLogin = new Button(Text = "Login", Y = Pos.Bottom(passwordLabel) +  Pos.op_Implicit(1), X = Pos.Center(), IsDefault = true)
 
 
-let ListSelectionDemo (multiple: bool) =
-    let okButton = new Button (ustr "Ok", true)
-    okButton.add_Clicked (Action (Application.RequestStop))
-    let cancelButton = new Button (ustr "Cancel")
-    cancelButton.add_Clicked (Action (Application.RequestStop))
+        // When login button is clicked display a message popup
+        btnLogin.Accept.Add(fun _ ->
+            if userNameText.Text = "admin" && passwordText.Text = "password" then
+                MessageBox.Query("Logging In", "Login Successful", "Ok") |> ignore
+                ExampleWindow.UserName <- userNameText.Text.ToString()
+                Application.RequestStop()
+            else
+                MessageBox.ErrorQuery("Logging In", "Incorrect username or password", "Ok") |> ignore
+        )
 
 
-    let d = new Dialog (ustr "Selection Demo", 60, 20, okButton, cancelButton)
-    let animals = ResizeArray<_> ()
-    animals.AddRange([| "Alpaca"; "Llama"; "Lion"; "Shark"; "Goat" |])
-    let msg =
-        new Label (ustr "Use space bar or control-t to toggle selection",
-            X = Pos.At 1,
-            Y = Pos.At 1,
-            Width = Dim.Fill () - Dim.op_Implicit 1,
-            Height = Dim.op_Implicit 1)
-    let list =
-        new ListView (animals,
-            X = Pos.At 1,
-            Y = Pos.At 3,
-            Width = Dim.Fill () - Dim.op_Implicit 4,
-            Height = Dim.Fill () - Dim.op_Implicit 4,
-            AllowsMarking = true,
-            AllowsMultipleSelection = multiple)
-    d.Add (msg, list)
-    Application.Run d
-    let mutable result = ""
-    do
-        let mutable i = 0
-        while i < animals.Count do
-        if list.Source.IsMarked i
-        then result <- result + animals.[i] + " "
-        i <- i + 1
-    MessageBox.Query (60, 10, ustr "Selected Animals", ustr (if result = "" then "No animals selected" else result), ustr "Ok") |> ignore
+        // Add the views to the Window
+        this.Add(usernameLabel, userNameText, passwordLabel, passwordText, btnLogin)
 
 
-let OnKeyDownPressUpDemo () =
-    let closeButton = new Button (ustr "Close")
-    closeButton.add_Clicked (Action (Application.RequestStop))
+    static member val UserName = "" with get, set
 
 
-    let container = new Dialog (ustr "KeyDown & KeyPress & KeyUp demo", 80, 20, closeButton, Width = Dim.Fill (), Height = Dim.Fill ())
+[<EntryPoint>]
+let main argv =
+    Application.Init()
+    Application.Run<ExampleWindow>().Dispose()
     
     
-    let list = ResizeArray<_> ()
-    let listView = 
-        new ListView (list,
-            X = Pos.At 0,
-            Y = Pos.At 0,
-            Width = Dim.Fill () - Dim.op_Implicit 1,
-            Height = Dim.Fill () - Dim.op_Implicit 2,
-            ColorScheme = Colors.TopLevel)
-    container.Add (listView)
+    // Before the application exits, reset Terminal.Gui for clean shutdown
+    Application.Shutdown()
     
     
-    let keyDownPressUp (keyEvent: KeyEvent, updown: string) =
-        match updown with
-        | "Down"
-        | "Up"
-        | "Press" -> 
-            list.Add (keyEvent.ToString ())    
-        | _ -> failwithf "Unknown: %s" updown
-        listView.MoveDown ()
-
-    container.add_KeyDown(Action<View.KeyEventEventArgs> (fun (e: View.KeyEventEventArgs) -> keyDownPressUp (e.KeyEvent, "Down") |> ignore))
-    container.add_KeyPress(Action<View.KeyEventEventArgs> (fun (e: View.KeyEventEventArgs) -> keyDownPressUp (e.KeyEvent, "Press") |> ignore))
-    container.add_KeyUp(Action<View.KeyEventEventArgs> (fun (e: View.KeyEventEventArgs) -> keyDownPressUp (e.KeyEvent, "Up") |> ignore))
-    Application.Run (container)
-
-let Main () =
-    if Debugger.IsAttached then
-        CultureInfo.DefaultThreadCurrentUICulture <- CultureInfo.GetCultureInfo ("en-US")
-    Application.Init()
-    let top = Application.Top
-    let margin = 3
-    let win = 
-        new Window (ustr "Hello",
-            X = Pos.At 1,
-            Y = Pos.At 1,
-            Width = Dim.Fill () - Dim.op_Implicit margin,
-            Height = Dim.Fill () - Dim.op_Implicit margin)
-    let menuItems =
-        [|MenuItemDetails (ustr "F_ind",ustr "", Unchecked.defaultof<_>);
-            MenuItemDetails (ustr "_Replace", ustr "", Unchecked.defaultof<_>);
-            MenuItemDetails (ustr "_Item1", ustr "", Unchecked.defaultof<_>);
-            MenuItemDetails (ustr "_Also From Sub Menu", ustr "", Unchecked.defaultof<_>)|]
-    menuItems.[0].Action <- fun _ -> ShowMenuItem (menuItems.[0])
-    menuItems.[1].Action <- fun _ -> ShowMenuItem (menuItems.[1])
-    menuItems.[2].Action <- fun _ -> ShowMenuItem (menuItems.[2])
-    menuItems.[3].Action <- fun _ -> ShowMenuItem (menuItems.[3])
-    menu <-
-        new MenuBar (
-            [| MenuBarItem(ustr "_File",
-                    [| MenuItem (ustr "Text _Editor Demo", ustring.Empty, (fun () -> Editor top))
-                       MenuItem (ustr "_New", ustr "Creates new file", fun () -> NewFile())
-                       MenuItem (ustr "_Open", ustring.Empty, fun () -> Open())
-                       MenuItem (ustr "_Hex", ustring.Empty, (fun () -> ShowHex top))
-                       MenuItem (ustr "_Close", ustring.Empty, (fun () -> Close()))
-                       MenuItem (ustr "_Disabled", ustring.Empty, (fun () -> ()), (fun () -> false))
-                       Unchecked.defaultof<_>
-                       MenuItem (ustr "_Quit", ustring.Empty, (fun () -> if Quit() then top.Running <- false)) |])
-               MenuBarItem (ustr "_Edit",
-                    [| MenuItem (ustr "_Copy", ustring.Empty, fun () -> Copy())
-                       MenuItem (ustr "C_ut", ustring.Empty, fun () -> Cut())
-                       MenuItem (ustr "_Paste", ustring.Empty, fun () -> Paste())
-                       MenuBarItem (ustr "_Find and Replace",
-                           [| menuItems.[0] :> MenuItem
-                              menuItems.[1] :> MenuItem |]) :> MenuItem
-                       menuItems.[3] :> MenuItem
-                    |])
-               MenuBarItem (ustr "_List Demos", 
-                    [| MenuItem (ustr "Select _Multiple Items", ustring.Empty, (fun () -> ListSelectionDemo true))
-                       MenuItem (ustr "Select _Single Item", ustring.Empty, (fun () -> ListSelectionDemo false)) |])   
-               MenuBarItem (ustr "A_ssorted",
-                    [| MenuItem (ustr "_Show text alignments", ustring.Empty, (fun () -> ShowTextAlignments())) 
-                       MenuItem (ustr "_OnKeyDown/Press/Up", ustring.Empty, (fun () -> OnKeyDownPressUpDemo())) |])
-               MenuBarItem (ustr "_Test Menu and SubMenus",
-                    [| MenuBarItem (ustr "SubMenu1Item_1",
-                            [| MenuBarItem (ustr "SubMenu2Item_1",
-                                    [| MenuBarItem (ustr "SubMenu3Item_1",
-                                            [| menuItems.[2] :> MenuItem |]) :> MenuItem
-                                    |]) :> MenuItem
-                            |]) :> MenuItem
-                    |])
-               MenuBarItem (ustr "_About...", ustr "Demonstrates top-level menu item", (fun () -> MessageBox.ErrorQuery (50, 7, ustr "Error", ustr "This is a demo app for gui.cs", ustr "Ok") |> ignore)) |])
-    menuKeysStyle <- new CheckBox (3, 25, ustr "UseKeysUpDownAsKeysLeftRight", true)
-    menuKeysStyle.add_Toggled (Action<bool> (MenuKeysStyleToggled))
-    menuAutoMouseNav <- new CheckBox (40, 25, ustr "UseMenuAutoNavigation", true)
-    menuAutoMouseNav.add_Toggled (Action<bool> (MenuAutoMouseNavToggled))
-    ShowEntries win
-    let mutable count = 0
-    ml <- new Label (Rect (3, 17, 47, 1), ustr "Mouse: ")
-    Application.RootMouseEvent <- Action<MouseEvent> (
-            fun (me: MouseEvent) ->
-                ml.Text <- ustr (
-                     (((sprintf "Mouse: (%O,%O) - %O %O" me.X) me.Y) me.Flags) (count <- count + 1; count)))
-    let test = new Label (3, 18, ustr "Se iniciará el análisis")
-    win.Add test
-    win.Add ml
-    let drag = new Label (ustr "Drag: ", X = Pos.At 70, Y = Pos.At 24)
-    let dragText = 
-        new TextField (ustr "",
-            X = Pos.Right drag,
-            Y = Pos.Top drag,
-            Width = Dim.op_Implicit 40)
-    let statusBar = new StatusBar ([|
-        StatusItem(Key.F1, ustr "~F1~ Help", Action Help)
-        StatusItem(Key.F2, ustr "~F2~ Load", Action Load)
-        StatusItem(Key.F3, ustr "~F3~ Save", Action Save)
-        StatusItem(Key.Q, ustr "~^Q~ Quit", fun () -> if (Quit()) then top.Running <- false) |])
-    win.Add (drag, dragText)
-    let bottom = new Label (ustr "This should go on the bottom of the same top-level!")
-    win.Add bottom
-    let bottom2 = new Label (ustr "This should go on the bottom of another top-level!")
-    top.Add bottom2
-    top.add_LayoutComplete (Action<View.LayoutEventArgs>
-        (fun e ->
-            bottom.X <- win.X
-            bottom.Y <- Pos.Bottom win - Pos.Top win - Pos.At margin
-            bottom2.X <- Pos.Left win
-            bottom2.Y <- Pos.Bottom win)
-        )
-    top.Add win
-    top.Add (menu, statusBar)
-    Application.Run ()
-    Application.Shutdown ();
-
-module Demo =
-    [<EntryPoint>]
-    let main _ =
-        Main ()
-        0
+    // To see this output on the screen it must be done after shutdown,
+    // which restores the previous screen.
+    printfn "Username: %s" ExampleWindow.UserName
+    
+    0 // return an integer exit code

+ 122 - 17
README.md

@@ -1,17 +1,16 @@
 ![Terminal.Gui](https://socialify.git.ci/gui-cs/Terminal.Gui/image?description=1&font=Rokkitt&forks=1&language=1&logo=https%3A%2F%2Fraw.githubusercontent.com%2Fgui-cs%2FTerminal.Gui%2Fdevelop%2Fdocfx%2Fimages%2Flogo.png&name=1&owner=1&pattern=Circuit%20Board&stargazers=1&theme=Auto)
 ![Terminal.Gui](https://socialify.git.ci/gui-cs/Terminal.Gui/image?description=1&font=Rokkitt&forks=1&language=1&logo=https%3A%2F%2Fraw.githubusercontent.com%2Fgui-cs%2FTerminal.Gui%2Fdevelop%2Fdocfx%2Fimages%2Flogo.png&name=1&owner=1&pattern=Circuit%20Board&stargazers=1&theme=Auto)
 ![.NET Core](https://github.com/gui-cs/Terminal.Gui/workflows/.NET%20Core/badge.svg?branch=develop)
 ![.NET Core](https://github.com/gui-cs/Terminal.Gui/workflows/.NET%20Core/badge.svg?branch=develop)
-![Code scanning - action](https://github.com/gui-cs/Terminal.Gui/workflows/Code%20scanning%20-%20action/badge.svg)
 [![Version](https://img.shields.io/nuget/v/Terminal.Gui.svg)](https://www.nuget.org/packages/Terminal.Gui)
 [![Version](https://img.shields.io/nuget/v/Terminal.Gui.svg)](https://www.nuget.org/packages/Terminal.Gui)
 ![Code Coverage](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/migueldeicaza/90ef67a684cb71db1817921a970f8d27/raw/code-coverage.json)
 ![Code Coverage](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/migueldeicaza/90ef67a684cb71db1817921a970f8d27/raw/code-coverage.json)
 [![Downloads](https://img.shields.io/nuget/dt/Terminal.Gui)](https://www.nuget.org/packages/Terminal.Gui)
 [![Downloads](https://img.shields.io/nuget/dt/Terminal.Gui)](https://www.nuget.org/packages/Terminal.Gui)
 [![License](https://img.shields.io/github/license/gui-cs/gui.cs.svg)](LICENSE)
 [![License](https://img.shields.io/github/license/gui-cs/gui.cs.svg)](LICENSE)
 ![Bugs](https://img.shields.io/github/issues/gui-cs/gui.cs/bug)
 ![Bugs](https://img.shields.io/github/issues/gui-cs/gui.cs/bug)
 
 
-***The current, stable, release of Terminal.Gui is [v1.x](https://www.nuget.org/packages/Terminal.Gui). It is stable, rich, and broadly used. The team is now focused on designing and building a significant upgrade we're referring to as `v2`. Therefore:***
- * *`v1` is now in maintenance mode, meaning we will accept PRs for v1.x (the `develop` branch) only for issues impacting existing functionality.*
- * *All new development happens on the `v2_develop` branch. See the V2 discussion [here](https://github.com/gui-cs/Terminal.GuiV2Docs/discussions/1940).*
- * *Developers are encouraged to continue building on [v1.x](https://www.nuget.org/packages/Terminal.Gui) until we announce `v2` is stable.*
-
+* The current, stable, release of Terminal.Gui v1 is [![Version](https://img.shields.io/nuget/v/Terminal.Gui.svg)](https://www.nuget.org/packages/Terminal.Gui).
+* The current `prealpha` release of Terminal.Gui v2 can be found on [Nuget](https://www.nuget.org/packages/Terminal.Gui).
+* Developers starting new TUI projects are encouraged to target `v2`. The API is signifcantly changed, and significantly improved. There will be breaking changes in the API before Beta, but the core API is stable.
+* `v1` is in maintenance mode and we will only accept PRs for issues impacting existing functionality.
+ 
 **Terminal.Gui**: A toolkit for building rich console apps for .NET, .NET Core, and Mono that works on Windows, the Mac, and Linux/Unix.
 **Terminal.Gui**: A toolkit for building rich console apps for .NET, .NET Core, and Mono that works on Windows, the Mac, and Linux/Unix.
 
 
 ![Sample app](docfx/images/sample.gif)
 ![Sample app](docfx/images/sample.gif)
@@ -36,23 +35,129 @@ dotnet run
 * [API Documentation](https://gui-cs.github.io/Terminal.GuiV2Docs/api/Terminal.Gui.html)
 * [API Documentation](https://gui-cs.github.io/Terminal.GuiV2Docs/api/Terminal.Gui.html)
 * [Documentation Home](https://gui-cs.github.io/Terminal.GuiV2Docs)
 * [Documentation Home](https://gui-cs.github.io/Terminal.GuiV2Docs)
 
 
+_The Documentation matches the most recent Nuget release from the `v2_develop` branch. The documentation for v1 is here: ([![Version](https://img.shields.io/nuget/v/Terminal.Gui.svg)](https://www.nuget.org/packages/Terminal.Gui))_
+
+See the [`Terminal.Gui/` README](https://github.com/gui-cs/Terminal.Gui/tree/master/Terminal.Gui) for an overview of how the library is structured. 
+
 ## Showcase & Examples
 ## Showcase & Examples
 
 
-* **[UI Catalog](https://github.com/gui-cs/Terminal.GuiV2Docs/tree/master/UICatalog)** - The UI Catalog project provides an easy to use and extend sample illustrating the capabilities of **Terminal.Gui**. Run `dotnet run --project UICatalog` to run the UI Catalog.
-* **[C# Example](https://github.com/gui-cs/Terminal.GuiV2Docs/tree/master/Example)** - Run `dotnet run` in the `Example` directory to run the C# Example.
-* **[F# Example](https://github.com/gui-cs/Terminal.GuiV2Docs/tree/master/FSharpExample)** - An example showing how to build a Terminal.Gui app using F#.
-* **[Reactive Example](https://github.com/gui-cs/Terminal.GuiV2Docs/tree/master/ReactiveExample)** - A sample app that shows how to use `System.Reactive` and `ReactiveUI` with `Terminal.Gui`. The app uses the MVVM architecture that may seem familiar to folks coming from WPF, Xamarin Forms, UWP, Avalonia, or Windows Forms. In this app, we implement the data bindings using ReactiveUI `WhenAnyValue` syntax and [Pharmacist](https://github.com/reactiveui/pharmacist) — a tool that converts all events in a NuGet package into observable wrappers.
-* **[PowerShell's `Out-ConsoleGridView`](https://github.com/PowerShell/GraphicalTools)** - `OCGV` sends the output from a command to an interactive table. 
-* **[F7History](https://github.com/gui-cs/F7History)** - Graphical Command History for PowerShell (built on PowerShell's `Out-ConsoleGridView`).
-* **[PoshRedisViewer](https://github.com/En3Tho/PoshRedisViewer)** - A compact Redis viewer module for PowerShell written in F#.
-* **[PoshDotnetDumpAnalyzeViewer](https://github.com/En3Tho/PoshDotnetDumpAnalyzeViewer)** - dotnet-dump UI module for PowerShell.
-* **[TerminalGuiDesigner](https://github.com/tznind/TerminalGuiDesigner)** - Cross platform view designer for building Terminal.Gui applications.
+**Terminal.Gui** can be used with any .Net language to create feature rich and robust applications.  
+[Showcase](https://github.com/gui-cs/Terminal.Gui/blob/develop/Showcase.md) is a place where you can find all kind of projects from simple examples to advanced real world apps that fully utilize capabilities of the toolkit.  
+The team is looking forward to seeing new amazing projects made by the community to be added there!
+
+## Sample Usage in C#
+
+The following example shows a basic Terminal.Gui application in C#:
+
+```csharp
+// This is a simple example application.  For the full range of functionality
+// see the UICatalog project
+
+// A simple Terminal.Gui example in C# - using C# 9.0 Top-level statements
+
+using System;
+using Terminal.Gui;
+
+Application.Run<ExampleWindow> ().Dispose ();
+
+// Before the application exits, reset Terminal.Gui for clean shutdown
+Application.Shutdown ();
+
+// To see this output on the screen it must be done after shutdown,
+// which restores the previous screen.
+Console.WriteLine ($@"Username: {ExampleWindow.UserName}");
+
+// Defines a top-level window with border and title
+public class ExampleWindow : Window
+{
+    public static string UserName;
+
+    public ExampleWindow ()
+    {
+        Title = $"Example App ({Application.QuitKey} to quit)";
+
+        // Create input components and labels
+        var usernameLabel = new Label { Text = "Username:" };
+
+        var userNameText = new TextField
+        {
+            // Position text field adjacent to the label
+            X = Pos.Right (usernameLabel) + 1,
+
+            // Fill remaining horizontal space
+            Width = Dim.Fill ()
+        };
+
+        var passwordLabel = new Label
+        {
+            Text = "Password:", X = Pos.Left (usernameLabel), Y = Pos.Bottom (usernameLabel) + 1
+        };
+
+        var passwordText = new TextField
+        {
+            Secret = true,
+
+            // align with the text box above
+            X = Pos.Left (userNameText),
+            Y = Pos.Top (passwordLabel),
+            Width = Dim.Fill ()
+        };
+
+        // Create login button
+        var btnLogin = new Button
+        {
+            Text = "Login",
+            Y = Pos.Bottom (passwordLabel) + 1,
+
+            // center the login button horizontally
+            X = Pos.Center (),
+            IsDefault = true
+        };
+
+        // When login button is clicked display a message popup
+        btnLogin.Accept += (s, e) =>
+                           {
+                               if (userNameText.Text == "admin" && passwordText.Text == "password")
+                               {
+                                   MessageBox.Query ("Logging In", "Login Successful", "Ok");
+                                   UserName = userNameText.Text;
+                                   Application.RequestStop ();
+                               }
+                               else
+                               {
+                                   MessageBox.ErrorQuery ("Logging In", "Incorrect username or password", "Ok");
+                               }
+                           };
+
+        // Add the views to the Window
+        Add (usernameLabel, userNameText, passwordLabel, passwordText, btnLogin);
+    }
+}
+```
+
+When run the application looks as follows:
+
+![Simple Usage app](./docfx/images/Example.png)
+
+## Installing
+
+Use NuGet to install the `Terminal.Gui` NuGet package: https://www.nuget.org/packages/Terminal.Gui
+
+### Installation in .NET Core Projects
+
+To install Terminal.Gui into a .NET Core project, use the `dotnet` CLI tool with this command.
+
+```
+dotnet add package Terminal.Gui
+```
+
+Or, you can use the [Terminal.Gui.Templates](https://github.com/gui-cs/Terminal.Gui.templates).
 
 
 ## Contributing
 ## Contributing
 
 
-See [CONTRIBUTING.md](https://github.com/gui-cs/Terminal.GuiV2Docs/blob/master/CONTRIBUTING.md).
+See [CONTRIBUTING.md](./CONTRIBUTING.md).
 
 
-Debates on architecture and design can be found in Issues tagged with [design](https://github.com/gui-cs/Terminal.GuiV2Docs/issues?q=is%3Aopen+is%3Aissue+label%3Adesign).
+Debates on architecture and design can be found in Issues tagged with [design](https://github.com/gui-cs/Terminal.Gui/issues?q=is%3Aopen+is%3Aissue+label%3Av2+label%3Adesign).
 
 
 ## History
 ## History
 
 

+ 2 - 2
Release.ps1

@@ -5,8 +5,8 @@ param(
     [int]$Version
     [int]$Version
 )
 )
 
 
-$branch = "v2_develop"
-$tag = "v2.0.0-alpha.$Version"
+$branch = "v2_release"
+$tag = "$Version-prealpha"
 $releaseMessage = "Release $tag"
 $releaseMessage = "Release $tag"
 
 
 try {
 try {

+ 89 - 0
SelfContained/Program.cs

@@ -0,0 +1,89 @@
+// This is a simple example application for a self-contained single file.
+
+using System.Diagnostics.CodeAnalysis;
+using Terminal.Gui;
+
+namespace SelfContained;
+
+public static class Program
+{
+    [RequiresUnreferencedCode ("Calls Terminal.Gui.Application.Run<T>(Func<Exception, Boolean>, ConsoleDriver)")]
+    private static void Main (string [] args)
+    {
+        Application.Run<ExampleWindow> ().Dispose ();
+
+        // Before the application exits, reset Terminal.Gui for clean shutdown
+        Application.Shutdown ();
+
+        // To see this output on the screen it must be done after shutdown,
+        // which restores the previous screen.
+        Console.WriteLine ($@"Username: {ExampleWindow.UserName}");
+    }
+}
+
+// Defines a top-level window with border and title
+public class ExampleWindow : Window
+{
+    public static string? UserName;
+
+    public ExampleWindow ()
+    {
+        Title = $"Example App ({Application.QuitKey} to quit)";
+
+        // Create input components and labels
+        var usernameLabel = new Label { Text = "Username:" };
+
+        var userNameText = new TextField
+        {
+            // Position text field adjacent to the label
+            X = Pos.Right (usernameLabel) + 1,
+
+            // Fill remaining horizontal space
+            Width = Dim.Fill ()
+        };
+
+        var passwordLabel = new Label
+        {
+            Text = "Password:", X = Pos.Left (usernameLabel), Y = Pos.Bottom (usernameLabel) + 1
+        };
+
+        var passwordText = new TextField
+        {
+            Secret = true,
+
+            // align with the text box above
+            X = Pos.Left (userNameText),
+            Y = Pos.Top (passwordLabel),
+            Width = Dim.Fill ()
+        };
+
+        // Create login button
+        var btnLogin = new Button
+        {
+            Text = "Login",
+            Y = Pos.Bottom (passwordLabel) + 1,
+
+            // center the login button horizontally
+            X = Pos.Center (),
+            IsDefault = true
+        };
+
+        // When login button is clicked display a message popup
+        btnLogin.Accept += (s, e) =>
+                           {
+                               if (userNameText.Text == "admin" && passwordText.Text == "password")
+                               {
+                                   MessageBox.Query ("Logging In", "Login Successful", "Ok");
+                                   UserName = userNameText.Text;
+                                   Application.RequestStop ();
+                               }
+                               else
+                               {
+                                   MessageBox.ErrorQuery ("Logging In", "Incorrect username or password", "Ok");
+                               }
+                           };
+
+        // Add the views to the Window
+        Add (usernameLabel, userNameText, passwordLabel, passwordText, btnLogin);
+    }
+}

+ 16 - 0
SelfContained/Properties/PublishProfiles/FolderProfile_net8.0_linux-x64_Debug.pubxml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+https://go.microsoft.com/fwlink/?LinkID=208121.
+-->
+<Project>
+  <PropertyGroup>
+    <Configuration>Debug</Configuration>
+    <Platform>Any CPU</Platform>
+    <PublishDir>bin\Debug\net8.0\publish\linux-x64\</PublishDir>
+    <PublishProtocol>FileSystem</PublishProtocol>
+    <_TargetId>Folder</_TargetId>
+    <TargetFramework>net8.0</TargetFramework>
+    <RuntimeIdentifier>linux-x64</RuntimeIdentifier>
+    <SelfContained>true</SelfContained>
+  </PropertyGroup>
+</Project>

+ 16 - 0
SelfContained/Properties/PublishProfiles/FolderProfile_net8.0_linux-x64_Release.pubxml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+https://go.microsoft.com/fwlink/?LinkID=208121.
+-->
+<Project>
+  <PropertyGroup>
+    <Configuration>Release</Configuration>
+    <Platform>Any CPU</Platform>
+    <PublishDir>bin\Release\net8.0\publish\linux-x64\</PublishDir>
+    <PublishProtocol>FileSystem</PublishProtocol>
+    <_TargetId>Folder</_TargetId>
+    <TargetFramework>net8.0</TargetFramework>
+    <RuntimeIdentifier>linux-x64</RuntimeIdentifier>
+    <SelfContained>true</SelfContained>
+  </PropertyGroup>
+</Project>

+ 16 - 0
SelfContained/Properties/PublishProfiles/FolderProfile_net8.0_osx-x64_Debug.pubxml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+https://go.microsoft.com/fwlink/?LinkID=208121.
+-->
+<Project>
+  <PropertyGroup>
+    <Configuration>Debug</Configuration>
+    <Platform>Any CPU</Platform>
+    <PublishDir>bin\Debug\net8.0\publish\osx-x64\</PublishDir>
+    <PublishProtocol>FileSystem</PublishProtocol>
+    <_TargetId>Folder</_TargetId>
+    <TargetFramework>net8.0</TargetFramework>
+    <RuntimeIdentifier>osx-x64</RuntimeIdentifier>
+    <SelfContained>true</SelfContained>
+  </PropertyGroup>
+</Project>

+ 16 - 0
SelfContained/Properties/PublishProfiles/FolderProfile_net8.0_osx-x64_Release.pubxml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+https://go.microsoft.com/fwlink/?LinkID=208121.
+-->
+<Project>
+  <PropertyGroup>
+    <Configuration>Release</Configuration>
+    <Platform>Any CPU</Platform>
+    <PublishDir>bin\Release\net8.0\publish\osx-x64\</PublishDir>
+    <PublishProtocol>FileSystem</PublishProtocol>
+    <_TargetId>Folder</_TargetId>
+    <TargetFramework>net8.0</TargetFramework>
+    <RuntimeIdentifier>osx-x64</RuntimeIdentifier>
+    <SelfContained>true</SelfContained>
+  </PropertyGroup>
+</Project>

+ 17 - 0
SelfContained/Properties/PublishProfiles/FolderProfile_net8.0_win-x64_Debug.pubxml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+https://go.microsoft.com/fwlink/?LinkID=208121.
+-->
+<Project>
+  <PropertyGroup>
+    <Configuration>Debug</Configuration>
+    <Platform>Any CPU</Platform>
+    <PublishDir>bin\Debug\net8.0\publish\win-x64\</PublishDir>
+    <PublishProtocol>FileSystem</PublishProtocol>
+    <_TargetId>Folder</_TargetId>
+    <TargetFramework>net8.0</TargetFramework>
+    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
+    <SelfContained>true</SelfContained>
+    <PublishReadyToRun>false</PublishReadyToRun>
+  </PropertyGroup>
+</Project>

+ 17 - 0
SelfContained/Properties/PublishProfiles/FolderProfile_net8.0_win-x64_Release.pubxml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+https://go.microsoft.com/fwlink/?LinkID=208121.
+-->
+<Project>
+  <PropertyGroup>
+    <Configuration>Release</Configuration>
+    <Platform>Any CPU</Platform>
+    <PublishDir>bin\Release\net8.0\publish\win-x64\</PublishDir>
+    <PublishProtocol>FileSystem</PublishProtocol>
+    <_TargetId>Folder</_TargetId>
+    <TargetFramework>net8.0</TargetFramework>
+    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
+    <SelfContained>true</SelfContained>
+    <PublishReadyToRun>false</PublishReadyToRun>
+  </PropertyGroup>
+</Project>

+ 9 - 0
SelfContained/README.md

@@ -0,0 +1,9 @@
+# Terminal.Gui C# SelfContained
+
+This example shows how to use the `Terminal.Gui` library to create a simple `self-contained` `single file` GUI application in C#.
+
+With `Debug` the `.csproj` is used and with `Release` the latest `nuget package` is used, either in `Solution Configurations` or in `Profile Publish`.
+
+To publish the self-contained single file in `Debug` or `Release` mode, it is not necessary to select it in the `Solution Configurations`, just choose the `Debug` or `Release` configuration in the `Publish Profile`.
+
+When executing the file directly from the self-contained single file and needing to debug it, it will be necessary to attach it to the debugger, just like any other standalone application. However, when trying to attach the file running on `Linux` or `macOS` to the debugger, it will issue the error "`Failed to attach to process: Unknown Error: 0x80131c3c`". This issue has already been reported on [Developer Community](https://developercommunity.visualstudio.com/t/Failed-to-attach-to-process:-Unknown-Err/10694351). Maybe it would be a good idea to vote in favor of this fix because I think `Visual Studio for macOS` is going to be discontinued and we need this fix to remotely attach a process running on `Linux` or `macOS` to `Windows 11`.

+ 25 - 0
SelfContained/SelfContained.csproj

@@ -0,0 +1,25 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net8.0</TargetFramework>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <Nullable>enable</Nullable>
+    <PublishTrimmed>true</PublishTrimmed>
+    <TrimMode>Link</TrimMode>
+    <PublishSingleFile>true</PublishSingleFile>
+    <InvariantGlobalization>true</InvariantGlobalization>
+    <DebugType>embedded</DebugType>
+  </PropertyGroup>
+
+  <ItemGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
+    <ProjectReference Include="..\Terminal.Gui\Terminal.Gui.csproj" />
+    <TrimmerRootAssembly Include="Terminal.Gui" />
+  </ItemGroup>
+
+  <ItemGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
+    <PackageReference Include="Terminal.Gui" Version="[2.0.0-pre.1788,3)" />
+    <TrimmerRootAssembly Include="Terminal.Gui" />
+  </ItemGroup>
+
+</Project>

+ 31 - 0
Showcase.md

@@ -0,0 +1,31 @@
+# Showcase #
+
+* **[UI Catalog](https://github.com/gui-cs/Terminal.Gui/tree/master/UICatalog)** - The UI Catalog project provides an easy to use and extend sample illustrating the capabilities of **Terminal.Gui**. Run `dotnet run --project UICatalog` to run the UI Catalog.
+  ![Sample app](docfx/images/sample.gif)  
+  ⠀
+* **[PowerShell's `Out-ConsoleGridView`](https://github.com/PowerShell/GraphicalTools)** - `OCGV` sends the output from a command to an interactive table.
+  ![OutConsoleGridView.png](docfx/images/OutConsoleGridView.png)  
+  ⠀
+* **[F7History](https://github.com/gui-cs/F7History)** - Graphical Command History for PowerShell (built on PowerShell's `Out-ConsoleGridView`).
+  ![F7History.gif](docfx/images/F7History.gif)  
+  ⠀
+* **[PoshRedisViewer](https://github.com/En3Tho/PoshRedisViewer)** - A compact Redis viewer module for PowerShell written in F#.
+  ![PoshRedisViewer.png](docfx/images/PoshRedisViewer.png)  
+  ⠀
+* **[PoshDotnetDumpAnalyzeViewer](https://github.com/En3Tho/PoshDotnetDumpAnalyzeViewer)** - dotnet-dump UI module for PowerShell.
+  ![PoshDotnetDumpAnalyzerViewer.png](docfx/images/PoshDotnetDumpAnalyzerViewer.png)  
+  ⠀
+* **[TerminalGuiDesigner](https://github.com/tznind/TerminalGuiDesigner)** - Cross platform view designer for building Terminal.Gui applications.
+  ![TerminalGuiDesigner.gif](docfx/images/TerminalGuiDesigner.gif)
+
+* **[Capital and Cargo](https://github.com/dhorions/Capital-and-Cargo)** - A retro console game where you buy, sell, produce and transport goods built with Terminal.Gui
+ ![image](https://github.com/gui-cs/Terminal.Gui/assets/1682004/ed89f3d6-020f-4a8a-ae18-e057514f4c43)
+
+  
+# Examples #
+
+* **[C# Example](https://github.com/gui-cs/Terminal.Gui/tree/master/Example)** - Run `dotnet run` in the `Example` directory to run the C# Example.
+
+* **[F# Example](https://github.com/gui-cs/Terminal.Gui/tree/master/FSharpExample)** - An example showing how to build a Terminal.Gui app using F#.
+
+* **[Reactive Example](https://github.com/gui-cs/Terminal.Gui/tree/master/ReactiveExample)** - A sample app that shows how to use `System.Reactive` and `ReactiveUI` with `Terminal.Gui`. The app uses the MVVM architecture that may seem familiar to folks coming from WPF, Xamarin Forms, UWP, Avalonia, or Windows Forms. In this app, we implement the data bindings using ReactiveUI `WhenAnyValue` syntax and [Pharmacist](https://github.com/reactiveui/pharmacist) — a tool that converts all events in a NuGet package into observable wrappers. 

+ 11 - 1
Terminal.Gui/Application/Application.cs

@@ -1,4 +1,5 @@
 using System.Diagnostics;
 using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
 using System.Globalization;
 using System.Globalization;
 using System.Reflection;
 using System.Reflection;
 
 
@@ -56,7 +57,7 @@ public static partial class Application
         string assemblyLocation = AppDomain.CurrentDomain.BaseDirectory;
         string assemblyLocation = AppDomain.CurrentDomain.BaseDirectory;
 
 
         // Find the resource file name of the assembly
         // Find the resource file name of the assembly
-        var resourceFilename = $"{Path.GetFileNameWithoutExtension (assembly.Location)}.resources.dll";
+        var resourceFilename = $"{Path.GetFileNameWithoutExtension (AppContext.BaseDirectory)}.resources.dll";
 
 
         // Return all culture for which satellite folder found with culture code.
         // Return all culture for which satellite folder found with culture code.
         return culture.Where (
         return culture.Where (
@@ -192,6 +193,8 @@ public static partial class Application
     ///     <see cref="ConsoleDriver"/> to use. If neither <paramref name="driver"/> or <paramref name="driverName"/> are
     ///     <see cref="ConsoleDriver"/> to use. If neither <paramref name="driver"/> or <paramref name="driverName"/> are
     ///     specified the default driver for the platform will be used.
     ///     specified the default driver for the platform will be used.
     /// </param>
     /// </param>
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
     public static void Init (ConsoleDriver driver = null, string driverName = null) { InternalInit (driver, driverName); }
     public static void Init (ConsoleDriver driver = null, string driverName = null) { InternalInit (driver, driverName); }
 
 
     internal static bool _initialized;
     internal static bool _initialized;
@@ -206,6 +209,8 @@ public static partial class Application
     // Unit Tests - To initialize the app with a custom Toplevel, using the FakeDriver. calledViaRunT will be false, causing all state to be reset.
     // Unit Tests - To initialize the app with a custom Toplevel, using the FakeDriver. calledViaRunT will be false, causing all state to be reset.
     // 
     // 
     // calledViaRunT: If false (default) all state will be reset. If true the state will not be reset.
     // calledViaRunT: If false (default) all state will be reset. If true the state will not be reset.
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
     internal static void InternalInit (
     internal static void InternalInit (
         ConsoleDriver driver = null,
         ConsoleDriver driver = null,
         string driverName = null,
         string driverName = null,
@@ -318,6 +323,7 @@ public static partial class Application
 
 
     /// <summary>Gets of list of <see cref="ConsoleDriver"/> types that are available.</summary>
     /// <summary>Gets of list of <see cref="ConsoleDriver"/> types that are available.</summary>
     /// <returns></returns>
     /// <returns></returns>
+    [RequiresUnreferencedCode ("AOT")]
     public static List<Type> GetDriverTypes ()
     public static List<Type> GetDriverTypes ()
     {
     {
         // use reflection to get the list of drivers
         // use reflection to get the list of drivers
@@ -660,6 +666,8 @@ public static partial class Application
     ///     </para>
     ///     </para>
     /// </remarks>
     /// </remarks>
     /// <returns>The created <see cref="Toplevel"/> object. The caller is responsible for disposing this object.</returns>
     /// <returns>The created <see cref="Toplevel"/> object. The caller is responsible for disposing this object.</returns>
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
     public static Toplevel Run (Func<Exception, bool> errorHandler = null, ConsoleDriver driver = null) { return Run<Toplevel> (errorHandler, driver); }
     public static Toplevel Run (Func<Exception, bool> errorHandler = null, ConsoleDriver driver = null) { return Run<Toplevel> (errorHandler, driver); }
 
 
     /// <summary>
     /// <summary>
@@ -683,6 +691,8 @@ public static partial class Application
     ///     <see langword="null"/> if <see cref="Init"/> has already been called.
     ///     <see langword="null"/> if <see cref="Init"/> has already been called.
     /// </param>
     /// </param>
     /// <returns>The created T object. The caller is responsible for disposing this object.</returns>
     /// <returns>The created T object. The caller is responsible for disposing this object.</returns>
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
     public static T Run<T> (Func<Exception, bool> errorHandler = null, ConsoleDriver driver = null)
     public static T Run<T> (Func<Exception, bool> errorHandler = null, ConsoleDriver driver = null)
         where T : Toplevel, new()
         where T : Toplevel, new()
     {
     {

+ 3 - 3
Terminal.Gui/Configuration/AttributeJsonConverter.cs

@@ -3,7 +3,7 @@ using System.Text.Json.Serialization;
 
 
 namespace Terminal.Gui;
 namespace Terminal.Gui;
 
 
-/// <summary>Json converter fro the <see cref="Attribute"/> class.</summary>
+/// <summary>Json converter from the <see cref="Attribute"/> class.</summary>
 internal class AttributeJsonConverter : JsonConverter<Attribute>
 internal class AttributeJsonConverter : JsonConverter<Attribute>
 {
 {
     private static AttributeJsonConverter _instance;
     private static AttributeJsonConverter _instance;
@@ -57,11 +57,11 @@ internal class AttributeJsonConverter : JsonConverter<Attribute>
             switch (propertyName?.ToLower ())
             switch (propertyName?.ToLower ())
             {
             {
                 case "foreground":
                 case "foreground":
-                    foreground = JsonSerializer.Deserialize<Color> (color, options);
+                    foreground = JsonSerializer.Deserialize (color, _serializerContext.Color);
 
 
                     break;
                     break;
                 case "background":
                 case "background":
-                    background = JsonSerializer.Deserialize<Color> (color, options);
+                    background = JsonSerializer.Deserialize (color, _serializerContext.Color);
 
 
                     break;
                     break;
 
 

+ 1 - 1
Terminal.Gui/Configuration/ColorSchemeJsonConverter.cs

@@ -59,7 +59,7 @@ internal class ColorSchemeJsonConverter : JsonConverter<ColorScheme>
 
 
             string propertyName = reader.GetString ();
             string propertyName = reader.GetString ();
             reader.Read ();
             reader.Read ();
-            var attribute = JsonSerializer.Deserialize<Attribute> (ref reader, options);
+            var attribute = JsonSerializer.Deserialize (ref reader, _serializerContext.Attribute);
 
 
             switch (propertyName.ToLower ())
             switch (propertyName.ToLower ())
             {
             {

+ 22 - 4
Terminal.Gui/Configuration/ConfigurationManager.cs

@@ -106,9 +106,12 @@ public static class ConfigurationManager
         },
         },
 
 
         // Enables Key to be "Ctrl+Q" vs "Ctrl\u002BQ"
         // Enables Key to be "Ctrl+Q" vs "Ctrl\u002BQ"
-        Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
+        Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
+        TypeInfoResolver = SourceGenerationContext.Default
     };
     };
 
 
+    internal static readonly SourceGenerationContext _serializerContext = new (_serializerOptions);
+
     [SuppressMessage ("Style", "IDE1006:Naming Styles", Justification = "<Pending>")]
     [SuppressMessage ("Style", "IDE1006:Naming Styles", Justification = "<Pending>")]
     internal static StringBuilder _jsonErrors = new ();
     internal static StringBuilder _jsonErrors = new ();
 
 
@@ -150,6 +153,8 @@ public static class ConfigurationManager
     /// </summary>
     /// </summary>
     public static SettingsScope? Settings
     public static SettingsScope? Settings
     {
     {
+        [RequiresUnreferencedCode ("AOT")]
+        [RequiresDynamicCode ("AOT")]
         get
         get
         {
         {
             if (_settings is null)
             if (_settings is null)
@@ -181,6 +186,8 @@ public static class ConfigurationManager
     public static event EventHandler<ConfigurationManagerEventArgs>? Applied;
     public static event EventHandler<ConfigurationManagerEventArgs>? Applied;
 
 
     /// <summary>Applies the configuration settings to the running <see cref="Application"/> instance.</summary>
     /// <summary>Applies the configuration settings to the running <see cref="Application"/> instance.</summary>
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
     public static void Apply ()
     public static void Apply ()
     {
     {
         var settings = false;
         var settings = false;
@@ -222,7 +229,7 @@ public static class ConfigurationManager
         var emptyScope = new SettingsScope ();
         var emptyScope = new SettingsScope ();
         emptyScope.Clear ();
         emptyScope.Clear ();
 
 
-        return JsonSerializer.Serialize (emptyScope, _serializerOptions);
+        return JsonSerializer.Serialize (emptyScope, typeof (SettingsScope), _serializerContext);
     }
     }
 
 
     /// <summary>
     /// <summary>
@@ -235,6 +242,8 @@ public static class ConfigurationManager
     ///     If <see langword="true"/> the state of <see cref="ConfigurationManager"/> will be reset to the
     ///     If <see langword="true"/> the state of <see cref="ConfigurationManager"/> will be reset to the
     ///     defaults.
     ///     defaults.
     /// </param>
     /// </param>
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
     public static void Load (bool reset = false)
     public static void Load (bool reset = false)
     {
     {
         Debug.WriteLine ("ConfigurationManager.Load()");
         Debug.WriteLine ("ConfigurationManager.Load()");
@@ -322,6 +331,8 @@ public static class ConfigurationManager
     ///     <see langword="true"/>.
     ///     <see langword="true"/>.
     /// </summary>
     /// </summary>
     /// <remarks></remarks>
     /// <remarks></remarks>
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
     public static void Reset ()
     public static void Reset ()
     {
     {
         Debug.WriteLine (@"ConfigurationManager.Reset()");
         Debug.WriteLine (@"ConfigurationManager.Reset()");
@@ -475,6 +486,8 @@ public static class ConfigurationManager
     ///         make sure you copy the Theme definitions from the existing <c>Terminal.Gui.Resources.config.json</c> file.
     ///         make sure you copy the Theme definitions from the existing <c>Terminal.Gui.Resources.config.json</c> file.
     ///     </para>
     ///     </para>
     /// </remarks>
     /// </remarks>
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
     internal static void GetHardCodedDefaults ()
     internal static void GetHardCodedDefaults ()
     {
     {
         if (_allConfigProperties is null)
         if (_allConfigProperties is null)
@@ -496,6 +509,7 @@ public static class ConfigurationManager
     ///     Initializes the internal state of ConfigurationManager. Nominally called once as part of application startup
     ///     Initializes the internal state of ConfigurationManager. Nominally called once as part of application startup
     ///     to initialize global state. Also called from some Unit Tests to ensure correctness (e.g. Reset()).
     ///     to initialize global state. Also called from some Unit Tests to ensure correctness (e.g. Reset()).
     /// </summary>
     /// </summary>
+    [RequiresUnreferencedCode ("AOT")]
     internal static void Initialize ()
     internal static void Initialize ()
     {
     {
         _allConfigProperties = new ();
         _allConfigProperties = new ();
@@ -585,16 +599,20 @@ public static class ConfigurationManager
 
 
     /// <summary>Creates a JSON document with the configuration specified.</summary>
     /// <summary>Creates a JSON document with the configuration specified.</summary>
     /// <returns></returns>
     /// <returns></returns>
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
     internal static string ToJson ()
     internal static string ToJson ()
     {
     {
         //Debug.WriteLine ("ConfigurationManager.ToJson()");
         //Debug.WriteLine ("ConfigurationManager.ToJson()");
 
 
-        return JsonSerializer.Serialize (Settings!, _serializerOptions);
+        return JsonSerializer.Serialize (Settings!, typeof (SettingsScope), _serializerContext);
     }
     }
 
 
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
     internal static Stream ToStream ()
     internal static Stream ToStream ()
     {
     {
-        string json = JsonSerializer.Serialize (Settings!, _serializerOptions);
+        string json = JsonSerializer.Serialize (Settings!, typeof (SettingsScope), _serializerContext);
 
 
         // turn it into a stream
         // turn it into a stream
         var stream = new MemoryStream ();
         var stream = new MemoryStream ();

+ 3 - 3
Terminal.Gui/Configuration/DictionaryJsonConverter.cs

@@ -28,8 +28,8 @@ internal class DictionaryJsonConverter<T> : JsonConverter<Dictionary<string, T>>
                 {
                 {
                     string key = reader.GetString ();
                     string key = reader.GetString ();
                     reader.Read ();
                     reader.Read ();
-                    var value = JsonSerializer.Deserialize<T> (ref reader, options);
-                    dictionary.Add (key, value);
+                    var value = JsonSerializer.Deserialize (ref reader, typeof (T), _serializerContext);
+                    dictionary.Add (key, (T)value);
                 }
                 }
             }
             }
             else if (reader.TokenType == JsonTokenType.EndArray)
             else if (reader.TokenType == JsonTokenType.EndArray)
@@ -51,7 +51,7 @@ internal class DictionaryJsonConverter<T> : JsonConverter<Dictionary<string, T>>
 
 
             //writer.WriteString (item.Key, item.Key);
             //writer.WriteString (item.Key, item.Key);
             writer.WritePropertyName (item.Key);
             writer.WritePropertyName (item.Key);
-            JsonSerializer.Serialize (writer, item.Value, options);
+            JsonSerializer.Serialize (writer, item.Value, typeof (T), _serializerContext);
             writer.WriteEndObject ();
             writer.WriteEndObject ();
         }
         }
 
 

+ 1 - 1
Terminal.Gui/Configuration/KeyCodeJsonConverter.cs

@@ -42,7 +42,7 @@ internal class KeyCodeJsonConverter : JsonConverter<KeyCode>
                                 }
                                 }
 
 
                                 // The enum uses "D0..D9" for the number keys
                                 // The enum uses "D0..D9" for the number keys
-                                if (Enum.TryParse (reader.GetString ().TrimStart ('D', 'd'), false, out key))
+                                if (Enum.TryParse (reader.GetString ()!.TrimStart ('D', 'd'), false, out key))
                                 {
                                 {
                                     break;
                                     break;
                                 }
                                 }

+ 13 - 5
Terminal.Gui/Configuration/ScopeJsonConverter.cs

@@ -1,5 +1,6 @@
 #nullable enable
 #nullable enable
 using System.Diagnostics;
 using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
 using System.Reflection;
 using System.Reflection;
 using System.Text.Json;
 using System.Text.Json;
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
@@ -11,9 +12,12 @@ namespace Terminal.Gui;
 ///     data to/from <see cref="ConfigurationManager"/> JSON documents.
 ///     data to/from <see cref="ConfigurationManager"/> JSON documents.
 /// </summary>
 /// </summary>
 /// <typeparam name="scopeT"></typeparam>
 /// <typeparam name="scopeT"></typeparam>
-internal class ScopeJsonConverter<scopeT> : JsonConverter<scopeT> where scopeT : Scope<scopeT>
+internal class ScopeJsonConverter<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] scopeT> : JsonConverter<scopeT> where scopeT : Scope<scopeT>
 {
 {
+    [RequiresDynamicCode ("Calls System.Type.MakeGenericType(params Type[])")]
+#pragma warning disable IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
     public override scopeT Read (ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
     public override scopeT Read (ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+#pragma warning restore IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
     {
     {
         if (reader.TokenType != JsonTokenType.StartObject)
         if (reader.TokenType != JsonTokenType.StartObject)
         {
         {
@@ -85,7 +89,7 @@ internal class ScopeJsonConverter<scopeT> : JsonConverter<scopeT> where scopeT :
                     try
                     try
                     {
                     {
                         scope! [propertyName].PropertyValue =
                         scope! [propertyName].PropertyValue =
-                            JsonSerializer.Deserialize (ref reader, propertyType!, options);
+                            JsonSerializer.Deserialize (ref reader, propertyType!, _serializerContext);
                     }
                     }
                     catch (Exception ex)
                     catch (Exception ex)
                     {
                     {
@@ -133,7 +137,7 @@ internal class ScopeJsonConverter<scopeT> : JsonConverter<scopeT> where scopeT :
                 if (property is { })
                 if (property is { })
                 {
                 {
                     PropertyInfo prop = scope.GetType ().GetProperty (propertyName!)!;
                     PropertyInfo prop = scope.GetType ().GetProperty (propertyName!)!;
-                    prop.SetValue (scope, JsonSerializer.Deserialize (ref reader, prop.PropertyType, options));
+                    prop.SetValue (scope, JsonSerializer.Deserialize (ref reader, prop.PropertyType, _serializerContext));
                 }
                 }
                 else
                 else
                 {
                 {
@@ -160,7 +164,8 @@ internal class ScopeJsonConverter<scopeT> : JsonConverter<scopeT> where scopeT :
         foreach (PropertyInfo p in properties)
         foreach (PropertyInfo p in properties)
         {
         {
             writer.WritePropertyName (ConfigProperty.GetJsonPropertyName (p));
             writer.WritePropertyName (ConfigProperty.GetJsonPropertyName (p));
-            JsonSerializer.Serialize (writer, scope.GetType ().GetProperty (p.Name)?.GetValue (scope), options);
+            object? prop = scope.GetType ().GetProperty (p.Name)?.GetValue (scope);
+            JsonSerializer.Serialize (writer, prop, prop!.GetType (), _serializerContext);
         }
         }
 
 
         foreach (KeyValuePair<string, ConfigProperty> p in from p in scope
         foreach (KeyValuePair<string, ConfigProperty> p in from p in scope
@@ -205,7 +210,8 @@ internal class ScopeJsonConverter<scopeT> : JsonConverter<scopeT> where scopeT :
             }
             }
             else
             else
             {
             {
-                JsonSerializer.Serialize (writer, p.Value.PropertyValue, options);
+                object? prop = p.Value.PropertyValue;
+                JsonSerializer.Serialize (writer, prop, prop!.GetType (), _serializerContext);
             }
             }
         }
         }
 
 
@@ -221,6 +227,8 @@ internal class ScopeJsonConverter<scopeT> : JsonConverter<scopeT> where scopeT :
     internal class ReadHelper<converterT> : ReadHelper
     internal class ReadHelper<converterT> : ReadHelper
     {
     {
         private readonly ReadDelegate _readDelegate;
         private readonly ReadDelegate _readDelegate;
+
+        [RequiresUnreferencedCode ("Calls System.Delegate.CreateDelegate(Type, Object, String)")]
         public ReadHelper (object converter) { _readDelegate = (ReadDelegate)Delegate.CreateDelegate (typeof (ReadDelegate), converter, "Read"); }
         public ReadHelper (object converter) { _readDelegate = (ReadDelegate)Delegate.CreateDelegate (typeof (ReadDelegate), converter, "Read"); }
 
 
         public override object? Read (ref Utf8JsonReader reader, Type type, JsonSerializerOptions options)
         public override object? Read (ref Utf8JsonReader reader, Type type, JsonSerializerOptions options)

+ 10 - 1
Terminal.Gui/Configuration/SettingsScope.cs

@@ -1,5 +1,6 @@
 #nullable enable
 #nullable enable
 using System.Diagnostics;
 using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
 using System.Reflection;
 using System.Reflection;
 using System.Text.Json;
 using System.Text.Json;
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
@@ -37,12 +38,14 @@ public class SettingsScope : Scope<SettingsScope>
     /// <summary>Updates the <see cref="SettingsScope"/> with the settings in a JSON string.</summary>
     /// <summary>Updates the <see cref="SettingsScope"/> with the settings in a JSON string.</summary>
     /// <param name="stream">Json document to update the settings with.</param>
     /// <param name="stream">Json document to update the settings with.</param>
     /// <param name="source">The source (filename/resource name) the Json document was read from.</param>
     /// <param name="source">The source (filename/resource name) the Json document was read from.</param>
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
     public SettingsScope? Update (Stream stream, string source)
     public SettingsScope? Update (Stream stream, string source)
     {
     {
         // Update the existing settings with the new settings.
         // Update the existing settings with the new settings.
         try
         try
         {
         {
-            Update (JsonSerializer.Deserialize<SettingsScope> (stream, _serializerOptions)!);
+            Update ((SettingsScope)JsonSerializer.Deserialize (stream, typeof (SettingsScope), _serializerOptions)!);
             OnUpdated ();
             OnUpdated ();
             Debug.WriteLine ($"ConfigurationManager: Read configuration from \"{source}\"");
             Debug.WriteLine ($"ConfigurationManager: Read configuration from \"{source}\"");
             if (!Sources.Contains (source))
             if (!Sources.Contains (source))
@@ -67,6 +70,8 @@ public class SettingsScope : Scope<SettingsScope>
 
 
     /// <summary>Updates the <see cref="SettingsScope"/> with the settings in a JSON file.</summary>
     /// <summary>Updates the <see cref="SettingsScope"/> with the settings in a JSON file.</summary>
     /// <param name="filePath"></param>
     /// <param name="filePath"></param>
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
     public SettingsScope? Update (string filePath)
     public SettingsScope? Update (string filePath)
     {
     {
         string realPath = filePath.Replace ("~", Environment.GetFolderPath (Environment.SpecialFolder.UserProfile));
         string realPath = filePath.Replace ("~", Environment.GetFolderPath (Environment.SpecialFolder.UserProfile));
@@ -93,6 +98,8 @@ public class SettingsScope : Scope<SettingsScope>
     /// <summary>Updates the <see cref="SettingsScope"/> with the settings in a JSON string.</summary>
     /// <summary>Updates the <see cref="SettingsScope"/> with the settings in a JSON string.</summary>
     /// <param name="json">Json document to update the settings with.</param>
     /// <param name="json">Json document to update the settings with.</param>
     /// <param name="source">The source (filename/resource name) the Json document was read from.</param>
     /// <param name="source">The source (filename/resource name) the Json document was read from.</param>
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
     public SettingsScope? Update (string json, string source)
     public SettingsScope? Update (string json, string source)
     {
     {
         var stream = new MemoryStream ();
         var stream = new MemoryStream ();
@@ -107,6 +114,8 @@ public class SettingsScope : Scope<SettingsScope>
     /// <summary>Updates the <see cref="SettingsScope"/> with the settings from a Json resource.</summary>
     /// <summary>Updates the <see cref="SettingsScope"/> with the settings from a Json resource.</summary>
     /// <param name="assembly"></param>
     /// <param name="assembly"></param>
     /// <param name="resourceName"></param>
     /// <param name="resourceName"></param>
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
     public SettingsScope? UpdateFromResource (Assembly assembly, string resourceName)
     public SettingsScope? UpdateFromResource (Assembly assembly, string resourceName)
     {
     {
         if (resourceName is null || string.IsNullOrEmpty (resourceName))
         if (resourceName is null || string.IsNullOrEmpty (resourceName))

+ 23 - 0
Terminal.Gui/Configuration/SourceGenerationContext.cs

@@ -0,0 +1,23 @@
+using System.Text.Json.Serialization;
+
+namespace Terminal.Gui;
+
+/// <summary>
+///     Allow AOT and self-contained single file applications with the <see cref="System.Text.Json.Serialization"/>
+/// </summary>
+[JsonSerializable (typeof (Attribute))]
+[JsonSerializable (typeof (Color))]
+[JsonSerializable (typeof (ThemeScope))]
+[JsonSerializable (typeof (ColorScheme))]
+[JsonSerializable (typeof (SettingsScope))]
+[JsonSerializable (typeof (AppScope))]
+[JsonSerializable (typeof (Key))]
+[JsonSerializable (typeof (GlyphDefinitions))]
+[JsonSerializable (typeof (ConfigProperty))]
+[JsonSerializable (typeof (ShadowStyle))]
+[JsonSerializable (typeof (string))]
+[JsonSerializable (typeof (bool))]
+[JsonSerializable (typeof (bool?))]
+[JsonSerializable (typeof (Dictionary<ColorName, string>))]
+internal partial class SourceGenerationContext : JsonSerializerContext
+{ }

+ 113 - 0
Terminal.Gui/Configuration/ThemeManager.cs

@@ -1,6 +1,7 @@
 #nullable enable
 #nullable enable
 using System.Collections;
 using System.Collections;
 using System.Diagnostics;
 using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
 namespace Terminal.Gui;
 namespace Terminal.Gui;
@@ -64,6 +65,9 @@ public class ThemeManager : IDictionary<string, ThemeScope>
     public string Theme
     public string Theme
     {
     {
         get => SelectedTheme;
         get => SelectedTheme;
+
+        [RequiresUnreferencedCode ("AOT")]
+        [RequiresDynamicCode ("AOT")]
         set => SelectedTheme = value;
         set => SelectedTheme = value;
     }
     }
 
 
@@ -73,9 +77,14 @@ public class ThemeManager : IDictionary<string, ThemeScope>
     [SerializableConfigurationProperty (Scope = typeof (SettingsScope), OmitClassName = true)]
     [SerializableConfigurationProperty (Scope = typeof (SettingsScope), OmitClassName = true)]
     public static Dictionary<string, ThemeScope>? Themes
     public static Dictionary<string, ThemeScope>? Themes
     {
     {
+        [RequiresUnreferencedCode ("AOT")]
+        [RequiresDynamicCode ("AOT")]
         get => Settings? ["Themes"]
         get => Settings? ["Themes"]
                        ?.PropertyValue as
                        ?.PropertyValue as
                    Dictionary<string, ThemeScope>; // themes ?? new Dictionary<string, ThemeScope> ();
                    Dictionary<string, ThemeScope>; // themes ?? new Dictionary<string, ThemeScope> ();
+
+        [RequiresUnreferencedCode ("AOT")]
+        [RequiresDynamicCode ("AOT")]
         set =>
         set =>
 
 
             //if (themes is null || value is null) {
             //if (themes is null || value is null) {
@@ -93,6 +102,9 @@ public class ThemeManager : IDictionary<string, ThemeScope>
     internal static string SelectedTheme
     internal static string SelectedTheme
     {
     {
         get => _theme;
         get => _theme;
+
+        [RequiresUnreferencedCode ("Calls Terminal.Gui.ConfigurationManager.Settings")]
+        [RequiresDynamicCode ("Calls Terminal.Gui.ConfigurationManager.Settings")]
         set
         set
         {
         {
             string oldTheme = _theme;
             string oldTheme = _theme;
@@ -109,6 +121,8 @@ public class ThemeManager : IDictionary<string, ThemeScope>
     /// <summary>Event fired he selected theme has changed. application.</summary>
     /// <summary>Event fired he selected theme has changed. application.</summary>
     public event EventHandler<ThemeManagerEventArgs>? ThemeChanged;
     public event EventHandler<ThemeManagerEventArgs>? ThemeChanged;
 
 
+    [RequiresUnreferencedCode ("Calls Terminal.Gui.ThemeManager.Themes")]
+    [RequiresDynamicCode ("Calls Terminal.Gui.ThemeManager.Themes")]
     internal static void GetHardCodedDefaults ()
     internal static void GetHardCodedDefaults ()
     {
     {
         //Debug.WriteLine ("Themes.GetHardCodedDefaults()");
         //Debug.WriteLine ("Themes.GetHardCodedDefaults()");
@@ -129,6 +143,8 @@ public class ThemeManager : IDictionary<string, ThemeScope>
         ThemeChanged?.Invoke (this, new ThemeManagerEventArgs (theme));
         ThemeChanged?.Invoke (this, new ThemeManagerEventArgs (theme));
     }
     }
 
 
+    [RequiresUnreferencedCode ("Calls Terminal.Gui.ThemeManager.Themes")]
+    [RequiresDynamicCode ("Calls Terminal.Gui.ThemeManager.Themes")]
     internal static void Reset ()
     internal static void Reset ()
     {
     {
         Debug.WriteLine ("Themes.Reset()");
         Debug.WriteLine ("Themes.Reset()");
@@ -140,33 +156,130 @@ public class ThemeManager : IDictionary<string, ThemeScope>
     #region IDictionary
     #region IDictionary
 
 
 #pragma warning disable 1591
 #pragma warning disable 1591
+    [UnconditionalSuppressMessage ("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>")]
+    [UnconditionalSuppressMessage ("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.", Justification = "<Pending>")]
     public ICollection<string> Keys => ((IDictionary<string, ThemeScope>)Themes!).Keys;
     public ICollection<string> Keys => ((IDictionary<string, ThemeScope>)Themes!).Keys;
+
+    [UnconditionalSuppressMessage ("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>")]
+    [UnconditionalSuppressMessage ("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.", Justification = "<Pending>")]
     public ICollection<ThemeScope> Values => ((IDictionary<string, ThemeScope>)Themes!).Values;
     public ICollection<ThemeScope> Values => ((IDictionary<string, ThemeScope>)Themes!).Values;
+
+    [UnconditionalSuppressMessage ("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>")]
+    [UnconditionalSuppressMessage ("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.", Justification = "<Pending>")]
     public int Count => ((ICollection<KeyValuePair<string, ThemeScope>>)Themes!).Count;
     public int Count => ((ICollection<KeyValuePair<string, ThemeScope>>)Themes!).Count;
+
+    [UnconditionalSuppressMessage ("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>")]
+    [UnconditionalSuppressMessage ("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.", Justification = "<Pending>")]
     public bool IsReadOnly => ((ICollection<KeyValuePair<string, ThemeScope>>)Themes!).IsReadOnly;
     public bool IsReadOnly => ((ICollection<KeyValuePair<string, ThemeScope>>)Themes!).IsReadOnly;
 
 
     public ThemeScope this [string key]
     public ThemeScope this [string key]
     {
     {
+        [RequiresUnreferencedCode ("AOT")]
+        [RequiresDynamicCode ("AOT")]
+#pragma warning disable IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
+#pragma warning disable IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
         get => ((IDictionary<string, ThemeScope>)Themes!) [key];
         get => ((IDictionary<string, ThemeScope>)Themes!) [key];
+#pragma warning restore IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
+#pragma warning restore IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
+
+        [RequiresUnreferencedCode ("AOT")]
+        [RequiresDynamicCode ("AOT")]
+#pragma warning disable IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
+#pragma warning disable IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
         set => ((IDictionary<string, ThemeScope>)Themes!) [key] = value;
         set => ((IDictionary<string, ThemeScope>)Themes!) [key] = value;
+#pragma warning restore IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
+#pragma warning restore IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
     }
     }
 
 
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
+#pragma warning disable IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
+#pragma warning disable IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
     public void Add (string key, ThemeScope value) { ((IDictionary<string, ThemeScope>)Themes!).Add (key, value); }
     public void Add (string key, ThemeScope value) { ((IDictionary<string, ThemeScope>)Themes!).Add (key, value); }
+#pragma warning restore IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
+#pragma warning restore IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
+
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
+#pragma warning disable IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
+#pragma warning disable IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
     public bool ContainsKey (string key) { return ((IDictionary<string, ThemeScope>)Themes!).ContainsKey (key); }
     public bool ContainsKey (string key) { return ((IDictionary<string, ThemeScope>)Themes!).ContainsKey (key); }
+#pragma warning restore IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
+#pragma warning restore IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
+
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
+#pragma warning disable IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
+#pragma warning disable IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
     public bool Remove (string key) { return ((IDictionary<string, ThemeScope>)Themes!).Remove (key); }
     public bool Remove (string key) { return ((IDictionary<string, ThemeScope>)Themes!).Remove (key); }
+#pragma warning restore IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
+#pragma warning restore IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
+#pragma warning disable IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
+#pragma warning disable IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
     public bool TryGetValue (string key, out ThemeScope value) { return ((IDictionary<string, ThemeScope>)Themes!).TryGetValue (key, out value!); }
     public bool TryGetValue (string key, out ThemeScope value) { return ((IDictionary<string, ThemeScope>)Themes!).TryGetValue (key, out value!); }
+#pragma warning restore IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
+#pragma warning restore IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
+
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
+#pragma warning disable IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
+#pragma warning disable IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
     public void Add (KeyValuePair<string, ThemeScope> item) { ((ICollection<KeyValuePair<string, ThemeScope>>)Themes!).Add (item); }
     public void Add (KeyValuePair<string, ThemeScope> item) { ((ICollection<KeyValuePair<string, ThemeScope>>)Themes!).Add (item); }
+#pragma warning restore IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
+#pragma warning restore IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
+
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
+#pragma warning disable IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
+#pragma warning disable IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
     public void Clear () { ((ICollection<KeyValuePair<string, ThemeScope>>)Themes!).Clear (); }
     public void Clear () { ((ICollection<KeyValuePair<string, ThemeScope>>)Themes!).Clear (); }
+#pragma warning restore IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
+#pragma warning restore IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
+
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
+#pragma warning disable IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
+#pragma warning disable IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
     public bool Contains (KeyValuePair<string, ThemeScope> item) { return ((ICollection<KeyValuePair<string, ThemeScope>>)Themes!).Contains (item); }
     public bool Contains (KeyValuePair<string, ThemeScope> item) { return ((ICollection<KeyValuePair<string, ThemeScope>>)Themes!).Contains (item); }
+#pragma warning restore IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
+#pragma warning restore IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
 
 
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
+#pragma warning disable IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
+#pragma warning disable IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
     public void CopyTo (KeyValuePair<string, ThemeScope> [] array, int arrayIndex)
     public void CopyTo (KeyValuePair<string, ThemeScope> [] array, int arrayIndex)
+#pragma warning restore IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
+#pragma warning restore IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
     {
     {
         ((ICollection<KeyValuePair<string, ThemeScope>>)Themes!).CopyTo (array, arrayIndex);
         ((ICollection<KeyValuePair<string, ThemeScope>>)Themes!).CopyTo (array, arrayIndex);
     }
     }
 
 
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
+#pragma warning disable IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
+#pragma warning disable IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
     public bool Remove (KeyValuePair<string, ThemeScope> item) { return ((ICollection<KeyValuePair<string, ThemeScope>>)Themes!).Remove (item); }
     public bool Remove (KeyValuePair<string, ThemeScope> item) { return ((ICollection<KeyValuePair<string, ThemeScope>>)Themes!).Remove (item); }
+#pragma warning restore IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
+#pragma warning restore IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
+
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
+#pragma warning disable IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
+#pragma warning disable IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
     public IEnumerator<KeyValuePair<string, ThemeScope>> GetEnumerator () { return ((IEnumerable<KeyValuePair<string, ThemeScope>>)Themes!).GetEnumerator (); }
     public IEnumerator<KeyValuePair<string, ThemeScope>> GetEnumerator () { return ((IEnumerable<KeyValuePair<string, ThemeScope>>)Themes!).GetEnumerator (); }
+#pragma warning restore IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
+#pragma warning restore IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
+
+    [RequiresUnreferencedCode ("Calls Terminal.Gui.ThemeManager.Themes")]
+    [RequiresDynamicCode ("Calls Terminal.Gui.ThemeManager.Themes")]
+#pragma warning disable IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
+#pragma warning disable IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
     IEnumerator IEnumerable.GetEnumerator () { return ((IEnumerable)Themes!).GetEnumerator (); }
     IEnumerator IEnumerable.GetEnumerator () { return ((IEnumerable)Themes!).GetEnumerator (); }
+#pragma warning restore IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
+#pragma warning restore IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
 #pragma warning restore 1591
 #pragma warning restore 1591
 
 
     #endregion
     #endregion

+ 2 - 0
Terminal.Gui/ConsoleDrivers/CursesDriver/UnmanagedLibrary.cs

@@ -13,6 +13,7 @@
 // limitations under the License.
 // limitations under the License.
 
 
 #define GUICS
 #define GUICS
+using System.Diagnostics.CodeAnalysis;
 using System.Runtime.InteropServices;
 using System.Runtime.InteropServices;
 
 
 namespace Unix.Terminal;
 namespace Unix.Terminal;
@@ -69,6 +70,7 @@ internal class UnmanagedLibrary
         }
         }
     }
     }
 
 
+    [UnconditionalSuppressMessage ("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.", Justification = "<Pending>")]
     static UnmanagedLibrary ()
     static UnmanagedLibrary ()
     {
     {
         PlatformID platform = Environment.OSVersion.Platform;
         PlatformID platform = Environment.OSVersion.Platform;

+ 3 - 0
Terminal.Gui/ConsoleDrivers/NetDriver.cs

@@ -3,6 +3,7 @@
 //
 //
 
 
 using System.Diagnostics;
 using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
 using System.Runtime.InteropServices;
 using System.Runtime.InteropServices;
 using static Terminal.Gui.ConsoleDrivers.ConsoleKeyMapping;
 using static Terminal.Gui.ConsoleDrivers.ConsoleKeyMapping;
 using static Terminal.Gui.NetEvents;
 using static Terminal.Gui.NetEvents;
@@ -452,6 +453,7 @@ internal class NetEvents : IDisposable
         HandleKeyboardEvent (newConsoleKeyInfo);
         HandleKeyboardEvent (newConsoleKeyInfo);
     }
     }
 
 
+    [UnconditionalSuppressMessage ("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.", Justification = "<Pending>")]
     private MouseButtonState MapMouseFlags (MouseFlags mouseFlags)
     private MouseButtonState MapMouseFlags (MouseFlags mouseFlags)
     {
     {
         MouseButtonState mbs = default;
         MouseButtonState mbs = default;
@@ -1249,6 +1251,7 @@ internal class NetDriver : ConsoleDriver
     #region Color Handling
     #region Color Handling
 
 
     // Cache the list of ConsoleColor values.
     // Cache the list of ConsoleColor values.
+    [UnconditionalSuppressMessage ("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.", Justification = "<Pending>")]
     private static readonly HashSet<int> ConsoleColorValues = new (
     private static readonly HashSet<int> ConsoleColorValues = new (
                                                                    Enum.GetValues (typeof (ConsoleColor))
                                                                    Enum.GetValues (typeof (ConsoleColor))
                                                                        .OfType<ConsoleColor> ()
                                                                        .OfType<ConsoleColor> ()

+ 3 - 3
Terminal.Gui/ConsoleDrivers/WindowsDriver.cs

@@ -116,7 +116,7 @@ internal class WindowsConsole
 
 
             var s = _stringBuilder.ToString ();
             var s = _stringBuilder.ToString ();
 
 
-            result = WriteConsole (_screenBuffer, s, (uint)s.Length, out uint _, null);
+            result = WriteConsole (_screenBuffer, s, (uint)s.Length, out uint _, nint.Zero);
         }
         }
 
 
         if (!result)
         if (!result)
@@ -134,7 +134,7 @@ internal class WindowsConsole
 
 
     public bool WriteANSI (string ansi)
     public bool WriteANSI (string ansi)
     {
     {
-        return WriteConsole (_screenBuffer, ansi, (uint)ansi.Length, out uint _, null);
+        return WriteConsole (_screenBuffer, ansi, (uint)ansi.Length, out uint _, nint.Zero);
     }
     }
 
 
     public void ReadFromConsoleOutput (Size size, Coord coords, ref SmallRect window)
     public void ReadFromConsoleOutput (Size size, Coord coords, ref SmallRect window)
@@ -804,7 +804,7 @@ internal class WindowsConsole
         string lpbufer,
         string lpbufer,
         uint NumberOfCharsToWriten,
         uint NumberOfCharsToWriten,
         out uint lpNumberOfCharsWritten,
         out uint lpNumberOfCharsWritten,
-        object lpReserved
+        nint lpReserved
     );
     );
 
 
     [DllImport ("kernel32.dll")]
     [DllImport ("kernel32.dll")]

+ 3 - 1
Terminal.Gui/FileServices/FileDialogStyle.cs

@@ -1,4 +1,5 @@
-using System.Globalization;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
 using System.IO.Abstractions;
 using System.IO.Abstractions;
 using Terminal.Gui.Resources;
 using Terminal.Gui.Resources;
 using static System.Environment;
 using static System.Environment;
@@ -143,6 +144,7 @@ public class FileDialogStyle
     /// </summary>
     /// </summary>
     public string WrongFileTypeFeedback { get; set; } = Strings.fdWrongFileTypeFeedback;
     public string WrongFileTypeFeedback { get; set; } = Strings.fdWrongFileTypeFeedback;
 
 
+    [UnconditionalSuppressMessage ("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.", Justification = "<Pending>")]
     private Dictionary<IDirectoryInfo, string> DefaultTreeRootGetter ()
     private Dictionary<IDirectoryInfo, string> DefaultTreeRootGetter ()
     {
     {
         Dictionary<IDirectoryInfo, string> roots = new ();
         Dictionary<IDirectoryInfo, string> roots = new ();

+ 2 - 4
Terminal.Gui/README.md

@@ -6,9 +6,7 @@ All files required to build the **Terminal.Gui** library (and NuGet package).
 
 
 - `\` - The root folder contains the source code for the library.
 - `\` - The root folder contains the source code for the library.
 	- `Terminal.Gui.sln` - The Visual Studio solution
 	- `Terminal.Gui.sln` - The Visual Studio solution
-	- `Application.cs` - A `static` class that provides the base 'application driver'. Given it defines a **Terminal.Gui** application it is both logically and literally (because `static`) a singleton. It has direct dependencies on `MainLoop`, `Events.cs` `NetDriver`, `CursesDriver`, `WindowsDriver`, `Responder`, `View`, and `TopLevel` (and nothing else).
-	- `MainLoop.cs` - Defines `IMainLoopDriver` and implements the `MainLoop` class.
-	- A few supporting class files
+	- `Application\` - The core `Application` logic, including `Application.cs`, which is is a `static` class that provides the base 'application engine', `RunState`, and `MainLoop`.
 
 
 - `ConsoleDrivers\`
 - `ConsoleDrivers\`
 	- `ConsoleDriver.cs` - Definition for the Console Driver API.
 	- `ConsoleDriver.cs` - Definition for the Console Driver API.
@@ -38,7 +36,7 @@ All files required to build the **Terminal.Gui** library (and NuGet package).
 	- `Dialog` -
 	- `Dialog` -
 	- etc...
 	- etc...
 
 
-- `Types/` - A folder (not namespace) containing implementations of `Point`, `Rect`, and `Size` which are ancient versions of the modern `System.Drawing.Point`, `System.Drawing.Size`, and `System.Drawning.Rectangle`.
+- `FileServcies/` - File services classes.
 
 
 ## Version numbers
 ## Version numbers
 
 

+ 5 - 7
Terminal.Gui/Terminal.Gui.csproj

@@ -25,10 +25,13 @@
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <DefineTrace>true</DefineTrace>
     <DefineTrace>true</DefineTrace>
     <DebugType>portable</DebugType>
     <DebugType>portable</DebugType>
-    <DefineConstants>$(DefineConstants);JETBRAINS_ANNOTATIONS;CONTRACTS_FULL;CODE_ANALYSIS</DefineConstants>
+    <DefineConstants>$(DefineConstants);CONTRACTS_FULL;CODE_ANALYSIS</DefineConstants>
     <ImplicitUsings>enable</ImplicitUsings>
     <ImplicitUsings>enable</ImplicitUsings>
     <NoLogo>true</NoLogo>
     <NoLogo>true</NoLogo>
     <SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
     <SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
+    <JsonSerializerIsReflectionEnabledByDefault>false</JsonSerializerIsReflectionEnabledByDefault>
+    <IsTrimmable>true</IsTrimmable>
+    <IsAotCompatible>true</IsAotCompatible>
   </PropertyGroup>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
   <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
     <DefineDebug>true</DefineDebug>
     <DefineDebug>true</DefineDebug>
@@ -50,7 +53,7 @@
   <!-- =================================================================== -->
   <!-- =================================================================== -->
   <ItemGroup>
   <ItemGroup>
     <PackageReference Include="ColorHelper" Version="[1.8.1,2)" />
     <PackageReference Include="ColorHelper" Version="[1.8.1,2)" />
-    <PackageReference Include="JetBrains.Annotations" Version="[2024,)" PrivateAssets="all" />
+    <PackageReference Include="JetBrains.Annotations" Version="[2024.2.0,)" PrivateAssets="all" />
     <PackageReference Include="Microsoft.CodeAnalysis" Version="[4.10,5)" PrivateAssets="all" />
     <PackageReference Include="Microsoft.CodeAnalysis" Version="[4.10,5)" PrivateAssets="all" />
     <PackageReference Include="Microsoft.CodeAnalysis.Common" Version="[4.10,5)" PrivateAssets="all" />
     <PackageReference Include="Microsoft.CodeAnalysis.Common" Version="[4.10,5)" PrivateAssets="all" />
     <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="[4.10,5)" PrivateAssets="all" />
     <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="[4.10,5)" PrivateAssets="all" />
@@ -59,11 +62,6 @@
     <PackageReference Include="System.IO.Abstractions" Version="[21.0.22,22)" />
     <PackageReference Include="System.IO.Abstractions" Version="[21.0.22,22)" />
     <PackageReference Include="System.Text.Json" Version="[8.0.4,9)" />
     <PackageReference Include="System.Text.Json" Version="[8.0.4,9)" />
     <PackageReference Include="Wcwidth" Version="[2,3)" />
     <PackageReference Include="Wcwidth" Version="[2,3)" />
-    <ProjectReference Include="..\Analyzers\Terminal.Gui.Analyzers.Internal\Terminal.Gui.Analyzers.Internal.csproj">
-      <PrivateAssets>all</PrivateAssets>
-      <OutputItemType>Analyzer</OutputItemType>
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
-    </ProjectReference>
   </ItemGroup>
   </ItemGroup>
   <!-- =================================================================== -->
   <!-- =================================================================== -->
   <!-- Global Usings and Type Aliases -->
   <!-- Global Usings and Type Aliases -->

+ 1 - 1
Terminal.Gui/Views/Button.cs

@@ -39,7 +39,7 @@ public class Button : View, IDesignable
     /// Gets or sets whether <see cref="Button"/>s are shown with a shadow effect by default.
     /// Gets or sets whether <see cref="Button"/>s are shown with a shadow effect by default.
     /// </summary>
     /// </summary>
     [SerializableConfigurationProperty (Scope = typeof (ThemeScope))]
     [SerializableConfigurationProperty (Scope = typeof (ThemeScope))]
-    [JsonConverter (typeof (JsonStringEnumConverter))]
+    [JsonConverter (typeof (JsonStringEnumConverter<ShadowStyle>))]
 
 
     public static ShadowStyle DefaultShadow { get; set; } = ShadowStyle.None;
     public static ShadowStyle DefaultShadow { get; set; } = ShadowStyle.None;
 
 

+ 4 - 4
Terminal.Gui/Views/Dialog.cs

@@ -19,13 +19,13 @@ public class Dialog : Window
     /// <summary>The default <see cref="Alignment"/> for <see cref="Dialog"/>.</summary>
     /// <summary>The default <see cref="Alignment"/> for <see cref="Dialog"/>.</summary>
     /// <remarks>This property can be set in a Theme.</remarks>
     /// <remarks>This property can be set in a Theme.</remarks>
     [SerializableConfigurationProperty (Scope = typeof (ThemeScope))]
     [SerializableConfigurationProperty (Scope = typeof (ThemeScope))]
-    [JsonConverter (typeof (JsonStringEnumConverter))]
+    [JsonConverter (typeof (JsonStringEnumConverter<Alignment>))]
     public static Alignment DefaultButtonAlignment { get; set; } = Alignment.End;
     public static Alignment DefaultButtonAlignment { get; set; } = Alignment.End;
 
 
     /// <summary>The default <see cref="Alignment"/> for <see cref="Dialog"/>.</summary>
     /// <summary>The default <see cref="Alignment"/> for <see cref="Dialog"/>.</summary>
     /// <remarks>This property can be set in a Theme.</remarks>
     /// <remarks>This property can be set in a Theme.</remarks>
     [SerializableConfigurationProperty (Scope = typeof (ThemeScope))]
     [SerializableConfigurationProperty (Scope = typeof (ThemeScope))]
-    [JsonConverter (typeof (JsonStringEnumConverter))]
+    [JsonConverter (typeof (JsonStringEnumConverter<AlignmentModes>))]
     public static AlignmentModes DefaultButtonAlignmentModes { get; set; } = AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems;
     public static AlignmentModes DefaultButtonAlignmentModes { get; set; } = AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems;
 
 
     /// <summary>
     /// <summary>
@@ -47,7 +47,7 @@ public class Dialog : Window
     /// Gets or sets whether all <see cref="Window"/>s are shown with a shadow effect by default.
     /// Gets or sets whether all <see cref="Window"/>s are shown with a shadow effect by default.
     /// </summary>
     /// </summary>
     [SerializableConfigurationProperty (Scope = typeof (ThemeScope))]
     [SerializableConfigurationProperty (Scope = typeof (ThemeScope))]
-    [JsonConverter (typeof (JsonStringEnumConverter))]
+    [JsonConverter (typeof (JsonStringEnumConverter<ShadowStyle>))]
     public new static ShadowStyle DefaultShadow { get; set; } = ShadowStyle.None;
     public new static ShadowStyle DefaultShadow { get; set; } = ShadowStyle.None;
 
 
     /// <summary>
     /// <summary>
@@ -56,7 +56,7 @@ public class Dialog : Window
     /// </summary>
     /// </summary>
 
 
     [SerializableConfigurationProperty (Scope = typeof (ThemeScope))]
     [SerializableConfigurationProperty (Scope = typeof (ThemeScope))]
-    [JsonConverter (typeof (JsonStringEnumConverter))]
+    [JsonConverter (typeof (JsonStringEnumConverter<LineStyle>))]
     public new static LineStyle DefaultBorderStyle { get; set; } = LineStyle.Single;
     public new static LineStyle DefaultBorderStyle { get; set; } = LineStyle.Single;
 
 
     private readonly List<Button> _buttons = new ();
     private readonly List<Button> _buttons = new ();

+ 1 - 1
Terminal.Gui/Views/FrameView.cs

@@ -36,6 +36,6 @@ public class FrameView : View
     ///     <see cref="FrameView"/>s.
     ///     <see cref="FrameView"/>s.
     /// </remarks>
     /// </remarks>
     [SerializableConfigurationProperty (Scope = typeof (ThemeScope))]
     [SerializableConfigurationProperty (Scope = typeof (ThemeScope))]
-    [JsonConverter (typeof (JsonStringEnumConverter))]
+    [JsonConverter (typeof (JsonStringEnumConverter<LineStyle>))]
     public static LineStyle DefaultBorderStyle { get; set; } = LineStyle.Single;
     public static LineStyle DefaultBorderStyle { get; set; } = LineStyle.Single;
 }
 }

+ 1 - 1
Terminal.Gui/Views/MessageBox.cs

@@ -31,7 +31,7 @@ public static class MessageBox
     ///     <see cref="ConfigurationManager"/>.
     ///     <see cref="ConfigurationManager"/>.
     /// </summary>
     /// </summary>
     [SerializableConfigurationProperty (Scope = typeof (ThemeScope))]
     [SerializableConfigurationProperty (Scope = typeof (ThemeScope))]
-    [JsonConverter (typeof (JsonStringEnumConverter))]
+    [JsonConverter (typeof (JsonStringEnumConverter<LineStyle>))]
     public static LineStyle DefaultBorderStyle { get; set; } = LineStyle.Single;
     public static LineStyle DefaultBorderStyle { get; set; } = LineStyle.Single;
 
 
     /// <summary>
     /// <summary>

+ 1 - 1
Terminal.Gui/Views/Window.cs

@@ -73,6 +73,6 @@ public class Window : Toplevel
     ///     s.
     ///     s.
     /// </remarks>
     /// </remarks>
     [SerializableConfigurationProperty (Scope = typeof (ThemeScope))]
     [SerializableConfigurationProperty (Scope = typeof (ThemeScope))]
-    [JsonConverter (typeof (JsonStringEnumConverter))]
+    [JsonConverter (typeof (JsonStringEnumConverter<LineStyle>))]
     public static LineStyle DefaultBorderStyle { get; set; } = LineStyle.Single;
     public static LineStyle DefaultBorderStyle { get; set; } = LineStyle.Single;
 }
 }

+ 6 - 0
Terminal.sln

@@ -43,6 +43,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{C7A51224-5
 		README.md = README.md
 		README.md = README.md
 	EndProjectSection
 	EndProjectSection
 EndProject
 EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SelfContained", "SelfContained\SelfContained.csproj", "{524DEA78-7E7C-474D-B42D-52ED4C04FF14}"
+EndProject
 Global
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
 		Debug|Any CPU = Debug|Any CPU
@@ -73,6 +75,10 @@ Global
 		{58FDCA8F-08F7-4D80-9DA3-6A9AED01E163}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{58FDCA8F-08F7-4D80-9DA3-6A9AED01E163}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{58FDCA8F-08F7-4D80-9DA3-6A9AED01E163}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{58FDCA8F-08F7-4D80-9DA3-6A9AED01E163}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{58FDCA8F-08F7-4D80-9DA3-6A9AED01E163}.Release|Any CPU.Build.0 = Release|Any CPU
 		{58FDCA8F-08F7-4D80-9DA3-6A9AED01E163}.Release|Any CPU.Build.0 = Release|Any CPU
+		{524DEA78-7E7C-474D-B42D-52ED4C04FF14}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{524DEA78-7E7C-474D-B42D-52ED4C04FF14}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{524DEA78-7E7C-474D-B42D-52ED4C04FF14}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{524DEA78-7E7C-474D-B42D-52ED4C04FF14}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 		HideSolutionNode = FALSE

+ 4 - 80
UICatalog/Scenario.cs

@@ -93,6 +93,10 @@ public class Scenario : IDisposable
     /// <returns></returns>
     /// <returns></returns>
     public string GetName () { return ScenarioMetadata.GetName (GetType ()); }
     public string GetName () { return ScenarioMetadata.GetName (GetType ()); }
 
 
+    /// <summary>Helper to get the <see cref="Application.QuitKey"/> and the <see cref="Scenario"/> Name (defined in <see cref="ScenarioMetadata"/>)</summary>
+    /// <returns></returns>
+    public string GetQuitKeyAndName () { return $"{Application.QuitKey} to Quit - Scenario: {GetName ()}"; }
+
     /// <summary>
     /// <summary>
     ///     Returns a list of all <see cref="Scenario"/> instanaces defined in the project, sorted by
     ///     Returns a list of all <see cref="Scenario"/> instanaces defined in the project, sorted by
     ///     <see cref="ScenarioMetadata.Name"/>.
     ///     <see cref="ScenarioMetadata.Name"/>.
@@ -132,90 +136,12 @@ public class Scenario : IDisposable
     /// </remarks>
     /// </remarks>
     public virtual void Main ()
     public virtual void Main ()
     {
     {
-        Init ();
-        Setup ();
-        Run ();
-    }
-
-    /// <summary>
-    ///     Helper that calls <see cref="Application.Init"/> and creates the default <see cref="Terminal.Gui.Window"/>
-    ///     implementation with a frame and label
-    ///     showing the name of the <see cref="Scenario"/> and logic to exit back to the Scenario picker UI. Override
-    ///     <see cref="Init"/> to provide any <see cref="Terminal.Gui.Toplevel"/> behavior needed.
-    /// </summary>
-    /// <remarks>
-    ///     <para>
-    ///         The base implementation calls <see cref="Application.Init"/> and creates a <see cref="Window"/> for
-    ///         <see cref="Win"/> and adds it to <see cref="Application.Top"/>.
-    ///     </para>
-    ///     <para>
-    ///         Overrides that do not call the base.<see cref="Run"/>, must call <see cref="Application.Init"/> before
-    ///         creating any views or calling other Terminal.Gui APIs.
-    ///     </para>
-    /// </remarks>
-    [ObsoleteAttribute ("This method is obsolete and will be removed in v2. Use Main instead.", false)]
-    public virtual void Init ()
-    {
-        Application.Init ();
-
-        ConfigurationManager.Themes.Theme = Theme;
-        ConfigurationManager.Apply ();
-
-        Top = new ();
-
-        Win = new ()
-        {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}",
-            X = 0,
-            Y = 0,
-            Width = Dim.Fill (),
-            Height = Dim.Fill (),
-            ColorScheme = Colors.ColorSchemes [TopLevelColorScheme]
-        };
-        Top.Add (Win);
     }
     }
 
 
-    /// <summary>
-    ///     Runs the <see cref="Scenario"/>. Override to start the <see cref="Scenario"/> using a <see cref="Toplevel"/>
-    ///     different than `Top`.
-    /// </summary>
-    /// <remarks>
-    ///     Overrides that do not call the base.<see cref="Run"/>, must call <see cref="Application.Shutdown"/> before
-    ///     returning.
-    /// </remarks>
-    [ObsoleteAttribute ("This method is obsolete and will be removed in v2. Use Main instead.", false)]
-    public virtual void Run ()
-    {
-        // Must explicitly call Application.Shutdown method to shutdown.
-        Application.Run (Top);
-        Top.Dispose ();
-        Application.Shutdown ();
-    }
-
-    /// <summary>Override this to implement the <see cref="Scenario"/> setup logic (create controls, etc...).</summary>
-    /// <remarks>This is typically the best place to put scenario logic code.</remarks>
-    [ObsoleteAttribute ("This method is obsolete and will be removed in v2. Use Main instead.", false)]
-    public virtual void Setup () { }
-
-    /// <summary>
-    ///     The Toplevel for the <see cref="Scenario"/>. This should be set to <see cref="Terminal.Gui.Application.Top"/>.
-    /// </summary>
-
-    //[ObsoleteAttribute ("This property is obsolete and will be removed in v2. Use Main instead.", false)]
-    public Toplevel Top { get; set; }
-
     /// <summary>Gets the Scenario Name + Description with the Description padded based on the longest known Scenario name.</summary>
     /// <summary>Gets the Scenario Name + Description with the Description padded based on the longest known Scenario name.</summary>
     /// <returns></returns>
     /// <returns></returns>
     public override string ToString () { return $"{GetName ().PadRight (_maxScenarioNameLen)}{GetDescription ()}"; }
     public override string ToString () { return $"{GetName ().PadRight (_maxScenarioNameLen)}{GetDescription ()}"; }
 
 
-    /// <summary>
-    ///     The Window for the <see cref="Scenario"/>. This should be set to <see cref="Terminal.Gui.Application.Top"/> in
-    ///     most cases.
-    /// </summary>
-
-    //[ObsoleteAttribute ("This property is obsolete and will be removed in v2. Use Main instead.", false)]
-    public Window Win { get; set; }
-
     #region IDispose
     #region IDispose
 
 
     public void Dispose ()
     public void Dispose ()
@@ -231,8 +157,6 @@ public class Scenario : IDisposable
         {
         {
             if (disposing)
             if (disposing)
             {
             {
-                Top?.Dispose ();
-                Win?.Dispose ();
             }
             }
 
 
             _disposedValue = true;
             _disposedValue = true;

+ 1 - 1
UICatalog/Scenarios/ASCIICustomButton.cs

@@ -149,7 +149,7 @@ public class ASCIICustomButtonTest : Scenario
 
 
         public ScrollViewTestWindow ()
         public ScrollViewTestWindow ()
         {
         {
-            Title = "ScrollViewTestWindow";
+            Title = $"{Application.QuitKey} to Quit - Scenario: ScrollViewTestWindow";
 
 
             Label titleLabel = null;
             Label titleLabel = null;
 
 

+ 1 - 1
UICatalog/Scenarios/Adornments.cs

@@ -13,7 +13,7 @@ public class Adornments : Scenario
 
 
         Window app = new ()
         Window app = new ()
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}"
+            Title = GetQuitKeyAndName ()
         };
         };
 
 
         var editor = new AdornmentsEditor
         var editor = new AdornmentsEditor

+ 1 - 1
UICatalog/Scenarios/AllViewsTester.cs

@@ -53,7 +53,7 @@ public class AllViewsTester : Scenario
 
 
         var app = new Window
         var app = new Window
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}",
+            Title = GetQuitKeyAndName (),
             ColorScheme = Colors.ColorSchemes ["TopLevel"]
             ColorScheme = Colors.ColorSchemes ["TopLevel"]
         };
         };
 
 

+ 1 - 1
UICatalog/Scenarios/AnimationScenario.cs

@@ -23,7 +23,7 @@ public class AnimationScenario : Scenario
 
 
         var win = new Window
         var win = new Window
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}",
+            Title = GetQuitKeyAndName (),
             X = 0,
             X = 0,
             Y = 0,
             Y = 0,
             Width = Dim.Fill (),
             Width = Dim.Fill (),

+ 1 - 1
UICatalog/Scenarios/Bars.cs

@@ -28,7 +28,7 @@ public class Bars : Scenario
     // QuitKey and it only sticks if changed after init
     // QuitKey and it only sticks if changed after init
     private void App_Loaded (object sender, EventArgs e)
     private void App_Loaded (object sender, EventArgs e)
     {
     {
-        Application.Top.Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}";
+        Application.Top.Title = GetQuitKeyAndName ();
 
 
         ObservableCollection<string> eventSource = new ();
         ObservableCollection<string> eventSource = new ();
         ListView eventLog = new ListView ()
         ListView eventLog = new ListView ()

+ 1 - 1
UICatalog/Scenarios/BasicColors.cs

@@ -14,7 +14,7 @@ public class BasicColors : Scenario
 
 
         Window app = new ()
         Window app = new ()
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}",
+            Title = GetQuitKeyAndName (),
         };
         };
 
 
         var vx = 30;
         var vx = 30;

+ 1 - 1
UICatalog/Scenarios/Buttons.cs

@@ -18,7 +18,7 @@ public class Buttons : Scenario
 
 
         Window main = new ()
         Window main = new ()
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}"
+            Title = GetQuitKeyAndName ()
         };
         };
 
 
         // Add a label & text field so we can demo IsDefault
         // Add a label & text field so we can demo IsDefault

+ 1 - 1
UICatalog/Scenarios/ChineseUI.cs

@@ -12,7 +12,7 @@ public class ChineseUI : Scenario
 
 
         var win = new Window
         var win = new Window
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}",
+            Title = GetQuitKeyAndName (),
             X = 0,
             X = 0,
             Y = 0,
             Y = 0,
             Width = Dim.Fill (),
             Width = Dim.Fill (),

+ 19 - 9
UICatalog/Scenarios/ClassExplorer.cs

@@ -17,11 +17,15 @@ public class ClassExplorer : Scenario
     private TextView _textView;
     private TextView _textView;
     private TreeView<object> _treeView;
     private TreeView<object> _treeView;
 
 
-    public override void Setup ()
+    public override void Main ()
     {
     {
-        Win.Title = GetName ();
-        Win.Y = 1; // menu
-        Win.Height = Dim.Fill (1); // status bar
+        Application.Init ();
+        var top = new Toplevel ();
+
+        var win = new Window
+        {
+            Title = GetName ()
+        };
 
 
         var menu = new MenuBar
         var menu = new MenuBar
         {
         {
@@ -55,15 +59,15 @@ public class ClassExplorer : Scenario
                                 )
                                 )
             ]
             ]
         };
         };
-        Top.Add (menu);
+        top.Add (menu);
 
 
         _treeView = new TreeView<object> { X = 0, Y = 1, Width = Dim.Percent (50), Height = Dim.Fill () };
         _treeView = new TreeView<object> { X = 0, Y = 1, Width = Dim.Percent (50), Height = Dim.Fill () };
 
 
         var lblSearch = new Label { Text = "Search" };
         var lblSearch = new Label { Text = "Search" };
         var tfSearch = new TextField { Width = 20, X = Pos.Right (lblSearch) };
         var tfSearch = new TextField { Width = 20, X = Pos.Right (lblSearch) };
 
 
-        Win.Add (lblSearch);
-        Win.Add (tfSearch);
+        win.Add (lblSearch);
+        win.Add (tfSearch);
 
 
         TreeViewTextFilter<object> filter = new (_treeView);
         TreeViewTextFilter<object> filter = new (_treeView);
         _treeView.Filter = filter;
         _treeView.Filter = filter;
@@ -83,11 +87,17 @@ public class ClassExplorer : Scenario
         _treeView.TreeBuilder = new DelegateTreeBuilder<object> (ChildGetter, CanExpand);
         _treeView.TreeBuilder = new DelegateTreeBuilder<object> (ChildGetter, CanExpand);
         _treeView.SelectionChanged += TreeView_SelectionChanged;
         _treeView.SelectionChanged += TreeView_SelectionChanged;
 
 
-        Win.Add (_treeView);
+        win.Add (_treeView);
 
 
         _textView = new TextView { X = Pos.Right (_treeView), Y = 0, Width = Dim.Fill (), Height = Dim.Fill () };
         _textView = new TextView { X = Pos.Right (_treeView), Y = 0, Width = Dim.Fill (), Height = Dim.Fill () };
 
 
-        Win.Add (_textView);
+        win.Add (_textView);
+
+        top.Add (win);
+
+        Application.Run (top);
+        top.Dispose ();
+        Application.Shutdown ();
     }
     }
 
 
     private bool CanExpand (object arg) { return arg is Assembly || arg is Type || arg is ShowForType; }
     private bool CanExpand (object arg) { return arg is Assembly || arg is Type || arg is ShowForType; }

+ 8 - 12
UICatalog/Scenarios/Clipping.cs

@@ -8,24 +8,16 @@ namespace UICatalog.Scenarios;
 [ScenarioCategory ("Scrolling")]
 [ScenarioCategory ("Scrolling")]
 public class Clipping : Scenario
 public class Clipping : Scenario
 {
 {
-    public override void Init ()
+    public override void Main ()
     {
     {
         Application.Init ();
         Application.Init ();
-        Top = new ();
-        Top.ColorScheme = Colors.ColorSchemes ["Base"];
-    }
+        var win = new Window { Title = GetQuitKeyAndName () };
 
 
-    public override void Setup ()
-    {
-        //Win.X = 1;
-        //Win.Y = 2;
-        //Win.Width = Dim.Fill () - 4;
-        //Win.Height = Dim.Fill () - 2;
         var label = new Label
         var label = new Label
         {
         {
             X = 0, Y = 0, Text = "ScrollView (new Rectangle (3, 3, 50, 20)) with a 200, 100 GetContentSize ()..."
             X = 0, Y = 0, Text = "ScrollView (new Rectangle (3, 3, 50, 20)) with a 200, 100 GetContentSize ()..."
         };
         };
-        Top.Add (label);
+        win.Add (label);
 
 
         var scrollView = new ScrollView { X = 3, Y = 3, Width = 50, Height = 20 };
         var scrollView = new ScrollView { X = 3, Y = 3, Width = 50, Height = 20 };
         scrollView.ColorScheme = Colors.ColorSchemes ["Menu"];
         scrollView.ColorScheme = Colors.ColorSchemes ["Menu"];
@@ -84,6 +76,10 @@ public class Clipping : Scenario
 
 
         scrollView.Add (embedded1);
         scrollView.Add (embedded1);
 
 
-        Top.Add (scrollView);
+        win.Add (scrollView);
+
+        Application.Run (win);
+        win.Dispose ();
+        Application.Shutdown ();
     }
     }
 }
 }

+ 13 - 12
UICatalog/Scenarios/CollectionNavigatorTester.cs

@@ -74,19 +74,16 @@ public class CollectionNavigatorTester : Scenario
         "quitter"
         "quitter"
     }.ToList ());
     }.ToList ());
 
 
+    private Toplevel top;
     private ListView _listView;
     private ListView _listView;
     private TreeView _treeView;
     private TreeView _treeView;
 
 
     // Don't create a Window, just return the top-level view
     // Don't create a Window, just return the top-level view
-    public override void Init ()
+    public override void Main ()
     {
     {
         Application.Init ();
         Application.Init ();
-        Top = new ();
-        Top.ColorScheme = Colors.ColorSchemes ["Base"];
-    }
+        top = new Toplevel { ColorScheme = Colors.ColorSchemes ["Base"] };
 
 
-    public override void Setup ()
-    {
         var allowMarking = new MenuItem ("Allow _Marking", "", null)
         var allowMarking = new MenuItem ("Allow _Marking", "", null)
         {
         {
             CheckType = MenuItemCheckStyle.Checked, Checked = false
             CheckType = MenuItemCheckStyle.Checked, Checked = false
@@ -128,14 +125,18 @@ public class CollectionNavigatorTester : Scenario
             ]
             ]
         };
         };
 
 
-        Top.Add (menu);
+        top.Add (menu);
 
 
         _items = new (_items.OrderBy (i => i, StringComparer.OrdinalIgnoreCase));
         _items = new (_items.OrderBy (i => i, StringComparer.OrdinalIgnoreCase));
 
 
         CreateListView ();
         CreateListView ();
         var vsep = new LineView (Orientation.Vertical) { X = Pos.Right (_listView), Y = 1, Height = Dim.Fill () };
         var vsep = new LineView (Orientation.Vertical) { X = Pos.Right (_listView), Y = 1, Height = Dim.Fill () };
-        Top.Add (vsep);
+        top.Add (vsep);
         CreateTreeView ();
         CreateTreeView ();
+
+        Application.Run (top);
+        top.Dispose ();
+        Application.Shutdown ();
     }
     }
 
 
     private void CreateListView ()
     private void CreateListView ()
@@ -149,7 +150,7 @@ public class CollectionNavigatorTester : Scenario
             Width = Dim.Percent (50),
             Width = Dim.Percent (50),
             Height = 1
             Height = 1
         };
         };
-        Top.Add (label);
+        top.Add (label);
 
 
         _listView = new ListView
         _listView = new ListView
         {
         {
@@ -160,7 +161,7 @@ public class CollectionNavigatorTester : Scenario
             AllowsMarking = false,
             AllowsMarking = false,
             AllowsMultipleSelection = false
             AllowsMultipleSelection = false
         };
         };
-        Top.Add (_listView);
+        top.Add (_listView);
 
 
         _listView.SetSource (_items);
         _listView.SetSource (_items);
 
 
@@ -178,14 +179,14 @@ public class CollectionNavigatorTester : Scenario
             Width = Dim.Percent (50),
             Width = Dim.Percent (50),
             Height = 1
             Height = 1
         };
         };
-        Top.Add (label);
+        top.Add (label);
 
 
         _treeView = new TreeView
         _treeView = new TreeView
         {
         {
             X = Pos.Right (_listView) + 1, Y = Pos.Bottom (label), Width = Dim.Fill (), Height = Dim.Fill ()
             X = Pos.Right (_listView) + 1, Y = Pos.Bottom (label), Width = Dim.Fill (), Height = Dim.Fill ()
         };
         };
         _treeView.Style.HighlightModelTextOnly = true;
         _treeView.Style.HighlightModelTextOnly = true;
-        Top.Add (_treeView);
+        top.Add (_treeView);
 
 
         var root = new TreeNode ("IsLetterOrDigit examples");
         var root = new TreeNode ("IsLetterOrDigit examples");
 
 

+ 1 - 1
UICatalog/Scenarios/ColorPicker.cs

@@ -30,7 +30,7 @@ public class ColorPickers : Scenario
 
 
         Window app = new ()
         Window app = new ()
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}",
+            Title = GetQuitKeyAndName (),
         };
         };
 
 
         // Foreground ColorPicker.
         // Foreground ColorPicker.

+ 24 - 24
UICatalog/Scenarios/CombiningMarks.cs

@@ -6,33 +6,33 @@ namespace UICatalog.Scenarios;
 [ScenarioCategory ("Text and Formatting")]
 [ScenarioCategory ("Text and Formatting")]
 public class CombiningMarks : Scenario
 public class CombiningMarks : Scenario
 {
 {
-    public override void Init ()
+    public override void Main ()
     {
     {
         Application.Init ();
         Application.Init ();
-        ConfigurationManager.Themes.Theme = Theme;
+        ConfigurationManager.Themes!.Theme = Theme;
         ConfigurationManager.Apply ();
         ConfigurationManager.Apply ();
-        Top = new ();
-        Top.ColorScheme = Colors.ColorSchemes [TopLevelColorScheme];
-    }
+        var top = new Toplevel { ColorScheme = Colors.ColorSchemes [TopLevelColorScheme] };
 
 
-    public override void Setup ()
-    {
-        Top.DrawContentComplete += (s, e) =>
-                                               {
-                                                   Application.Driver.Move (0, 0);
-                                                   Application.Driver.AddStr ("Terminal.Gui only supports combining marks that normalize. See Issue #2616.");
-                                                   Application.Driver.Move (0, 2);
-                                                   Application.Driver.AddStr ("\u0301\u0301\u0328<- \"\\u301\\u301\\u328]\" using AddStr.");
-                                                   Application.Driver.Move (0, 3);
-                                                   Application.Driver.AddStr ("[a\u0301\u0301\u0328]<- \"[a\\u301\\u301\\u328]\" using AddStr.");
-                                                   Application.Driver.Move (0, 4);
-                                                   Application.Driver.AddRune ('[');
-                                                   Application.Driver.AddRune ('a');
-                                                   Application.Driver.AddRune ('\u0301');
-                                                   Application.Driver.AddRune ('\u0301');
-                                                   Application.Driver.AddRune ('\u0328');
-                                                   Application.Driver.AddRune (']');
-                                                   Application.Driver.AddStr ("<- \"[a\\u301\\u301\\u328]\" using AddRune for each.");
-                                               };
+        top.DrawContentComplete += (s, e) =>
+                                   {
+                                       Application.Driver.Move (0, 0);
+                                       Application.Driver.AddStr ("Terminal.Gui only supports combining marks that normalize. See Issue #2616.");
+                                       Application.Driver.Move (0, 2);
+                                       Application.Driver.AddStr ("\u0301\u0301\u0328<- \"\\u301\\u301\\u328]\" using AddStr.");
+                                       Application.Driver.Move (0, 3);
+                                       Application.Driver.AddStr ("[a\u0301\u0301\u0328]<- \"[a\\u301\\u301\\u328]\" using AddStr.");
+                                       Application.Driver.Move (0, 4);
+                                       Application.Driver.AddRune ('[');
+                                       Application.Driver.AddRune ('a');
+                                       Application.Driver.AddRune ('\u0301');
+                                       Application.Driver.AddRune ('\u0301');
+                                       Application.Driver.AddRune ('\u0328');
+                                       Application.Driver.AddRune (']');
+                                       Application.Driver.AddStr ("<- \"[a\\u301\\u301\\u328]\" using AddRune for each.");
+                                   };
+
+        Application.Run (top);
+        top.Dispose ();
+        Application.Shutdown ();
     }
     }
 }
 }

+ 13 - 7
UICatalog/Scenarios/ComboBoxIteration.cs

@@ -9,18 +9,20 @@ namespace UICatalog.Scenarios;
 [ScenarioCategory ("ComboBox")]
 [ScenarioCategory ("ComboBox")]
 public class ComboBoxIteration : Scenario
 public class ComboBoxIteration : Scenario
 {
 {
-    public override void Setup ()
+    public override void Main ()
     {
     {
+        Application.Init ();
         ObservableCollection<string> items = ["one", "two", "three"];
         ObservableCollection<string> items = ["one", "two", "three"];
 
 
+        var win = new Window { Title = GetQuitKeyAndName () };
         var lbListView = new Label { Width = 10, Height = 1 };
         var lbListView = new Label { Width = 10, Height = 1 };
-        Win.Add (lbListView);
+        win.Add (lbListView);
 
 
         var listview = new ListView
         var listview = new ListView
         {
         {
             Y = Pos.Bottom (lbListView) + 1, Width = 10, Height = Dim.Fill (2), Source = new ListWrapper<string> (items)
             Y = Pos.Bottom (lbListView) + 1, Width = 10, Height = Dim.Fill (2), Source = new ListWrapper<string> (items)
         };
         };
-        Win.Add (listview);
+        win.Add (listview);
 
 
         var lbComboBox = new Label
         var lbComboBox = new Label
         {
         {
@@ -53,8 +55,8 @@ public class ComboBoxIteration : Scenario
                                                 listview.SelectedItem = text.Item;
                                                 listview.SelectedItem = text.Item;
                                             }
                                             }
                                         };
                                         };
-        Win.Add (lbComboBox, comboBox);
-        Win.Add (new TextField { X = Pos.Right (listview) + 1, Y = Pos.Top (comboBox) + 3, Height = 1, Width = 20 });
+        win.Add (lbComboBox, comboBox);
+        win.Add (new TextField { X = Pos.Right (listview) + 1, Y = Pos.Top (comboBox) + 3, Height = 1, Width = 20 });
 
 
         var btnTwo = new Button { X = Pos.Right (comboBox) + 1, Text = "Two" };
         var btnTwo = new Button { X = Pos.Right (comboBox) + 1, Text = "Two" };
 
 
@@ -65,7 +67,7 @@ public class ComboBoxIteration : Scenario
                               listview.SetSource (items);
                               listview.SetSource (items);
                               listview.SelectedItem = 0;
                               listview.SelectedItem = 0;
                           };
                           };
-        Win.Add (btnTwo);
+        win.Add (btnTwo);
 
 
         var btnThree = new Button { X = Pos.Right (comboBox) + 1, Y = Pos.Top (comboBox), Text = "Three" };
         var btnThree = new Button { X = Pos.Right (comboBox) + 1, Y = Pos.Top (comboBox), Text = "Three" };
 
 
@@ -76,6 +78,10 @@ public class ComboBoxIteration : Scenario
                                 listview.SetSource (items);
                                 listview.SetSource (items);
                                 listview.SelectedItem = 0;
                                 listview.SelectedItem = 0;
                             };
                             };
-        Win.Add (btnThree);
+        win.Add (btnThree);
+
+        Application.Run (win);
+        win.Dispose ();
+        Application.Shutdown ();
     }
     }
 }
 }

+ 1 - 1
UICatalog/Scenarios/ComputedLayout.cs

@@ -20,7 +20,7 @@ public class ComputedLayout : Scenario
 
 
         Window app = new ()
         Window app = new ()
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}",
+            Title = GetQuitKeyAndName (),
         };
         };
 
 
         // Demonstrate using Dim to create a horizontal ruler that always measures the parent window's width
         // Demonstrate using Dim to create a horizontal ruler that always measures the parent window's width

+ 1 - 1
UICatalog/Scenarios/ContentScrolling.cs

@@ -104,7 +104,7 @@ public class ContentScrolling : Scenario
 
 
         Window app = new ()
         Window app = new ()
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}",
+            Title = GetQuitKeyAndName (),
 
 
             // Use a different colorscheme so ViewSettings.ClearContentOnly is obvious
             // Use a different colorscheme so ViewSettings.ClearContentOnly is obvious
             ColorScheme = Colors.ColorSchemes ["Toplevel"]
             ColorScheme = Colors.ColorSchemes ["Toplevel"]

+ 1 - 1
UICatalog/Scenarios/ContextMenus.cs

@@ -25,7 +25,7 @@ public class ContextMenus : Scenario
         // Setup - Create a top-level application window and configure it.
         // Setup - Create a top-level application window and configure it.
         Window appWindow = new ()
         Window appWindow = new ()
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}"
+            Title = GetQuitKeyAndName ()
         };
         };
 
 
         var text = "Context Menu";
         var text = "Context Menu";

+ 1 - 1
UICatalog/Scenarios/DatePickers.cs

@@ -13,7 +13,7 @@ public class DatePickers : Scenario
 
 
         Window app = new ()
         Window app = new ()
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}"
+            Title = GetQuitKeyAndName ()
         };
         };
 
 
         var datePicker = new DatePicker { Y = Pos.Center (), X = Pos.Center () };
         var datePicker = new DatePicker { Y = Pos.Center (), X = Pos.Center () };

+ 1 - 1
UICatalog/Scenarios/Dialogs.cs

@@ -17,7 +17,7 @@ public class Dialogs : Scenario
 
 
         Window app = new ()
         Window app = new ()
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}"
+            Title = GetQuitKeyAndName ()
         };
         };
 
 
         var frame = new FrameView
         var frame = new FrameView

+ 1 - 1
UICatalog/Scenarios/DimAutoDemo.cs

@@ -15,7 +15,7 @@ public class DimAutoDemo : Scenario
         // Setup - Create a top-level application window and configure it.
         // Setup - Create a top-level application window and configure it.
         Window appWindow = new ()
         Window appWindow = new ()
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}",
+            Title = GetQuitKeyAndName (),
         };
         };
 
 
         // For diagnostics
         // For diagnostics

+ 1 - 1
UICatalog/Scenarios/DynamicMenuBar.cs

@@ -21,7 +21,7 @@ public class DynamicMenuBar : Scenario
         // Setup - Create a top-level application window and configure it.
         // Setup - Create a top-level application window and configure it.
         DynamicMenuBarSample appWindow = new ()
         DynamicMenuBarSample appWindow = new ()
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}"
+            Title = GetQuitKeyAndName ()
         };
         };
 
 
         // Run - Start the application.
         // Run - Start the application.

+ 1 - 1
UICatalog/Scenarios/DynamicStatusBar.cs

@@ -317,7 +317,7 @@ public class DynamicStatusBar : Scenario
         {
         {
             DataContext = new DynamicStatusItemModel ();
             DataContext = new DynamicStatusItemModel ();
 
 
-            Title = $"{Application.QuitKey} to Quit";
+            Title = $"{Application.QuitKey} to Quit - Scenario: Dynamic StatusBar";
 
 
             var _frmStatusBar = new FrameView
             var _frmStatusBar = new FrameView
             {
             {

+ 1 - 1
UICatalog/Scenarios/Editor.cs

@@ -46,7 +46,7 @@ public class Editor : Scenario
         // Setup - Create a top-level application window and configure it.
         // Setup - Create a top-level application window and configure it.
         _appWindow = new ()
         _appWindow = new ()
         {
         {
-            //Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}",
+            //Title = GetQuitKeyAndName (),
             Title = _fileName ?? "Untitled",
             Title = _fileName ?? "Untitled",
             BorderStyle = LineStyle.None
             BorderStyle = LineStyle.None
         };
         };

+ 36 - 30
UICatalog/Scenarios/FileDialogExamples.cs

@@ -26,104 +26,110 @@ public class FileDialogExamples : Scenario
     private TextField _tbCancelButton;
     private TextField _tbCancelButton;
     private TextField _tbOkButton;
     private TextField _tbOkButton;
 
 
-    public override void Setup ()
+    public override void Main ()
     {
     {
+        Application.Init ();
         var y = 0;
         var y = 0;
         var x = 1;
         var x = 1;
+        var win = new Window { Title = GetQuitKeyAndName () };
 
 
         _cbMustExist = new CheckBox { State = CheckState.Checked, Y = y++, X = x, Text = "Must Exist" };
         _cbMustExist = new CheckBox { State = CheckState.Checked, Y = y++, X = x, Text = "Must Exist" };
-        Win.Add (_cbMustExist);
+        win.Add (_cbMustExist);
 
 
         _cbUseColors = new CheckBox { State = FileDialogStyle.DefaultUseColors ? CheckState.Checked : CheckState.UnChecked, Y = y++, X = x, Text = "Use Colors" };
         _cbUseColors = new CheckBox { State = FileDialogStyle.DefaultUseColors ? CheckState.Checked : CheckState.UnChecked, Y = y++, X = x, Text = "Use Colors" };
-        Win.Add (_cbUseColors);
+        win.Add (_cbUseColors);
 
 
         _cbCaseSensitive = new CheckBox { State = CheckState.UnChecked, Y = y++, X = x, Text = "Case Sensitive Search" };
         _cbCaseSensitive = new CheckBox { State = CheckState.UnChecked, Y = y++, X = x, Text = "Case Sensitive Search" };
-        Win.Add (_cbCaseSensitive);
+        win.Add (_cbCaseSensitive);
 
 
         _cbAllowMultipleSelection = new CheckBox { State = CheckState.UnChecked, Y = y++, X = x, Text = "Multiple" };
         _cbAllowMultipleSelection = new CheckBox { State = CheckState.UnChecked, Y = y++, X = x, Text = "Multiple" };
-        Win.Add (_cbAllowMultipleSelection);
+        win.Add (_cbAllowMultipleSelection);
 
 
         _cbShowTreeBranchLines = new CheckBox { State = CheckState.Checked, Y = y++, X = x, Text = "Tree Branch Lines" };
         _cbShowTreeBranchLines = new CheckBox { State = CheckState.Checked, Y = y++, X = x, Text = "Tree Branch Lines" };
-        Win.Add (_cbShowTreeBranchLines);
+        win.Add (_cbShowTreeBranchLines);
 
 
         _cbAlwaysTableShowHeaders = new CheckBox { State = CheckState.Checked, Y = y++, X = x, Text = "Always Show Headers" };
         _cbAlwaysTableShowHeaders = new CheckBox { State = CheckState.Checked, Y = y++, X = x, Text = "Always Show Headers" };
-        Win.Add (_cbAlwaysTableShowHeaders);
+        win.Add (_cbAlwaysTableShowHeaders);
 
 
         _cbDrivesOnlyInTree = new CheckBox { State = CheckState.UnChecked, Y = y++, X = x, Text = "Only Show Drives" };
         _cbDrivesOnlyInTree = new CheckBox { State = CheckState.UnChecked, Y = y++, X = x, Text = "Only Show Drives" };
-        Win.Add (_cbDrivesOnlyInTree);
+        win.Add (_cbDrivesOnlyInTree);
 
 
         y = 0;
         y = 0;
         x = 24;
         x = 24;
 
 
-        Win.Add (
+        win.Add (
                  new LineView (Orientation.Vertical) { X = x++, Y = 1, Height = 4 }
                  new LineView (Orientation.Vertical) { X = x++, Y = 1, Height = 4 }
                 );
                 );
-        Win.Add (new Label { X = x++, Y = y++, Text = "Caption" });
+        win.Add (new Label { X = x++, Y = y++, Text = "Caption" });
 
 
         _rgCaption = new RadioGroup { X = x, Y = y };
         _rgCaption = new RadioGroup { X = x, Y = y };
         _rgCaption.RadioLabels = new [] { "Ok", "Open", "Save" };
         _rgCaption.RadioLabels = new [] { "Ok", "Open", "Save" };
-        Win.Add (_rgCaption);
+        win.Add (_rgCaption);
 
 
         y = 0;
         y = 0;
         x = 34;
         x = 34;
 
 
-        Win.Add (
+        win.Add (
                  new LineView (Orientation.Vertical) { X = x++, Y = 1, Height = 4 }
                  new LineView (Orientation.Vertical) { X = x++, Y = 1, Height = 4 }
                 );
                 );
-        Win.Add (new Label { X = x++, Y = y++, Text = "OpenMode" });
+        win.Add (new Label { X = x++, Y = y++, Text = "OpenMode" });
 
 
         _rgOpenMode = new RadioGroup { X = x, Y = y };
         _rgOpenMode = new RadioGroup { X = x, Y = y };
         _rgOpenMode.RadioLabels = new [] { "File", "Directory", "Mixed" };
         _rgOpenMode.RadioLabels = new [] { "File", "Directory", "Mixed" };
-        Win.Add (_rgOpenMode);
+        win.Add (_rgOpenMode);
 
 
         y = 0;
         y = 0;
         x = 48;
         x = 48;
 
 
-        Win.Add (
+        win.Add (
                  new LineView (Orientation.Vertical) { X = x++, Y = 1, Height = 4 }
                  new LineView (Orientation.Vertical) { X = x++, Y = 1, Height = 4 }
                 );
                 );
-        Win.Add (new Label { X = x++, Y = y++, Text = "Icons" });
+        win.Add (new Label { X = x++, Y = y++, Text = "Icons" });
 
 
         _rgIcons = new RadioGroup { X = x, Y = y };
         _rgIcons = new RadioGroup { X = x, Y = y };
         _rgIcons.RadioLabels = new [] { "None", "Unicode", "Nerd*" };
         _rgIcons.RadioLabels = new [] { "None", "Unicode", "Nerd*" };
-        Win.Add (_rgIcons);
+        win.Add (_rgIcons);
 
 
-        Win.Add (new Label { Y = Pos.AnchorEnd (2), Text = "* Requires installing Nerd fonts" });
-        Win.Add (new Label { Y = Pos.AnchorEnd (1), Text = "  (see: https://github.com/devblackops/Terminal-Icons)" });
+        win.Add (new Label { Y = Pos.AnchorEnd (2), Text = "* Requires installing Nerd fonts" });
+        win.Add (new Label { Y = Pos.AnchorEnd (1), Text = "  (see: https://github.com/devblackops/Terminal-Icons)" });
 
 
         y = 5;
         y = 5;
         x = 24;
         x = 24;
 
 
-        Win.Add (
+        win.Add (
                  new LineView (Orientation.Vertical) { X = x++, Y = y + 1, Height = 4 }
                  new LineView (Orientation.Vertical) { X = x++, Y = y + 1, Height = 4 }
                 );
                 );
-        Win.Add (new Label { X = x++, Y = y++, Text = "Allowed" });
+        win.Add (new Label { X = x++, Y = y++, Text = "Allowed" });
 
 
         _rgAllowedTypes = new RadioGroup { X = x, Y = y };
         _rgAllowedTypes = new RadioGroup { X = x, Y = y };
         _rgAllowedTypes.RadioLabels = new [] { "Any", "Csv (Recommended)", "Csv (Strict)" };
         _rgAllowedTypes.RadioLabels = new [] { "Any", "Csv (Recommended)", "Csv (Strict)" };
-        Win.Add (_rgAllowedTypes);
+        win.Add (_rgAllowedTypes);
 
 
         y = 5;
         y = 5;
         x = 45;
         x = 45;
 
 
-        Win.Add (
+        win.Add (
                  new LineView (Orientation.Vertical) { X = x++, Y = y + 1, Height = 4 }
                  new LineView (Orientation.Vertical) { X = x++, Y = y + 1, Height = 4 }
                 );
                 );
-        Win.Add (new Label { X = x++, Y = y++, Text = "Buttons" });
+        win.Add (new Label { X = x++, Y = y++, Text = "Buttons" });
 
 
-        Win.Add (new Label { X = x, Y = y++, Text = "Ok Text:" });
+        win.Add (new Label { X = x, Y = y++, Text = "Ok Text:" });
         _tbOkButton = new TextField { X = x, Y = y++, Width = 12 };
         _tbOkButton = new TextField { X = x, Y = y++, Width = 12 };
-        Win.Add (_tbOkButton);
-        Win.Add (new Label { X = x, Y = y++, Text = "Cancel Text:" });
+        win.Add (_tbOkButton);
+        win.Add (new Label { X = x, Y = y++, Text = "Cancel Text:" });
         _tbCancelButton = new TextField { X = x, Y = y++, Width = 12 };
         _tbCancelButton = new TextField { X = x, Y = y++, Width = 12 };
-        Win.Add (_tbCancelButton);
+        win.Add (_tbCancelButton);
         _cbFlipButtonOrder = new CheckBox { X = x, Y = y++, Text = "Flip Order" };
         _cbFlipButtonOrder = new CheckBox { X = x, Y = y++, Text = "Flip Order" };
-        Win.Add (_cbFlipButtonOrder);
+        win.Add (_cbFlipButtonOrder);
 
 
         var btn = new Button { X = 1, Y = 9, Text = "Run Dialog" };
         var btn = new Button { X = 1, Y = 9, Text = "Run Dialog" };
 
 
         SetupHandler (btn);
         SetupHandler (btn);
-        Win.Add (btn);
+        win.Add (btn);
+
+        Application.Run (win);
+        win.Dispose ();
+        Application.Shutdown ();
     }
     }
 
 
     private void ConfirmOverwrite (object sender, FilesSelectedEventArgs e)
     private void ConfirmOverwrite (object sender, FilesSelectedEventArgs e)

+ 1 - 1
UICatalog/Scenarios/Generic.cs

@@ -14,7 +14,7 @@ public sealed class MyScenario : Scenario
         // Setup - Create a top-level application window and configure it.
         // Setup - Create a top-level application window and configure it.
         Window appWindow = new ()
         Window appWindow = new ()
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}",
+            Title = GetQuitKeyAndName (),
         };
         };
 
 
         var button = new Button { X = Pos.Center (), Y = Pos.Center (), Text = "Press me!" };
         var button = new Button { X = Pos.Center (), Y = Pos.Center (), Text = "Press me!" };

+ 1 - 1
UICatalog/Scenarios/HotKeys.cs

@@ -13,7 +13,7 @@ public class HotKeys : Scenario
 
 
         Window app = new ()
         Window app = new ()
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}"
+            Title = GetQuitKeyAndName ()
         };
         };
 
 
         var textViewLabel = new Label { Text = "_TextView:", X = 0, Y = 0 };
         var textViewLabel = new Label { Text = "_TextView:", X = 0, Y = 0 };

+ 58 - 52
UICatalog/Scenarios/Images.cs

@@ -15,14 +15,15 @@ namespace UICatalog.Scenarios;
 [ScenarioCategory ("Drawing")]
 [ScenarioCategory ("Drawing")]
 public class Images : Scenario
 public class Images : Scenario
 {
 {
-    public override void Setup ()
+    public override void Main ()
     {
     {
-        base.Setup ();
+        Application.Init ();
+        var win = new Window { Title = $"{Application.QuitKey} to Quit - Scenario: {GetName()}" };
 
 
         bool canTrueColor = Application.Driver.SupportsTrueColor;
         bool canTrueColor = Application.Driver.SupportsTrueColor;
 
 
         var lblDriverName = new Label { X = 0, Y = 0, Text = $"Driver is {Application.Driver.GetType ().Name}" };
         var lblDriverName = new Label { X = 0, Y = 0, Text = $"Driver is {Application.Driver.GetType ().Name}" };
-        Win.Add (lblDriverName);
+        win.Add (lblDriverName);
 
 
         var cbSupportsTrueColor = new CheckBox
         var cbSupportsTrueColor = new CheckBox
         {
         {
@@ -32,7 +33,7 @@ public class Images : Scenario
             CanFocus = false,
             CanFocus = false,
             Text = "supports true color "
             Text = "supports true color "
         };
         };
-        Win.Add (cbSupportsTrueColor);
+        win.Add (cbSupportsTrueColor);
 
 
         var cbUseTrueColor = new CheckBox
         var cbUseTrueColor = new CheckBox
         {
         {
@@ -43,63 +44,68 @@ public class Images : Scenario
             Text = "Use true color"
             Text = "Use true color"
         };
         };
         cbUseTrueColor.Toggle += (_, evt) => Application.Force16Colors = evt.NewValue == CheckState.UnChecked;
         cbUseTrueColor.Toggle += (_, evt) => Application.Force16Colors = evt.NewValue == CheckState.UnChecked;
-        Win.Add (cbUseTrueColor);
+        win.Add (cbUseTrueColor);
 
 
         var btnOpenImage = new Button { X = Pos.Right (cbUseTrueColor) + 2, Y = 0, Text = "Open Image" };
         var btnOpenImage = new Button { X = Pos.Right (cbUseTrueColor) + 2, Y = 0, Text = "Open Image" };
-        Win.Add (btnOpenImage);
+        win.Add (btnOpenImage);
 
 
         var imageView = new ImageView
         var imageView = new ImageView
         {
         {
             X = 0, Y = Pos.Bottom (lblDriverName), Width = Dim.Fill (), Height = Dim.Fill ()
             X = 0, Y = Pos.Bottom (lblDriverName), Width = Dim.Fill (), Height = Dim.Fill ()
         };
         };
-        Win.Add (imageView);
+        win.Add (imageView);
 
 
         btnOpenImage.Accept += (_, _) =>
         btnOpenImage.Accept += (_, _) =>
-                                {
-                                    var ofd = new OpenDialog { Title = "Open Image", AllowsMultipleSelection = false };
-                                    Application.Run (ofd);
-
-                                    if (ofd.Path is { })
-                                    {
-                                        Directory.SetCurrentDirectory (Path.GetFullPath (Path.GetDirectoryName (ofd.Path)!));
-                                    }
-
-                                    if (ofd.Canceled)
-                                    {
-                                        ofd.Dispose ();
-                                        return;
-                                    }
-
-                                    string path = ofd.FilePaths [0];
-
-                                    ofd.Dispose ();
-
-                                    if (string.IsNullOrWhiteSpace (path))
-                                    {
-                                        return;
-                                    }
-
-                                    if (!File.Exists (path))
-                                    {
-                                        return;
-                                    }
-
-                                    Image<Rgba32> img;
-
-                                    try
-                                    {
-                                        img = Image.Load<Rgba32> (File.ReadAllBytes (path));
-                                    }
-                                    catch (Exception ex)
-                                    {
-                                        MessageBox.ErrorQuery ("Could not open file", ex.Message, "Ok");
-
-                                        return;
-                                    }
-
-                                    imageView.SetImage (img);
-                                    Application.Refresh ();
-                                };
+                               {
+                                   var ofd = new OpenDialog { Title = "Open Image", AllowsMultipleSelection = false };
+                                   Application.Run (ofd);
+
+                                   if (ofd.Path is { })
+                                   {
+                                       Directory.SetCurrentDirectory (Path.GetFullPath (Path.GetDirectoryName (ofd.Path)!));
+                                   }
+
+                                   if (ofd.Canceled)
+                                   {
+                                       ofd.Dispose ();
+
+                                       return;
+                                   }
+
+                                   string path = ofd.FilePaths [0];
+
+                                   ofd.Dispose ();
+
+                                   if (string.IsNullOrWhiteSpace (path))
+                                   {
+                                       return;
+                                   }
+
+                                   if (!File.Exists (path))
+                                   {
+                                       return;
+                                   }
+
+                                   Image<Rgba32> img;
+
+                                   try
+                                   {
+                                       img = Image.Load<Rgba32> (File.ReadAllBytes (path));
+                                   }
+                                   catch (Exception ex)
+                                   {
+                                       MessageBox.ErrorQuery ("Could not open file", ex.Message, "Ok");
+
+                                       return;
+                                   }
+
+                                   imageView.SetImage (img);
+                                   Application.Refresh ();
+                               };
+
+        Application.Run (win);
+        win.Dispose ();
+        Application.Shutdown ();
     }
     }
 
 
     private class ImageView : View
     private class ImageView : View

+ 13 - 4
UICatalog/Scenarios/InvertColors.cs

@@ -10,9 +10,14 @@ namespace UICatalog.Scenarios;
 [ScenarioCategory ("Text and Formatting")]
 [ScenarioCategory ("Text and Formatting")]
 public class InvertColors : Scenario
 public class InvertColors : Scenario
 {
 {
-    public override void Setup ()
+    public override void Main ()
     {
     {
-        Win.ColorScheme = Colors.ColorSchemes ["TopLevel"];
+        Application.Init ();
+        var win = new Window
+        {
+            Title = GetQuitKeyAndName (),
+            ColorScheme = Colors.ColorSchemes ["TopLevel"]
+        };
 
 
         List<Label> labels = new ();
         List<Label> labels = new ();
         ColorName [] foreColors = Enum.GetValues (typeof (ColorName)).Cast<ColorName> ().ToArray ();
         ColorName [] foreColors = Enum.GetValues (typeof (ColorName)).Cast<ColorName> ().ToArray ();
@@ -25,7 +30,7 @@ public class InvertColors : Scenario
 
 
             var label = new Label { ColorScheme = new ColorScheme (), Y = y, Text = $"{fore} on {back}" };
             var label = new Label { ColorScheme = new ColorScheme (), Y = y, Text = $"{fore} on {back}" };
             label.ColorScheme = new ColorScheme (label.ColorScheme) { Normal = color };
             label.ColorScheme = new ColorScheme (label.ColorScheme) { Normal = color };
-            Win.Add (label);
+            win.Add (label);
             labels.Add (label);
             labels.Add (label);
         }
         }
 
 
@@ -43,6 +48,10 @@ public class InvertColors : Scenario
                                   label.SetNeedsDisplay ();
                                   label.SetNeedsDisplay ();
                               }
                               }
                           };
                           };
-        Win.Add (button);
+        win.Add (button);
+
+        Application.Run (win);
+        win.Dispose ();
+        Application.Shutdown ();
     }
     }
 }
 }

+ 1 - 1
UICatalog/Scenarios/KeyBindings.cs

@@ -22,7 +22,7 @@ public sealed class KeyBindings : Scenario
         // Setup - Create a top-level application window and configure it.
         // Setup - Create a top-level application window and configure it.
         Window appWindow = new ()
         Window appWindow = new ()
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}",
+            Title = GetQuitKeyAndName (),
             SuperViewRendersLineCanvas = true,
             SuperViewRendersLineCanvas = true,
         };
         };
 
 

+ 19 - 13
UICatalog/Scenarios/Keys.cs

@@ -7,16 +7,18 @@ namespace UICatalog.Scenarios;
 [ScenarioCategory ("Mouse and Keyboard")]
 [ScenarioCategory ("Mouse and Keyboard")]
 public class Keys : Scenario
 public class Keys : Scenario
 {
 {
-    public override void Setup ()
+    public override void Main ()
     {
     {
+        Application.Init ();
         ObservableCollection<string> keyPressedList = [];
         ObservableCollection<string> keyPressedList = [];
         ObservableCollection<string> invokingKeyBindingsList = new ();
         ObservableCollection<string> invokingKeyBindingsList = new ();
 
 
+        var win = new Window { Title = GetQuitKeyAndName () };
         var editLabel = new Label { X = 0, Y = 0, Text = "Type text here:" };
         var editLabel = new Label { X = 0, Y = 0, Text = "Type text here:" };
-        Win.Add (editLabel);
+        win.Add (editLabel);
 
 
         var edit = new TextField { X = Pos.Right (editLabel) + 1, Y = Pos.Top (editLabel), Width = Dim.Fill (2) };
         var edit = new TextField { X = Pos.Right (editLabel) + 1, Y = Pos.Top (editLabel), Width = Dim.Fill (2) };
-        Win.Add (edit);
+        win.Add (edit);
 
 
         edit.KeyDown += (s, a) => { keyPressedList.Add (a.ToString ()); };
         edit.KeyDown += (s, a) => { keyPressedList.Add (a.ToString ()); };
 
 
@@ -33,9 +35,9 @@ public class Keys : Scenario
         {
         {
             X = Pos.Left (editLabel), Y = Pos.Top (editLabel) + 1, Text = "Last TextView.KeyPressed:"
             X = Pos.Left (editLabel), Y = Pos.Top (editLabel) + 1, Text = "Last TextView.KeyPressed:"
         };
         };
-        Win.Add (keyPressedLabel);
+        win.Add (keyPressedLabel);
         var labelTextViewKeypress = new Label { X = Pos.Right (keyPressedLabel) + 1, Y = Pos.Top (keyPressedLabel) };
         var labelTextViewKeypress = new Label { X = Pos.Right (keyPressedLabel) + 1, Y = Pos.Top (keyPressedLabel) };
-        Win.Add (labelTextViewKeypress);
+        win.Add (labelTextViewKeypress);
 
 
         edit.KeyDown += (s, e) => labelTextViewKeypress.Text = e.ToString ();
         edit.KeyDown += (s, e) => labelTextViewKeypress.Text = e.ToString ();
 
 
@@ -43,9 +45,9 @@ public class Keys : Scenario
         {
         {
             X = Pos.Left (keyPressedLabel), Y = Pos.Bottom (keyPressedLabel), Text = "Last Application.KeyDown:"
             X = Pos.Left (keyPressedLabel), Y = Pos.Bottom (keyPressedLabel), Text = "Last Application.KeyDown:"
         };
         };
-        Win.Add (keyPressedLabel);
+        win.Add (keyPressedLabel);
         var labelAppKeypress = new Label { X = Pos.Right (keyPressedLabel) + 1, Y = Pos.Top (keyPressedLabel) };
         var labelAppKeypress = new Label { X = Pos.Right (keyPressedLabel) + 1, Y = Pos.Top (keyPressedLabel) };
-        Win.Add (labelAppKeypress);
+        win.Add (labelAppKeypress);
 
 
         Application.KeyDown += (s, e) => labelAppKeypress.Text = e.ToString ();
         Application.KeyDown += (s, e) => labelAppKeypress.Text = e.ToString ();
 
 
@@ -54,7 +56,7 @@ public class Keys : Scenario
         {
         {
             X = Pos.Left (editLabel), Y = Pos.Top (editLabel) + 4, Text = "Application Key Events:"
             X = Pos.Left (editLabel), Y = Pos.Top (editLabel) + 4, Text = "Application Key Events:"
         };
         };
-        Win.Add (keyLogLabel);
+        win.Add (keyLogLabel);
         int maxKeyString = Key.CursorRight.WithAlt.WithCtrl.WithShift.ToString ().Length;
         int maxKeyString = Key.CursorRight.WithAlt.WithCtrl.WithShift.ToString ().Length;
         var yOffset = 1;
         var yOffset = 1;
         ObservableCollection<string> keyEventlist = new ();
         ObservableCollection<string> keyEventlist = new ();
@@ -68,14 +70,14 @@ public class Keys : Scenario
             Source = new ListWrapper<string> (keyEventlist)
             Source = new ListWrapper<string> (keyEventlist)
         };
         };
         keyEventListView.ColorScheme = Colors.ColorSchemes ["TopLevel"];
         keyEventListView.ColorScheme = Colors.ColorSchemes ["TopLevel"];
-        Win.Add (keyEventListView);
+        win.Add (keyEventListView);
 
 
         // OnKeyPressed
         // OnKeyPressed
         var onKeyPressedLabel = new Label
         var onKeyPressedLabel = new Label
         {
         {
             X = Pos.Right (keyEventListView) + 1, Y = Pos.Top (editLabel) + 4, Text = "TextView KeyDown:"
             X = Pos.Right (keyEventListView) + 1, Y = Pos.Top (editLabel) + 4, Text = "TextView KeyDown:"
         };
         };
-        Win.Add (onKeyPressedLabel);
+        win.Add (onKeyPressedLabel);
 
 
         yOffset = 1;
         yOffset = 1;
 
 
@@ -88,7 +90,7 @@ public class Keys : Scenario
             Source = new ListWrapper<string> (keyPressedList)
             Source = new ListWrapper<string> (keyPressedList)
         };
         };
         onKeyPressedListView.ColorScheme = Colors.ColorSchemes ["TopLevel"];
         onKeyPressedListView.ColorScheme = Colors.ColorSchemes ["TopLevel"];
-        Win.Add (onKeyPressedListView);
+        win.Add (onKeyPressedListView);
 
 
         // OnInvokeKeyBindings
         // OnInvokeKeyBindings
         var onInvokingKeyBindingsLabel = new Label
         var onInvokingKeyBindingsLabel = new Label
@@ -97,7 +99,7 @@ public class Keys : Scenario
             Y = Pos.Top (editLabel) + 4,
             Y = Pos.Top (editLabel) + 4,
             Text = "TextView InvokingKeyBindings:"
             Text = "TextView InvokingKeyBindings:"
         };
         };
-        Win.Add (onInvokingKeyBindingsLabel);
+        win.Add (onInvokingKeyBindingsLabel);
 
 
         var onInvokingKeyBindingsListView = new ListView
         var onInvokingKeyBindingsListView = new ListView
         {
         {
@@ -108,7 +110,7 @@ public class Keys : Scenario
             Source = new ListWrapper<string> (invokingKeyBindingsList)
             Source = new ListWrapper<string> (invokingKeyBindingsList)
         };
         };
         onInvokingKeyBindingsListView.ColorScheme = Colors.ColorSchemes ["TopLevel"];
         onInvokingKeyBindingsListView.ColorScheme = Colors.ColorSchemes ["TopLevel"];
-        Win.Add (onInvokingKeyBindingsListView);
+        win.Add (onInvokingKeyBindingsListView);
 
 
         //Application.KeyDown += (s, a) => KeyDownPressUp (a, "Down");
         //Application.KeyDown += (s, a) => KeyDownPressUp (a, "Down");
         Application.KeyDown += (s, a) => KeyDownPressUp (a, "Down");
         Application.KeyDown += (s, a) => KeyDownPressUp (a, "Down");
@@ -123,5 +125,9 @@ public class Keys : Scenario
             onKeyPressedListView.MoveDown ();
             onKeyPressedListView.MoveDown ();
             onInvokingKeyBindingsListView.MoveDown ();
             onInvokingKeyBindingsListView.MoveDown ();
         }
         }
+
+        Application.Run (win);
+        win.Dispose ();
+        Application.Shutdown ();
     }
     }
 }
 }

+ 1 - 1
UICatalog/Scenarios/LineCanvasExperiment.cs

@@ -14,7 +14,7 @@ public class LineCanvasExperiment : Scenario
 
 
         Window app = new ()
         Window app = new ()
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}"
+            Title = GetQuitKeyAndName ()
         };
         };
 
 
         var frame1 = new FrameView
         var frame1 = new FrameView

+ 10 - 4
UICatalog/Scenarios/LineDrawing.cs

@@ -10,8 +10,10 @@ namespace UICatalog.Scenarios;
 [ScenarioCategory ("Drawing")]
 [ScenarioCategory ("Drawing")]
 public class LineDrawing : Scenario
 public class LineDrawing : Scenario
 {
 {
-    public override void Setup ()
+    public override void Main ()
     {
     {
+        Application.Init ();
+        var win = new Window { Title = GetQuitKeyAndName () };
         var canvas = new DrawingArea { X = 0, Y = 0, Width = Dim.Fill (), Height = Dim.Fill () };
         var canvas = new DrawingArea { X = 0, Y = 0, Width = Dim.Fill (), Height = Dim.Fill () };
 
 
         var tools = new ToolsView { Title = "Tools", X = Pos.Right (canvas) - 20, Y = 2 };
         var tools = new ToolsView { Title = "Tools", X = Pos.Right (canvas) - 20, Y = 2 };
@@ -20,10 +22,14 @@ public class LineDrawing : Scenario
         tools.SetStyle += b => canvas.LineStyle = b;
         tools.SetStyle += b => canvas.LineStyle = b;
         tools.AddLayer += () => canvas.AddLayer ();
         tools.AddLayer += () => canvas.AddLayer ();
 
 
-        Win.Add (canvas);
-        Win.Add (tools);
+        win.Add (canvas);
+        win.Add (tools);
 
 
-        Win.KeyDown += (s, e) => { e.Handled = canvas.OnKeyDown (e); };
+        win.KeyDown += (s, e) => { e.Handled = canvas.OnKeyDown (e); };
+
+        Application.Run (win);
+        win.Dispose ();
+        Application.Shutdown ();
     }
     }
 
 
     private class DrawingArea : View
     private class DrawingArea : View

+ 7 - 5
UICatalog/Scenarios/LineViewExample.cs

@@ -13,7 +13,7 @@ public class LineViewExample : Scenario
     {
     {
         Application.Init ();
         Application.Init ();
         // Setup - Create a top-level application window and configure it.
         // Setup - Create a top-level application window and configure it.
-        Toplevel appWindow = new ();
+        Toplevel top = new ();
 
 
         var menu = new MenuBar
         var menu = new MenuBar
         {
         {
@@ -22,8 +22,9 @@ public class LineViewExample : Scenario
                 new ("_File", new MenuItem [] { new ("_Quit", "", () => Quit ()) })
                 new ("_File", new MenuItem [] { new ("_Quit", "", () => Quit ()) })
             ]
             ]
         };
         };
-        appWindow.Add (menu);
+        top.Add (menu);
 
 
+        var appWindow = new Window ();
         appWindow.Add (new Label { Y = 1, Text = "Regular Line" });
         appWindow.Add (new Label { Y = 1, Text = "Regular Line" });
 
 
         // creates a horizontal line
         // creates a horizontal line
@@ -78,11 +79,12 @@ public class LineViewExample : Scenario
                                            new (Application.QuitKey, "Quit", Quit)
                                            new (Application.QuitKey, "Quit", Quit)
                                        }
                                        }
                                       );
                                       );
-        appWindow.Add (statusBar);
+        top.Add (statusBar);
+        top.Add (appWindow);
 
 
         // Run - Start the application.
         // Run - Start the application.
-        Application.Run (appWindow);
-        appWindow.Dispose ();
+        Application.Run (top);
+        top.Dispose ();
 
 
         // Shutdown - Calling Application.Shutdown is required.
         // Shutdown - Calling Application.Shutdown is required.
         Application.Shutdown ();
         Application.Shutdown ();

+ 10 - 9
UICatalog/Scenarios/ListColumns.cs

@@ -53,17 +53,16 @@ public class ListColumns : Scenario
         Application.Init ();
         Application.Init ();
 
 
         // Setup - Create a top-level application window and configure it.
         // Setup - Create a top-level application window and configure it.
-        Toplevel appWindow = new ()
+        Toplevel top = new ();
+        Window appWindow = new ()
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}"
+            Title = GetQuitKeyAndName ()
         };
         };
 
 
         _listColView = new ()
         _listColView = new ()
         {
         {
-            X = 0,
-            Y = 1,
             Width = Dim.Fill (),
             Width = Dim.Fill (),
-            Height = Dim.Fill (1),
+            Height = Dim.Fill (),
             Style = new ()
             Style = new ()
             {
             {
                 ShowHeaders = false,
                 ShowHeaders = false,
@@ -212,7 +211,7 @@ public class ListColumns : Scenario
             ]
             ]
         };
         };
 
 
-        appWindow.Add (menu);
+        top.Add (menu);
 
 
         var statusBar = new StatusBar (
         var statusBar = new StatusBar (
                                        new Shortcut []
                                        new Shortcut []
@@ -223,7 +222,7 @@ public class ListColumns : Scenario
                                            new (Application.QuitKey, "Quit", Quit)
                                            new (Application.QuitKey, "Quit", Quit)
                                        }
                                        }
                                       );
                                       );
-        appWindow.Add (statusBar);
+        top.Add (statusBar);
 
 
         appWindow.Add (_listColView);
         appWindow.Add (_listColView);
 
 
@@ -257,9 +256,11 @@ public class ListColumns : Scenario
 
 
         _listColView.KeyBindings.Add (Key.Space, Command.Accept);
         _listColView.KeyBindings.Add (Key.Space, Command.Accept);
 
 
+        top.Add (appWindow);
+
         // Run - Start the application.
         // Run - Start the application.
-        Application.Run (appWindow);
-        appWindow.Dispose ();
+        Application.Run (top);
+        top.Dispose ();
 
 
         // Shutdown - Calling Application.Shutdown is required.
         // Shutdown - Calling Application.Shutdown is required.
         Application.Shutdown ();
         Application.Shutdown ();

+ 1 - 1
UICatalog/Scenarios/ListViewWithSelection.cs

@@ -27,7 +27,7 @@ public class ListViewWithSelection : Scenario
 
 
         _appWindow = new ()
         _appWindow = new ()
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}",
+            Title = GetQuitKeyAndName (),
         };
         };
 
 
         _scenarios = GetScenarios ();
         _scenarios = GetScenarios ();

+ 10 - 4
UICatalog/Scenarios/ListsAndCombos.cs

@@ -12,8 +12,9 @@ namespace UICatalog.Scenarios;
 [ScenarioCategory ("ComboBox")]
 [ScenarioCategory ("ComboBox")]
 public class ListsAndCombos : Scenario
 public class ListsAndCombos : Scenario
 {
 {
-    public override void Setup ()
+    public override void Main ()
     {
     {
+        Application.Init ();
         //TODO: Duplicated code in Demo.cs Consider moving to shared assembly
         //TODO: Duplicated code in Demo.cs Consider moving to shared assembly
         ObservableCollection<string> items = [];
         ObservableCollection<string> items = [];
 
 
@@ -31,6 +32,7 @@ public class ListsAndCombos : Scenario
             }
             }
         }
         }
 
 
+        var win = new Window { Title = GetQuitKeyAndName () };
         // ListView
         // ListView
         var lbListView = new Label
         var lbListView = new Label
         {
         {
@@ -50,7 +52,7 @@ public class ListsAndCombos : Scenario
             Source = new ListWrapper<string> (items)
             Source = new ListWrapper<string> (items)
         };
         };
         listview.SelectedItemChanged += (s, e) => lbListView.Text = items [listview.SelectedItem];
         listview.SelectedItemChanged += (s, e) => lbListView.Text = items [listview.SelectedItem];
-        Win.Add (lbListView, listview);
+        win.Add (lbListView, listview);
 
 
         var scrollBar = new ScrollBarView (listview, true);
         var scrollBar = new ScrollBarView (listview, true);
 
 
@@ -107,7 +109,7 @@ public class ListsAndCombos : Scenario
         comboBox.SetSource (items);
         comboBox.SetSource (items);
 
 
         comboBox.SelectedItemChanged += (s, text) => lbComboBox.Text = text.Value.ToString ();
         comboBox.SelectedItemChanged += (s, text) => lbComboBox.Text = text.Value.ToString ();
-        Win.Add (lbComboBox, comboBox);
+        win.Add (lbComboBox, comboBox);
 
 
         var scrollBarCbx = new ScrollBarView (comboBox.Subviews [1], true);
         var scrollBarCbx = new ScrollBarView (comboBox.Subviews [1], true);
 
 
@@ -153,6 +155,10 @@ public class ListsAndCombos : Scenario
         };
         };
         btnMoveDown.Accept += (s, e) => { listview.MoveDown (); };
         btnMoveDown.Accept += (s, e) => { listview.MoveDown (); };
 
 
-        Win.Add (btnMoveUp, btnMoveDown);
+        win.Add (btnMoveUp, btnMoveDown);
+
+        Application.Run (win);
+        win.Dispose ();
+        Application.Shutdown ();
     }
     }
 }
 }

+ 20 - 13
UICatalog/Scenarios/Localization.cs

@@ -41,9 +41,11 @@ public class Localization : Scenario
         Application.Refresh ();
         Application.Refresh ();
     }
     }
 
 
-    public override void Setup ()
+    public override void Main ()
     {
     {
-        base.Setup ();
+        Application.Init ();
+        var top = new Toplevel ();
+        var win = new Window { Title = GetQuitKeyAndName () };
         _cultureInfoSource = Application.SupportedCultures.Append (CultureInfo.InvariantCulture).ToArray ();
         _cultureInfoSource = Application.SupportedCultures.Append (CultureInfo.InvariantCulture).ToArray ();
 
 
         _cultureInfoNameSource = Application.SupportedCultures.Select (c => $"{c.NativeName} ({c.Name})")
         _cultureInfoNameSource = Application.SupportedCultures.Select (c => $"{c.NativeName} ({c.Name})")
@@ -93,7 +95,7 @@ public class Localization : Scenario
                     )
                     )
             ]
             ]
         };
         };
-        Top.Add (menu);
+        top.Add (menu);
 
 
         var selectLanguageLabel = new Label
         var selectLanguageLabel = new Label
         {
         {
@@ -103,7 +105,7 @@ public class Localization : Scenario
             Width = Dim.Fill (2),
             Width = Dim.Fill (2),
             Text = "Please select a language."
             Text = "Please select a language."
         };
         };
-        Win.Add (selectLanguageLabel);
+        win.Add (selectLanguageLabel);
 
 
         _languageComboBox = new()
         _languageComboBox = new()
         {
         {
@@ -117,7 +119,7 @@ public class Localization : Scenario
         };
         };
         _languageComboBox.SetSource<string> (new (_cultureInfoNameSource));
         _languageComboBox.SetSource<string> (new (_cultureInfoNameSource));
         _languageComboBox.SelectedItemChanged += LanguageComboBox_SelectChanged;
         _languageComboBox.SelectedItemChanged += LanguageComboBox_SelectChanged;
-        Win.Add (_languageComboBox);
+        win.Add (_languageComboBox);
 
 
         var textAndFileDialogLabel = new Label
         var textAndFileDialogLabel = new Label
         {
         {
@@ -129,13 +131,13 @@ public class Localization : Scenario
             Text =
             Text =
                 "Right click on the text field to open a context menu, click the button to open a file dialog.\r\nOpen mode will loop through 'File', 'Directory' and 'Mixed' as 'Open' or 'Save' button clicked."
                 "Right click on the text field to open a context menu, click the button to open a file dialog.\r\nOpen mode will loop through 'File', 'Directory' and 'Mixed' as 'Open' or 'Save' button clicked."
         };
         };
-        Win.Add (textAndFileDialogLabel);
+        win.Add (textAndFileDialogLabel);
 
 
         var textField = new TextView
         var textField = new TextView
         {
         {
             X = 2, Y = Pos.Bottom (textAndFileDialogLabel) + 1, Width = Dim.Fill (32), Height = 1
             X = 2, Y = Pos.Bottom (textAndFileDialogLabel) + 1, Width = Dim.Fill (32), Height = 1
         };
         };
-        Win.Add (textField);
+        win.Add (textField);
 
 
         _allowAnyCheckBox = new()
         _allowAnyCheckBox = new()
         {
         {
@@ -144,21 +146,21 @@ public class Localization : Scenario
             State = CheckState.UnChecked,
             State = CheckState.UnChecked,
             Text = "Allow any"
             Text = "Allow any"
         };
         };
-        Win.Add (_allowAnyCheckBox);
+        win.Add (_allowAnyCheckBox);
 
 
         var openDialogButton = new Button
         var openDialogButton = new Button
         {
         {
             X = Pos.Right (_allowAnyCheckBox) + 1, Y = Pos.Bottom (textAndFileDialogLabel) + 1, Text = "Open"
             X = Pos.Right (_allowAnyCheckBox) + 1, Y = Pos.Bottom (textAndFileDialogLabel) + 1, Text = "Open"
         };
         };
         openDialogButton.Accept += (sender, e) => ShowFileDialog (false);
         openDialogButton.Accept += (sender, e) => ShowFileDialog (false);
-        Win.Add (openDialogButton);
+        win.Add (openDialogButton);
 
 
         var saveDialogButton = new Button
         var saveDialogButton = new Button
         {
         {
             X = Pos.Right (openDialogButton) + 1, Y = Pos.Bottom (textAndFileDialogLabel) + 1, Text = "Save"
             X = Pos.Right (openDialogButton) + 1, Y = Pos.Bottom (textAndFileDialogLabel) + 1, Text = "Save"
         };
         };
         saveDialogButton.Accept += (sender, e) => ShowFileDialog (true);
         saveDialogButton.Accept += (sender, e) => ShowFileDialog (true);
-        Win.Add (saveDialogButton);
+        win.Add (saveDialogButton);
 
 
         var wizardLabel = new Label
         var wizardLabel = new Label
         {
         {
@@ -168,13 +170,18 @@ public class Localization : Scenario
             Width = Dim.Fill (2),
             Width = Dim.Fill (2),
             Text = "Click the button to open a wizard."
             Text = "Click the button to open a wizard."
         };
         };
-        Win.Add (wizardLabel);
+        win.Add (wizardLabel);
 
 
         var wizardButton = new Button { X = 2, Y = Pos.Bottom (wizardLabel) + 1, Text = "Open _wizard" };
         var wizardButton = new Button { X = 2, Y = Pos.Bottom (wizardLabel) + 1, Text = "Open _wizard" };
         wizardButton.Accept += (sender, e) => ShowWizard ();
         wizardButton.Accept += (sender, e) => ShowWizard ();
-        Win.Add (wizardButton);
+        win.Add (wizardButton);
 
 
-        Win.Unloaded += (sender, e) => Quit ();
+        win.Unloaded += (sender, e) => Quit ();
+        top.Add (win);
+
+        Application.Run (top);
+        top.Dispose ();
+        Application.Shutdown ();
     }
     }
 
 
     public void ShowFileDialog (bool isSaveFile)
     public void ShowFileDialog (bool isSaveFile)

+ 1 - 1
UICatalog/Scenarios/MenuBarScenario.cs

@@ -22,7 +22,7 @@ public class MenuBarScenario : Scenario
         // Setup - Create a top-level application window and configure it.
         // Setup - Create a top-level application window and configure it.
         Window appWindow = new ()
         Window appWindow = new ()
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}",
+            Title = GetQuitKeyAndName (),
             BorderStyle = LineStyle.None
             BorderStyle = LineStyle.None
         };
         };
 
 

+ 1 - 1
UICatalog/Scenarios/MessageBoxes.cs

@@ -15,7 +15,7 @@ public class MessageBoxes : Scenario
 
 
         Window app = new ()
         Window app = new ()
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}"
+            Title = GetQuitKeyAndName ()
         };
         };
 
 
         var frame = new FrameView
         var frame = new FrameView

+ 1 - 1
UICatalog/Scenarios/Mouse.cs

@@ -15,7 +15,7 @@ public class Mouse : Scenario
 
 
         Window win = new ()
         Window win = new ()
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}"
+            Title = GetQuitKeyAndName ()
         };
         };
 
 
         Slider<MouseFlags> filterSlider = new ()
         Slider<MouseFlags> filterSlider = new ()

+ 1 - 1
UICatalog/Scenarios/MultiColouredTable.cs

@@ -22,7 +22,7 @@ public class MultiColouredTable : Scenario
         // Setup - Create a top-level application window and configure it.
         // Setup - Create a top-level application window and configure it.
         Toplevel appWindow = new ()
         Toplevel appWindow = new ()
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}"
+            Title = GetQuitKeyAndName ()
         };
         };
 
 
         _tableView = new () { X = 0, Y = 1, Width = Dim.Fill (), Height = Dim.Fill (1) };
         _tableView = new () { X = 0, Y = 1, Width = Dim.Fill (), Height = Dim.Fill (1) };

+ 13 - 5
UICatalog/Scenarios/ProcessTable.cs

@@ -11,11 +11,15 @@ public class ProcessTable : Scenario
 {
 {
     private TableView tableView;
     private TableView tableView;
 
 
-    public override void Setup ()
+    public override void Main ()
     {
     {
-        Win.Title = GetName ();
-        Win.Y = 1; // menu
-        Win.Height = Dim.Fill (1); // status bar
+        Application.Init ();
+        var win = new Window
+        {
+            Title = GetName (),
+            Y = 1, // menu
+            Height = Dim.Fill (1) // status bar
+        };
 
 
         tableView = new TableView { X = 0, Y = 0, Width = Dim.Fill (), Height = Dim.Fill (1) };
         tableView = new TableView { X = 0, Y = 0, Width = Dim.Fill (), Height = Dim.Fill (1) };
 
 
@@ -33,7 +37,11 @@ public class ProcessTable : Scenario
                                 }
                                 }
                                );
                                );
 
 
-        Win.Add (tableView);
+        win.Add (tableView);
+
+        Application.Run (win);
+        win.Dispose ();
+        Application.Shutdown ();
     }
     }
 
 
     private void CreateProcessTable ()
     private void CreateProcessTable ()

+ 12 - 5
UICatalog/Scenarios/Progress.cs

@@ -15,13 +15,16 @@ namespace UICatalog.Scenarios;
 [ScenarioCategory ("Progress")]
 [ScenarioCategory ("Progress")]
 public class Progress : Scenario
 public class Progress : Scenario
 {
 {
+    private Window win;
     private uint _mainLooopTimeoutTick = 100; // ms
     private uint _mainLooopTimeoutTick = 100; // ms
     private object _mainLoopTimeout;
     private object _mainLoopTimeout;
     private Timer _systemTimer;
     private Timer _systemTimer;
     private uint _systemTimerTick = 100; // ms
     private uint _systemTimerTick = 100; // ms
 
 
-    public override void Setup ()
+    public override void Main ()
     {
     {
+        Application.Init ();
+        win = new Window { Title = GetQuitKeyAndName () };
         // Demo #1 - Use System.Timer (and threading)
         // Demo #1 - Use System.Timer (and threading)
         var systemTimerDemo = new ProgressDemo
         var systemTimerDemo = new ProgressDemo
         {
         {
@@ -78,7 +81,7 @@ public class Progress : Scenario
                                                      Debug.WriteLine ("bad entry");
                                                      Debug.WriteLine ("bad entry");
                                                  }
                                                  }
                                              };
                                              };
-        Win.Add (systemTimerDemo);
+        win.Add (systemTimerDemo);
 
 
         // Demo #2 - Use Application.AddTimeout (no threads)
         // Demo #2 - Use Application.AddTimeout (no threads)
         var mainLoopTimeoutDemo = new ProgressDemo
         var mainLoopTimeoutDemo = new ProgressDemo
@@ -135,7 +138,7 @@ public class Progress : Scenario
                                                          }
                                                          }
                                                      }
                                                      }
                                                  };
                                                  };
-        Win.Add (mainLoopTimeoutDemo);
+        win.Add (mainLoopTimeoutDemo);
 
 
         var startBoth = new Button { X = Pos.Center (), Y = Pos.Bottom (mainLoopTimeoutDemo) + 1, Text = "Start Both" };
         var startBoth = new Button { X = Pos.Center (), Y = Pos.Bottom (mainLoopTimeoutDemo) + 1, Text = "Start Both" };
 
 
@@ -144,12 +147,16 @@ public class Progress : Scenario
                                  systemTimerDemo.Start ();
                                  systemTimerDemo.Start ();
                                  mainLoopTimeoutDemo.Start ();
                                  mainLoopTimeoutDemo.Start ();
                              };
                              };
-        Win.Add (startBoth);
+        win.Add (startBoth);
+
+        Application.Run (win);
+        win.Dispose ();
+        Application.Shutdown ();
     }
     }
 
 
     protected override void Dispose (bool disposing)
     protected override void Dispose (bool disposing)
     {
     {
-        foreach (ProgressDemo v in Win.Subviews.OfType<ProgressDemo> ())
+        foreach (ProgressDemo v in win.Subviews.OfType<ProgressDemo> ())
         {
         {
             v?.StopBtnClick ();
             v?.StopBtnClick ();
         }
         }

+ 1 - 1
UICatalog/Scenarios/ProgressBarStyles.cs

@@ -30,7 +30,7 @@ public class ProgressBarStyles : Scenario
 
 
         Window app = new ()
         Window app = new ()
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}", BorderStyle = LineStyle.Single,
+            Title = GetQuitKeyAndName (), BorderStyle = LineStyle.Single,
         };
         };
 
 
         var editor = new AdornmentsEditor ()
         var editor = new AdornmentsEditor ()

+ 1 - 1
UICatalog/Scenarios/Scrolling.cs

@@ -19,7 +19,7 @@ public class Scrolling : Scenario
 
 
         var app = new Window
         var app = new Window
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}",
+            Title = GetQuitKeyAndName (),
 
 
             // Offset to stress clipping
             // Offset to stress clipping
             X = 3,
             X = 3,

+ 18 - 12
UICatalog/Scenarios/SendKeys.cs

@@ -7,28 +7,30 @@ namespace UICatalog.Scenarios;
 [ScenarioCategory ("Mouse and Keyboard")]
 [ScenarioCategory ("Mouse and Keyboard")]
 public class SendKeys : Scenario
 public class SendKeys : Scenario
 {
 {
-    public override void Setup ()
+    public override void Main ()
     {
     {
+        Application.Init ();
+        var win = new Window { Title = GetQuitKeyAndName () };
         var label = new Label { X = Pos.Center (), Y = Pos.Center () - 6, Text = "Insert the text to send:" };
         var label = new Label { X = Pos.Center (), Y = Pos.Center () - 6, Text = "Insert the text to send:" };
-        Win.Add (label);
+        win.Add (label);
 
 
         var txtInput = new TextField { X = Pos.Center (), Y = Pos.Center () - 5, Width = 20, Text = "MockKeyPresses" };
         var txtInput = new TextField { X = Pos.Center (), Y = Pos.Center () - 5, Width = 20, Text = "MockKeyPresses" };
-        Win.Add (txtInput);
+        win.Add (txtInput);
 
 
         var ckbShift = new CheckBox { X = Pos.Center (), Y = Pos.Center () - 4, Text = "Shift" };
         var ckbShift = new CheckBox { X = Pos.Center (), Y = Pos.Center () - 4, Text = "Shift" };
-        Win.Add (ckbShift);
+        win.Add (ckbShift);
 
 
         var ckbAlt = new CheckBox { X = Pos.Center (), Y = Pos.Center () - 3, Text = "Alt" };
         var ckbAlt = new CheckBox { X = Pos.Center (), Y = Pos.Center () - 3, Text = "Alt" };
-        Win.Add (ckbAlt);
+        win.Add (ckbAlt);
 
 
         var ckbControl = new CheckBox { X = Pos.Center (), Y = Pos.Center () - 2, Text = "Control" };
         var ckbControl = new CheckBox { X = Pos.Center (), Y = Pos.Center () - 2, Text = "Control" };
-        Win.Add (ckbControl);
+        win.Add (ckbControl);
 
 
         label = new Label { X = Pos.Center (), Y = Pos.Center () + 1, Text = "Result keys:" };
         label = new Label { X = Pos.Center (), Y = Pos.Center () + 1, Text = "Result keys:" };
-        Win.Add (label);
+        win.Add (label);
 
 
         var txtResult = new TextField { X = Pos.Center (), Y = Pos.Center () + 2, Width = 20 };
         var txtResult = new TextField { X = Pos.Center (), Y = Pos.Center () + 2, Width = 20 };
-        Win.Add (txtResult);
+        win.Add (txtResult);
 
 
         var rKeys = "";
         var rKeys = "";
         var rControlKeys = "";
         var rControlKeys = "";
@@ -60,13 +62,13 @@ public class SendKeys : Scenario
                              };
                              };
 
 
         var lblShippedKeys = new Label { X = Pos.Center (), Y = Pos.Center () + 3 };
         var lblShippedKeys = new Label { X = Pos.Center (), Y = Pos.Center () + 3 };
-        Win.Add (lblShippedKeys);
+        win.Add (lblShippedKeys);
 
 
         var lblShippedControlKeys = new Label { X = Pos.Center (), Y = Pos.Center () + 5 };
         var lblShippedControlKeys = new Label { X = Pos.Center (), Y = Pos.Center () + 5 };
-        Win.Add (lblShippedControlKeys);
+        win.Add (lblShippedControlKeys);
 
 
         var button = new Button { X = Pos.Center (), Y = Pos.Center () + 7, IsDefault = true, Text = "Process keys" };
         var button = new Button { X = Pos.Center (), Y = Pos.Center () + 7, IsDefault = true, Text = "Process keys" };
-        Win.Add (button);
+        win.Add (button);
 
 
         void ProcessInput ()
         void ProcessInput ()
         {
         {
@@ -100,7 +102,7 @@ public class SendKeys : Scenario
 
 
         button.Accept += (s, e) => ProcessInput ();
         button.Accept += (s, e) => ProcessInput ();
 
 
-        Win.KeyDown += (s, e) =>
+        win.KeyDown += (s, e) =>
                        {
                        {
                            if (e.KeyCode == KeyCode.Enter)
                            if (e.KeyCode == KeyCode.Enter)
                            {
                            {
@@ -108,5 +110,9 @@ public class SendKeys : Scenario
                                e.Handled = true;
                                e.Handled = true;
                            }
                            }
                        };
                        };
+
+        Application.Run (win);
+        win.Dispose ();
+        Application.Shutdown ();
     }
     }
 }
 }

+ 1 - 1
UICatalog/Scenarios/ShadowStyles.cs

@@ -17,7 +17,7 @@ public class ShadowStyles : Scenario
 
 
         Window app = new ()
         Window app = new ()
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}"
+            Title = GetQuitKeyAndName ()
         };
         };
 
 
 
 

+ 1 - 1
UICatalog/Scenarios/Shortcuts.cs

@@ -31,7 +31,7 @@ public class Shortcuts : Scenario
     private void App_Loaded (object sender, EventArgs e)
     private void App_Loaded (object sender, EventArgs e)
     {
     {
         Application.QuitKey = Key.Z.WithCtrl;
         Application.QuitKey = Key.Z.WithCtrl;
-        Application.Top.Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}";
+        Application.Top.Title = GetQuitKeyAndName ();
 
 
         ObservableCollection<string> eventSource = new ();
         ObservableCollection<string> eventSource = new ();
 
 

+ 1 - 1
UICatalog/Scenarios/Sliders.cs

@@ -129,7 +129,7 @@ public class Sliders : Scenario
 
 
         Window app = new ()
         Window app = new ()
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}"
+            Title = GetQuitKeyAndName ()
         };
         };
 
 
         MakeSliders (
         MakeSliders (

+ 8 - 3
UICatalog/Scenarios/Snake.cs

@@ -15,9 +15,10 @@ public class Snake : Scenario
 {
 {
     private bool isDisposed;
     private bool isDisposed;
 
 
-    public override void Setup ()
+    public override void Main ()
     {
     {
-        base.Setup ();
+        Application.Init ();
+        var win = new Window { Title = GetQuitKeyAndName () };
 
 
         var state = new SnakeState ();
         var state = new SnakeState ();
 
 
@@ -25,7 +26,7 @@ public class Snake : Scenario
 
 
         var snakeView = new SnakeView (state) { Width = state.Width, Height = state.Height };
         var snakeView = new SnakeView (state) { Width = state.Width, Height = state.Height };
 
 
-        Win.Add (snakeView);
+        win.Add (snakeView);
 
 
         var sw = new Stopwatch ();
         var sw = new Stopwatch ();
 
 
@@ -51,6 +52,10 @@ public class Snake : Scenario
                       }
                       }
                   }
                   }
                  );
                  );
+
+        Application.Run (win);
+        win.Dispose ();
+        Application.Shutdown ();
     }
     }
 
 
     protected override void Dispose (bool disposing)
     protected override void Dispose (bool disposing)

+ 1 - 1
UICatalog/Scenarios/SpinnerStyles.cs

@@ -18,7 +18,7 @@ public class SpinnerViewStyles : Scenario
 
 
         Window app = new ()
         Window app = new ()
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}"
+            Title = GetQuitKeyAndName ()
         };
         };
 
 
         const int DEFAULT_DELAY = 130;
         const int DEFAULT_DELAY = 130;

+ 33 - 27
UICatalog/Scenarios/Text.cs

@@ -17,11 +17,13 @@ public class Text : Scenario
     private Label _labelMirroringTimeField;
     private Label _labelMirroringTimeField;
     private TimeField _timeField;
     private TimeField _timeField;
 
 
-    public override void Setup ()
+    public override void Main ()
     {
     {
+        Application.Init ();
+        var win = new Window { Title = GetQuitKeyAndName () };
         // TextField is a simple, single-line text input control
         // TextField is a simple, single-line text input control
         var label = new Label { Text = "_TextField:" };
         var label = new Label { Text = "_TextField:" };
-        Win.Add (label);
+        win.Add (label);
 
 
         var textField = new TextField
         var textField = new TextField
         {
         {
@@ -43,7 +45,7 @@ public class Text : Scenario
                                                       .ToList ();
                                                       .ToList ();
         }
         }
 
 
-        Win.Add (textField);
+        win.Add (textField);
 
 
         var labelMirroringTextField = new Label
         var labelMirroringTextField = new Label
         {
         {
@@ -54,12 +56,12 @@ public class Text : Scenario
             Height = 1,
             Height = 1,
             Text = textField.Text
             Text = textField.Text
         };
         };
-        Win.Add (labelMirroringTextField);
+        win.Add (labelMirroringTextField);
         textField.TextChanged += (s, prev) => { labelMirroringTextField.Text = textField.Text; };
         textField.TextChanged += (s, prev) => { labelMirroringTextField.Text = textField.Text; };
 
 
         // TextView is a rich (as in functionality, not formatting) text editing control
         // TextView is a rich (as in functionality, not formatting) text editing control
         label = new() { Text = "T_extView:", Y = Pos.Bottom (label) + 1 };
         label = new() { Text = "T_extView:", Y = Pos.Bottom (label) + 1 };
-        Win.Add (label);
+        win.Add (label);
 
 
         var textView = new TextView
         var textView = new TextView
         {
         {
@@ -80,7 +82,7 @@ public class Text : Scenario
                                                       .ToList ();
                                                       .ToList ();
         }
         }
 
 
-        Win.Add (textView);
+        win.Add (textView);
 
 
         var labelMirroringTextView = new Label
         var labelMirroringTextView = new Label
         {
         {
@@ -90,7 +92,7 @@ public class Text : Scenario
             Width = Dim.Fill (1) - 1,
             Width = Dim.Fill (1) - 1,
             Height = Dim.Height (textView) - 1
             Height = Dim.Height (textView) - 1
         };
         };
-        Win.Add (labelMirroringTextView);
+        win.Add (labelMirroringTextView);
 
 
         // Use ContentChanged to detect if the user has typed something in a TextView.
         // Use ContentChanged to detect if the user has typed something in a TextView.
         // The TextChanged property is only fired if the TextView.Text property is
         // The TextChanged property is only fired if the TextView.Text property is
@@ -107,7 +109,7 @@ public class Text : Scenario
         {
         {
             X = Pos.Left (textView), Y = Pos.Bottom (textView), State = textView.Multiline ? CheckState.Checked : CheckState.UnChecked, Text = "_Multiline"
             X = Pos.Left (textView), Y = Pos.Bottom (textView), State = textView.Multiline ? CheckState.Checked : CheckState.UnChecked, Text = "_Multiline"
         };
         };
-        Win.Add (chxMultiline);
+        win.Add (chxMultiline);
 
 
         var chxWordWrap = new CheckBox
         var chxWordWrap = new CheckBox
         {
         {
@@ -117,7 +119,7 @@ public class Text : Scenario
             Text = "_Word Wrap"
             Text = "_Word Wrap"
         };
         };
         chxWordWrap.Toggle += (s, e) => textView.WordWrap = e.NewValue == CheckState.Checked;
         chxWordWrap.Toggle += (s, e) => textView.WordWrap = e.NewValue == CheckState.Checked;
-        Win.Add (chxWordWrap);
+        win.Add (chxWordWrap);
 
 
         // TextView captures Tabs (so users can enter /t into text) by default;
         // TextView captures Tabs (so users can enter /t into text) by default;
         // This means using Tab to navigate doesn't work by default. This shows
         // This means using Tab to navigate doesn't work by default. This shows
@@ -163,11 +165,11 @@ public class Text : Scenario
 
 
                                       textView.AllowsTab = e.NewValue == CheckState.Checked;
                                       textView.AllowsTab = e.NewValue == CheckState.Checked;
                                   };
                                   };
-        Win.Add (chxCaptureTabs);
+        win.Add (chxCaptureTabs);
 
 
         // Hex editor
         // Hex editor
         label = new() { Text = "_HexView:", Y = Pos.Bottom (chxMultiline) + 1 };
         label = new() { Text = "_HexView:", Y = Pos.Bottom (chxMultiline) + 1 };
-        Win.Add (label);
+        win.Add (label);
 
 
         var hexEditor =
         var hexEditor =
             new HexView (
             new HexView (
@@ -176,7 +178,7 @@ public class Text : Scenario
             {
             {
                 X = Pos.Right (label) + 1, Y = Pos.Bottom (chxMultiline) + 1, Width = Dim.Percent (50) - 1, Height = Dim.Percent (30)
                 X = Pos.Right (label) + 1, Y = Pos.Bottom (chxMultiline) + 1, Width = Dim.Percent (50) - 1, Height = Dim.Percent (30)
             };
             };
-        Win.Add (hexEditor);
+        win.Add (hexEditor);
 
 
         var labelMirroringHexEditor = new Label
         var labelMirroringHexEditor = new Label
         {
         {
@@ -195,14 +197,14 @@ public class Text : Scenario
                                 byte [] array = ((MemoryStream)hexEditor.Source).ToArray ();
                                 byte [] array = ((MemoryStream)hexEditor.Source).ToArray ();
                                 labelMirroringHexEditor.Text = Encoding.UTF8.GetString (array, 0, array.Length);
                                 labelMirroringHexEditor.Text = Encoding.UTF8.GetString (array, 0, array.Length);
                             };
                             };
-        Win.Add (labelMirroringHexEditor);
+        win.Add (labelMirroringHexEditor);
 
 
         // DateField
         // DateField
         label = new() { Text = "_DateField:", Y = Pos.Bottom (hexEditor) + 1 };
         label = new() { Text = "_DateField:", Y = Pos.Bottom (hexEditor) + 1 };
-        Win.Add (label);
+        win.Add (label);
 
 
         var dateField = new DateField (DateTime.Now) { X = Pos.Right (label) + 1, Y = Pos.Bottom (hexEditor) + 1, Width = 20 };
         var dateField = new DateField (DateTime.Now) { X = Pos.Right (label) + 1, Y = Pos.Bottom (hexEditor) + 1, Width = 20 };
-        Win.Add (dateField);
+        win.Add (dateField);
 
 
         var labelMirroringDateField = new Label
         var labelMirroringDateField = new Label
         {
         {
@@ -213,13 +215,13 @@ public class Text : Scenario
             Height = Dim.Height (dateField),
             Height = Dim.Height (dateField),
             Text = dateField.Text
             Text = dateField.Text
         };
         };
-        Win.Add (labelMirroringDateField);
+        win.Add (labelMirroringDateField);
 
 
         dateField.TextChanged += (s, prev) => { labelMirroringDateField.Text = dateField.Text; };
         dateField.TextChanged += (s, prev) => { labelMirroringDateField.Text = dateField.Text; };
 
 
         // TimeField
         // TimeField
         label = new() { Text = "T_imeField:", Y = Pos.Top (dateField), X = Pos.Right (labelMirroringDateField) + 5 };
         label = new() { Text = "T_imeField:", Y = Pos.Top (dateField), X = Pos.Right (labelMirroringDateField) + 5 };
-        Win.Add (label);
+        win.Add (label);
 
 
         _timeField = new()
         _timeField = new()
         {
         {
@@ -229,7 +231,7 @@ public class Text : Scenario
             IsShortFormat = false,
             IsShortFormat = false,
             Time = DateTime.Now.TimeOfDay
             Time = DateTime.Now.TimeOfDay
         };
         };
-        Win.Add (_timeField);
+        win.Add (_timeField);
 
 
         _labelMirroringTimeField = new()
         _labelMirroringTimeField = new()
         {
         {
@@ -240,7 +242,7 @@ public class Text : Scenario
             Height = Dim.Height (_timeField),
             Height = Dim.Height (_timeField),
             Text = _timeField.Text
             Text = _timeField.Text
         };
         };
-        Win.Add (_labelMirroringTimeField);
+        win.Add (_labelMirroringTimeField);
 
 
         _timeField.TimeChanged += TimeChanged;
         _timeField.TimeChanged += TimeChanged;
 
 
@@ -251,7 +253,7 @@ public class Text : Scenario
             Y = Pos.Bottom (dateField) + 1,
             Y = Pos.Bottom (dateField) + 1,
             Text = "_NetMaskedTextProvider [ 999 000 LLL >LLL |AAA aaa ]:"
             Text = "_NetMaskedTextProvider [ 999 000 LLL >LLL |AAA aaa ]:"
         };
         };
-        Win.Add (netProviderLabel);
+        win.Add (netProviderLabel);
 
 
         var netProvider = new NetMaskedTextProvider ("999 000 LLL >LLL |AAA aaa");
         var netProvider = new NetMaskedTextProvider ("999 000 LLL >LLL |AAA aaa");
 
 
@@ -259,7 +261,7 @@ public class Text : Scenario
         {
         {
             X = Pos.Right (netProviderLabel) + 1, Y = Pos.Y (netProviderLabel), Provider = netProvider
             X = Pos.Right (netProviderLabel) + 1, Y = Pos.Y (netProviderLabel), Provider = netProvider
         };
         };
-        Win.Add (netProviderField);
+        win.Add (netProviderField);
 
 
         var labelMirroringNetProviderField = new Label
         var labelMirroringNetProviderField = new Label
         {
         {
@@ -270,7 +272,7 @@ public class Text : Scenario
             Height = Dim.Height (netProviderField),
             Height = Dim.Height (netProviderField),
             Text = netProviderField.Text
             Text = netProviderField.Text
         };
         };
-        Win.Add (labelMirroringNetProviderField);
+        win.Add (labelMirroringNetProviderField);
 
 
         netProviderField.Provider.TextChanged += (s, prev) => { labelMirroringNetProviderField.Text = netProviderField.Text; };
         netProviderField.Provider.TextChanged += (s, prev) => { labelMirroringNetProviderField.Text = netProviderField.Text; };
 
 
@@ -281,7 +283,7 @@ public class Text : Scenario
             Y = Pos.Bottom (netProviderLabel) + 1,
             Y = Pos.Bottom (netProviderLabel) + 1,
             Text = "Text_RegexProvider [ ^([0-9]?[0-9]?[0-9]|1000)$ ]:"
             Text = "Text_RegexProvider [ ^([0-9]?[0-9]?[0-9]|1000)$ ]:"
         };
         };
-        Win.Add (regexProvider);
+        win.Add (regexProvider);
 
 
         var provider2 = new TextRegexProvider ("^([0-9]?[0-9]?[0-9]|1000)$") { ValidateOnInput = false };
         var provider2 = new TextRegexProvider ("^([0-9]?[0-9]?[0-9]|1000)$") { ValidateOnInput = false };
 
 
@@ -293,7 +295,7 @@ public class Text : Scenario
             TextAlignment = Alignment.Center,
             TextAlignment = Alignment.Center,
             Provider = provider2
             Provider = provider2
         };
         };
-        Win.Add (regexProviderField);
+        win.Add (regexProviderField);
 
 
         var labelMirroringRegexProviderField = new Label
         var labelMirroringRegexProviderField = new Label
         {
         {
@@ -304,7 +306,7 @@ public class Text : Scenario
             Height = Dim.Height (regexProviderField),
             Height = Dim.Height (regexProviderField),
             Text = regexProviderField.Text
             Text = regexProviderField.Text
         };
         };
-        Win.Add (labelMirroringRegexProviderField);
+        win.Add (labelMirroringRegexProviderField);
 
 
         regexProviderField.Provider.TextChanged += (s, prev) => { labelMirroringRegexProviderField.Text = regexProviderField.Text; };
         regexProviderField.Provider.TextChanged += (s, prev) => { labelMirroringRegexProviderField.Text = regexProviderField.Text; };
 
 
@@ -428,8 +430,12 @@ public class Text : Scenario
             }
             }
         };
         };
 
 
-        Win.Add (labelAppendAutocomplete);
-        Win.Add (appendAutocompleteTextField);
+        win.Add (labelAppendAutocomplete);
+        win.Add (appendAutocompleteTextField);
+
+        Application.Run (win);
+        win.Dispose ();
+        Application.Shutdown ();
     }
     }
 
 
     private void TimeChanged (object sender, DateTimeEventArgs<TimeSpan> e) { _labelMirroringTimeField.Text = _timeField.Text; }
     private void TimeChanged (object sender, DateTimeEventArgs<TimeSpan> e) { _labelMirroringTimeField.Text = _timeField.Text; }

+ 1 - 1
UICatalog/Scenarios/TextAlignmentAndDirection.cs

@@ -16,7 +16,7 @@ public class TextAlignmentAndDirection : Scenario
 
 
         Window app = new ()
         Window app = new ()
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}"
+            Title = GetQuitKeyAndName ()
         };
         };
 
 
         var txt = $"Hello World{Environment.NewLine}HELLO WORLD{Environment.NewLine}世界 您好";
         var txt = $"Hello World{Environment.NewLine}HELLO WORLD{Environment.NewLine}世界 您好";

+ 1 - 1
UICatalog/Scenarios/TextFormatterDemo.cs

@@ -16,7 +16,7 @@ public class TextFormatterDemo : Scenario
 
 
         var app = new Window
         var app = new Window
         {
         {
-            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}"
+            Title = GetQuitKeyAndName ()
         };
         };
 
 
         // Make Win smaller so sizing the window horizontally will make the
         // Make Win smaller so sizing the window horizontally will make the

+ 13 - 7
UICatalog/Scenarios/Threading.cs

@@ -20,8 +20,10 @@ public class Threading : Scenario
     private ListView _logJob;
     private ListView _logJob;
     private Action _sync;
     private Action _sync;
 
 
-    public override void Setup ()
+    public override void Main ()
     {
     {
+        Application.Init ();
+        var win = new Window { Title = GetQuitKeyAndName () };
         _action = LoadData;
         _action = LoadData;
 
 
         _lambda = async () =>
         _lambda = async () =>
@@ -56,7 +58,7 @@ public class Threading : Scenario
         _btnActionCancel = new Button { X = 1, Y = 1, Text = "Cancelable Load Items" };
         _btnActionCancel = new Button { X = 1, Y = 1, Text = "Cancelable Load Items" };
         _btnActionCancel.Accept += (s, e) => Application.Invoke (CallLoadItemsAsync);
         _btnActionCancel.Accept += (s, e) => Application.Invoke (CallLoadItemsAsync);
 
 
-        Win.Add (new Label { X = Pos.X (_btnActionCancel), Y = Pos.Y (_btnActionCancel) + 4, Text = "Data Items:" });
+        win.Add (new Label { X = Pos.X (_btnActionCancel), Y = Pos.Y (_btnActionCancel) + 4, Text = "Data Items:" });
 
 
         _itemsList = new ListView
         _itemsList = new ListView
         {
         {
@@ -67,7 +69,7 @@ public class Threading : Scenario
             ColorScheme = Colors.ColorSchemes ["TopLevel"]
             ColorScheme = Colors.ColorSchemes ["TopLevel"]
         };
         };
 
 
-        Win.Add (new Label { X = Pos.Right (_itemsList) + 10, Y = Pos.Y (_btnActionCancel) + 4, Text = "Task Logs:" });
+        win.Add (new Label { X = Pos.Right (_itemsList) + 10, Y = Pos.Y (_btnActionCancel) + 4, Text = "Task Logs:" });
 
 
         _logJob = new ListView
         _logJob = new ListView
         {
         {
@@ -101,7 +103,7 @@ public class Threading : Scenario
         var btnQuit = new Button { X = 80, Y = 22, Text = "Quit" };
         var btnQuit = new Button { X = 80, Y = 22, Text = "Quit" };
         btnQuit.Accept += (s, e) => Application.RequestStop ();
         btnQuit.Accept += (s, e) => Application.RequestStop ();
 
 
-        Win.Add (
+        win.Add (
                  _itemsList,
                  _itemsList,
                  _btnActionCancel,
                  _btnActionCancel,
                  _logJob,
                  _logJob,
@@ -115,13 +117,17 @@ public class Threading : Scenario
                  btnQuit
                  btnQuit
                 );
                 );
 
 
-        void Top_Loaded (object sender, EventArgs args)
+        void Win_Loaded (object sender, EventArgs args)
         {
         {
             _btnActionCancel.SetFocus ();
             _btnActionCancel.SetFocus ();
-            Top.Loaded -= Top_Loaded;
+            win.Loaded -= Win_Loaded;
         }
         }
 
 
-        Top.Loaded += Top_Loaded;
+        win.Loaded += Win_Loaded;
+
+        Application.Run (win);
+        win.Dispose ();
+        Application.Shutdown ();
     }
     }
 
 
     private async void CallLoadItemsAsync ()
     private async void CallLoadItemsAsync ()

+ 22 - 12
UICatalog/Scenarios/TileViewNesting.cs

@@ -19,11 +19,15 @@ public class TileViewNesting : Scenario
     private View _workArea;
     private View _workArea;
 
 
     /// <summary>Setup the scenario.</summary>
     /// <summary>Setup the scenario.</summary>
-    public override void Setup ()
+    public override void Main ()
     {
     {
+        Application.Init ();
         // Scenario Windows.
         // Scenario Windows.
-        Win.Title = GetName ();
-        Win.Y = 1;
+        var win = new Window
+        {
+            Title = GetName (),
+            Y = 1
+        };
 
 
         var lblViews = new Label { Text = "Number Of Views:" };
         var lblViews = new Label { Text = "Number Of Views:" };
         _textField = new() { X = Pos.Right (lblViews), Width = 10, Text = "2" };
         _textField = new() { X = Pos.Right (lblViews), Width = 10, Text = "2" };
@@ -52,19 +56,25 @@ public class TileViewNesting : Scenario
             ]
             ]
         };
         };
 
 
-        Win.Add (lblViews);
-        Win.Add (_textField);
-        Win.Add (_cbHorizontal);
-        Win.Add (_cbBorder);
-        Win.Add (_cbTitles);
-        Win.Add (_cbUseLabels);
-        Win.Add (_workArea);
+        win.Add (lblViews);
+        win.Add (_textField);
+        win.Add (_cbHorizontal);
+        win.Add (_cbBorder);
+        win.Add (_cbTitles);
+        win.Add (_cbUseLabels);
+        win.Add (_workArea);
 
 
         SetupTileView ();
         SetupTileView ();
 
 
-        Top.Add (menu);
+        var top = new Toplevel ();
+        top.Add (menu);
+        top.Add (win);
+
+        top.Loaded += (s, e) => _loaded = true;
 
 
-        Win.Loaded += (s, e) => _loaded = true;
+        Application.Run (top);
+        top.Dispose ();
+        Application.Shutdown ();
     }
     }
 
 
     private void AddMoreViews (TileView to)
     private void AddMoreViews (TileView to)

+ 19 - 13
UICatalog/Scenarios/TimeAndDate.cs

@@ -15,8 +15,10 @@ public class TimeAndDate : Scenario
     private Label _lblOldTime;
     private Label _lblOldTime;
     private Label _lblTimeFmt;
     private Label _lblTimeFmt;
 
 
-    public override void Setup ()
+    public override void Main ()
     {
     {
+        Application.Init ();
+        var win = new Window { Title = GetQuitKeyAndName () };
         var longTime = new TimeField
         var longTime = new TimeField
         {
         {
             X = Pos.Center (),
             X = Pos.Center (),
@@ -26,7 +28,7 @@ public class TimeAndDate : Scenario
             Time = DateTime.Now.TimeOfDay
             Time = DateTime.Now.TimeOfDay
         };
         };
         longTime.TimeChanged += TimeChanged;
         longTime.TimeChanged += TimeChanged;
-        Win.Add (longTime);
+        win.Add (longTime);
 
 
         var shortTime = new TimeField
         var shortTime = new TimeField
         {
         {
@@ -37,21 +39,21 @@ public class TimeAndDate : Scenario
             Time = DateTime.Now.TimeOfDay
             Time = DateTime.Now.TimeOfDay
         };
         };
         shortTime.TimeChanged += TimeChanged;
         shortTime.TimeChanged += TimeChanged;
-        Win.Add (shortTime);
+        win.Add (shortTime);
 
 
         var shortDate = new DateField (DateTime.Now)
         var shortDate = new DateField (DateTime.Now)
         {
         {
             X = Pos.Center (), Y = Pos.Bottom (shortTime) + 1, ReadOnly = true
             X = Pos.Center (), Y = Pos.Bottom (shortTime) + 1, ReadOnly = true
         };
         };
         shortDate.DateChanged += DateChanged;
         shortDate.DateChanged += DateChanged;
-        Win.Add (shortDate);
+        win.Add (shortDate);
 
 
         var longDate = new DateField (DateTime.Now)
         var longDate = new DateField (DateTime.Now)
         {
         {
             X = Pos.Center (), Y = Pos.Bottom (shortDate) + 1, ReadOnly = false
             X = Pos.Center (), Y = Pos.Bottom (shortDate) + 1, ReadOnly = false
         };
         };
         longDate.DateChanged += DateChanged;
         longDate.DateChanged += DateChanged;
-        Win.Add (longDate);
+        win.Add (longDate);
 
 
         _lblOldTime = new()
         _lblOldTime = new()
         {
         {
@@ -62,7 +64,7 @@ public class TimeAndDate : Scenario
             Width = Dim.Fill (),
             Width = Dim.Fill (),
             Text = "Old Time: "
             Text = "Old Time: "
         };
         };
-        Win.Add (_lblOldTime);
+        win.Add (_lblOldTime);
 
 
         _lblNewTime = new()
         _lblNewTime = new()
         {
         {
@@ -73,7 +75,7 @@ public class TimeAndDate : Scenario
             Width = Dim.Fill (),
             Width = Dim.Fill (),
             Text = "New Time: "
             Text = "New Time: "
         };
         };
-        Win.Add (_lblNewTime);
+        win.Add (_lblNewTime);
 
 
         _lblTimeFmt = new()
         _lblTimeFmt = new()
         {
         {
@@ -84,7 +86,7 @@ public class TimeAndDate : Scenario
             Width = Dim.Fill (),
             Width = Dim.Fill (),
             Text = "Time Format: "
             Text = "Time Format: "
         };
         };
-        Win.Add (_lblTimeFmt);
+        win.Add (_lblTimeFmt);
 
 
         _lblOldDate = new()
         _lblOldDate = new()
         {
         {
@@ -95,7 +97,7 @@ public class TimeAndDate : Scenario
             Width = Dim.Fill (),
             Width = Dim.Fill (),
             Text = "Old Date: "
             Text = "Old Date: "
         };
         };
-        Win.Add (_lblOldDate);
+        win.Add (_lblOldDate);
 
 
         _lblNewDate = new()
         _lblNewDate = new()
         {
         {
@@ -106,7 +108,7 @@ public class TimeAndDate : Scenario
             Width = Dim.Fill (),
             Width = Dim.Fill (),
             Text = "New Date: "
             Text = "New Date: "
         };
         };
-        Win.Add (_lblNewDate);
+        win.Add (_lblNewDate);
 
 
         _lblDateFmt = new()
         _lblDateFmt = new()
         {
         {
@@ -117,11 +119,11 @@ public class TimeAndDate : Scenario
             Width = Dim.Fill (),
             Width = Dim.Fill (),
             Text = "Date Format: "
             Text = "Date Format: "
         };
         };
-        Win.Add (_lblDateFmt);
+        win.Add (_lblDateFmt);
 
 
         var swapButton = new Button
         var swapButton = new Button
         {
         {
-            X = Pos.Center (), Y = Pos.Bottom (Win) - 5, Text = "Swap Long/Short & Read/Read Only"
+            X = Pos.Center (), Y = Pos.Bottom (win) - 5, Text = "Swap Long/Short & Read/Read Only"
         };
         };
 
 
         swapButton.Accept += (s, e) =>
         swapButton.Accept += (s, e) =>
@@ -135,7 +137,11 @@ public class TimeAndDate : Scenario
                                  longDate.ReadOnly = !longDate.ReadOnly;
                                  longDate.ReadOnly = !longDate.ReadOnly;
                                  shortDate.ReadOnly = !shortDate.ReadOnly;
                                  shortDate.ReadOnly = !shortDate.ReadOnly;
                              };
                              };
-        Win.Add (swapButton);
+        win.Add (swapButton);
+
+        Application.Run (win);
+        win.Dispose ();
+        Application.Shutdown ();
     }
     }
 
 
     private void DateChanged (object sender, DateTimeEventArgs<DateTime> e)
     private void DateChanged (object sender, DateTimeEventArgs<DateTime> e)

部分文件因文件數量過多而無法顯示