ToplevelOverlapped.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. namespace Terminal.Gui;
  5. public partial class Toplevel {
  6. /// <summary>
  7. /// Gets or sets if this Toplevel is a container for overlapped children.
  8. /// </summary>
  9. public bool IsOverlappedContainer { get; set; }
  10. /// <summary>
  11. /// Gets or sets if this Toplevel is in overlapped mode within a Toplevel container.
  12. /// </summary>
  13. public bool IsOverlapped => Application.OverlappedTop != null && Application.OverlappedTop != this && !Modal;
  14. }
  15. public static partial class Application {
  16. /// <summary>
  17. /// Gets the list of the Overlapped children which are not modal <see cref="Toplevel"/> from the
  18. /// <see cref="OverlappedTop"/>.
  19. /// </summary>
  20. public static List<Toplevel> OverlappedChildren {
  21. get {
  22. if (OverlappedTop != null) {
  23. var _overlappedChildren = new List<Toplevel> ();
  24. foreach (var top in _topLevels) {
  25. if (top != OverlappedTop && !top.Modal) {
  26. _overlappedChildren.Add (top);
  27. }
  28. }
  29. return _overlappedChildren;
  30. }
  31. return null;
  32. }
  33. }
  34. /// <summary>
  35. /// The <see cref="Toplevel"/> object used for the application on startup which
  36. /// <see cref="Toplevel.IsOverlappedContainer"/> is true.
  37. /// </summary>
  38. public static Toplevel OverlappedTop {
  39. get {
  40. if (Top.IsOverlappedContainer) {
  41. return Top;
  42. }
  43. return null;
  44. }
  45. }
  46. static bool OverlappedChildNeedsDisplay ()
  47. {
  48. if (OverlappedTop == null) {
  49. return false;
  50. }
  51. foreach (var top in _topLevels) {
  52. if (top != Current && top.Visible && (top.NeedsDisplay || top.SubViewNeedsDisplay || top.LayoutNeeded)) {
  53. OverlappedTop.SetSubViewNeedsDisplay ();
  54. return true;
  55. }
  56. }
  57. return false;
  58. }
  59. static bool SetCurrentOverlappedAsTop ()
  60. {
  61. if (OverlappedTop == null && Current != Top && Current?.SuperView == null && Current?.Modal == false) {
  62. if (Current.Frame != new Rect (0, 0, Driver.Cols, Driver.Rows)) {
  63. // BUGBUG: Use Dim.Fill
  64. Current.Frame = new Rect (0, 0, Driver.Cols, Driver.Rows);
  65. }
  66. Top = Current;
  67. return true;
  68. }
  69. return false;
  70. }
  71. /// <summary>
  72. /// Move to the next Overlapped child from the <see cref="OverlappedTop"/>.
  73. /// </summary>
  74. public static void OverlappedMoveNext ()
  75. {
  76. if (OverlappedTop != null && !Current.Modal) {
  77. lock (_topLevels) {
  78. _topLevels.MoveNext ();
  79. var isOverlapped = false;
  80. while (_topLevels.Peek () == OverlappedTop || !_topLevels.Peek ().Visible) {
  81. if (!isOverlapped && _topLevels.Peek () == OverlappedTop) {
  82. isOverlapped = true;
  83. } else if (isOverlapped && _topLevels.Peek () == OverlappedTop) {
  84. MoveCurrent (Top);
  85. break;
  86. }
  87. _topLevels.MoveNext ();
  88. }
  89. Current = _topLevels.Peek ();
  90. }
  91. }
  92. }
  93. /// <summary>
  94. /// Move to the previous Overlapped child from the <see cref="OverlappedTop"/>.
  95. /// </summary>
  96. public static void OverlappedMovePrevious ()
  97. {
  98. if (OverlappedTop != null && !Current.Modal) {
  99. lock (_topLevels) {
  100. _topLevels.MovePrevious ();
  101. var isOverlapped = false;
  102. while (_topLevels.Peek () == OverlappedTop || !_topLevels.Peek ().Visible) {
  103. if (!isOverlapped && _topLevels.Peek () == OverlappedTop) {
  104. isOverlapped = true;
  105. } else if (isOverlapped && _topLevels.Peek () == OverlappedTop) {
  106. MoveCurrent (Top);
  107. break;
  108. }
  109. _topLevels.MovePrevious ();
  110. }
  111. Current = _topLevels.Peek ();
  112. }
  113. }
  114. }
  115. /// <summary>
  116. /// Move to the next Overlapped child from the <see cref="OverlappedTop"/> and set it as the
  117. /// <see cref="Top"/> if it is not already.
  118. /// </summary>
  119. /// <param name="top"></param>
  120. /// <returns></returns>
  121. public static bool MoveToOverlappedChild (Toplevel top)
  122. {
  123. if (top.Visible && OverlappedTop != null && Current?.Modal == false) {
  124. lock (_topLevels) {
  125. _topLevels.MoveTo (top, 0, new ToplevelEqualityComparer ());
  126. Current = top;
  127. }
  128. return true;
  129. }
  130. return false;
  131. }
  132. /// <summary>
  133. /// Brings the superview of the most focused overlapped view is on front.
  134. /// </summary>
  135. public static void BringOverlappedTopToFront ()
  136. {
  137. if (OverlappedTop != null) {
  138. return;
  139. }
  140. var top = FindTopFromView (Top?.MostFocused);
  141. if (top != null && Top.Subviews.Count > 1 && Top.Subviews [Top.Subviews.Count - 1] != top) {
  142. Top.BringSubviewToFront (top);
  143. }
  144. }
  145. /// <summary>
  146. /// Gets the current visible Toplevel overlapped child that matches the arguments pattern.
  147. /// </summary>
  148. /// <param name="type">The type.</param>
  149. /// <param name="exclude">The strings to exclude.</param>
  150. /// <returns>The matched view.</returns>
  151. public static Toplevel GetTopOverlappedChild (Type type = null, string [] exclude = null)
  152. {
  153. if (OverlappedTop == null) {
  154. return null;
  155. }
  156. foreach (var top in OverlappedChildren) {
  157. if (type != null && top.GetType () == type && exclude?.Contains (top.Data.ToString ()) == false) {
  158. return top;
  159. }
  160. if (type != null && top.GetType () != type || exclude?.Contains (top.Data.ToString ()) == true) {
  161. continue;
  162. }
  163. return top;
  164. }
  165. return null;
  166. }
  167. }