TileViewNesting.cs 6.7 KB

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