Adjust the file structure
This commit is contained in:
1 parent
9b0205a030
commit
d920bf678e
16 files changed
+95
-173
No files matched your search
@@ -1,717 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using HandyControl.Data;
|
||||
using HandyControl.Interactivity;
|
||||
using HandyControl.Tools.Extension;
|
||||
|
||||
namespace HandyControl.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// 颜色拾取器
|
||||
/// </summary>
|
||||
[TemplatePart(Name = ElementBorderColor, Type = typeof(Border))]
|
||||
[TemplatePart(Name = ElementBorderPicker, Type = typeof(Border))]
|
||||
[TemplatePart(Name = ElementBorderDrag, Type = typeof(Border))]
|
||||
[TemplatePart(Name = ElementPanelColor, Type = typeof(Panel))]
|
||||
[TemplatePart(Name = ElementSliderColor, Type = typeof(Panel))]
|
||||
[TemplatePart(Name = ElementSliderOpacity, Type = typeof(Panel))]
|
||||
[TemplatePart(Name = ElementPanelRgb, Type = typeof(Panel))]
|
||||
public class ColorPicker : Control, ISingleOpen
|
||||
{
|
||||
#region Constants
|
||||
|
||||
private const string ElementBorderColor = "PART_BorderColor";
|
||||
private const string ElementBorderPicker = "PART_BorderPicker";
|
||||
private const string ElementBorderDrag = "PART_BorderDrag";
|
||||
private const string ElementPanelColor = "PART_PanelColor";
|
||||
private const string ElementSliderColor = "PART_SliderColor";
|
||||
private const string ElementSliderOpacity = "PART_SliderOpacity";
|
||||
private const string ElementPanelRgb = "PART_PanelRgb";
|
||||
|
||||
#endregion Constants
|
||||
|
||||
#region Data
|
||||
|
||||
private Panel _panelRgb;
|
||||
|
||||
private Border _borderColor;
|
||||
|
||||
private Border _borderPicker;
|
||||
|
||||
private Border _borderDrag;
|
||||
|
||||
private Panel _panelColor;
|
||||
|
||||
private Slider _sliderColor;
|
||||
|
||||
private Slider _sliderOpacity;
|
||||
|
||||
private bool _appliedTemplate;
|
||||
|
||||
/// <summary>
|
||||
/// 当前显示的颜色类型
|
||||
/// </summary>
|
||||
private int _colorType;
|
||||
|
||||
/// <summary>
|
||||
/// 是否已经加载控件
|
||||
/// </summary>
|
||||
private bool _isLoaded;
|
||||
|
||||
/// <summary>
|
||||
/// 是否需要更新小球位置
|
||||
/// </summary>
|
||||
private bool _isNeedUpdatePicker = true;
|
||||
|
||||
/// <summary>
|
||||
/// 是否在拖动小球
|
||||
/// </summary>
|
||||
private bool _isOnDragging;
|
||||
|
||||
/// <summary>
|
||||
/// 是否需要更新信息
|
||||
/// </summary>
|
||||
private bool IsNeedUpdateInfo { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 颜色选取面板宽度
|
||||
/// </summary>
|
||||
private const double ColorPanelWidth = 230;
|
||||
|
||||
/// <summary>
|
||||
/// 颜色选取面板高度
|
||||
/// </summary>
|
||||
private const double ColorPanelHeight = 122;
|
||||
|
||||
/// <summary>
|
||||
/// 预设的颜色(一共18个,两行)
|
||||
/// </summary>
|
||||
private readonly List<string> _colorPresetList = new List<string>
|
||||
{
|
||||
"#f44336",
|
||||
"#e91e63",
|
||||
"#9c27b0",
|
||||
"#673ab7",
|
||||
"#3f51b5",
|
||||
"#2196f3",
|
||||
"#03a9f4",
|
||||
"#00bcd4",
|
||||
"#009688",
|
||||
|
||||
"#4caf50",
|
||||
"#8bc34a",
|
||||
"#cddc39",
|
||||
"#ffeb3b",
|
||||
"#ffc107",
|
||||
"#ff9800",
|
||||
"#ff5722",
|
||||
"#795548",
|
||||
"#9e9e9e"
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 颜色范围集合
|
||||
/// </summary>
|
||||
private readonly List<ColorRange> _colorRangeList = new List<ColorRange>
|
||||
{
|
||||
new ColorRange
|
||||
{
|
||||
Color1 = Color.FromRgb(255, 0, 0),
|
||||
Color2 = Color.FromRgb(255, 0, 255)
|
||||
},
|
||||
new ColorRange
|
||||
{
|
||||
Color1 = Color.FromRgb(255, 0, 255),
|
||||
Color2 = Color.FromRgb(0, 0, 255)
|
||||
},
|
||||
new ColorRange
|
||||
{
|
||||
Color1 = Color.FromRgb(0, 0, 255),
|
||||
Color2 = Color.FromRgb(0, 255, 255)
|
||||
},
|
||||
new ColorRange
|
||||
{
|
||||
Color1 = Color.FromRgb(0, 255, 255),
|
||||
Color2 = Color.FromRgb(0, 255, 0)
|
||||
},
|
||||
new ColorRange
|
||||
{
|
||||
Color1 = Color.FromRgb(0, 255, 0),
|
||||
Color2 = Color.FromRgb(255, 255, 0)
|
||||
},
|
||||
new ColorRange
|
||||
{
|
||||
Color1 = Color.FromRgb(255, 255, 0),
|
||||
Color2 = Color.FromRgb(255, 0, 0)
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 颜色分隔集合
|
||||
/// </summary>
|
||||
private readonly List<Color> _colorSeparateList = new List<Color>
|
||||
{
|
||||
Color.FromRgb(255, 0, 0),
|
||||
Color.FromRgb(255, 0, 255),
|
||||
Color.FromRgb(0, 0, 255),
|
||||
Color.FromRgb(0, 255, 255),
|
||||
Color.FromRgb(0, 255, 0),
|
||||
Color.FromRgb(255, 255, 0)
|
||||
};
|
||||
|
||||
#endregion Data
|
||||
|
||||
#region Public Events
|
||||
|
||||
/// <summary>
|
||||
/// 颜色改变事件
|
||||
/// </summary>
|
||||
public static readonly RoutedEvent SelectedColorChangedEvent =
|
||||
EventManager.RegisterRoutedEvent("SelectedColorChanged", RoutingStrategy.Bubble,
|
||||
typeof(EventHandler<FunctionEventArgs<Color>>), typeof(ColorPicker));
|
||||
|
||||
/// <summary>
|
||||
/// 颜色改变事件
|
||||
/// </summary>
|
||||
public event EventHandler<FunctionEventArgs<Color>> SelectedColorChanged
|
||||
{
|
||||
add => AddHandler(SelectedColorChangedEvent, value);
|
||||
remove => RemoveHandler(SelectedColorChangedEvent, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 取消事件
|
||||
/// </summary>
|
||||
public static readonly RoutedEvent CanceledEvent =
|
||||
EventManager.RegisterRoutedEvent("Canceled", RoutingStrategy.Bubble,
|
||||
typeof(EventHandler), typeof(ColorPicker));
|
||||
|
||||
/// <summary>
|
||||
/// 取消事件
|
||||
/// </summary>
|
||||
public event EventHandler Canceled
|
||||
{
|
||||
add => AddHandler(CanceledEvent, value);
|
||||
remove => RemoveHandler(CanceledEvent, value);
|
||||
}
|
||||
|
||||
#endregion Public Events
|
||||
|
||||
#region Properties
|
||||
|
||||
internal static readonly DependencyProperty ChannelAProperty = DependencyProperty.Register(
|
||||
"ChannelA", typeof(int), typeof(ColorPicker), new PropertyMetadata(255));
|
||||
|
||||
internal int ChannelA
|
||||
{
|
||||
get => (int)GetValue(ChannelAProperty);
|
||||
set => SetValue(ChannelAProperty, value);
|
||||
}
|
||||
|
||||
internal static readonly DependencyProperty ChannelRProperty = DependencyProperty.Register(
|
||||
"ChannelR", typeof(int), typeof(ColorPicker), new PropertyMetadata(255));
|
||||
|
||||
internal int ChannelR
|
||||
{
|
||||
get => (int)GetValue(ChannelRProperty);
|
||||
set => SetValue(ChannelRProperty, value);
|
||||
}
|
||||
|
||||
internal static readonly DependencyProperty ChannelGProperty = DependencyProperty.Register(
|
||||
"ChannelG", typeof(int), typeof(ColorPicker), new PropertyMetadata(255));
|
||||
|
||||
internal int ChannelG
|
||||
{
|
||||
get => (int)GetValue(ChannelGProperty);
|
||||
set => SetValue(ChannelGProperty, value);
|
||||
}
|
||||
|
||||
internal static readonly DependencyProperty ChannelBProperty = DependencyProperty.Register(
|
||||
"ChannelB", typeof(int), typeof(ColorPicker), new PropertyMetadata(255));
|
||||
|
||||
internal int ChannelB
|
||||
{
|
||||
get => (int)GetValue(ChannelBProperty);
|
||||
set => SetValue(ChannelBProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty SelectedBrushProperty = DependencyProperty.Register(
|
||||
"SelectedBrush", typeof(SolidColorBrush), typeof(ColorPicker), new PropertyMetadata(Brushes.White,
|
||||
(o, args) =>
|
||||
{
|
||||
var ctl = (ColorPicker)o;
|
||||
var v = (SolidColorBrush)args.NewValue;
|
||||
|
||||
if (ctl.IsNeedUpdateInfo)
|
||||
{
|
||||
ctl.IsNeedUpdateInfo = false;
|
||||
ctl.ChannelR = v.Color.R;
|
||||
ctl.ChannelG = v.Color.G;
|
||||
ctl.ChannelB = v.Color.B;
|
||||
ctl.ChannelA = v.Color.A;
|
||||
ctl.IsNeedUpdateInfo = true;
|
||||
}
|
||||
ctl.UpdateStatus(v.Color);
|
||||
ctl.SelectedBrushWithoutOpacity = new SolidColorBrush(Color.FromRgb(v.Color.R, v.Color.G, v.Color.B));
|
||||
}));
|
||||
|
||||
/// <summary>
|
||||
/// 当前选中的颜色
|
||||
/// </summary>
|
||||
public SolidColorBrush SelectedBrush
|
||||
{
|
||||
get => (SolidColorBrush)GetValue(SelectedBrushProperty);
|
||||
set => SetValue(SelectedBrushProperty, value);
|
||||
}
|
||||
|
||||
internal static readonly DependencyProperty SelectedBrushWithoutOpacityProperty = DependencyProperty.Register(
|
||||
"SelectedBrushWithoutOpacity", typeof(SolidColorBrush), typeof(ColorPicker), new PropertyMetadata(Brushes.White));
|
||||
|
||||
internal SolidColorBrush SelectedBrushWithoutOpacity
|
||||
{
|
||||
get => (SolidColorBrush)GetValue(SelectedBrushWithoutOpacityProperty);
|
||||
set => SetValue(SelectedBrushWithoutOpacityProperty, value);
|
||||
}
|
||||
|
||||
internal static readonly DependencyProperty BackColorProperty = DependencyProperty.Register(
|
||||
"BackColor", typeof(SolidColorBrush), typeof(ColorPicker), new PropertyMetadata(Brushes.Red));
|
||||
|
||||
internal SolidColorBrush BackColor
|
||||
{
|
||||
get => (SolidColorBrush)GetValue(BackColorProperty);
|
||||
set => SetValue(BackColorProperty, value);
|
||||
}
|
||||
|
||||
internal static readonly DependencyProperty ShowListProperty = DependencyProperty.Register(
|
||||
"ShowList", typeof(List<bool>), typeof(ColorPicker), new PropertyMetadata(new List<bool>
|
||||
{
|
||||
true, false, false
|
||||
}));
|
||||
|
||||
internal List<bool> ShowList
|
||||
{
|
||||
get => (List<bool>)GetValue(ShowListProperty);
|
||||
set => SetValue(ShowListProperty, value);
|
||||
}
|
||||
|
||||
#endregion Properties
|
||||
|
||||
/// <summary>
|
||||
/// 当前显示的颜色类型
|
||||
/// </summary>
|
||||
private int ColorType
|
||||
{
|
||||
get => _colorType;
|
||||
set
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
_colorType = 1;
|
||||
}
|
||||
else if (value > 1)
|
||||
{
|
||||
_colorType = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_colorType = value;
|
||||
}
|
||||
|
||||
var list = new List<bool>();
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
list.Add(false);
|
||||
}
|
||||
list[_colorType] = true;
|
||||
ShowList = list;
|
||||
}
|
||||
}
|
||||
|
||||
public ColorPicker()
|
||||
{
|
||||
CommandBindings.Add(new CommandBinding(ControlCommands.Confirm, ButtonConfirm_OnClick));
|
||||
CommandBindings.Add(new CommandBinding(ControlCommands.Switch, ButtonSwitch_OnClick));
|
||||
CommandBindings.Add(new CommandBinding(ControlCommands.Cancel, ButtonCancel_OnClick));
|
||||
CommandBindings.Add(new CommandBinding(ControlCommands.Dropper, ButtonDropper_OnClick));
|
||||
|
||||
Loaded += (s, e) =>
|
||||
{
|
||||
if (!_isLoaded)
|
||||
{
|
||||
Init();
|
||||
_isLoaded = true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
_appliedTemplate = false;
|
||||
if (_sliderColor != null)
|
||||
{
|
||||
_sliderColor.ValueChanged -= SliderColor_OnValueChanged;
|
||||
}
|
||||
|
||||
if (_sliderOpacity != null)
|
||||
{
|
||||
_sliderOpacity.ValueChanged -= SliderOpacity_OnValueChanged;
|
||||
}
|
||||
|
||||
_panelColor?.Children.Clear();
|
||||
|
||||
_panelRgb?.RemoveHandler(NumericUpDown.ValueChangedEvent, new EventHandler<FunctionEventArgs<double>>(NumericUpDownRgb_OnValueChanged));
|
||||
|
||||
base.OnApplyTemplate();
|
||||
|
||||
_borderColor = GetTemplateChild(ElementBorderColor) as Border;
|
||||
_borderDrag = GetTemplateChild(ElementBorderDrag) as Border;
|
||||
_borderPicker = GetTemplateChild(ElementBorderPicker) as Border;
|
||||
_panelColor = GetTemplateChild(ElementPanelColor) as Panel;
|
||||
_sliderColor = GetTemplateChild(ElementSliderColor) as Slider;
|
||||
_sliderOpacity = GetTemplateChild(ElementSliderOpacity) as Slider;
|
||||
_panelRgb = GetTemplateChild(ElementPanelRgb) as Panel;
|
||||
|
||||
if (_sliderColor != null)
|
||||
{
|
||||
_sliderColor.ValueChanged += SliderColor_OnValueChanged;
|
||||
}
|
||||
|
||||
if (_sliderOpacity != null)
|
||||
{
|
||||
_sliderOpacity.ValueChanged += SliderOpacity_OnValueChanged;
|
||||
}
|
||||
|
||||
if (_borderDrag != null)
|
||||
{
|
||||
var behavior = new MouseDragElementBehavior();
|
||||
behavior.DragFinished += MouseDragElementBehavior_OnDragFinished;
|
||||
behavior.DragBegun += MouseDragElementBehavior_OnDragging;
|
||||
behavior.Dragging += MouseDragElementBehavior_OnDragging;
|
||||
var collection = Interaction.GetBehaviors(_borderDrag);
|
||||
collection.Add(behavior);
|
||||
}
|
||||
|
||||
_appliedTemplate = true;
|
||||
if (_isLoaded)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
_panelRgb?.AddHandler(NumericUpDown.ValueChangedEvent, new EventHandler<FunctionEventArgs<double>>(NumericUpDownRgb_OnValueChanged));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
private void Init()
|
||||
{
|
||||
UpdateStatus(SelectedBrush.Color);
|
||||
_panelColor.Children.Clear();
|
||||
foreach (var item in _colorPresetList)
|
||||
{
|
||||
_panelColor.Children.Add(CreateColorButton(item));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建颜色按钮
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private Button CreateColorButton(string colorStr)
|
||||
{
|
||||
var color = ColorConverter.ConvertFromString(colorStr) ?? default(Color);
|
||||
var brush = new SolidColorBrush((Color)color);
|
||||
|
||||
var button = new Button
|
||||
{
|
||||
Margin = new Thickness(0, 0, 12, 12),
|
||||
Style = FindResource("ButtonCustom") as Style,
|
||||
Content = new Border
|
||||
{
|
||||
Background = brush,
|
||||
Width = 12,
|
||||
Height = 12,
|
||||
CornerRadius = new CornerRadius(2)
|
||||
}
|
||||
};
|
||||
|
||||
button.Click += (s, e) =>
|
||||
{
|
||||
SelectedBrush = brush;
|
||||
ChannelA = byte.MaxValue;
|
||||
};
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 内部更新
|
||||
/// </summary>
|
||||
private void UpdateStatus(Color color)
|
||||
{
|
||||
if (_isOnDragging) return;
|
||||
|
||||
var r = color.R;
|
||||
var g = color.G;
|
||||
var b = color.B;
|
||||
var list = new List<byte>
|
||||
{
|
||||
r,
|
||||
g,
|
||||
b
|
||||
};
|
||||
|
||||
var max = list.Max();
|
||||
var min = list.Min();
|
||||
|
||||
if (min == max)
|
||||
{
|
||||
if (!(r == g && b == g))
|
||||
{
|
||||
BackColor = Brushes.Red;
|
||||
IsNeedUpdateInfo = false;
|
||||
if (!_sliderColor.IsMouseOver && !_sliderOpacity.IsMouseOver)
|
||||
{
|
||||
_sliderColor.Value = 0;
|
||||
}
|
||||
IsNeedUpdateInfo = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var maxIndex = list.IndexOf(max);
|
||||
var minIndex = list.IndexOf(min);
|
||||
var commonIndex = 3 - maxIndex - minIndex;
|
||||
if (commonIndex == 3)
|
||||
{
|
||||
BackColor = Brushes.Red;
|
||||
IsNeedUpdateInfo = false;
|
||||
if (!_sliderColor.IsMouseOver && !_sliderOpacity.IsMouseOver)
|
||||
{
|
||||
_sliderColor.Value = 0;
|
||||
}
|
||||
IsNeedUpdateInfo = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var common = list[commonIndex];
|
||||
list[maxIndex] = 255;
|
||||
list[minIndex] = 0;
|
||||
common = (byte)(255 * (min - common) / (double)(min - max));
|
||||
list[commonIndex] = common;
|
||||
BackColor = new SolidColorBrush(Color.FromRgb(list[0], list[1], list[2]));
|
||||
|
||||
list[commonIndex] = 0;
|
||||
var cIndex = _colorSeparateList.IndexOf(Color.FromRgb(list[0], list[1], list[2]));
|
||||
int sub;
|
||||
var direc = 0;
|
||||
if (cIndex < 5 && cIndex > 0)
|
||||
{
|
||||
var nextColorList = _colorSeparateList[cIndex + 1].ToList();
|
||||
var prevColorList = _colorSeparateList[cIndex - 1].ToList();
|
||||
if (nextColorList[minIndex] > 0)
|
||||
{
|
||||
var target = prevColorList[commonIndex];
|
||||
direc = 1;
|
||||
sub = target - common;
|
||||
}
|
||||
else
|
||||
{
|
||||
sub = common;
|
||||
}
|
||||
}
|
||||
else if (cIndex == 0)
|
||||
{
|
||||
sub = common;
|
||||
if (minIndex == 2)
|
||||
{
|
||||
sub = 255 - common;
|
||||
direc = -5;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sub = 255 - common;
|
||||
}
|
||||
var scale = sub / 255.0;
|
||||
var scaleTotal = cIndex - direc + scale;
|
||||
IsNeedUpdateInfo = false;
|
||||
if (!_sliderColor.IsMouseOver && !_sliderOpacity.IsMouseOver)
|
||||
{
|
||||
_sliderColor.Value = scaleTotal;
|
||||
}
|
||||
IsNeedUpdateInfo = true;
|
||||
}
|
||||
}
|
||||
|
||||
var matrix = _borderPicker.RenderTransform.Value;
|
||||
var x = max == 0 ? 0 : (1 - min / (double)max) * ColorPanelWidth;
|
||||
var y = (1 - max / 255.0) * ColorPanelHeight;
|
||||
if (_isNeedUpdatePicker)
|
||||
{
|
||||
_borderPicker.RenderTransform = new MatrixTransform(matrix.M11, matrix.M12, matrix.M21, matrix.M22, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
private void SliderColor_OnValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
|
||||
{
|
||||
if (!_appliedTemplate || !IsNeedUpdateInfo) return;
|
||||
var index = Math.Min(5, (int)Math.Floor(e.NewValue));
|
||||
var sub = e.NewValue - index;
|
||||
var range = _colorRangeList[index];
|
||||
|
||||
var color = range.GetColor(sub);
|
||||
BackColor = new SolidColorBrush(color);
|
||||
var matrix = _borderPicker.RenderTransform.Value;
|
||||
_isNeedUpdatePicker = false;
|
||||
UpdateColorWhenDrag(new Point(matrix.OffsetX, matrix.OffsetY));
|
||||
_isNeedUpdatePicker = true;
|
||||
}
|
||||
|
||||
private void SliderOpacity_OnValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
|
||||
{
|
||||
if (!_appliedTemplate || !IsNeedUpdateInfo) return;
|
||||
var color = SelectedBrush.Color;
|
||||
SelectedBrush = new SolidColorBrush(Color.FromArgb((byte)_sliderOpacity.Value, color.R, color.G, color.B));
|
||||
}
|
||||
|
||||
private void MouseDragElementBehavior_OnDragging(object sender, MouseEventArgs e)
|
||||
{
|
||||
var p = e.GetPosition(_borderColor);
|
||||
_isOnDragging = true;
|
||||
UpdateColorWhenDrag(p);
|
||||
_isOnDragging = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 拖动时更新颜色
|
||||
/// </summary>
|
||||
private void UpdateColorWhenDrag(Point p)
|
||||
{
|
||||
var matrix = _borderPicker.RenderTransform.Value;
|
||||
|
||||
if (p.X < 0)
|
||||
{
|
||||
p.X = 0;
|
||||
}
|
||||
else if (p.X > ColorPanelWidth)
|
||||
{
|
||||
p.X = ColorPanelWidth;
|
||||
}
|
||||
|
||||
if (p.Y < 0)
|
||||
{
|
||||
p.Y = 0;
|
||||
}
|
||||
else if (p.Y > ColorPanelHeight)
|
||||
{
|
||||
p.Y = ColorPanelHeight;
|
||||
}
|
||||
|
||||
if (_isNeedUpdatePicker)
|
||||
{
|
||||
_borderPicker.RenderTransform = new MatrixTransform(matrix.M11, matrix.M12, matrix.M21, matrix.M22, p.X, p.Y);
|
||||
}
|
||||
|
||||
var scaleX = p.X / ColorPanelWidth;
|
||||
var scaleY = 1 - p.Y / ColorPanelHeight;
|
||||
|
||||
var colorYLeft = Color.FromRgb((byte)(255 * scaleY), (byte)(255 * scaleY), (byte)(255 * scaleY));
|
||||
var colorYRight = Color.FromRgb((byte)(BackColor.Color.R * scaleY), (byte)(BackColor.Color.G * scaleY), (byte)(BackColor.Color.B * scaleY));
|
||||
|
||||
var subR = colorYLeft.R - colorYRight.R;
|
||||
var subG = colorYLeft.G - colorYRight.G;
|
||||
var subB = colorYLeft.B - colorYRight.B;
|
||||
|
||||
var color = Color.FromArgb((byte)_sliderOpacity.Value, (byte)(colorYLeft.R - subR * scaleX),
|
||||
(byte)(colorYLeft.G - subG * scaleX), (byte)(colorYLeft.B - subB * scaleX));
|
||||
SelectedBrush = new SolidColorBrush(color);
|
||||
}
|
||||
|
||||
private void MouseDragElementBehavior_OnDragFinished(object sender, MouseEventArgs e) => _borderDrag.RenderTransform = new MatrixTransform();
|
||||
|
||||
private void ButtonSwitch_OnClick(object sender, RoutedEventArgs e) => ColorType++;
|
||||
|
||||
// ReSharper disable once UnusedParameter.Local
|
||||
private void NumericUpDownRgb_OnValueChanged(object sender, FunctionEventArgs<double> e)
|
||||
{
|
||||
if (!_appliedTemplate || !IsNeedUpdateInfo) return;
|
||||
if (e.OriginalSource is NumericUpDown ctl && ctl.Tag is string tag)
|
||||
{
|
||||
var color = SelectedBrush.Color;
|
||||
IsNeedUpdateInfo = false;
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
case "R":
|
||||
{
|
||||
SelectedBrush = new SolidColorBrush(Color.FromArgb(color.A, (byte)e.Info, color.G, color.B));
|
||||
break;
|
||||
}
|
||||
case "G":
|
||||
{
|
||||
SelectedBrush = new SolidColorBrush(Color.FromArgb(color.A, color.R, (byte)e.Info, color.B));
|
||||
break;
|
||||
}
|
||||
case "B":
|
||||
{
|
||||
SelectedBrush = new SolidColorBrush(Color.FromArgb(color.A, color.R, color.G, (byte)e.Info));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IsNeedUpdateInfo = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void ButtonConfirm_OnClick(object sender, RoutedEventArgs e)
|
||||
=> RaiseEvent(new FunctionEventArgs<Color>(SelectedColorChangedEvent, this)
|
||||
{
|
||||
Info = SelectedBrush.Color
|
||||
});
|
||||
|
||||
private void ButtonCancel_OnClick(object sender, RoutedEventArgs e) => RaiseEvent(new RoutedEventArgs(CanceledEvent));
|
||||
|
||||
public void Dispose() => System.Windows.Window.GetWindow(this)?.Close();
|
||||
|
||||
public bool CanDispose { get; } = true;
|
||||
|
||||
private void ButtonDropper_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
MouseHook.Start();
|
||||
MouseHook.MouseAction += MouseHook_MouseAction;
|
||||
}
|
||||
|
||||
private void MouseHook_MouseAction(object sender, MouseHook.RawMouseEventArgs e)
|
||||
{
|
||||
SelectedBrush = new SolidColorBrush(GetColorAt(e.Point.x, e.Point.y));
|
||||
if (e.Message == MouseHook.MouseMessages.WM_LBUTTONDOWN)
|
||||
{
|
||||
MouseHook.Stop();
|
||||
MouseHook.MouseAction -= MouseHook_MouseAction;
|
||||
}
|
||||
}
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern IntPtr GetDesktopWindow();
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern IntPtr GetWindowDC(IntPtr window);
|
||||
[DllImport("gdi32.dll", SetLastError = true)]
|
||||
public static extern uint GetPixel(IntPtr dc, int x, int y);
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern int ReleaseDC(IntPtr window, IntPtr dc);
|
||||
|
||||
public static Color GetColorAt(int x, int y)
|
||||
{
|
||||
IntPtr desk = GetDesktopWindow();
|
||||
IntPtr dc = GetWindowDC(desk);
|
||||
int a = (int)GetPixel(dc, x, y);
|
||||
ReleaseDC(desk, dc);
|
||||
return Color.FromArgb(255, (byte)((a >> 0) & 0xff), (byte)((a >> 8) & 0xff), (byte)((a >> 16) & 0xff));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HandyControl
|
||||
{
|
||||
public static class MouseHook
|
||||
{
|
||||
//public static event EventHandler MouseAction = delegate { };
|
||||
public static event EventHandler<RawMouseEventArgs> MouseAction = delegate { };
|
||||
public class RawMouseEventArgs : EventArgs
|
||||
{
|
||||
internal MouseMessages Message { get; set; }
|
||||
internal POINT Point { get; set; }
|
||||
}
|
||||
|
||||
public static void Start()
|
||||
{
|
||||
_hookID = SetHook(_proc);
|
||||
}
|
||||
public static void Stop()
|
||||
{
|
||||
UnhookWindowsHookEx(_hookID);
|
||||
}
|
||||
|
||||
private static LowLevelMouseProc _proc = HookCallback;
|
||||
private static IntPtr _hookID = IntPtr.Zero;
|
||||
|
||||
private static IntPtr SetHook(LowLevelMouseProc proc)
|
||||
{
|
||||
using (Process curProcess = Process.GetCurrentProcess())
|
||||
using (ProcessModule curModule = curProcess.MainModule)
|
||||
{
|
||||
return SetWindowsHookEx(WH_MOUSE_LL, proc,
|
||||
GetModuleHandle(curModule.ModuleName), 0);
|
||||
}
|
||||
}
|
||||
|
||||
private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
private static IntPtr HookCallback(
|
||||
int nCode, IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
if (nCode < 0) return CallNextHookEx(_hookID, nCode, wParam, lParam);
|
||||
MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
|
||||
MouseAction(null, new RawMouseEventArgs() { Message = (MouseMessages)wParam, Point = hookStruct.pt });
|
||||
|
||||
return CallNextHookEx(_hookID, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
private const int WH_MOUSE_LL = 14;
|
||||
|
||||
public enum MouseMessages
|
||||
{
|
||||
WM_LBUTTONDOWN = 0x0201,
|
||||
WM_LBUTTONUP = 0x0202,
|
||||
WM_MOUSEMOVE = 0x0200,
|
||||
WM_MOUSEWHEEL = 0x020A,
|
||||
WM_RBUTTONDOWN = 0x0204,
|
||||
WM_RBUTTONUP = 0x0205
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct POINT
|
||||
{
|
||||
public int x;
|
||||
public int y;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct MSLLHOOKSTRUCT
|
||||
{
|
||||
public POINT pt;
|
||||
public uint mouseData;
|
||||
public uint flags;
|
||||
public uint time;
|
||||
public IntPtr dwExtraInfo;
|
||||
}
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
private static extern IntPtr SetWindowsHookEx(int idHook,
|
||||
LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
|
||||
IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
private static extern IntPtr GetModuleHandle(string lpModuleName);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user