-
Notifications
You must be signed in to change notification settings - Fork 255
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-Authored-By: huangjia2107 <[email protected]>
- Loading branch information
1 parent
74f2ac1
commit f50e43f
Showing
8 changed files
with
1,069 additions
and
0 deletions.
There are no files selected for viewing
220 changes: 220 additions & 0 deletions
220
src/WPFDevelopers.Shared/Controls/ColorPicker/ColorPicker.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,220 @@ | ||
using System; | ||
using System.Windows; | ||
using System.Windows.Controls; | ||
using System.Windows.Controls.Primitives; | ||
using System.Windows.Input; | ||
using System.Windows.Media; | ||
using WPFDevelopers.Utilities; | ||
|
||
namespace WPFDevelopers.Controls | ||
{ | ||
[TemplatePart(Name = HueSliderColorTemplateName, Type = typeof(Slider))] | ||
[TemplatePart(Name = CanvasTemplateName, Type = typeof(Canvas))] | ||
[TemplatePart(Name = ThumbTemplateName, Type = typeof(Thumb))] | ||
[TemplatePart(Name = ButtonTemplateName, Type = typeof(Button))] | ||
public class ColorPicker : Control | ||
{ | ||
|
||
private const string HueSliderColorTemplateName = "PART_HueSlider"; | ||
|
||
private const string CanvasTemplateName = "PART_Canvas"; | ||
|
||
private const string ThumbTemplateName = "PART_Thumb"; | ||
|
||
private const string ButtonTemplateName = "PART_Button"; | ||
|
||
private Slider _hueSliderColor; | ||
|
||
private Canvas _canvas; | ||
|
||
private Thumb _thumb; | ||
|
||
private Button _button; | ||
|
||
private bool _isInnerUpdateSelectedColor = false; | ||
|
||
private int currentGridStateIndex; | ||
|
||
private ColorTypeEnum[] colorTypeEnums; | ||
|
||
private static readonly DependencyPropertyKey HueColorPropertyKey = | ||
DependencyProperty.RegisterReadOnly("HueColor", typeof(Color), typeof(ColorPicker), new PropertyMetadata(Colors.Red)); | ||
public static readonly DependencyProperty HueColorProperty = HueColorPropertyKey.DependencyProperty; | ||
public Color HueColor | ||
{ | ||
get { return (Color)GetValue(HueColorProperty); } | ||
} | ||
|
||
public Color SelectedColor | ||
{ | ||
get { return (Color)GetValue(SelectedColorProperty); } | ||
set { SetValue(SelectedColorProperty, value); } | ||
} | ||
|
||
public static readonly DependencyProperty SelectedColorProperty = | ||
DependencyProperty.Register("SelectedColor", typeof(Color), typeof(ColorPicker), new FrameworkPropertyMetadata(Colors.Red, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnSelectedColorChanged)); | ||
|
||
static void OnSelectedColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) | ||
{ | ||
var ctrl = d as ColorPicker; | ||
if (ctrl._isInnerUpdateSelectedColor) | ||
{ | ||
ctrl._isInnerUpdateSelectedColor = false; | ||
return; | ||
} | ||
var color = (Color)e.NewValue; | ||
double h = 0, s = 0, b = 0; | ||
ColorUtil.HsbFromColor(color, ref h, ref s, ref b); | ||
var hsb = new HSB { H = h, S = s, B = b }; | ||
ctrl.SetValue(HueColorPropertyKey, ColorUtil.ColorFromHsb(hsb.H, 1, 1)); | ||
ctrl.SetValue(HSBPropertyKey, hsb); | ||
Canvas.SetLeft(ctrl._thumb, s * ctrl._canvas.ActualWidth - ctrl._thumb.ActualWidth / 2); | ||
Canvas.SetTop(ctrl._thumb, (1 - b) * ctrl._canvas.ActualHeight - ctrl._thumb.ActualHeight / 2); | ||
ctrl._hueSliderColor.Value = 1 - h; | ||
} | ||
|
||
private static readonly DependencyPropertyKey HSBPropertyKey = | ||
DependencyProperty.RegisterReadOnly("HSB", typeof(HSB), typeof(ColorPicker), new PropertyMetadata(new HSB())); | ||
|
||
public static readonly DependencyProperty HSBHProperty = HSBPropertyKey.DependencyProperty; | ||
|
||
public HSB HSB | ||
{ | ||
get { return (HSB)GetValue(HSBHProperty); } | ||
} | ||
|
||
|
||
|
||
public ColorTypeEnum ColorType | ||
{ | ||
get { return (ColorTypeEnum)GetValue(ColorTypeProperty); } | ||
set { SetValue(ColorTypeProperty, value); } | ||
} | ||
|
||
public static readonly DependencyProperty ColorTypeProperty = | ||
DependencyProperty.Register("ColorType", typeof(ColorTypeEnum), typeof(ColorPicker), new PropertyMetadata(ColorTypeEnum.RGB)); | ||
|
||
|
||
|
||
static ColorPicker() | ||
{ | ||
DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorPicker), new FrameworkPropertyMetadata(typeof(ColorPicker))); | ||
} | ||
|
||
public override void OnApplyTemplate() | ||
{ | ||
base.OnApplyTemplate(); | ||
if (_hueSliderColor != null) | ||
_hueSliderColor.ValueChanged -= HueSliderColor_OnValueChanged; | ||
_canvas = GetTemplateChild(CanvasTemplateName) as Canvas; | ||
if (_canvas != null) | ||
{ | ||
|
||
_canvas.Loaded += Canvas_Loaded; | ||
_canvas.MouseUp += _canvas_MouseUp; | ||
} | ||
_thumb = GetTemplateChild(ThumbTemplateName) as Thumb; | ||
if (_thumb != null) | ||
_thumb.DragDelta += Thumb_DragDelta; | ||
_hueSliderColor = GetTemplateChild(HueSliderColorTemplateName) as Slider; | ||
if (_hueSliderColor != null) | ||
_hueSliderColor.ValueChanged += HueSliderColor_OnValueChanged; | ||
|
||
_button = GetTemplateChild(ButtonTemplateName) as Button; | ||
currentGridStateIndex = 0; | ||
colorTypeEnums = (ColorTypeEnum[])Enum.GetValues(typeof(ColorTypeEnum)); | ||
if (_button != null) | ||
_button.Click += _button_Click; | ||
|
||
} | ||
|
||
private void _button_Click(object sender, RoutedEventArgs e) | ||
{ | ||
currentGridStateIndex = (currentGridStateIndex + 1) % colorTypeEnums.Length; | ||
ColorType = colorTypeEnums[currentGridStateIndex]; | ||
} | ||
|
||
private void _canvas_MouseUp(object sender, MouseButtonEventArgs e) | ||
{ | ||
var canvasPosition = e.GetPosition(_canvas); | ||
GetHSB(canvasPosition); | ||
} | ||
|
||
private void Canvas_MouseDown(object sender, MouseButtonEventArgs e) | ||
{ | ||
var canvasPosition = e.GetPosition(_canvas); | ||
GetHSB(canvasPosition); | ||
} | ||
|
||
void GetHSB(Point point, bool isMove = true) | ||
{ | ||
var newLeft = point.X - _thumb.ActualWidth / 2; | ||
var newTop = point.Y - _thumb.ActualHeight / 2; | ||
var thumbW = _thumb.ActualWidth / 2; | ||
var thumbH = _thumb.ActualHeight / 2; | ||
var canvasRight = _canvas.ActualWidth - thumbW; | ||
var canvasBottom = _canvas.ActualHeight - thumbH; | ||
if (newLeft < -thumbW) | ||
newLeft = -thumbW; | ||
else if (newLeft > canvasRight) | ||
newLeft = canvasRight; | ||
if (newTop < -thumbH) | ||
newTop = -thumbH; | ||
else if (newTop > canvasBottom) | ||
newTop = canvasBottom; | ||
|
||
if (isMove) | ||
{ | ||
Canvas.SetLeft(_thumb, newLeft); | ||
Canvas.SetTop(_thumb, newTop); | ||
} | ||
|
||
var hsb = new HSB { H = HSB.H, S = (newLeft + thumbW) / _canvas.ActualWidth, B = 1 - (newTop + thumbH) / _canvas.ActualHeight }; | ||
SetValue(HSBPropertyKey, hsb); | ||
var currentColor = ColorUtil.ColorFromAhsb(1, HSB.H, HSB.S, HSB.B); | ||
if (SelectedColor != currentColor) | ||
{ | ||
_isInnerUpdateSelectedColor = true; | ||
SelectedColor = currentColor; | ||
} | ||
} | ||
|
||
private void Thumb_DragDelta(object sender, DragDeltaEventArgs e) | ||
{ | ||
var point = Mouse.GetPosition(_canvas); | ||
GetHSB(point); | ||
} | ||
|
||
private void Canvas_Loaded(object sender, RoutedEventArgs e) | ||
{ | ||
var width = (int)_canvas.ActualWidth; | ||
var height = (int)_canvas.ActualHeight; | ||
var point = new Point(width - _thumb.ActualWidth / 2, -_thumb.ActualHeight / 2); | ||
Canvas.SetLeft(_thumb, point.X); | ||
Canvas.SetTop(_thumb, point.Y); | ||
var hsb = new HSB { H = _hueSliderColor.Value, S = HSB.S, B = HSB.B }; | ||
SetValue(HSBPropertyKey, hsb); | ||
} | ||
|
||
private void HueSliderColor_OnValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) | ||
{ | ||
|
||
if (DoubleUtil.AreClose(HSB.H, e.NewValue)) | ||
return; | ||
var hsb = new HSB { H = 1 - e.NewValue, S = HSB.S, B = HSB.B }; | ||
SetValue(HSBPropertyKey, hsb); | ||
SetValue(HueColorPropertyKey, ColorUtil.ColorFromHsb(HSB.H, 1, 1)); | ||
|
||
var newLeft = Canvas.GetLeft(_thumb); | ||
var newTop = Canvas.GetTop(_thumb); | ||
var point = new Point(newLeft, newTop); | ||
GetHSB(point, false); | ||
} | ||
} | ||
public enum ColorTypeEnum | ||
{ | ||
RGB, | ||
HSL, | ||
HEX, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
namespace WPFDevelopers.Controls | ||
{ | ||
public struct HSB | ||
{ | ||
public double H { get; set; } | ||
public double S { get; set; } | ||
public double B { get; set; } | ||
} | ||
} |
151 changes: 151 additions & 0 deletions
151
src/WPFDevelopers.Shared/Core/Converts/ColorConverter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
using System; | ||
using System.Globalization; | ||
using System.Text.RegularExpressions; | ||
using System.Windows.Data; | ||
using System.Windows.Media; | ||
using WPFDevelopers.Utilities; | ||
|
||
namespace WPFDevelopers.Converts | ||
{ | ||
public class ColorToRedConverter : IValueConverter | ||
{ | ||
private Color? _curColor = null; | ||
|
||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | ||
{ | ||
_curColor = (Color)value; | ||
|
||
return _curColor.Value.R; | ||
} | ||
|
||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | ||
{ | ||
return Color.FromArgb(_curColor.Value.A, (byte)(double.Parse(value.ToString())), _curColor.Value.G, _curColor.Value.B); | ||
} | ||
} | ||
|
||
public class ColorToGreenConverter : IValueConverter | ||
{ | ||
private Color? _curColor = null; | ||
|
||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | ||
{ | ||
_curColor = (Color)value; | ||
|
||
return _curColor.Value.G; | ||
} | ||
|
||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | ||
{ | ||
return Color.FromArgb(_curColor.Value.A, _curColor.Value.R, (byte)(double.Parse(value.ToString())), _curColor.Value.B); | ||
} | ||
} | ||
|
||
public class ColorToBlueConverter : IValueConverter | ||
{ | ||
private Color? _curColor = null; | ||
|
||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | ||
{ | ||
_curColor = (Color)value; | ||
|
||
return _curColor.Value.B; | ||
} | ||
|
||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | ||
{ | ||
return Color.FromArgb(_curColor.Value.A, _curColor.Value.R, _curColor.Value.G, (byte)(double.Parse(value.ToString()))); | ||
} | ||
} | ||
|
||
public class ColorToBrushConverter : IValueConverter | ||
{ | ||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | ||
{ | ||
return new SolidColorBrush((Color)value); | ||
} | ||
|
||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
} | ||
|
||
public class ColorToStringConverter : IValueConverter | ||
{ | ||
private Color? _curColor = null; | ||
|
||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | ||
{ | ||
_curColor = (Color)value; | ||
|
||
return _curColor.ToString(); | ||
} | ||
|
||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | ||
{ | ||
var colorStr = (string)value; | ||
|
||
if (!string.IsNullOrWhiteSpace(colorStr) && Regex.IsMatch(colorStr, @"^#[\da-fA-F]{6,8}$")) | ||
return ColorConverter.ConvertFromString(colorStr); | ||
|
||
return _curColor.Value; | ||
} | ||
|
||
} | ||
|
||
public class HToColorConverter : IValueConverter | ||
{ | ||
private Color? _curColor = null; | ||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | ||
{ | ||
_curColor = (Color)value; | ||
return $"{ColorUtil.ColorFromH(_curColor.Value)}"; | ||
} | ||
|
||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | ||
{ | ||
var colorStr = (string)value; | ||
if (!string.IsNullOrWhiteSpace(colorStr) && double.TryParse(colorStr, out double hValue)) | ||
_curColor = ColorUtil.ConvertHSLToColor(_curColor.Value, hValue: hValue % 360); | ||
return _curColor; | ||
} | ||
} | ||
|
||
public class SToColorConverter : IValueConverter | ||
{ | ||
private Color? _curColor = null; | ||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | ||
{ | ||
_curColor = (Color)value; | ||
return $"{ColorUtil.ColorFromS(_curColor.Value)}%"; | ||
} | ||
|
||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | ||
{ | ||
var colorStr = (string)value; | ||
if (!string.IsNullOrWhiteSpace(colorStr) && double.TryParse(colorStr, out double sValue)) | ||
_curColor = ColorUtil.ConvertHSLToColor(_curColor.Value, sValue: sValue / 100); | ||
return _curColor; | ||
} | ||
} | ||
|
||
public class LToColorConverter : IValueConverter | ||
{ | ||
private Color? _curColor = null; | ||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | ||
{ | ||
_curColor = (Color)value; | ||
return $"{ColorUtil.ColorFromL(_curColor.Value)}%"; | ||
} | ||
|
||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | ||
{ | ||
var colorStr = (string)value; | ||
if (!string.IsNullOrWhiteSpace(colorStr) && double.TryParse(colorStr, out double lValue)) | ||
_curColor = ColorUtil.ConvertHSLToColor(_curColor.Value, lValue: lValue / 100); | ||
return _curColor; | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.