AllViewsView.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. #nullable enable
  2. namespace UICatalog.Scenarios;
  3. public class AllViewsView : View
  4. {
  5. private const int MAX_VIEW_FRAME_HEIGHT = 25;
  6. public AllViewsView ()
  7. {
  8. CanFocus = true;
  9. BorderStyle = LineStyle.Heavy;
  10. Arrangement = ViewArrangement.Resizable;
  11. HorizontalScrollBar.AutoShow = false;
  12. VerticalScrollBar.AutoShow = true;
  13. SubViewsLaidOut += (sender, _) =>
  14. {
  15. if (sender is View sendingView)
  16. {
  17. sendingView.SetContentSize (new Size (sendingView.Viewport.Width, sendingView.GetHeightRequiredForSubViews ()));
  18. }
  19. };
  20. AddCommand (Command.Up, () => ScrollVertical (-1));
  21. AddCommand (Command.Down, () => ScrollVertical (1));
  22. AddCommand (Command.PageUp, () => ScrollVertical (-SubViews.OfType<FrameView> ().First ().Frame.Height));
  23. AddCommand (Command.PageDown, () => ScrollVertical (SubViews.OfType<FrameView> ().First ().Frame.Height));
  24. AddCommand (
  25. Command.Start,
  26. () =>
  27. {
  28. Viewport = Viewport with { Y = 0 };
  29. return true;
  30. });
  31. AddCommand (
  32. Command.End,
  33. () =>
  34. {
  35. Viewport = Viewport with { Y = GetContentSize ().Height };
  36. return true;
  37. });
  38. AddCommand (Command.ScrollDown, () => ScrollVertical (1));
  39. AddCommand (Command.ScrollUp, () => ScrollVertical (-1));
  40. AddCommand (Command.ScrollRight, () => ScrollHorizontal (1));
  41. AddCommand (Command.ScrollLeft, () => ScrollHorizontal (-1));
  42. KeyBindings.Add (Key.CursorUp, Command.Up);
  43. KeyBindings.Add (Key.CursorDown, Command.Down);
  44. KeyBindings.Add (Key.CursorLeft, Command.Left);
  45. KeyBindings.Add (Key.CursorRight, Command.Right);
  46. KeyBindings.Add (Key.PageUp, Command.PageUp);
  47. KeyBindings.Add (Key.PageDown, Command.PageDown);
  48. KeyBindings.Add (Key.Home, Command.Start);
  49. KeyBindings.Add (Key.End, Command.End);
  50. KeyBindings.Add (PopoverMenu.DefaultKey, Command.Context);
  51. MouseBindings.Add (MouseFlags.Button1DoubleClicked, Command.Accept);
  52. MouseBindings.ReplaceCommands (MouseFlags.Button3Clicked, Command.Context);
  53. MouseBindings.ReplaceCommands (MouseFlags.Button1Clicked | MouseFlags.ButtonCtrl, Command.Context);
  54. MouseBindings.Add (MouseFlags.WheeledDown, Command.ScrollDown);
  55. MouseBindings.Add (MouseFlags.WheeledUp, Command.ScrollUp);
  56. MouseBindings.Add (MouseFlags.WheeledLeft, Command.ScrollLeft);
  57. MouseBindings.Add (MouseFlags.WheeledRight, Command.ScrollRight);
  58. }
  59. /// <inheritdoc/>
  60. public override void EndInit ()
  61. {
  62. base.EndInit ();
  63. List<Type> allClasses = GetAllViewClassesCollection ();
  64. View? previousView = null;
  65. foreach (Type type in allClasses)
  66. {
  67. View? view = CreateView (type);
  68. if (view is { })
  69. {
  70. FrameView frame = new ()
  71. {
  72. CanFocus = true,
  73. Title = type.Name,
  74. Y = previousView is { } ? Pos.Bottom (previousView) : 0,
  75. Width = Dim.Fill (),
  76. Height = Dim.Auto (DimAutoStyle.Content, maximumContentDim: MAX_VIEW_FRAME_HEIGHT)
  77. };
  78. frame.Add (view);
  79. Add (frame);
  80. previousView = frame;
  81. }
  82. }
  83. }
  84. private View? CreateView (Type type)
  85. {
  86. // If we are to create a generic Type
  87. if (type.IsGenericType)
  88. {
  89. // For each of the <T> arguments
  90. List<Type> typeArguments = new ();
  91. // use <object> or the original type if applicable
  92. foreach (Type arg in type.GetGenericArguments ())
  93. {
  94. if (arg.IsValueType && Nullable.GetUnderlyingType (arg) == null)
  95. {
  96. typeArguments.Add (arg);
  97. }
  98. else
  99. {
  100. // Check if the generic parameter has constraints
  101. Type [] constraints = arg.GetGenericParameterConstraints ();
  102. // Use the first constraint type to satisfy the constraint
  103. typeArguments.Add (constraints.Length > 0 ? constraints [0] : typeof (object));
  104. }
  105. }
  106. // And change what type we are instantiating from MyClass<T> to MyClass<object> or MyClass<T>
  107. try
  108. {
  109. type = type.MakeGenericType (typeArguments.ToArray ());
  110. }
  111. catch (ArgumentException ex)
  112. {
  113. Logging.Warning ($"Cannot create generic type {type} with arguments [{string.Join (", ", typeArguments.Select (t => t.Name))}]: {ex.Message}");
  114. return null;
  115. }
  116. }
  117. // Ensure the type does not contain any generic parameters
  118. if (type.ContainsGenericParameters)
  119. {
  120. Logging.Warning ($"Cannot create an instance of {type} because it contains generic parameters.");
  121. //throw new ArgumentException ($"Cannot create an instance of {type} because it contains generic parameters.");
  122. return null;
  123. }
  124. // Instantiate view
  125. var view = (View)Activator.CreateInstance (type)!;
  126. var demoText = "This, that, and the other thing.";
  127. if (view is IDesignable designable)
  128. {
  129. designable.EnableForDesign (ref demoText);
  130. }
  131. else
  132. {
  133. view.Text = demoText;
  134. view.Title = "_Test Title";
  135. }
  136. view.X = 0;
  137. view.Y = 0;
  138. view.Initialized += OnViewInitialized;
  139. return view;
  140. }
  141. private static List<Type> GetAllViewClassesCollection ()
  142. {
  143. List<Type> types = typeof (View).Assembly.GetTypes ()
  144. .Where (myType => myType is { IsClass: true, IsAbstract: false, IsPublic: true }
  145. && myType.IsSubclassOf (typeof (View)))
  146. .ToList ();
  147. types.Add (typeof (View));
  148. return types;
  149. }
  150. private void OnViewInitialized (object? sender, EventArgs e)
  151. {
  152. if (sender is not View view)
  153. {
  154. return;
  155. }
  156. if (view.Width == Dim.Absolute (0))
  157. {
  158. view.Width = Dim.Fill ();
  159. }
  160. if (view.Height == Dim.Absolute (0))
  161. {
  162. view.Height = MAX_VIEW_FRAME_HEIGHT - 2;
  163. }
  164. if (!view.Width.Has<DimAuto> (out _))
  165. {
  166. view.Width = Dim.Fill ();
  167. }
  168. if (!view.Height.Has<DimAuto> (out _))
  169. {
  170. view.Height = Dim.Auto (minimumContentDim: MAX_VIEW_FRAME_HEIGHT - 2, maximumContentDim: MAX_VIEW_FRAME_HEIGHT - 2);
  171. }
  172. }
  173. }