diff --git a/demo/Semi.Avalonia.Demo/Controls/ColorDetailControl.axaml b/demo/Semi.Avalonia.Demo/Controls/ColorDetailControl.axaml index 4cda6e4..ccfda64 100644 --- a/demo/Semi.Avalonia.Demo/Controls/ColorDetailControl.axaml +++ b/demo/Semi.Avalonia.Demo/Controls/ColorDetailControl.axaml @@ -1,12 +1,9 @@ + xmlns:controls="clr-namespace:Semi.Avalonia.Demo.Controls"> - + ResourceKeyProperty = AvaloniaProperty.Register( - nameof(ResourceKey)); + + public static readonly StyledProperty ResourceKeyProperty = + AvaloniaProperty.Register(nameof(ResourceKey)); + public string? ResourceKey { get => GetValue(ResourceKeyProperty); set => SetValue(ResourceKeyProperty, value); } - public static readonly StyledProperty ResourceNameProperty = AvaloniaProperty.Register( - nameof(ResourceName)); + public static readonly StyledProperty ResourceNameProperty = + AvaloniaProperty.Register(nameof(ResourceName)); public string? ResourceName { @@ -32,8 +31,8 @@ public class ColorDetailControl: TemplatedControl set => SetValue(ResourceNameProperty, value); } - public static readonly StyledProperty ColorResourceKeyProperty = AvaloniaProperty.Register( - nameof(ColorResourceKey)); + public static readonly StyledProperty ColorResourceKeyProperty = + AvaloniaProperty.Register(nameof(ColorResourceKey)); public string? ColorResourceKey { @@ -41,27 +40,28 @@ public class ColorDetailControl: TemplatedControl set => SetValue(ColorResourceKeyProperty, value); } - public static readonly DirectProperty HexProperty = AvaloniaProperty.RegisterDirect( - nameof(Hex), o => o.Hex); + public static readonly DirectProperty HexProperty = + AvaloniaProperty.RegisterDirect(nameof(Hex), o => o.Hex); + private string? _hex; + public string? Hex { get => _hex; private set => SetAndRaise(HexProperty, ref _hex, value); } - - public static readonly DirectProperty OpacityNumberProperty = AvaloniaProperty.RegisterDirect( - nameof(OpacityNumber), o => o.OpacityNumber); + + public static readonly DirectProperty OpacityNumberProperty = + AvaloniaProperty.RegisterDirect(nameof(OpacityNumber), o => o.OpacityNumber); + private string? _opacityNumber; + public string? OpacityNumber { get => _opacityNumber; private set => SetAndRaise(OpacityNumberProperty, ref _opacityNumber, value); } - - - - + static ColorDetailControl() { BackgroundProperty.Changed.AddClassHandler((o, e) => o.OnBackgroundChanged(e)); @@ -84,13 +84,17 @@ public class ColorDetailControl: TemplatedControl { switch (s) { - case KEY_ResourceKey: text = ResourceKey; + case KEY_ResourceKey: + text = ResourceKey; break; - case KEY_Hex: text = Hex; + case KEY_Hex: + text = Hex; break; - case KEY_Opacity: text = OpacityNumber; + case KEY_Opacity: + text = OpacityNumber; break; - case KEY_ColorResourceKey: text = ColorResourceKey; + case KEY_ColorResourceKey: + text = ColorResourceKey; break; default: text = string.Empty; break; } @@ -99,9 +103,7 @@ public class ColorDetailControl: TemplatedControl var toplevel = TopLevel.GetTopLevel(this); if (toplevel?.Clipboard is { } c) { - await c.SetTextAsync(text??string.Empty); + await c.SetTextAsync(text ?? string.Empty); } - } - } \ No newline at end of file diff --git a/demo/Semi.Avalonia.Demo/Controls/ColorItemControl.axaml b/demo/Semi.Avalonia.Demo/Controls/ColorItemControl.axaml index 6e2cd4e..7169196 100644 --- a/demo/Semi.Avalonia.Demo/Controls/ColorItemControl.axaml +++ b/demo/Semi.Avalonia.Demo/Controls/ColorItemControl.axaml @@ -1,25 +1,23 @@ + xmlns:controls="using:Semi.Avalonia.Demo.Controls"> - - - - + + + + - - + \ No newline at end of file diff --git a/demo/Semi.Avalonia.Demo/Controls/ColorItemControl.cs b/demo/Semi.Avalonia.Demo/Controls/ColorItemControl.cs index 04c8000..b73cf5e 100644 --- a/demo/Semi.Avalonia.Demo/Controls/ColorItemControl.cs +++ b/demo/Semi.Avalonia.Demo/Controls/ColorItemControl.cs @@ -1,5 +1,4 @@ using Avalonia; -using Avalonia.Controls; using Avalonia.Controls.Primitives; using Avalonia.Input; using CommunityToolkit.Mvvm.Messaging; @@ -9,8 +8,8 @@ namespace Semi.Avalonia.Demo.Controls; public class ColorItemControl : TemplatedControl { - public static readonly StyledProperty ColorNameProperty = AvaloniaProperty.Register( - nameof(ColorName)); + public static readonly StyledProperty ColorNameProperty = + AvaloniaProperty.Register(nameof(ColorName)); public string? ColorName { @@ -26,14 +25,18 @@ public class ColorItemControl : TemplatedControl get => GetValue(HexProperty); set => SetValue(HexProperty, value); } - + protected override void OnPointerPressed(PointerPressedEventArgs e) { base.OnPointerPressed(e); - if (this.DataContext is ColorItemViewModel v) + switch (this.DataContext) { - WeakReferenceMessenger.Default.Send(v); + case ColorItemViewModel colorItemViewModel: + WeakReferenceMessenger.Default.Send(colorItemViewModel); + break; + case ColorResource colorResource: + WeakReferenceMessenger.Default.Send(colorResource); + break; } - } } \ No newline at end of file diff --git a/demo/Semi.Avalonia.Demo/Pages/HighContrastDemo.axaml b/demo/Semi.Avalonia.Demo/Pages/HighContrastDemo.axaml new file mode 100644 index 0000000..4639ee9 --- /dev/null +++ b/demo/Semi.Avalonia.Demo/Pages/HighContrastDemo.axaml @@ -0,0 +1,320 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/demo/Semi.Avalonia.Demo/Pages/HighContrastDemo.axaml.cs b/demo/Semi.Avalonia.Demo/Pages/HighContrastDemo.axaml.cs new file mode 100644 index 0000000..e8f4350 --- /dev/null +++ b/demo/Semi.Avalonia.Demo/Pages/HighContrastDemo.axaml.cs @@ -0,0 +1,13 @@ +using Avalonia.Controls; +using Semi.Avalonia.Demo.ViewModels; + +namespace Semi.Avalonia.Demo.Pages; + +public partial class HighContrastDemo : UserControl +{ + public HighContrastDemo() + { + InitializeComponent(); + this.DataContext = new HighContrastDemoViewModel(); + } +} \ No newline at end of file diff --git a/demo/Semi.Avalonia.Demo/Pages/ThemeVariantDemo.axaml b/demo/Semi.Avalonia.Demo/Pages/ThemeVariantDemo.axaml index 7303773..6f5bcf9 100644 --- a/demo/Semi.Avalonia.Demo/Pages/ThemeVariantDemo.axaml +++ b/demo/Semi.Avalonia.Demo/Pages/ThemeVariantDemo.axaml @@ -4,18 +4,36 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:vm="clr-namespace:Semi.Avalonia.Demo.Pages" + x:DataType="vm:ThemeVariantDemoViewModel" d:DesignHeight="450" d:DesignWidth="800" mc:Ignorable="d"> - - + + + + + + + + + + + + + - - - + + \ No newline at end of file diff --git a/demo/Semi.Avalonia.Demo/Pages/ThemeVariantDemo.axaml.cs b/demo/Semi.Avalonia.Demo/Pages/ThemeVariantDemo.axaml.cs index 2d80dd9..ad7366f 100644 --- a/demo/Semi.Avalonia.Demo/Pages/ThemeVariantDemo.axaml.cs +++ b/demo/Semi.Avalonia.Demo/Pages/ThemeVariantDemo.axaml.cs @@ -1,8 +1,7 @@ -using Avalonia; +using System.Collections.Generic; using Avalonia.Controls; -using Avalonia.Interactivity; -using Avalonia.Markup.Xaml; using Avalonia.Styling; +using CommunityToolkit.Mvvm.ComponentModel; namespace Semi.Avalonia.Demo.Pages; @@ -11,10 +10,22 @@ public partial class ThemeVariantDemo : UserControl public ThemeVariantDemo() { InitializeComponent(); + this.DataContext = new ThemeVariantDemoViewModel(); } +} - private void Switch_OnIsCheckedChanged(object sender, RoutedEventArgs e) - { - scope.RequestedThemeVariant = scope.ActualThemeVariant == ThemeVariant.Dark ? ThemeVariant.Light : ThemeVariant.Dark; - } +public partial class ThemeVariantDemoViewModel : ObservableObject +{ + [ObservableProperty] private ThemeVariant? _selectedThemeVariant; + + public IEnumerable ThemeVariants => + [ + ThemeVariant.Default, + ThemeVariant.Light, + ThemeVariant.Dark, + SemiTheme.Aquatic, + SemiTheme.Desert, + SemiTheme.Dust, + SemiTheme.NightSky, + ]; } \ No newline at end of file diff --git a/demo/Semi.Avalonia.Demo/ViewModels/HighContrastDemoViewModel.cs b/demo/Semi.Avalonia.Demo/ViewModels/HighContrastDemoViewModel.cs new file mode 100644 index 0000000..968aefa --- /dev/null +++ b/demo/Semi.Avalonia.Demo/ViewModels/HighContrastDemoViewModel.cs @@ -0,0 +1,137 @@ +using System.Collections.Generic; +using System.Collections.ObjectModel; +using Avalonia; +using Avalonia.Controls; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Media; +using Avalonia.Styling; +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Messaging; + +namespace Semi.Avalonia.Demo.ViewModels; + +public partial class HighContrastDemoViewModel : ObservableObject +{ + [ObservableProperty] private ThemeVariant? _selectedThemeVariant; + [ObservableProperty] private ColorResource _selectedColorResource = null!; + + public IEnumerable ThemeVariants { get; } + public ObservableCollection ColorResources { get; set; } + + public HighContrastDemoViewModel() + { + ThemeVariants = + [ + SemiTheme.Aquatic, + SemiTheme.Desert, + SemiTheme.Dust, + SemiTheme.NightSky, + ]; + ColorResources = + [ + new ColorResource + { + ResourceKey = "WindowColor", + Brush = new SolidColorBrush(Color.Parse("#202020")), + Hex = "#FF202020", + Description = "Background of pages, panes, popups, and windows.", + PairWith = "WindowTextColor" + }, + new ColorResource + { + ResourceKey = "WindowTextColor", + Brush = new SolidColorBrush(Color.Parse("#FFFFFF")), + Hex = "WHITE", + Description = "Headings, body copy, lists, placeholder text, app and window borders.", + PairWith = "WindowColor" + }, + new ColorResource + { + ResourceKey = "HotlightColor", + Brush = new SolidColorBrush(Color.Parse("#75E9FC")), + Hex = "#FF75E9FC", + Description = "Hyperlinks.", + PairWith = "WindowColor" + }, + new ColorResource + { + ResourceKey = "GrayTextColor", + Brush = new SolidColorBrush(Color.Parse("#A6A6A6")), + Hex = "#FFA6A6A6", + Description = "Inactive (disabled) UI.", + PairWith = "WindowColor" + }, + new ColorResource + { + ResourceKey = "HighlightTextColor", + Brush = new SolidColorBrush(Color.Parse("#263B50")), + Hex = "#FF263B50", + Description = + "Foreground color for text or UI that is in selected, interacted with (hover, pressed), or in progress.", + PairWith = "HighlightColor" + }, + new ColorResource + { + ResourceKey = "HighlightColor", + Brush = new SolidColorBrush(Color.Parse("#8EE3F0")), + Hex = "#FF8EE3F0", + Description = + "Background or accent color for UI that is in selected, interacted with (hover, pressed), or in progress.", + PairWith = "HighlightTextColor" + }, + new ColorResource + { + ResourceKey = "ButtonTextColor", + Brush = new SolidColorBrush(Color.Parse("#FFFFFF")), + Hex = "WHITE", + Description = "Foreground color for buttons and any UI that can be interacted with.", + PairWith = "ButtonFaceColor" + }, + new ColorResource + { + ResourceKey = "ButtonFaceColor", + Brush = new SolidColorBrush(Color.Parse("#202020")), + Hex = "#FF202020", + Description = "Background color for buttons and any UI that can be interacted with.", + PairWith = "ButtonTextColor" + }, + ]; + WeakReferenceMessenger.Default.Register + (this, (_, item) => SelectedColorResource = item); + SelectedThemeVariant = SemiTheme.Aquatic; + } + + partial void OnSelectedThemeVariantChanged(ThemeVariant? value) + { + var topLevel = ResolveDefaultTopLevel(); + if (value is null) return; + foreach (var colorResource in ColorResources) + { + if (colorResource.ResourceKey is null) continue; + if (topLevel?.TryFindResource(colorResource.ResourceKey, value, out var o) == true && o is Color color) + { + colorResource.Brush = new SolidColorBrush(color); + colorResource.Hex = color.ToString().ToUpperInvariant(); + } + } + } + + private static TopLevel? ResolveDefaultTopLevel() + { + return Application.Current?.ApplicationLifetime switch + { + IClassicDesktopStyleApplicationLifetime desktopLifetime => desktopLifetime.MainWindow, + ISingleViewApplicationLifetime singleView => TopLevel.GetTopLevel(singleView.MainView), + _ => null + }; + } +} + +public partial class ColorResource : ObservableObject +{ + [ObservableProperty] private string? _resourceKey; + [ObservableProperty] private SolidColorBrush? _brush; + [ObservableProperty] private string? _hex; + [ObservableProperty] private string? _description; + [ObservableProperty] private string? _pairWith; +} \ No newline at end of file diff --git a/demo/Semi.Avalonia.Demo/Views/MainView.axaml b/demo/Semi.Avalonia.Demo/Views/MainView.axaml index c3f0835..3d35910 100644 --- a/demo/Semi.Avalonia.Demo/Views/MainView.axaml +++ b/demo/Semi.Avalonia.Demo/Views/MainView.axaml @@ -104,6 +104,9 @@ + + +