MainView.xaml.cs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. using System;
  2. using System.Collections;
  3. using System.Threading.Tasks;
  4. using Avalonia;
  5. using Avalonia.Controls;
  6. using Avalonia.Controls.ApplicationLifetimes;
  7. using Avalonia.LogicalTree;
  8. using Avalonia.Markup.Xaml;
  9. using Avalonia.Media;
  10. using Avalonia.Media.Immutable;
  11. using Avalonia.Platform;
  12. using Avalonia.VisualTree;
  13. using Avalonia.Styling;
  14. using ControlCatalog.Models;
  15. using ControlCatalog.Pages;
  16. using ControlCatalog.ViewModels;
  17. namespace ControlCatalog
  18. {
  19. public class MainView : UserControl
  20. {
  21. private readonly IPlatformSettings _platformSettings;
  22. public MainView()
  23. {
  24. AvaloniaXamlLoader.Load(this);
  25. _platformSettings = AvaloniaLocator.Current.GetRequiredService<IPlatformSettings>();
  26. PlatformSettingsOnColorValuesChanged(_platformSettings, _platformSettings.GetColorValues());
  27. var sideBar = this.Get<TabControl>("Sidebar");
  28. if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime)
  29. {
  30. var tabItems = (sideBar.Items as IList);
  31. tabItems?.Add(new TabItem()
  32. {
  33. Header = "Screens",
  34. Content = new ScreenPage()
  35. });
  36. }
  37. var themes = this.Get<ComboBox>("Themes");
  38. themes.SelectedItem = App.CurrentTheme;
  39. themes.SelectionChanged += (sender, e) =>
  40. {
  41. if (themes.SelectedItem is CatalogTheme theme)
  42. {
  43. App.SetCatalogThemes(theme);
  44. }
  45. };
  46. var themeVariants = this.Get<ComboBox>("ThemeVariants");
  47. themeVariants.SelectedItem = Application.Current!.RequestedThemeVariant;
  48. themeVariants.SelectionChanged += (sender, e) =>
  49. {
  50. if (themeVariants.SelectedItem is ThemeVariant themeVariant)
  51. {
  52. Application.Current!.RequestedThemeVariant = themeVariant;
  53. }
  54. };
  55. var flowDirections = this.Get<ComboBox>("FlowDirection");
  56. flowDirections.SelectionChanged += (sender, e) =>
  57. {
  58. if (flowDirections.SelectedItem is FlowDirection flowDirection)
  59. {
  60. TopLevel.GetTopLevel(this).FlowDirection = flowDirection;
  61. }
  62. };
  63. var decorations = this.Get<ComboBox>("Decorations");
  64. decorations.SelectionChanged += (sender, e) =>
  65. {
  66. if (VisualRoot is Window window
  67. && decorations.SelectedItem is SystemDecorations systemDecorations)
  68. {
  69. window.SystemDecorations = systemDecorations;
  70. }
  71. };
  72. var transparencyLevels = this.Get<ComboBox>("TransparencyLevels");
  73. IDisposable? topLevelBackgroundSideSetter = null, sideBarBackgroundSetter = null, paneBackgroundSetter = null;
  74. transparencyLevels.SelectionChanged += (sender, e) =>
  75. {
  76. topLevelBackgroundSideSetter?.Dispose();
  77. sideBarBackgroundSetter?.Dispose();
  78. paneBackgroundSetter?.Dispose();
  79. if (transparencyLevels.SelectedItem is WindowTransparencyLevel selected)
  80. {
  81. var topLevel = (TopLevel)this.GetVisualRoot()!;
  82. topLevel.TransparencyLevelHint = selected;
  83. if (selected != WindowTransparencyLevel.None)
  84. {
  85. var transparentBrush = new ImmutableSolidColorBrush(Colors.White, 0);
  86. var semiTransparentBrush = new ImmutableSolidColorBrush(Colors.Gray, 0.2);
  87. topLevelBackgroundSideSetter = topLevel.SetValue(BackgroundProperty, transparentBrush, Avalonia.Data.BindingPriority.Style);
  88. sideBarBackgroundSetter = sideBar.SetValue(BackgroundProperty, semiTransparentBrush, Avalonia.Data.BindingPriority.Style);
  89. paneBackgroundSetter = sideBar.SetValue(SplitView.PaneBackgroundProperty, semiTransparentBrush, Avalonia.Data.BindingPriority.Style);
  90. }
  91. }
  92. };
  93. }
  94. internal MainWindowViewModel ViewModel => (MainWindowViewModel)DataContext!;
  95. protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
  96. {
  97. base.OnAttachedToVisualTree(e);
  98. var decorations = this.Get<ComboBox>("Decorations");
  99. if (VisualRoot is Window window)
  100. decorations.SelectedIndex = (int)window.SystemDecorations;
  101. var insets = TopLevel.GetTopLevel(this)!.InsetsManager;
  102. if (insets != null)
  103. {
  104. // In real life application these events should be unsubscribed to avoid memory leaks.
  105. ViewModel.SafeAreaPadding = insets.SafeAreaPadding;
  106. insets.SafeAreaChanged += (sender, args) =>
  107. {
  108. ViewModel.SafeAreaPadding = insets.SafeAreaPadding;
  109. };
  110. ViewModel.DisplayEdgeToEdge = insets.DisplayEdgeToEdge;
  111. ViewModel.IsSystemBarVisible = insets.IsSystemBarVisible ?? true;
  112. ViewModel.PropertyChanged += async (sender, args) =>
  113. {
  114. if (args.PropertyName == nameof(ViewModel.DisplayEdgeToEdge))
  115. {
  116. insets.DisplayEdgeToEdge = ViewModel.DisplayEdgeToEdge;
  117. }
  118. else if (args.PropertyName == nameof(ViewModel.IsSystemBarVisible))
  119. {
  120. insets.IsSystemBarVisible = ViewModel.IsSystemBarVisible;
  121. }
  122. // Give the OS some time to apply new values and refresh the view model.
  123. await Task.Delay(100);
  124. ViewModel.DisplayEdgeToEdge = insets.DisplayEdgeToEdge;
  125. ViewModel.IsSystemBarVisible = insets.IsSystemBarVisible ?? true;
  126. };
  127. }
  128. _platformSettings.ColorValuesChanged += PlatformSettingsOnColorValuesChanged;
  129. PlatformSettingsOnColorValuesChanged(_platformSettings, _platformSettings.GetColorValues());
  130. }
  131. protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
  132. {
  133. base.OnDetachedFromLogicalTree(e);
  134. _platformSettings.ColorValuesChanged -= PlatformSettingsOnColorValuesChanged;
  135. }
  136. private void PlatformSettingsOnColorValuesChanged(object? sender, PlatformColorValues e)
  137. {
  138. Application.Current!.Resources["SystemAccentColor"] = e.AccentColor1;
  139. Application.Current.Resources["SystemAccentColorDark1"] = ChangeColorLuminosity(e.AccentColor1, -0.3);
  140. Application.Current.Resources["SystemAccentColorDark2"] = ChangeColorLuminosity(e.AccentColor1, -0.5);
  141. Application.Current.Resources["SystemAccentColorDark3"] = ChangeColorLuminosity(e.AccentColor1, -0.7);
  142. Application.Current.Resources["SystemAccentColorLight1"] = ChangeColorLuminosity(e.AccentColor1, 0.3);
  143. Application.Current.Resources["SystemAccentColorLight2"] = ChangeColorLuminosity(e.AccentColor1, 0.5);
  144. Application.Current.Resources["SystemAccentColorLight3"] = ChangeColorLuminosity(e.AccentColor1, 0.7);
  145. static Color ChangeColorLuminosity(Color color, double luminosityFactor)
  146. {
  147. var red = (double)color.R;
  148. var green = (double)color.G;
  149. var blue = (double)color.B;
  150. if (luminosityFactor < 0)
  151. {
  152. luminosityFactor = 1 + luminosityFactor;
  153. red *= luminosityFactor;
  154. green *= luminosityFactor;
  155. blue *= luminosityFactor;
  156. }
  157. else if (luminosityFactor >= 0)
  158. {
  159. red = (255 - red) * luminosityFactor + red;
  160. green = (255 - green) * luminosityFactor + green;
  161. blue = (255 - blue) * luminosityFactor + blue;
  162. }
  163. return new Color(color.A, (byte)red, (byte)green, (byte)blue);
  164. }
  165. }
  166. }
  167. }