diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml index be02188d..5863c3ba 100644 --- a/Ink Canvas/MainWindow.xaml +++ b/Ink Canvas/MainWindow.xaml @@ -7199,312 +7199,26 @@ MinWidth="60"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + @@ -7518,245 +7232,18 @@ MaxHeight="24" MinWidth="120"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + diff --git a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs index 0a2525f9..8f2fe6b2 100644 --- a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs +++ b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs @@ -1023,6 +1023,10 @@ namespace Ink_Canvas border.Background = new SolidColorBrush(Color.FromArgb(28, 24, 24, 27)); } } + else if (sender is Ink_Canvas.Controls.ColorPickerButton colorPicker) + { + lastBorderMouseDownObject = sender; + } } /// @@ -1083,6 +1087,10 @@ namespace Ink_Canvas border.Background = new SolidColorBrush(Colors.Transparent); } } + else if (sender is Ink_Canvas.Controls.ColorPickerButton colorPicker) + { + lastBorderMouseDownObject = null; + } } /// @@ -2820,22 +2828,22 @@ namespace Ink_Canvas private void UpdateQuickColorPaletteIndicator(Color selectedColor) { // 隐藏所有check图标(双行显示) - QuickColorWhiteCheck.Visibility = Visibility.Collapsed; - QuickColorOrangeCheck.Visibility = Visibility.Collapsed; - QuickColorYellowCheck.Visibility = Visibility.Collapsed; - QuickColorBlackCheck.Visibility = Visibility.Collapsed; - QuickColorBlueCheck.Visibility = Visibility.Collapsed; - QuickColorRedCheck.Visibility = Visibility.Collapsed; - QuickColorGreenCheck.Visibility = Visibility.Collapsed; - QuickColorPurpleCheck.Visibility = Visibility.Collapsed; + QuickColorWhite.IsChecked = false; + QuickColorOrange.IsChecked = false; + QuickColorYellow.IsChecked = false; + QuickColorBlack.IsChecked = false; + QuickColorBlue.IsChecked = false; + QuickColorRed.IsChecked = false; + QuickColorGreen.IsChecked = false; + QuickColorPurple.IsChecked = false; // 隐藏所有check图标(单行显示) - QuickColorWhiteCheckSingle.Visibility = Visibility.Collapsed; - QuickColorOrangeCheckSingle.Visibility = Visibility.Collapsed; - QuickColorYellowCheckSingle.Visibility = Visibility.Collapsed; - QuickColorBlackCheckSingle.Visibility = Visibility.Collapsed; - QuickColorRedCheckSingle.Visibility = Visibility.Collapsed; - QuickColorGreenCheckSingle.Visibility = Visibility.Collapsed; + QuickColorWhiteSingle.IsChecked = false; + QuickColorOrangeSingle.IsChecked = false; + QuickColorYellowSingle.IsChecked = false; + QuickColorBlackSingle.IsChecked = false; + QuickColorRedSingle.IsChecked = false; + QuickColorGreenSingle.IsChecked = false; // 显示当前选中颜色的check图标 // 在荧光笔模式下,使用更宽松的颜色匹配 @@ -2843,21 +2851,21 @@ namespace Ink_Canvas if (IsColorSimilar(selectedColor, Colors.White, tolerance) || IsColorSimilar(selectedColor, Color.FromRgb(250, 250, 250), tolerance)) { - QuickColorWhiteCheck.Visibility = Visibility.Visible; - QuickColorWhiteCheckSingle.Visibility = Visibility.Visible; + QuickColorWhite.IsChecked = true; + QuickColorWhiteSingle.IsChecked = true; } else if (IsColorSimilar(selectedColor, Colors.Black, tolerance)) { - QuickColorBlackCheck.Visibility = Visibility.Visible; - QuickColorBlackCheckSingle.Visibility = Visibility.Visible; + QuickColorBlack.IsChecked = true; + QuickColorBlackSingle.IsChecked = true; } else if (IsColorSimilar(selectedColor, Colors.Yellow, tolerance) || IsColorSimilar(selectedColor, Color.FromRgb(234, 179, 8), tolerance) || IsColorSimilar(selectedColor, Color.FromRgb(250, 204, 21), tolerance) || IsColorSimilar(selectedColor, Color.FromRgb(253, 224, 71), tolerance)) { - QuickColorYellowCheck.Visibility = Visibility.Visible; - QuickColorYellowCheckSingle.Visibility = Visibility.Visible; + QuickColorYellow.IsChecked = true; + QuickColorYellowSingle.IsChecked = true; } else if (IsColorSimilar(selectedColor, Color.FromRgb(255, 165, 0), tolerance) || IsColorSimilar(selectedColor, Color.FromRgb(251, 150, 80), tolerance) || @@ -2866,29 +2874,29 @@ namespace Ink_Canvas IsColorSimilar(selectedColor, Color.FromRgb(251, 146, 60), tolerance) || IsColorSimilar(selectedColor, Color.FromRgb(253, 126, 20), tolerance)) { - QuickColorOrangeCheck.Visibility = Visibility.Visible; - QuickColorOrangeCheckSingle.Visibility = Visibility.Visible; + QuickColorOrange.IsChecked = true; + QuickColorOrangeSingle.IsChecked = true; } else if (IsColorSimilar(selectedColor, Color.FromRgb(37, 99, 235), tolerance)) { - QuickColorBlueCheck.Visibility = Visibility.Visible; + QuickColorBlue.IsChecked = true; // 单行显示模式没有蓝色,所以不设置单行的check } else if (IsColorSimilar(selectedColor, Colors.Red, tolerance) || IsColorSimilar(selectedColor, Color.FromRgb(220, 38, 38), tolerance) || IsColorSimilar(selectedColor, Color.FromRgb(239, 68, 68), tolerance)) { - QuickColorRedCheck.Visibility = Visibility.Visible; - QuickColorRedCheckSingle.Visibility = Visibility.Visible; + QuickColorRed.IsChecked = true; + QuickColorRedSingle.IsChecked = true; } else if (IsColorSimilar(selectedColor, Color.FromRgb(22, 163, 74), tolerance)) { - QuickColorGreenCheck.Visibility = Visibility.Visible; - QuickColorGreenCheckSingle.Visibility = Visibility.Visible; + QuickColorGreen.IsChecked = true; + QuickColorGreenSingle.IsChecked = true; } else if (IsColorSimilar(selectedColor, Color.FromRgb(147, 51, 234), tolerance)) { - QuickColorPurpleCheck.Visibility = Visibility.Visible; + QuickColorPurple.IsChecked = true; // 单行显示模式没有紫色,所以不设置单行的check } } diff --git a/InkCanvas.Controls/CircularColorButton.xaml b/InkCanvas.Controls/CircularColorButton.xaml new file mode 100644 index 00000000..cbb7e76d --- /dev/null +++ b/InkCanvas.Controls/CircularColorButton.xaml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + diff --git a/InkCanvas.Controls/CircularColorButton.xaml.cs b/InkCanvas.Controls/CircularColorButton.xaml.cs new file mode 100644 index 00000000..12bfb7ad --- /dev/null +++ b/InkCanvas.Controls/CircularColorButton.xaml.cs @@ -0,0 +1,194 @@ +using System; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Media; + +namespace Ink_Canvas.Controls +{ + public partial class CircularColorButton : UserControl + { + public static readonly DependencyProperty ColorProperty = DependencyProperty.Register( + nameof(Color), typeof(Color), typeof(CircularColorButton), + new PropertyMetadata(Colors.Transparent, OnColorChanged)); + + private static void OnColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var button = (CircularColorButton)d; + if (button.ColorOverlay != null) + button.ColorOverlay.Background = new SolidColorBrush((Color)e.NewValue); + } + + public Color Color + { + get => (Color)GetValue(ColorProperty); + set => SetValue(ColorProperty, value); + } + + public static readonly DependencyProperty ColorOpacityProperty = DependencyProperty.Register( + nameof(ColorOpacity), typeof(double), typeof(CircularColorButton), + new PropertyMetadata(0.75, OnColorOpacityChanged)); + + private static void OnColorOpacityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var button = (CircularColorButton)d; + if (button.ColorOverlay != null) + button.ColorOverlay.Opacity = (double)e.NewValue; + } + + public double ColorOpacity + { + get => (double)GetValue(ColorOpacityProperty); + set => SetValue(ColorOpacityProperty, value); + } + + public static readonly DependencyProperty IsCheckedProperty = DependencyProperty.Register( + nameof(IsChecked), typeof(bool), typeof(CircularColorButton), + new PropertyMetadata(true, OnIsCheckedChanged)); + + private static void OnIsCheckedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var button = (CircularColorButton)d; + if (button.CheckViewbox != null) + button.CheckViewbox.Visibility = (bool)e.NewValue ? Visibility.Visible : Visibility.Collapsed; + } + + public bool IsChecked + { + get => (bool)GetValue(IsCheckedProperty); + set => SetValue(IsCheckedProperty, value); + } + + public static readonly DependencyProperty ButtonSizeProperty = DependencyProperty.Register( + nameof(ButtonSize), typeof(double), typeof(CircularColorButton), + new PropertyMetadata(45.0, OnButtonSizeChanged)); + + private static void OnButtonSizeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var button = (CircularColorButton)d; + if (button.ButtonBorder == null) return; + + var size = (double)e.NewValue; + button.ButtonBorder.Width = size; + button.ButtonBorder.Height = size; + var radius = (size - 3) / 2; + button.ColorOverlay.Width = radius * 2; + button.ColorOverlay.Height = radius * 2; + button.ImageClipGeometry.RadiusX = radius; + button.ImageClipGeometry.RadiusY = radius; + button.ImageClipGeometry.Center = new Point(radius, radius); + button.TransparentGridImage.Width = radius * 2; + button.TransparentGridImage.Height = radius * 2; + } + + public double ButtonSize + { + get => (double)GetValue(ButtonSizeProperty); + set => SetValue(ButtonSizeProperty, value); + } + + public static readonly DependencyProperty BorderBrushColorProperty = DependencyProperty.Register( + nameof(BorderBrushColor), typeof(Color), typeof(CircularColorButton), + new PropertyMetadata(Color.FromRgb(254, 215, 170), OnBorderBrushColorChanged)); + + private static void OnBorderBrushColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var button = (CircularColorButton)d; + if (button.ButtonBorder != null) + button.ButtonBorder.BorderBrush = new SolidColorBrush((Color)e.NewValue); + } + + public Color BorderBrushColor + { + get => (Color)GetValue(BorderBrushColorProperty); + set => SetValue(BorderBrushColorProperty, value); + } + + public static readonly DependencyProperty CheckIconSourceProperty = DependencyProperty.Register( + nameof(CheckIconSource), typeof(string), typeof(CircularColorButton), + new PropertyMetadata("/Resources/new-icons/checked-white.png", OnCheckIconSourceChanged)); + + private static void OnCheckIconSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var button = (CircularColorButton)d; + if (button.CheckImage != null) + button.CheckImage.Source = new System.Windows.Media.Imaging.BitmapImage(new Uri((string)e.NewValue, UriKind.Relative)); + } + + public string CheckIconSource + { + get => (string)GetValue(CheckIconSourceProperty); + set => SetValue(CheckIconSourceProperty, value); + } + + public event MouseButtonEventHandler ButtonMouseDown; + public event MouseEventHandler ButtonMouseLeave; + public event RoutedEventHandler ButtonMouseUp; + + public CircularColorButton() + { + InitializeComponent(); + Loaded += CircularColorButton_Loaded; + } + + private void CircularColorButton_Loaded(object sender, RoutedEventArgs e) + { + ApplyAllProperties(); + } + + private void ApplyAllProperties() + { + if (ButtonBorder != null) + { + ButtonBorder.BorderBrush = new SolidColorBrush(BorderBrushColor); + var size = ButtonSize; + ButtonBorder.Width = size; + ButtonBorder.Height = size; + } + if (ColorOverlay != null) + { + ColorOverlay.Background = new SolidColorBrush(Color); + ColorOverlay.Opacity = ColorOpacity; + var radius = (ButtonSize - 3) / 2; + ColorOverlay.Width = radius * 2; + ColorOverlay.Height = radius * 2; + } + if (ImageClipGeometry != null) + { + var radius = (ButtonSize - 3) / 2; + ImageClipGeometry.RadiusX = radius; + ImageClipGeometry.RadiusY = radius; + ImageClipGeometry.Center = new Point(radius, radius); + } + if (TransparentGridImage != null) + { + var radius = (ButtonSize - 3) / 2; + TransparentGridImage.Width = radius * 2; + TransparentGridImage.Height = radius * 2; + } + if (CheckViewbox != null) + { + CheckViewbox.Visibility = IsChecked ? Visibility.Visible : Visibility.Collapsed; + } + if (CheckImage != null) + { + CheckImage.Source = new System.Windows.Media.Imaging.BitmapImage(new Uri(CheckIconSource, UriKind.Relative)); + } + } + + private void ButtonBorder_MouseDown(object sender, MouseButtonEventArgs e) + { + ButtonMouseDown?.Invoke(this, e); + } + + private void ButtonBorder_MouseLeave(object sender, MouseEventArgs e) + { + ButtonMouseLeave?.Invoke(this, e); + } + + private void ButtonBorder_MouseUp(object sender, MouseButtonEventArgs e) + { + ButtonMouseUp?.Invoke(this, new RoutedEventArgs(e.RoutedEvent, this)); + } + } +} diff --git a/InkCanvas.Controls/ColorPickerButton.xaml b/InkCanvas.Controls/ColorPickerButton.xaml new file mode 100644 index 00000000..77c850a2 --- /dev/null +++ b/InkCanvas.Controls/ColorPickerButton.xaml @@ -0,0 +1,36 @@ + + + + + + + + + + diff --git a/InkCanvas.Controls/ColorPickerButton.xaml.cs b/InkCanvas.Controls/ColorPickerButton.xaml.cs new file mode 100644 index 00000000..be5a828d --- /dev/null +++ b/InkCanvas.Controls/ColorPickerButton.xaml.cs @@ -0,0 +1,149 @@ +using System; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Media; + +namespace Ink_Canvas.Controls +{ + public partial class ColorPickerButton : UserControl + { + public static readonly DependencyProperty ColorProperty = DependencyProperty.Register( + nameof(Color), typeof(Color), typeof(ColorPickerButton), + new PropertyMetadata(Colors.Black, OnColorChanged)); + + private static void OnColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var button = (ColorPickerButton)d; + if (button.ButtonBorder != null) + button.ButtonBorder.Background = new SolidColorBrush((Color)e.NewValue); + } + + public Color Color + { + get => (Color)GetValue(ColorProperty); + set => SetValue(ColorProperty, value); + } + + public static readonly DependencyProperty IsCheckedProperty = DependencyProperty.Register( + nameof(IsChecked), typeof(bool), typeof(ColorPickerButton), + new PropertyMetadata(false, OnIsCheckedChanged)); + + private static void OnIsCheckedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var button = (ColorPickerButton)d; + if (button.CheckPath != null) + button.CheckPath.Visibility = (bool)e.NewValue ? Visibility.Visible : Visibility.Collapsed; + } + + public bool IsChecked + { + get => (bool)GetValue(IsCheckedProperty); + set => SetValue(IsCheckedProperty, value); + } + + public static readonly DependencyProperty CheckIconFillProperty = DependencyProperty.Register( + nameof(CheckIconFill), typeof(Brush), typeof(ColorPickerButton), + new PropertyMetadata(Brushes.White, OnCheckIconFillChanged)); + + private static void OnCheckIconFillChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var button = (ColorPickerButton)d; + if (button.CheckPath != null) + button.CheckPath.Fill = (Brush)e.NewValue; + } + + public Brush CheckIconFill + { + get => (Brush)GetValue(CheckIconFillProperty); + set => SetValue(CheckIconFillProperty, value); + } + + public static readonly DependencyProperty ButtonSizeProperty = DependencyProperty.Register( + nameof(ButtonSize), typeof(double), typeof(ColorPickerButton), + new PropertyMetadata(13.0, OnButtonSizeChanged)); + + private static void OnButtonSizeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var button = (ColorPickerButton)d; + if (button.ButtonBorder != null) + { + button.ButtonBorder.Width = (double)e.NewValue; + button.ButtonBorder.Height = (double)e.NewValue; + } + } + + public double ButtonSize + { + get => (double)GetValue(ButtonSizeProperty); + set => SetValue(ButtonSizeProperty, value); + } + + public static readonly DependencyProperty CheckIconSizeProperty = DependencyProperty.Register( + nameof(CheckIconSize), typeof(double), typeof(ColorPickerButton), + new PropertyMetadata(8.0, OnCheckIconSizeChanged)); + + private static void OnCheckIconSizeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var button = (ColorPickerButton)d; + if (button.CheckPath != null) + { + button.CheckPath.Width = (double)e.NewValue; + button.CheckPath.Height = (double)e.NewValue; + } + } + + public double CheckIconSize + { + get => (double)GetValue(CheckIconSizeProperty); + set => SetValue(CheckIconSizeProperty, value); + } + + public event MouseButtonEventHandler ButtonMouseDown; + public event MouseEventHandler ButtonMouseLeave; + public event RoutedEventHandler ButtonMouseUp; + + public ColorPickerButton() + { + InitializeComponent(); + Loaded += ColorPickerButton_Loaded; + } + + private void ColorPickerButton_Loaded(object sender, RoutedEventArgs e) + { + ApplyAllProperties(); + } + + private void ApplyAllProperties() + { + if (ButtonBorder != null) + { + ButtonBorder.Background = new SolidColorBrush(Color); + ButtonBorder.Width = ButtonSize; + ButtonBorder.Height = ButtonSize; + } + if (CheckPath != null) + { + CheckPath.Fill = CheckIconFill; + CheckPath.Width = CheckIconSize; + CheckPath.Height = CheckIconSize; + CheckPath.Visibility = IsChecked ? Visibility.Visible : Visibility.Collapsed; + } + } + + private void ButtonBorder_MouseDown(object sender, MouseButtonEventArgs e) + { + ButtonMouseDown?.Invoke(this, e); + } + + private void ButtonBorder_MouseLeave(object sender, MouseEventArgs e) + { + ButtonMouseLeave?.Invoke(this, e); + } + + private void ButtonBorder_MouseUp(object sender, MouseButtonEventArgs e) + { + ButtonMouseUp?.Invoke(this, new RoutedEventArgs(e.RoutedEvent, this)); + } + } +}