From bf87bfeb9012c967953e01f8fd74ec2afe1e9965 Mon Sep 17 00:00:00 2001 From: rabbitism Date: Mon, 13 Feb 2023 00:14:56 +0800 Subject: [PATCH] feat: add color preview control. --- .../Controls/ColorDetailControl.axaml | 109 ++++++++++++++++++ .../Controls/ColorDetailControl.cs | 91 +++++++++++++++ .../Controls/ColorItemControl.axaml | 2 +- .../Pages/PaletteDemo.axaml | 37 +++--- .../ViewModels/PaletteDemoViewModel.cs | 104 +++++++++-------- src/Semi.Avalonia/Themes/Dark/SplitView.axaml | 2 +- 6 files changed, 274 insertions(+), 71 deletions(-) create mode 100644 demo/Semi.Avalonia.Demo/Controls/ColorDetailControl.axaml create mode 100644 demo/Semi.Avalonia.Demo/Controls/ColorDetailControl.cs diff --git a/demo/Semi.Avalonia.Demo/Controls/ColorDetailControl.axaml b/demo/Semi.Avalonia.Demo/Controls/ColorDetailControl.axaml new file mode 100644 index 0000000..81d842e --- /dev/null +++ b/demo/Semi.Avalonia.Demo/Controls/ColorDetailControl.axaml @@ -0,0 +1,109 @@ + + M5 7C3.89543 7 3 7.89543 3 9V19C3 20.1046 3.89543 21 5 21H15C16.1046 21 17 20.1046 17 19V9C17 7.89543 16.1046 7 15 7H5Z,M7 4C7 2.89543 7.89543 2 9 2H20C21.1046 2 22 2.89543 22 4V15C22 16.1046 21.1046 17 20 17H19V8C19 6 18 5 16 5H7V4Z + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/demo/Semi.Avalonia.Demo/Controls/ColorDetailControl.cs b/demo/Semi.Avalonia.Demo/Controls/ColorDetailControl.cs new file mode 100644 index 0000000..0dfc7d8 --- /dev/null +++ b/demo/Semi.Avalonia.Demo/Controls/ColorDetailControl.cs @@ -0,0 +1,91 @@ +using System.Globalization; +using Avalonia; +using Avalonia.Controls.Primitives; +using Avalonia.Input.Platform; +using Avalonia.Media; +using Avalonia.Media.Immutable; + +namespace Semi.Avalonia.Demo.Controls; + +public class ColorDetailControl: TemplatedControl +{ + public const string KEY_ResourceKey = "ResourceKey"; + public const string KEY_Hex = "Hex"; + public const string KEY_Opacity = "Opacity"; + + 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 string? ResourceName + { + get => GetValue(ResourceNameProperty); + set => SetValue(ResourceNameProperty, value); + } + + 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); + 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)); + } + + private void OnBackgroundChanged(AvaloniaPropertyChangedEventArgs args) + { + var color = args.GetNewValue(); + if (color is ISolidColorBrush b) + { + Hex = b.Color.ToString().ToUpperInvariant(); + OpacityNumber = b.Opacity.ToString(CultureInfo.InvariantCulture); + } + } + + public async void Copy(object o) + { + string? text = null; + if (o is string s) + { + switch (s) + { + case KEY_ResourceKey: text = ResourceKey; + break; + case KEY_Hex: text = Hex; + break; + case KEY_Opacity: text = OpacityNumber; + break; + default: text = string.Empty; break; + } + } + + if (Application.Current is { Clipboard: { } c }) + { + 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 479f9ba..a1274b3 100644 --- a/demo/Semi.Avalonia.Demo/Controls/ColorItemControl.axaml +++ b/demo/Semi.Avalonia.Demo/Controls/ColorItemControl.axaml @@ -27,7 +27,7 @@ Name="PART_HexTextBlock" Padding="8" VerticalAlignment="Bottom" - FontSize="8" + FontSize="10" Foreground="{TemplateBinding Foreground}" IsVisible="False" Opacity="0.8" diff --git a/demo/Semi.Avalonia.Demo/Pages/PaletteDemo.axaml b/demo/Semi.Avalonia.Demo/Pages/PaletteDemo.axaml index c90235e..3ed09a5 100644 --- a/demo/Semi.Avalonia.Demo/Pages/PaletteDemo.axaml +++ b/demo/Semi.Avalonia.Demo/Pages/PaletteDemo.axaml @@ -16,6 +16,7 @@ + @@ -31,6 +32,7 @@ - - - + - - + - + @@ -80,21 +77,21 @@ - + - + diff --git a/demo/Semi.Avalonia.Demo/ViewModels/PaletteDemoViewModel.cs b/demo/Semi.Avalonia.Demo/ViewModels/PaletteDemoViewModel.cs index 8cf0939..1b89ecb 100644 --- a/demo/Semi.Avalonia.Demo/ViewModels/PaletteDemoViewModel.cs +++ b/demo/Semi.Avalonia.Demo/ViewModels/PaletteDemoViewModel.cs @@ -10,9 +10,10 @@ namespace Semi.Avalonia.Demo.ViewModels; public class PaletteDemoViewModel: ObservableObject { - private string[] _colors = { "Amber","Blue","Cyan","Green","Grey","Indigo","LightBlue","LightGreen","Lime","Orange","Pink","Purple","Red","Teal","Violet","Yellow" }; - private ObservableCollection _lightSeries; - + private readonly string[] _predefinedColorNames = { "Amber","Blue","Cyan","Green","Grey","Indigo","LightBlue","LightGreen","Lime","Orange","Pink","Purple","Red","Teal","Violet","Yellow" }; + private IResourceDictionary _lightResourceDictionary; + private IResourceDictionary _darkResourceDictionary; + private ColorItemViewModel _selectedColor; public ColorItemViewModel SelectedColor @@ -20,49 +21,54 @@ public class PaletteDemoViewModel: ObservableObject get => _selectedColor; set => SetProperty(ref _selectedColor, value); } - - public ObservableCollection LightSeries - { - get => _lightSeries; - set => SetProperty(ref _lightSeries, value); - } - private ObservableCollection _darkSeries; - - public ObservableCollection DarkSeries + + private ObservableCollection _lightLists; + public ObservableCollection LightLists { - get => _darkSeries; - set => SetProperty(ref _darkSeries, value); + get => _lightLists; + set => SetProperty(ref _lightLists, value); + } + private ObservableCollection _darkLists; + public ObservableCollection DarkLists + { + get => _darkLists; + set => SetProperty(ref _darkLists, value); } public PaletteDemoViewModel() { - LightSeries = new ObservableCollection(); - var lightResourceDictionary = (ResourceDictionary)(AvaloniaXamlLoader.Load(new Uri("avares://Semi.Avalonia/Themes/Light/Palette.axaml"))); - foreach (var color in _colors) - { - ColorSeries s = new ColorSeries(); - s.Initialize(lightResourceDictionary, color, true); - LightSeries.Add(s); - } - DarkSeries = new ObservableCollection(); - var darkResouceDictionary = (ResourceDictionary)(AvaloniaXamlLoader.Load(new Uri("avares://Semi.Avalonia/Themes/Dark/Palette.axaml"))); - foreach (var color in _colors) - { - ColorSeries s = new ColorSeries(); - s.Initialize(darkResouceDictionary, color, false); - DarkSeries.Add(s); - } + _lightResourceDictionary = (ResourceDictionary)AvaloniaXamlLoader.Load(new Uri("avares://Semi.Avalonia/Themes/Light/Palette.axaml")); + _darkResourceDictionary = (ResourceDictionary)AvaloniaXamlLoader.Load(new Uri("avares://Semi.Avalonia/Themes/Dark/Palette.axaml")); + InitializePalette(); WeakReferenceMessenger.Default.Register(this, OnClickColorItem); } + private void InitializePalette() + { + LightLists = new ObservableCollection(); + foreach (var color in _predefinedColorNames) + { + ColorListViewModel s = new ColorListViewModel(); + s.Initialize(_lightResourceDictionary, color, true); + LightLists.Add(s); + } + DarkLists = new ObservableCollection(); + foreach (var color in _predefinedColorNames) + { + ColorListViewModel s = new ColorListViewModel(); + s.Initialize(_darkResourceDictionary, color, false); + DarkLists.Add(s); + } + } + private void OnClickColorItem(PaletteDemoViewModel vm, ColorItemViewModel item) { SelectedColor = item; } } -public class ColorSeries: ObservableObject +public class ColorListViewModel: ObservableObject { private ObservableCollection? _colors; @@ -104,25 +110,25 @@ public class ColorSeries: ObservableObject public class ColorItemViewModel : ObservableObject { - private IBrush _color; - public IBrush Color + private IBrush _brush; + public IBrush Brush { - get => _color; - set => SetProperty(ref _color, value); + get => _brush; + set => SetProperty(ref _brush, value); } - private IBrush _textColor; - public IBrush TextColor + private IBrush _textBrush; + public IBrush TextBrush { - get => _textColor; - set => SetProperty(ref _textColor, value); + get => _textBrush; + set => SetProperty(ref _textBrush, value); } - private string _name; - public string Name + private string _colorDisplayName; + public string ColorDisplayName { - get => _name; - set => SetProperty(ref _name, value); + get => _colorDisplayName; + set => SetProperty(ref _colorDisplayName, value); } private string _resourceKey; @@ -141,19 +147,19 @@ public class ColorItemViewModel : ObservableObject set => SetProperty(ref _hex, value); } - public ColorItemViewModel(string name, IBrush color, string resourceKey, bool light, int index) + public ColorItemViewModel(string colorDisplayName, IBrush brush, string resourceKey, bool light, int index) { - Name = name; - Color = color; + ColorDisplayName = colorDisplayName; + Brush = brush; ResourceKey = resourceKey; - Hex = color.ToString().ToUpperInvariant(); + Hex = brush.ToString().ToUpperInvariant(); if ((light && index < 5) || (!light && index > 5)) { - TextColor = Brushes.Black; + TextBrush = Brushes.Black; } else { - TextColor = Brushes.White; + TextBrush = Brushes.White; } } } \ No newline at end of file diff --git a/src/Semi.Avalonia/Themes/Dark/SplitView.axaml b/src/Semi.Avalonia/Themes/Dark/SplitView.axaml index 3d12d13..ff349b5 100644 --- a/src/Semi.Avalonia/Themes/Dark/SplitView.axaml +++ b/src/Semi.Avalonia/Themes/Dark/SplitView.axaml @@ -9,5 +9,5 @@ 00:00:00.1 0.1,0.9,0.2,1.0 - +