Repository: gui-cs/Terminal.Gui

Issue #2502: Discuss - There should only be one (`Application.Top`)
Created: 2023-04-04T22:42:21Z
This is all debatable, but here's my thinking:
TopLevel is currently built around several concepts that are muddled and have led to overly complex code:

A Toplevel is a view that can host a Menu and StatusBar. Other views cannot.
A Toplevel can run modally, and have its own Runstate (via Application.Run(). It is unclear why ANY VIEW can't be run this way, but it seems to be a limitation of the current implementation.
A Toplevel can be moved by the user (actually only the Toplevel subclass, Window). It should be possible to enable the moving of any View (e.g. View.CanMove = true or similar).

Application is the place where all of the above TopLevel gunk happens in addition to other "application" stuff.
The MdiContainer stuff is complex, perhaps overly so, and is not actually used by anyone outside of the project. It's also misnamed because Terminal.Gui doesn't actually support "documents" nor does it have a full "MDI" system like Windows (did). It seems to represent features useful in overlapping Views, but it is super confusing on how this works, and the naming doesn't help.  Application is full of code like if (MdiTop != null && top != MdiTop && top != Current && Current?.Running == false && !top.Running) which just screams poor-OO design and fragility. This all can be refactored to support specific scenarios and thus be simplified.
My proposal:


Application.Top should be set when an app starts, and should not be changeable. Changing it after Application.Begin has been called should result in an exception.


The Application class should do the following (and nothing else; other things should be moved elsewhere as appropriate):

Application-wide settings (like default quit key and diagnostics)
Initializing and configuring the console driver
Providing Runstate and managing the Mainloop
Providing a simple API for starting applications either with a default Top view or a developer-provided one
Proxying mouse/keyboard events from the driver to the Top



Stuff that will be moved out of (or deleted) from Application:

All the Mdi stuff
All the tracking of Current and toplevels. This stuff will just be part of View.
Code for moving from view to view in the focus or z-order heirarchies



All Views should support overlapping within a superview and have a menubar and statusbar.


All Views should support having subviews be overlapping


All the insane logic in Application.cs for dealing with Current, the stack of toplevels, etc, should be moved into the View hierarchy (either as part of View directly or a helper class)... and radically simplified. This includes getting rid of all of the Mdi stuff.


Any View can be run modally (as a popup that captures all user input) can be executed with a new API: view.Run(popupView) as is today, except they don't have to be of type Toplevel. When such a view is run, view.Modal is set to true letting the view know it's modal. We'll retain Application.Run() for backward compatibility, but it will simply do Application.Top.Run(popupView).


Making this happen requires the following to be done first:

#2491
#2487
#2488

But it seems doable, and will significantly simplify the programming model (and codebase).
What do folks think?

Duplicate issue #2490: Remove `Toplevel` -
Created: 2023-04-04T04:05:20Z
Modal - The term used when describing a View that was created using the Application.Run(view) or Application.Run<T> APIs. When a View is running as a modal, user input is restricted to just that View until Application.Run exits. A Modal View has its own RunState.


In v1, classes derived from Dialog were originally thought to only work modally. However, Wizard proved that a Dialog-based class can also work non-modally.


In v2, we will simplify the Dialog class, and let any class be run via Applicaiton.Run. The Modal property will be set by Application.Run so the class can detect it is running modally if it needs to.


TopLevel - The v1 term used to describe a view that can have a MenuBarand/or StatusBar.


In v2, we will delete the TopLevel class and ensure ANY View can have a menu bar and/or status bar (via Adornments). See #2488


NOTE: There will still be an Application.Top which is the View that is the root of the Application's view hierarchy.


In v2, there is only one Application.Top. It is the View that is the first view in the application.


If a developer wants an "MDI" like interface, they can turn on the menubar/status bar in the Application.Top and add Window subviews to their hearts content. With the LayoutStyle.Overlapped each of those subviews overlap each other, support dragging/sizing, etc... They can add/remove subviews to the Application.Top, hide/show, etc... There is no need for a TopLevel class.

Closing comment (2023-04-14T16:35:45Z): Dupe of #2502