SplitContainerNesting.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. using System;
  2. using System.ComponentModel;
  3. using System.Linq;
  4. using Terminal.Gui;
  5. using Terminal.Gui.Graphs;
  6. namespace UICatalog.Scenarios {
  7. [ScenarioMetadata (Name: "Split Container Nesting", Description: "Nest SplitContainers")]
  8. [ScenarioCategory ("Controls")]
  9. [ScenarioCategory ("LineView")]
  10. public class SplitContainerNesting : Scenario {
  11. private View workArea;
  12. private TextField textField;
  13. private CheckBox cbHorizontal;
  14. private CheckBox cbBorder;
  15. private CheckBox cbTitles;
  16. bool loaded = false;
  17. /// <summary>
  18. /// Setup the scenario.
  19. /// </summary>
  20. public override void Setup ()
  21. {
  22. // Scenario Windows.
  23. Win.Title = this.GetName ();
  24. Win.Y = 1;
  25. var lblPanels = new Label ("Number Of Panels:");
  26. textField = new TextField {
  27. X = Pos.Right (lblPanels),
  28. Width = 10,
  29. Text = "2",
  30. };
  31. textField.TextChanged += (s) => SetupSplitContainer ();
  32. cbHorizontal = new CheckBox ("Horizontal") {
  33. X = Pos.Right (textField) + 1
  34. };
  35. cbHorizontal.Toggled += (s) => SetupSplitContainer ();
  36. cbBorder = new CheckBox ("Border") {
  37. X = Pos.Right (cbHorizontal) + 1
  38. };
  39. cbBorder.Toggled += (s) => SetupSplitContainer ();
  40. cbTitles = new CheckBox ("Titles") {
  41. X = Pos.Right (cbBorder) + 1
  42. };
  43. cbTitles.Toggled += (s) => SetupSplitContainer ();
  44. workArea = new View {
  45. X = 0,
  46. Y = 1,
  47. Width = Dim.Fill (),
  48. Height = Dim.Fill (),
  49. };
  50. var menu = new MenuBar (new MenuBarItem [] {
  51. new MenuBarItem ("_File", new MenuItem [] {
  52. new MenuItem ("_Quit", "", () => Quit()),
  53. }) });
  54. Win.Add (lblPanels);
  55. Win.Add (textField);
  56. Win.Add (cbHorizontal);
  57. Win.Add (cbBorder);
  58. Win.Add (cbTitles);
  59. Win.Add (workArea);
  60. SetupSplitContainer ();
  61. Application.Top.Add (menu);
  62. Win.Loaded += () => loaded = true;
  63. }
  64. private void SetupSplitContainer ()
  65. {
  66. int numberOfPanels = GetNumberOfPanels ();
  67. bool titles = cbTitles.Checked;
  68. bool border = cbBorder.Checked;
  69. bool startHorizontal = cbHorizontal.Checked;
  70. workArea.RemoveAll ();
  71. if (numberOfPanels <= 0) {
  72. return;
  73. }
  74. var root = CreateSplitContainer (startHorizontal ?
  75. Terminal.Gui.Graphs.Orientation.Horizontal :
  76. Terminal.Gui.Graphs.Orientation.Vertical, false);
  77. root.Panel1.Add (CreateTextView (1));
  78. root.Panel1Title = titles ? "Panel 1" : string.Empty;
  79. root.Panel2.Add (CreateTextView (2));
  80. root.Panel2Title = titles ? "Panel 2" : string.Empty;
  81. root.IntegratedBorder = border ? BorderStyle.Rounded : BorderStyle.None;
  82. workArea.Add (root);
  83. if (numberOfPanels == 1) {
  84. root.Panel2.Visible = false;
  85. }
  86. if (numberOfPanels > 2) {
  87. AddMorePanels (root, 2, numberOfPanels);
  88. }
  89. if (loaded) {
  90. workArea.LayoutSubviews ();
  91. }
  92. }
  93. private View CreateTextView (int number)
  94. {
  95. return new TextView {
  96. Width = Dim.Fill (),
  97. Height = Dim.Fill (),
  98. Text = number.ToString ().Repeat (1000),
  99. AllowsTab = false,
  100. WordWrap = true,
  101. };
  102. }
  103. private void AddMorePanels (SplitContainer to, int done, int numberOfPanels)
  104. {
  105. if (done == numberOfPanels) {
  106. return;
  107. }
  108. View toSplit;
  109. if (!(to.Panel1 is SplitContainer)) {
  110. // we can split Panel1
  111. var tv = (TextView)to.Panel1.Subviews.Single ();
  112. var newContainer = CreateSplitContainer (to.Orientation, true);
  113. to.Remove (to.Panel1);
  114. to.Add (newContainer);
  115. to.Panel1 = newContainer;
  116. newContainer.Panel1.Add (tv);
  117. newContainer.Panel2.Add (CreateTextView (++done));
  118. AddMorePanels (to, done, numberOfPanels);
  119. } else
  120. if (!(to.Panel2 is SplitContainer)) {
  121. // we can split Panel2
  122. var tv = (TextView)to.Panel2.Subviews.Single ();
  123. var newContainer = CreateSplitContainer (to.Orientation, true);
  124. to.Remove (to.Panel2);
  125. to.Add (newContainer);
  126. to.Panel2 = newContainer;
  127. newContainer.Panel1.Add (tv);
  128. newContainer.Panel2.Add (CreateTextView (++done));
  129. AddMorePanels (to, done, numberOfPanels);
  130. } else {
  131. // Both Panel1 and Panel2 are already SplitContainer
  132. // So split one of the children
  133. if(done % 2 == 0) {
  134. AddMorePanels ((SplitContainer)to.Panel1, done, numberOfPanels);
  135. } else {
  136. AddMorePanels ((SplitContainer)to.Panel2, done, numberOfPanels);
  137. }
  138. }
  139. }
  140. private SplitContainer CreateSplitContainer (Orientation orientation, bool flip)
  141. {
  142. var toReturn = new SplitContainer {
  143. Width = Dim.Fill (),
  144. Height = Dim.Fill (),
  145. // flip the orientation
  146. Orientation = orientation
  147. };
  148. if (flip) {
  149. toReturn.Orientation = toReturn.Orientation == Orientation.Vertical ?
  150. Orientation.Horizontal :
  151. Orientation.Vertical;
  152. }
  153. return toReturn;
  154. }
  155. private int GetNumberOfPanels ()
  156. {
  157. if (int.TryParse (textField.Text.ToString (), out var panels) && panels >= 0) {
  158. return panels;
  159. } else {
  160. return 0;
  161. }
  162. }
  163. private void Quit ()
  164. {
  165. Application.RequestStop ();
  166. }
  167. }
  168. }