NavigationDemoHelper.cs 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. using System;
  2. using System.Collections.Generic;
  3. using Avalonia;
  4. using Avalonia.Controls;
  5. using Avalonia.Controls.Primitives;
  6. using Avalonia.Layout;
  7. using Avalonia.Media;
  8. namespace ControlCatalog.Pages
  9. {
  10. /// <summary>
  11. /// Shared helpers for ControlCatalog demo pages.
  12. /// </summary>
  13. internal static class NavigationDemoHelper
  14. {
  15. /// <summary>
  16. /// Pastel background brushes cycled by page index.
  17. /// </summary>
  18. internal static readonly IBrush[] PageBrushes =
  19. {
  20. new SolidColorBrush(Color.Parse("#BBDEFB")),
  21. new SolidColorBrush(Color.Parse("#C8E6C9")),
  22. new SolidColorBrush(Color.Parse("#FFE0B2")),
  23. new SolidColorBrush(Color.Parse("#E1BEE7")),
  24. new SolidColorBrush(Color.Parse("#FFCDD2")),
  25. new SolidColorBrush(Color.Parse("#B2EBF2")),
  26. };
  27. internal static IBrush GetPageBrush(int index) =>
  28. PageBrushes[((index % PageBrushes.Length) + PageBrushes.Length) % PageBrushes.Length];
  29. /// <summary>
  30. /// Creates a simple demo ContentPage with a centered title and subtitle.
  31. /// </summary>
  32. internal static ContentPage MakePage(string header, string body, int colorIndex) =>
  33. new ContentPage
  34. {
  35. Header = header,
  36. Background = GetPageBrush(colorIndex),
  37. Content = new StackPanel
  38. {
  39. HorizontalAlignment = HorizontalAlignment.Center,
  40. VerticalAlignment = VerticalAlignment.Center,
  41. Spacing = 8,
  42. Children =
  43. {
  44. new TextBlock
  45. {
  46. Text = header,
  47. FontSize = 20,
  48. FontWeight = FontWeight.SemiBold,
  49. HorizontalAlignment = HorizontalAlignment.Center
  50. },
  51. new TextBlock
  52. {
  53. Text = body,
  54. FontSize = 13,
  55. Opacity = 0.7,
  56. TextWrapping = TextWrapping.Wrap,
  57. TextAlignment = TextAlignment.Center,
  58. MaxWidth = 260
  59. }
  60. }
  61. },
  62. HorizontalContentAlignment = HorizontalAlignment.Stretch,
  63. VerticalContentAlignment = VerticalAlignment.Stretch
  64. };
  65. /// <summary>
  66. /// Creates a demo ContentPage with an icon, title, body, and hint text
  67. /// (used by DrawerPage detail pages).
  68. /// </summary>
  69. internal static ContentPage MakeSectionPage(
  70. string header, string iconData, string title, string body,
  71. int colorIndex, string? hint = null)
  72. {
  73. var panel = new StackPanel { Margin = new Thickness(24, 20), Spacing = 12 };
  74. panel.Children.Add(new PathIcon
  75. {
  76. Width = 48,
  77. Height = 48,
  78. Data = Geometry.Parse(iconData),
  79. Foreground = new SolidColorBrush(Color.Parse("#0078D4"))
  80. });
  81. panel.Children.Add(new TextBlock
  82. {
  83. Text = title,
  84. FontSize = 26,
  85. FontWeight = FontWeight.Bold
  86. });
  87. panel.Children.Add(new TextBlock
  88. {
  89. Text = body,
  90. FontSize = 14,
  91. Opacity = 0.8,
  92. TextWrapping = TextWrapping.Wrap
  93. });
  94. panel.Children.Add(new Separator { Margin = new Thickness(0, 8) });
  95. if (hint != null)
  96. {
  97. panel.Children.Add(new TextBlock
  98. {
  99. Text = hint,
  100. FontSize = 12,
  101. Opacity = 0.45,
  102. FontStyle = FontStyle.Italic,
  103. TextWrapping = TextWrapping.Wrap
  104. });
  105. }
  106. return new ContentPage
  107. {
  108. Header = header,
  109. Background = GetPageBrush(colorIndex),
  110. Content = new ScrollViewer { Content = panel },
  111. HorizontalContentAlignment = HorizontalAlignment.Stretch,
  112. VerticalContentAlignment = VerticalAlignment.Stretch
  113. };
  114. }
  115. private static readonly Geometry CloseIcon = Geometry.Parse(
  116. "M4.397 4.397a1 1 0 0 1 1.414 0L12 10.585l6.19-6.188a1 1 0 0 1 1.414 1.414L13.413 12l6.19 6.189a1 1 0 0 1-1.414 1.414L12 13.413l-6.189 6.19a1 1 0 0 1-1.414-1.414L10.585 12 4.397 5.811a1 1 0 0 1 0-1.414z");
  117. /// <summary>
  118. /// Builds the demo gallery home page for NavigationPage/TabbedPage/DrawerPage demo registries.
  119. /// </summary>
  120. internal static ContentPage CreateGalleryHomePage(
  121. NavigationPage nav,
  122. (string Group, string Title, string Description, Func<UserControl> Factory)[] demos)
  123. {
  124. var stack = new StackPanel { Margin = new Thickness(12), Spacing = 16 };
  125. var groups = new Dictionary<string, WrapPanel>();
  126. var groupOrder = new List<string>();
  127. foreach (var (group, title, description, factory) in demos)
  128. {
  129. if (!groups.ContainsKey(group))
  130. {
  131. groups[group] = new WrapPanel
  132. {
  133. Orientation = Orientation.Horizontal,
  134. HorizontalAlignment = HorizontalAlignment.Left
  135. };
  136. groupOrder.Add(group);
  137. }
  138. var demoFactory = factory;
  139. var demoTitle = title;
  140. var card = new Button
  141. {
  142. Width = 170,
  143. MinHeight = 80,
  144. Margin = new Thickness(0, 0, 8, 8),
  145. VerticalAlignment = VerticalAlignment.Top,
  146. HorizontalContentAlignment = HorizontalAlignment.Left,
  147. VerticalContentAlignment = VerticalAlignment.Top,
  148. Padding = new Thickness(12, 8),
  149. Content = new StackPanel
  150. {
  151. Spacing = 4,
  152. Children =
  153. {
  154. new TextBlock
  155. {
  156. Text = title,
  157. FontSize = 13,
  158. FontWeight = FontWeight.SemiBold,
  159. TextWrapping = TextWrapping.Wrap
  160. },
  161. new TextBlock
  162. {
  163. Text = description,
  164. FontSize = 11,
  165. Opacity = 0.6,
  166. TextWrapping = TextWrapping.Wrap
  167. }
  168. }
  169. }
  170. };
  171. card.Click += async (_, _) =>
  172. {
  173. var headerGrid = new Grid { ColumnDefinitions = new ColumnDefinitions("*, Auto") };
  174. headerGrid.Children.Add(new TextBlock
  175. {
  176. Text = demoTitle,
  177. VerticalAlignment = VerticalAlignment.Center
  178. });
  179. var closeBtn = new Button
  180. {
  181. Content = new PathIcon { Data = CloseIcon },
  182. Background = Brushes.Transparent,
  183. BorderThickness = new Thickness(0),
  184. Padding = new Thickness(8, 4),
  185. VerticalAlignment = VerticalAlignment.Center
  186. };
  187. Grid.SetColumn(closeBtn, 1);
  188. headerGrid.Children.Add(closeBtn);
  189. closeBtn.Click += async (_, _) => await nav.PopAsync(null);
  190. var page = new ContentPage
  191. {
  192. Header = headerGrid,
  193. Content = demoFactory(),
  194. HorizontalContentAlignment = HorizontalAlignment.Stretch,
  195. VerticalContentAlignment = VerticalAlignment.Stretch
  196. };
  197. NavigationPage.SetHasBackButton(page, false);
  198. await nav.PushAsync(page, null);
  199. };
  200. groups[group].Children.Add(card);
  201. }
  202. foreach (var groupName in groupOrder)
  203. {
  204. stack.Children.Add(new TextBlock
  205. {
  206. Text = groupName,
  207. FontSize = 13,
  208. FontWeight = FontWeight.SemiBold,
  209. Margin = new Thickness(0, 0, 0, 4),
  210. Opacity = 0.6
  211. });
  212. stack.Children.Add(groups[groupName]);
  213. }
  214. var homePage = new ContentPage
  215. {
  216. Content = new ScrollViewer { Content = stack },
  217. HorizontalContentAlignment = HorizontalAlignment.Stretch,
  218. VerticalContentAlignment = VerticalAlignment.Stretch
  219. };
  220. NavigationPage.SetHasNavigationBar(homePage, false);
  221. return homePage;
  222. }
  223. }
  224. }