123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- namespace Terminal.Gui;
- public partial class Toplevel
- {
- /// <summary>Gets or sets if this Toplevel is in overlapped mode within a Toplevel container.</summary>
- public bool IsOverlapped => Application.OverlappedTop is { } && Application.OverlappedTop != this && !Modal;
- /// <summary>Gets or sets if this Toplevel is a container for overlapped children.</summary>
- public bool IsOverlappedContainer { get; set; }
- }
- public static partial class Application
- {
- /// <summary>
- /// Gets the list of the Overlapped children which are not modal <see cref="Toplevel"/> from the
- /// <see cref="OverlappedTop"/>.
- /// </summary>
- public static List<Toplevel> OverlappedChildren
- {
- get
- {
- if (OverlappedTop is { })
- {
- List<Toplevel> _overlappedChildren = new ();
- foreach (Toplevel top in _topLevels)
- {
- if (top != OverlappedTop && !top.Modal)
- {
- _overlappedChildren.Add (top);
- }
- }
- return _overlappedChildren;
- }
- return null;
- }
- }
- /// <summary>
- /// The <see cref="Toplevel"/> object used for the application on startup which
- /// <see cref="Toplevel.IsOverlappedContainer"/> is true.
- /// </summary>
- public static Toplevel OverlappedTop
- {
- get
- {
- if (Top is { IsOverlappedContainer: true })
- {
- return Top;
- }
- return null;
- }
- }
- /// <summary>Brings the superview of the most focused overlapped view is on front.</summary>
- public static void BringOverlappedTopToFront ()
- {
- if (OverlappedTop is { })
- {
- return;
- }
- View top = FindTopFromView (Top?.MostFocused);
- if (top is { } && Top.Subviews.Count > 1 && Top.Subviews [Top.Subviews.Count - 1] != top)
- {
- Top.BringSubviewToFront (top);
- }
- }
- /// <summary>Gets the current visible Toplevel overlapped child that matches the arguments pattern.</summary>
- /// <param name="type">The type.</param>
- /// <param name="exclude">The strings to exclude.</param>
- /// <returns>The matched view.</returns>
- 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;
- }
- /// <summary>
- /// Move to the next Overlapped child from the <see cref="OverlappedTop"/> and set it as the <see cref="Top"/> if
- /// it is not already.
- /// </summary>
- /// <param name="top"></param>
- /// <returns></returns>
- 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;
- }
- /// <summary>Move to the next Overlapped child from the <see cref="OverlappedTop"/>.</summary>
- 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 ();
- }
- }
- }
- /// <summary>Move to the previous Overlapped child from the <see cref="OverlappedTop"/>.</summary>
- 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;
- }
- }
|