#nullable enable
namespace Terminal.Gui;
public static partial class Application // Toplevel handling
{
// BUGBUG: Technically, this is not the full lst of TopLevels. There be dragons here, e.g. see how Toplevel.Id is used. What
/// Holds the stack of TopLevel views.
// about TopLevels that are just a SubView of another View?
internal static readonly Stack _topLevels = new ();
/// The object used for the application on startup ()
/// The top.
public static Toplevel? Top { get; private set; }
// TODO: Determine why this can't just return _topLevels.Peek()?
///
/// The current object. This is updated in enters and leaves to
/// point to the current
/// .
///
///
/// This will only be distinct from in scenarios where is .
///
/// The current.
public static Toplevel? Current { get; private set; }
///
/// If is not already Current and visible, finds the last Modal Toplevel in the stack and makes it Current.
///
private static void EnsureModalOrVisibleAlwaysOnTop (Toplevel topLevel)
{
if (!topLevel.Running
|| (topLevel == Current && topLevel.Visible)
|| OverlappedTop == null
|| _topLevels.Peek ().Modal)
{
return;
}
foreach (Toplevel top in _topLevels.Reverse ())
{
if (top.Modal && top != Current)
{
MoveCurrent (top);
return;
}
}
if (!topLevel.Visible && topLevel == Current)
{
OverlappedMoveNext ();
}
}
/// Invoked when the terminal's size changed. The new size of the terminal is provided.
///
/// Event handlers can set to to prevent
/// from changing it's size to match the new terminal size.
///
public static event EventHandler? SizeChanging;
///
/// Called when the application's size changes. Sets the size of all s and fires the
/// event.
///
/// The new size.
/// if the size was changed.
public static bool OnSizeChanging (SizeChangedEventArgs args)
{
SizeChanging?.Invoke (null, args);
if (args.Cancel || args.Size is null)
{
return false;
}
foreach (Toplevel t in _topLevels)
{
t.SetRelativeLayout (args.Size.Value);
t.LayoutSubviews ();
t.PositionToplevels ();
t.OnSizeChanging (new (args.Size));
if (PositionCursor (t))
{
Driver?.UpdateCursor ();
}
}
Refresh ();
return true;
}
}