Browse Source

Add Application.Run<T> entry point (#247)

In more "modern" app programming models (such as WPF/UWP/XF), the "app" is a
derived class that contains the UI building behavior and is the entry point.

Typically in the constructor of such a class, you'd build the main UI, menus,
etc. In the context of gui.cs, that would mean the `Main` method would typically
be:

```
Application.Init();
Application.Run(new App());
```

In order to make the code flow consistent with the existing behavior, the existing
`Init` implementation was moved to a private method that now receives a `Func<TopLevel>`
to create the top level view upon initialization. The existing behavior is unchanged
since the new `Init` just invokes the previous `TopLevel.Create` as before.

The new `Run<T>` allows the `Main` method to simply be:

```
Application.Run<App>();
```

NOTE: this was added since doing `Application.Run(new App());` failed in the
`Window`-derived class when trying to access the static `Colors` since those were
initialized as part of `Init` and creating the `App` class was too early, preventing
this slightly simpler model.
Daniel Cazzulino 6 years ago
parent
commit
90ce395484
2 changed files with 30 additions and 2 deletions
  1. 14 0
      README.md
  2. 16 2
      Terminal.Gui/Core.cs

+ 14 - 0
README.md

@@ -124,6 +124,20 @@ class Demo {
 }
 }
 ```
 ```
 
 
+Alternatively, you can encapsulate the app behavior in a new `Window`-derived class, 
+say `App.cs` containing the code above, and simplify your `Main` method to:
+
+```csharp
+using Terminal.Gui;
+
+class Demo {
+    static void Main ()
+    {
+        Application.Run<App> ();
+    }
+}
+```
+
 The example above shows how to add views, two styles are used, a very
 The example above shows how to add views, two styles are used, a very
 nice layout system that I have no name for, but that [is
 nice layout system that I have no name for, but that [is
 documented](https://migueldeicaza.github.io/gui.cs/articles/overview.html#layout),
 documented](https://migueldeicaza.github.io/gui.cs/articles/overview.html#layout),

+ 16 - 2
Terminal.Gui/Core.cs

@@ -1635,7 +1635,12 @@ namespace Terminal.Gui {
 		/// <summary>
 		/// <summary>
 		/// Initializes the Application
 		/// Initializes the Application
 		/// </summary>
 		/// </summary>
-		public static void Init ()
+		public static void Init () => Init (() => Toplevel.Create ());
+
+		/// <summary>
+		/// Initializes the Application
+		/// </summary>
+		static void Init (Func<Toplevel> topLevelFactory)
 		{
 		{
 			if (Top != null)
 			if (Top != null)
 				return;
 				return;
@@ -1657,7 +1662,7 @@ namespace Terminal.Gui {
 			Driver.Init (TerminalResized);
 			Driver.Init (TerminalResized);
 			MainLoop = new Mono.Terminal.MainLoop (mainLoopDriver);
 			MainLoop = new Mono.Terminal.MainLoop (mainLoopDriver);
 			SynchronizationContext.SetSynchronizationContext (new MainLoopSyncContext (MainLoop));
 			SynchronizationContext.SetSynchronizationContext (new MainLoopSyncContext (MainLoop));
-			Top = Toplevel.Create ();
+			Top = topLevelFactory ();
 			Current = Top;
 			Current = Top;
 		}
 		}
 
 
@@ -1948,6 +1953,15 @@ namespace Terminal.Gui {
 			Run (Top);
 			Run (Top);
 		}
 		}
 
 
+		/// <summary>
+		/// Runs the application with a new instance of the specified toplevel view
+		/// </summary>
+		public static void Run<T> () where T : Toplevel, new()
+		{
+			Init (() => new T());
+			Run (Top);
+		}
+
 		/// <summary>
 		/// <summary>
 		///   Runs the main loop on the given container.
 		///   Runs the main loop on the given container.
 		/// </summary>
 		/// </summary>