TileViewNesting.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. using System.Linq;
  2. namespace UICatalog.Scenarios;
  3. [ScenarioMetadata ("Tile View Nesting", "Demonstrates recursive nesting of TileViews")]
  4. [ScenarioCategory ("Controls")]
  5. public class TileViewNesting : Scenario
  6. {
  7. private CheckBox _cbBorder;
  8. private CheckBox _cbHorizontal;
  9. private CheckBox _cbTitles;
  10. private CheckBox _cbUseLabels;
  11. private TextField _textField;
  12. private int _viewsCreated;
  13. private int _viewsToCreate;
  14. private View _workArea;
  15. /// <summary>Setup the scenario.</summary>
  16. public override void Main ()
  17. {
  18. Application.Init ();
  19. // Scenario Windows.
  20. var win = new Window
  21. {
  22. Title = GetName (),
  23. Y = 1
  24. };
  25. var lblViews = new Label { Text = "Number Of Views:" };
  26. _textField = new() { X = Pos.Right (lblViews), Width = 10, Text = "2" };
  27. _textField.TextChanged += (s, e) => SetupTileView ();
  28. _cbHorizontal = new() { X = Pos.Right (_textField) + 1, Text = "Horizontal" };
  29. _cbHorizontal.CheckedStateChanged += (s, e) => SetupTileView ();
  30. _cbBorder = new() { X = Pos.Right (_cbHorizontal) + 1, Text = "Border" };
  31. _cbBorder.CheckedStateChanged += (s, e) => SetupTileView ();
  32. _cbTitles = new() { X = Pos.Right (_cbBorder) + 1, Text = "Titles" };
  33. _cbTitles.CheckedStateChanged += (s, e) => SetupTileView ();
  34. _cbUseLabels = new() { X = Pos.Right (_cbTitles) + 1, Text = "Use Labels" };
  35. _cbUseLabels.CheckedStateChanged += (s, e) => SetupTileView ();
  36. _workArea = new() { X = 0, Y = 1, Width = Dim.Fill (), Height = Dim.Fill () };
  37. var menu = new MenuBar
  38. {
  39. Menus =
  40. [
  41. new ("_File", new MenuItem [] { new ("_Quit", "", () => Quit ()) })
  42. ]
  43. };
  44. win.Add (lblViews);
  45. win.Add (_textField);
  46. win.Add (_cbHorizontal);
  47. win.Add (_cbBorder);
  48. win.Add (_cbTitles);
  49. win.Add (_cbUseLabels);
  50. win.Add (_workArea);
  51. SetupTileView ();
  52. var top = new Toplevel ();
  53. top.Add (menu);
  54. top.Add (win);
  55. Application.Run (top);
  56. top.Dispose ();
  57. Application.Shutdown ();
  58. }
  59. private void AddMoreViews (TileView to)
  60. {
  61. if (_viewsCreated == _viewsToCreate)
  62. {
  63. return;
  64. }
  65. if (!(to.Tiles.ElementAt (0).ContentView is TileView))
  66. {
  67. Split (to, true);
  68. }
  69. if (!(to.Tiles.ElementAt (1).ContentView is TileView))
  70. {
  71. Split (to, false);
  72. }
  73. if (to.Tiles.ElementAt (0).ContentView is TileView && to.Tiles.ElementAt (1).ContentView is TileView)
  74. {
  75. AddMoreViews ((TileView)to.Tiles.ElementAt (0).ContentView);
  76. AddMoreViews ((TileView)to.Tiles.ElementAt (1).ContentView);
  77. }
  78. }
  79. private View CreateContentControl (int number) { return _cbUseLabels.CheckedState == CheckState.Checked ? CreateLabelView (number) : CreateTextView (number); }
  80. private View CreateLabelView (int number)
  81. {
  82. return new Label
  83. {
  84. Width = Dim.Fill (),
  85. Height = 1,
  86. Text = number.ToString ().Repeat (1000),
  87. CanFocus = true
  88. };
  89. }
  90. private View CreateTextView (int number)
  91. {
  92. return new TextView
  93. {
  94. Width = Dim.Fill (), Height = Dim.Fill (), Text = number.ToString ().Repeat (1000), AllowsTab = false
  95. //WordWrap = true, // TODO: This is very slow (like 10s to render with 45 views)
  96. };
  97. }
  98. private TileView CreateTileView (int titleNumber, Orientation orientation)
  99. {
  100. var toReturn = new TileView
  101. {
  102. Width = Dim.Fill (),
  103. Height = Dim.Fill (),
  104. // flip the orientation
  105. Orientation = orientation
  106. };
  107. toReturn.Tiles.ElementAt (0).Title = _cbTitles.CheckedState == CheckState.Checked ? $"View {titleNumber}" : string.Empty;
  108. toReturn.Tiles.ElementAt (1).Title = _cbTitles.CheckedState == CheckState.Checked ? $"View {titleNumber + 1}" : string.Empty;
  109. return toReturn;
  110. }
  111. private int GetNumberOfViews ()
  112. {
  113. if (int.TryParse (_textField.Text, out int views) && views >= 0)
  114. {
  115. return views;
  116. }
  117. return 0;
  118. }
  119. private void Quit () { Application.RequestStop (); }
  120. private void SetupTileView ()
  121. {
  122. int numberOfViews = GetNumberOfViews ();
  123. CheckState titles = _cbTitles.CheckedState;
  124. CheckState border = _cbBorder.CheckedState;
  125. CheckState startHorizontal = _cbHorizontal.CheckedState;
  126. foreach (View sub in _workArea.SubViews)
  127. {
  128. sub.Dispose ();
  129. }
  130. _workArea.RemoveAll ();
  131. if (numberOfViews <= 0)
  132. {
  133. return;
  134. }
  135. TileView root = CreateTileView (1, startHorizontal == CheckState.Checked ? Orientation.Horizontal : Orientation.Vertical);
  136. root.Tiles.ElementAt (0).ContentView.Add (CreateContentControl (1));
  137. root.Tiles.ElementAt (0).Title = _cbTitles.CheckedState == CheckState.Checked ? "View 1" : string.Empty;
  138. root.Tiles.ElementAt (1).ContentView.Add (CreateContentControl (2));
  139. root.Tiles.ElementAt (1).Title = _cbTitles.CheckedState == CheckState.Checked ? "View 2" : string.Empty;
  140. root.LineStyle = border == CheckState.Checked? LineStyle.Rounded : LineStyle.None;
  141. _workArea.Add (root);
  142. if (numberOfViews == 1)
  143. {
  144. root.Tiles.ElementAt (1).ContentView.Visible = false;
  145. }
  146. if (numberOfViews > 2)
  147. {
  148. _viewsCreated = 2;
  149. _viewsToCreate = numberOfViews;
  150. AddMoreViews (root);
  151. }
  152. }
  153. private void Split (TileView to, bool left)
  154. {
  155. if (_viewsCreated == _viewsToCreate)
  156. {
  157. return;
  158. }
  159. TileView newView;
  160. if (left)
  161. {
  162. to.TrySplitTile (0, 2, out newView);
  163. }
  164. else
  165. {
  166. to.TrySplitTile (1, 2, out newView);
  167. }
  168. _viewsCreated++;
  169. // During splitting the old Title will have been migrated to View1 so we only need
  170. // to set the Title on View2 (the one that gets our new TextView)
  171. newView.Tiles.ElementAt (1).Title = _cbTitles.CheckedState == CheckState.Checked ? $"View {_viewsCreated}" : string.Empty;
  172. // Flip orientation
  173. newView.Orientation = to.Orientation == Orientation.Vertical
  174. ? Orientation.Horizontal
  175. : Orientation.Vertical;
  176. newView.Tiles.ElementAt (1).ContentView.Add (CreateContentControl (_viewsCreated));
  177. }
  178. }