using System;
using System.Collections.Generic;
using System.Linq;
namespace Terminal.Gui;
public partial class Toplevel {
///
/// Gets or sets if this Toplevel is a container for overlapped children.
///
public bool IsOverlappedContainer { get; set; }
///
/// Gets or sets if this Toplevel is in overlapped mode within a Toplevel container.
///
public bool IsOverlapped => Application.OverlappedTop != null && Application.OverlappedTop != this && !Modal;
}
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 != null) {
var _overlappedChildren = new List ();
foreach (var top in _topLevels) {
if (top != OverlappedTop && !top.Modal) {
_overlappedChildren.Add (top);
}
}
return _overlappedChildren;
}
return null;
}
}
///
/// The object used for the application on startup which
/// is true.
///
public static Toplevel OverlappedTop {
get {
if (Top.IsOverlappedContainer) {
return Top;
}
return null;
}
}
static bool OverlappedChildNeedsDisplay ()
{
if (OverlappedTop == null) {
return false;
}
foreach (var top in _topLevels) {
if (top != Current && top.Visible && (top.NeedsDisplay || top.SubViewNeedsDisplay || top.LayoutNeeded)) {
OverlappedTop.SetSubViewNeedsDisplay ();
return true;
}
}
return false;
}
static bool SetCurrentOverlappedAsTop ()
{
if (OverlappedTop == null && Current != Top && Current?.SuperView == null && Current?.Modal == false) {
Top = Current;
return true;
}
return false;
}
///
/// Move to the next Overlapped child from the .
///
public static void OverlappedMoveNext ()
{
if (OverlappedTop != null && !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 != null && !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 ();
}
}
}
///
/// 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 != null && Current?.Modal == false) {
lock (_topLevels) {
_topLevels.MoveTo (top, 0, new ToplevelEqualityComparer ());
Current = top;
}
return true;
}
return false;
}
///
/// Brings the superview of the most focused overlapped view is on front.
///
public static void BringOverlappedTopToFront ()
{
if (OverlappedTop != null) {
return;
}
var top = FindTopFromView (Top?.MostFocused);
if (top != null && 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 == null) {
return null;
}
foreach (var top in OverlappedChildren) {
if (type != null && top.GetType () == type && exclude?.Contains (top.Data.ToString ()) == false) {
return top;
}
if (type != null && top.GetType () != type || exclude?.Contains (top.Data.ToString ()) == true) {
continue;
}
return top;
}
return null;
}
}