-
Notifications
You must be signed in to change notification settings - Fork 726
Description
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
Toplevelis a view that can host a Menu and StatusBar. Other views cannot. - A
Toplevelcan run modally, and have its ownRunstate(viaApplication.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
Toplevelcan be moved by the user (actually only theToplevelsubclass,Window). It should be possible to enable the moving of any View (e.g.View.CanMove = trueor 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.Topshould be set when an app starts, and should not be changeable. Changing it afterApplication.Beginhas been called should result in an exception. -
The
Applicationclass 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
Runstateand managing theMainloop - Providing a simple API for starting applications either with a default
Topview 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
Mdistuff - All the tracking of
Currentandtoplevels. This stuff will just be part ofView. - Code for moving from view to view in the focus or z-order heirarchies
- All the
-
All
Viewsshould support overlapping within a superview and have a menubar and statusbar. -
All
Viewsshould support having subviews be overlapping -
All the insane logic in
Application.csfor dealing withCurrent, the stack oftoplevels, etc, should be moved into theViewhierarchy (either as part ofViewdirectly or a helper class)... and radically simplified. This includes getting rid of all of theMdistuff. -
Any
Viewcan 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 typeToplevel. When such a view is run,view.Modalis set totrueletting the view know it's modal. We'll retainApplication.Run()for backward compatibility, but it will simply doApplication.Top.Run(popupView).
Making this happen requires the following to be done first:
- Master Issue: Get rid of
Toplevel- IntroduceRunnableandOverlappedinstead #2491 - Add ability for
Frameto host subviews (adornments) #2487 - Refactor
MenuBarandStatusBarto be adornments #2488
But it seems doable, and will significantly simplify the programming model (and codebase).
What do folks think?