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.
This commit is contained in:
Daniel Cazzulino
2019-09-04 00:14:27 -03:00
committed by Miguel de Icaza
parent a50d79bd7b
commit 90ce395484
2 changed files with 30 additions and 2 deletions

View File

@@ -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
nice layout system that I have no name for, but that [is
documented](https://migueldeicaza.github.io/gui.cs/articles/overview.html#layout),

View File

@@ -1635,7 +1635,12 @@ namespace Terminal.Gui {
/// <summary>
/// Initializes the Application
/// </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)
return;
@@ -1657,7 +1662,7 @@ namespace Terminal.Gui {
Driver.Init (TerminalResized);
MainLoop = new Mono.Terminal.MainLoop (mainLoopDriver);
SynchronizationContext.SetSynchronizationContext (new MainLoopSyncContext (MainLoop));
Top = Toplevel.Create ();
Top = topLevelFactory ();
Current = Top;
}
@@ -1948,6 +1953,15 @@ namespace Terminal.Gui {
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>
/// Runs the main loop on the given container.
/// </summary>