namespace Terminal.Gui;
public partial class Toplevel
{
/// Gets or sets if this Toplevel is in overlapped mode within a Toplevel container.
public bool IsOverlapped => Application.OverlappedTop is { } && Application.OverlappedTop != this && !Modal;
/// Gets or sets if this Toplevel is a container for overlapped children.
public bool IsOverlappedContainer { get; set; }
}
public static partial class Application
{
///
/// Gets the list of the Overlapped children which are not modal from the
/// .
///
public static List OverlappedChildren
{
get
{
if (OverlappedTop is { })
{
List _overlappedChildren = new ();
foreach (Toplevel top in _topLevels)
{
if (top != OverlappedTop && !top.Modal)
{
_overlappedChildren.Add (top);
}
}
return _overlappedChildren;
}
return null;
}
}
#nullable enable
///
/// The object used for the application on startup which
/// is true.
///
public static Toplevel? OverlappedTop
{
get
{
if (Top is { IsOverlappedContainer: true })
{
return Top;
}
return null;
}
}
#nullable restore
/// Brings the superview of the most focused overlapped view is on front.
public static void BringOverlappedTopToFront ()
{
if (OverlappedTop is { })
{
return;
}
View top = FindTopFromView (Top?.MostFocused);
if (top is Toplevel && Top.Subviews.Count > 1 && Top.Subviews [Top.Subviews.Count - 1] != top)
{
Top.BringSubviewToFront (top);
}
}
/// Gets the current visible Toplevel overlapped child that matches the arguments pattern.
/// The type.
/// The strings to exclude.
/// The matched view.
public static Toplevel GetTopOverlappedChild (Type type = null, string [] exclude = null)
{
if (OverlappedTop is null)
{
return null;
}
foreach (Toplevel top in OverlappedChildren)
{
if (type is { } && top.GetType () == type && exclude?.Contains (top.Data.ToString ()) == false)
{
return top;
}
if ((type is { } && top.GetType () != type) || exclude?.Contains (top.Data.ToString ()) == true)
{
continue;
}
return top;
}
return null;
}
///
/// Move to the next Overlapped child from the and set it as the if
/// it is not already.
///
///
///
public static bool MoveToOverlappedChild (Toplevel top)
{
if (top.Visible && OverlappedTop is { } && Current?.Modal == false)
{
lock (_topLevels)
{
_topLevels.MoveTo (top, 0, new ToplevelEqualityComparer ());
Current = top;
}
return true;
}
return false;
}
/// Move to the next Overlapped child from the .
public static void OverlappedMoveNext ()
{
if (OverlappedTop is { } && !Current.Modal)
{
lock (_topLevels)
{
_topLevels.MoveNext ();
var isOverlapped = false;
while (_topLevels.Peek () == OverlappedTop || !_topLevels.Peek ().Visible)
{
if (!isOverlapped && _topLevels.Peek () == OverlappedTop)
{
isOverlapped = true;
}
else if (isOverlapped && _topLevels.Peek () == OverlappedTop)
{
MoveCurrent (Top);
break;
}
_topLevels.MoveNext ();
}
Current = _topLevels.Peek ();
}
}
}
/// Move to the previous Overlapped child from the .
public static void OverlappedMovePrevious ()
{
if (OverlappedTop is { } && !Current.Modal)
{
lock (_topLevels)
{
_topLevels.MovePrevious ();
var isOverlapped = false;
while (_topLevels.Peek () == OverlappedTop || !_topLevels.Peek ().Visible)
{
if (!isOverlapped && _topLevels.Peek () == OverlappedTop)
{
isOverlapped = true;
}
else if (isOverlapped && _topLevels.Peek () == OverlappedTop)
{
MoveCurrent (Top);
break;
}
_topLevels.MovePrevious ();
}
Current = _topLevels.Peek ();
}
}
}
private static bool OverlappedChildNeedsDisplay ()
{
if (OverlappedTop is null)
{
return false;
}
foreach (Toplevel top in _topLevels)
{
if (top != Current && top.Visible && (top.NeedsDisplay || top.SubViewNeedsDisplay || top.LayoutNeeded))
{
OverlappedTop.SetSubViewNeedsDisplay ();
return true;
}
}
return false;
}
private static bool SetCurrentOverlappedAsTop ()
{
if (OverlappedTop is null && Current != Top && Current?.SuperView is null && Current?.Modal == false)
{
Top = Current;
return true;
}
return false;
}
}