This commit is contained in:
Wiesław Šoltés 2022-05-05 14:46:00 +02:00
Родитель 8259d011ba
Коммит a1de72cc31
9 изменённых файлов: 530 добавлений и 475 удалений

Просмотреть файл

@ -1,112 +1,26 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Reactive.Disposables;
using Avalonia;
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Controls.Mixins;
using Avalonia.Controls.Primitives;
using Avalonia.Data.Converters;
using Avalonia.Input;
using Avalonia.Media;
using ThemeEditor.Controls.ColorPicker.Converters;
using ThemeEditor.Controls.ColorPicker.Props;
namespace ThemeEditor.Controls.ColorPicker;
public class ColorPicker : TemplatedControl
{
public static readonly StyledProperty<double> Value1Property =
AvaloniaProperty.Register<ColorPicker, double>(nameof(Value1));
public static readonly StyledProperty<double> Value2Property =
AvaloniaProperty.Register<ColorPicker, double>(nameof(Value2));
public static readonly StyledProperty<double> Value3Property =
AvaloniaProperty.Register<ColorPicker, double>(nameof(Value3));
public static readonly StyledProperty<double> Value4Property =
AvaloniaProperty.Register<ColorPicker, double>(nameof(Value4));
public static readonly StyledProperty<Color> ColorProperty =
AvaloniaProperty.Register<ColorPicker, Color>(nameof(Color));
public static readonly StyledProperty<IEnumerable<ColorPickerProperties>> PropertiesProperty =
AvaloniaProperty.Register<ColorPicker, IEnumerable<ColorPickerProperties>>(nameof(Properties));
private Canvas? _colorCanvas;
private Thumb? _colorThumb;
private Canvas? _hueCanvas;
private Thumb? _hueThumb;
private Canvas? _alphaCanvas;
private Thumb? _alphaThumb;
private bool _updating;
private bool _captured;
private readonly IValueConverter _value1Converter = new HueConverter();
private readonly IValueConverter _value2Converter = new SaturationConverter();
private readonly IValueConverter _value3Converter = new ValueConverter();
private readonly IValueConverter _value4Converter = new AlphaConverter();
public ColorPicker()
{
Properties = new AvaloniaList<ColorPickerProperties>()
{
new HexProperties
{
Header = "Hex",
ColorPicker = this
},
new AlphaProperties
{
Header = "Alpha",
ColorPicker = this
},
new RgbProperties
{
Header = "RGB",
ColorPicker = this
},
new HsvProperties
{
Header = "HSV",
ColorPicker = this
},
new CmykProperties
{
Header = "CMYK",
ColorPicker = this
}
};
this.GetObservable(Value1Property).Subscribe(_ => OnValueChange());
this.GetObservable(Value2Property).Subscribe(_ => OnValueChange());
this.GetObservable(Value3Property).Subscribe(_ => OnValueChange());
this.GetObservable(Value4Property).Subscribe(_ => OnValueChange());
this.GetObservable(ColorProperty).Subscribe(_ => OnColorChange());
}
public double Value1
{
get { return GetValue(Value1Property); }
set { SetValue(Value1Property, value); }
}
public double Value2
{
get { return GetValue(Value2Property); }
set { SetValue(Value2Property, value); }
}
public double Value3
{
get { return GetValue(Value3Property); }
set { SetValue(Value3Property, value); }
}
public double Value4
{
get { return GetValue(Value4Property); }
set { SetValue(Value4Property, value); }
}
private ColorPickerPresenter? _colorPickerPresenter;
private CompositeDisposable? _disposable;
public Color Color
{
@ -122,364 +36,53 @@ public class ColorPicker : TemplatedControl
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
if (_colorCanvas != null)
{
_colorCanvas.PointerPressed -= ColorCanvas_PointerPressed;
_colorCanvas.PointerReleased -= ColorCanvas_PointerReleased;
_colorCanvas.PointerMoved -= ColorCanvas_PointerMoved;
}
_disposable?.Dispose();
if (_colorThumb != null)
{
_colorThumb.DragDelta -= ColorThumb_DragDelta;
}
_colorPickerPresenter = e.NameScope.Find<ColorPickerPresenter>("PART_ColorPickerPresenter");
if (_hueCanvas != null)
if (_colorPickerPresenter is { })
{
_hueCanvas.PointerPressed -= HueCanvas_PointerPressed;
_hueCanvas.PointerReleased -= HueCanvas_PointerReleased;
_hueCanvas.PointerMoved -= HueCanvas_PointerMoved;
}
_disposable = new CompositeDisposable();
if (_hueThumb != null)
{
_hueThumb.DragDelta -= HueThumb_DragDelta;
}
Properties = new AvaloniaList<ColorPickerProperties>
{
new HexProperties { Header = "Hex", Presenter = _colorPickerPresenter },
new AlphaProperties { Header = "Alpha", Presenter = _colorPickerPresenter },
new RgbProperties { Header = "RGB", Presenter = _colorPickerPresenter },
new HsvProperties { Header = "HSV", Presenter = _colorPickerPresenter },
new CmykProperties { Header = "CMYK", Presenter = _colorPickerPresenter }
};
if (_alphaCanvas != null)
{
_alphaCanvas.PointerPressed -= AlphaCanvas_PointerPressed;
_alphaCanvas.PointerReleased -= AlphaCanvas_PointerReleased;
_alphaCanvas.PointerMoved -= AlphaCanvas_PointerMoved;
}
_colorPickerPresenter.GetObservable(ColorPickerPresenter.Value1Property)
.Subscribe(_ => _colorPickerPresenter.OnValueChange())
.DisposeWith(_disposable);
if (_alphaThumb != null)
{
_alphaThumb.DragDelta -= AlphaThumb_DragDelta;
}
_colorPickerPresenter.GetObservable(ColorPickerPresenter.Value2Property)
.Subscribe(_ => _colorPickerPresenter.OnValueChange())
.DisposeWith(_disposable);
_colorCanvas = e.NameScope.Find<Canvas>("PART_ColorCanvas");
_colorThumb = e.NameScope.Find<Thumb>("PART_ColorThumb");
_hueCanvas = e.NameScope.Find<Canvas>("PART_HueCanvas");
_hueThumb = e.NameScope.Find<Thumb>("PART_HueThumb");
_alphaCanvas = e.NameScope.Find<Canvas>("PART_AlphaCanvas");
_alphaThumb = e.NameScope.Find<Thumb>("PART_AlphaThumb");
_colorPickerPresenter.GetObservable(ColorPickerPresenter.Value3Property)
.Subscribe(_ => _colorPickerPresenter.OnValueChange())
.DisposeWith(_disposable);
if (_colorCanvas != null)
{
_colorCanvas.PointerPressed += ColorCanvas_PointerPressed;
_colorCanvas.PointerReleased += ColorCanvas_PointerReleased;
_colorCanvas.PointerMoved += ColorCanvas_PointerMoved;
}
_colorPickerPresenter.GetObservable(ColorPickerPresenter.Value4Property)
.Subscribe(_ => _colorPickerPresenter.OnValueChange())
.DisposeWith(_disposable);
if (_colorThumb != null)
{
_colorThumb.DragDelta += ColorThumb_DragDelta;
}
_colorPickerPresenter._colorPicker = this;
if (_hueCanvas != null)
{
_hueCanvas.PointerPressed += HueCanvas_PointerPressed;
_hueCanvas.PointerReleased += HueCanvas_PointerReleased;
_hueCanvas.PointerMoved += HueCanvas_PointerMoved;
}
if (_hueThumb != null)
{
_hueThumb.DragDelta += HueThumb_DragDelta;
}
if (_alphaCanvas != null)
{
_alphaCanvas.PointerPressed += AlphaCanvas_PointerPressed;
_alphaCanvas.PointerReleased += AlphaCanvas_PointerReleased;
_alphaCanvas.PointerMoved += AlphaCanvas_PointerMoved;
}
if (_alphaThumb != null)
{
_alphaThumb.DragDelta += AlphaThumb_DragDelta;
this.GetObservable(ColorProperty)
.Subscribe(_ => _colorPickerPresenter.OnColorChange())
.DisposeWith(_disposable);
}
}
protected override Size ArrangeOverride(Size finalSize)
{
var size = base.ArrangeOverride(finalSize);
OnColorChange();
_colorPickerPresenter?.OnColorChange();
return size;
}
private bool IsTemplateValid()
{
return _colorCanvas != null
&& _colorThumb != null
&& _hueCanvas != null
&& _hueThumb != null
&& _alphaCanvas != null
&& _alphaThumb != null;
}
private double Clamp(double val, double min, double max)
{
return Math.Min(Math.Max(val, min), max);
}
private void MoveThumb(Canvas? canvas, Thumb? thumb, double x, double y)
{
if (canvas != null && thumb != null)
{
var left = Clamp(x, 0, canvas.Bounds.Width);
var top = Clamp(y, 0, canvas.Bounds.Height);
Canvas.SetLeft(thumb, left);
Canvas.SetTop(thumb, top);
}
}
private T? Convert<T>(IValueConverter converter, T? value, T? range)
{
return (T?)converter.Convert(value, typeof(T), range, CultureInfo.CurrentCulture);
}
private T? ConvertBack<T>(IValueConverter converter, T? value, T? range)
{
return (T?)converter.ConvertBack(value, typeof(T), range, CultureInfo.CurrentCulture);
}
private double GetValue1Range() => _hueCanvas?.Bounds.Height ?? 0.0;
private double GetValue2Range() => _colorCanvas?.Bounds.Width ?? 0.0;
private double GetValue3Range() => _colorCanvas?.Bounds.Height ?? 0.0;
private double GetValue4Range() => _alphaCanvas?.Bounds.Width ?? 0.0;
private void UpdateThumbsFromColor()
{
ColorPickerHelpers.FromColor(Color, out var h, out var s, out var v, out var a);
var hueY = Convert(_value1Converter, h, GetValue1Range());
var colorX = Convert(_value2Converter, s, GetValue2Range());
var colorY = Convert(_value3Converter, v, GetValue3Range());
var alphaX = Convert(_value4Converter, a, GetValue4Range());
MoveThumb(_hueCanvas, _hueThumb, 0, hueY);
MoveThumb(_colorCanvas, _colorThumb, colorX, colorY);
MoveThumb(_alphaCanvas, _alphaThumb, alphaX, 0);
}
private void UpdateThumbsFromValues()
{
var hueY = Convert(_value1Converter, Value1, GetValue1Range());
var colorX = Convert(_value2Converter, Value2, GetValue2Range());
var colorY = Convert(_value3Converter, Value3, GetValue3Range());
var alphaX = Convert(_value4Converter, Value4, GetValue4Range());
MoveThumb(_hueCanvas, _hueThumb, 0, hueY);
MoveThumb(_colorCanvas, _colorThumb, colorX, colorY);
MoveThumb(_alphaCanvas, _alphaThumb, alphaX, 0);
}
private void UpdateValuesFromThumbs()
{
var hueY = Canvas.GetTop(_hueThumb);
var colorX = Canvas.GetLeft(_colorThumb);
var colorY = Canvas.GetTop(_colorThumb);
var alphaX = Canvas.GetLeft(_alphaThumb);
Value1 = ConvertBack(_value1Converter, hueY, GetValue1Range());
Value2 = ConvertBack(_value2Converter, colorX, GetValue2Range());
Value3 = ConvertBack(_value3Converter, colorY, GetValue3Range());
Value4 = ConvertBack(_value4Converter, alphaX, GetValue4Range());
Color = ColorPickerHelpers.FromHSVA(Value1, Value2, Value3, Value4);
}
private void UpdateColorFromThumbs()
{
var hueY = Canvas.GetTop(_hueThumb);
var colorX = Canvas.GetLeft(_colorThumb);
var colorY = Canvas.GetTop(_colorThumb);
var alphaX = Canvas.GetLeft(_alphaThumb);
var h = ConvertBack(_value1Converter, hueY, GetValue1Range());
var s = ConvertBack(_value2Converter, colorX, GetValue2Range());
var v = ConvertBack(_value3Converter, colorY, GetValue3Range());
var a = ConvertBack(_value4Converter, alphaX, GetValue4Range());
Color = ColorPickerHelpers.FromHSVA(h, s, v, a);
}
private void OnValueChange()
{
if (_updating == false && IsTemplateValid())
{
_updating = true;
UpdateThumbsFromValues();
UpdateValuesFromThumbs();
UpdateColorFromThumbs();
_updating = false;
}
}
private void OnColorChange()
{
if (_updating == false && IsTemplateValid())
{
_updating = true;
UpdateThumbsFromColor();
UpdateValuesFromThumbs();
UpdateColorFromThumbs();
_updating = false;
}
}
private void ColorCanvas_PointerPressed(object? sender, PointerPressedEventArgs e)
{
var position = e.GetPosition(_colorCanvas);
_updating = true;
MoveThumb(_colorCanvas, _colorThumb, position.X, position.Y);
UpdateValuesFromThumbs();
UpdateColorFromThumbs();
if (_colorCanvas is { } && _colorThumb is { })
{
_colorCanvas.Cursor = new Cursor(StandardCursorType.None);
_colorThumb.Cursor = new Cursor(StandardCursorType.None);
}
_updating = false;
_captured = true;
}
private void ColorCanvas_PointerReleased(object? sender, PointerReleasedEventArgs e)
{
if (_captured)
{
if (_colorCanvas is { } && _colorThumb is { })
{
_colorCanvas.Cursor = Cursor.Default;
_colorThumb.Cursor = Cursor.Default;
}
_captured = false;
}
}
private void ColorCanvas_PointerMoved(object? sender, PointerEventArgs e)
{
if (_captured)
{
var position = e.GetPosition(_colorCanvas);
_updating = true;
MoveThumb(_colorCanvas, _colorThumb, position.X, position.Y);
UpdateValuesFromThumbs();
UpdateColorFromThumbs();
_updating = false;
}
}
private void ColorThumb_DragDelta(object? sender, VectorEventArgs e)
{
var left = Canvas.GetLeft(_colorThumb);
var top = Canvas.GetTop(_colorThumb);
_updating = true;
MoveThumb(_colorCanvas, _colorThumb, left + e.Vector.X, top + e.Vector.Y);
UpdateValuesFromThumbs();
UpdateColorFromThumbs();
_updating = false;
}
private void HueCanvas_PointerPressed(object? sender, PointerPressedEventArgs e)
{
var position = e.GetPosition(_hueCanvas);
_updating = true;
MoveThumb(_hueCanvas, _hueThumb, 0, position.Y);
UpdateValuesFromThumbs();
UpdateColorFromThumbs();
if (_hueCanvas is { } && _hueThumb is { })
{
_hueCanvas.Cursor = new Cursor(StandardCursorType.SizeNorthSouth);
_hueThumb.Cursor = new Cursor(StandardCursorType.SizeNorthSouth);
}
_updating = false;
_captured = true;
}
private void HueCanvas_PointerReleased(object? sender, PointerReleasedEventArgs e)
{
if (_captured)
{
if (_hueCanvas is { } && _hueThumb is { })
{
_hueCanvas.Cursor = Cursor.Default;
_hueThumb.Cursor = Cursor.Default;
}
_captured = false;
}
}
private void HueCanvas_PointerMoved(object? sender, PointerEventArgs e)
{
if (_captured)
{
var position = e.GetPosition(_hueCanvas);
_updating = true;
MoveThumb(_hueCanvas, _hueThumb, 0, position.Y);
UpdateValuesFromThumbs();
UpdateColorFromThumbs();
_updating = false;
}
}
private void HueThumb_DragDelta(object? sender, VectorEventArgs e)
{
var top = Canvas.GetTop(_hueThumb);
_updating = true;
MoveThumb(_hueCanvas, _hueThumb, 0, top + e.Vector.Y);
UpdateValuesFromThumbs();
UpdateColorFromThumbs();
_updating = false;
}
private void AlphaCanvas_PointerPressed(object? sender, PointerPressedEventArgs e)
{
var position = e.GetPosition(_alphaCanvas);
_updating = true;
MoveThumb(_alphaCanvas, _alphaThumb, position.X, 0);
UpdateValuesFromThumbs();
UpdateColorFromThumbs();
if (_alphaCanvas is { } && _alphaThumb is { })
{
_alphaCanvas.Cursor = new Cursor(StandardCursorType.SizeWestEast);
_alphaThumb.Cursor = new Cursor(StandardCursorType.SizeWestEast);
}
_updating = false;
_captured = true;
}
private void AlphaCanvas_PointerReleased(object? sender, PointerReleasedEventArgs e)
{
if (_captured)
{
if (_alphaCanvas is { } && _alphaThumb is { })
{
_alphaCanvas.Cursor = Cursor.Default;
_alphaThumb.Cursor = Cursor.Default;
}
_captured = false;
}
}
private void AlphaCanvas_PointerMoved(object? sender, PointerEventArgs e)
{
if (_captured)
{
var position = e.GetPosition(_alphaCanvas);
_updating = true;
MoveThumb(_alphaCanvas, _alphaThumb, position.X, 0);
UpdateValuesFromThumbs();
UpdateColorFromThumbs();
_updating = false;
}
}
private void AlphaThumb_DragDelta(object? sender, VectorEventArgs e)
{
var left = Canvas.GetLeft(_alphaThumb);
_updating = true;
MoveThumb(_alphaCanvas, _alphaThumb, left + e.Vector.X, 0);
UpdateValuesFromThumbs();
UpdateColorFromThumbs();
_updating = false;
}
}

Просмотреть файл

@ -0,0 +1,442 @@
using System;
using System.Globalization;
using System.Reactive.Disposables;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Data.Converters;
using Avalonia.Input;
using Avalonia.Media;
using ThemeEditor.Controls.ColorPicker.Converters;
namespace ThemeEditor.Controls.ColorPicker;
public class ColorPickerPresenter : TemplatedControl
{
public static readonly StyledProperty<double> Value1Property =
AvaloniaProperty.Register<ColorPickerPresenter, double>(nameof(Value1));
public static readonly StyledProperty<double> Value2Property =
AvaloniaProperty.Register<ColorPickerPresenter, double>(nameof(Value2));
public static readonly StyledProperty<double> Value3Property =
AvaloniaProperty.Register<ColorPickerPresenter, double>(nameof(Value3));
public static readonly StyledProperty<double> Value4Property =
AvaloniaProperty.Register<ColorPickerPresenter, double>(nameof(Value4));
private CompositeDisposable? _disposable;
private Canvas? _colorCanvas;
private Thumb? _colorThumb;
private Canvas? _hueCanvas;
private Thumb? _hueThumb;
private Canvas? _alphaCanvas;
private Thumb? _alphaThumb;
private bool _updating;
private bool _captured;
private readonly IValueConverter _value1Converter = new HueConverter();
private readonly IValueConverter _value2Converter = new SaturationConverter();
private readonly IValueConverter _value3Converter = new ValueConverter();
private readonly IValueConverter _value4Converter = new AlphaConverter();
internal ColorPicker? _colorPicker;
public double Value1
{
get => GetValue(Value1Property);
set => SetValue(Value1Property, value);
}
public double Value2
{
get => GetValue(Value2Property);
set => SetValue(Value2Property, value);
}
public double Value3
{
get => GetValue(Value3Property);
set => SetValue(Value3Property, value);
}
public double Value4
{
get => GetValue(Value4Property);
set => SetValue(Value4Property, value);
}
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
_disposable?.Dispose();
if (_colorCanvas != null)
{
_colorCanvas.PointerPressed -= ColorCanvas_PointerPressed;
_colorCanvas.PointerReleased -= ColorCanvas_PointerReleased;
_colorCanvas.PointerMoved -= ColorCanvas_PointerMoved;
}
if (_colorThumb != null)
{
_colorThumb.DragDelta -= ColorThumb_DragDelta;
}
if (_hueCanvas != null)
{
_hueCanvas.PointerPressed -= HueCanvas_PointerPressed;
_hueCanvas.PointerReleased -= HueCanvas_PointerReleased;
_hueCanvas.PointerMoved -= HueCanvas_PointerMoved;
}
if (_hueThumb != null)
{
_hueThumb.DragDelta -= HueThumb_DragDelta;
}
if (_alphaCanvas != null)
{
_alphaCanvas.PointerPressed -= AlphaCanvas_PointerPressed;
_alphaCanvas.PointerReleased -= AlphaCanvas_PointerReleased;
_alphaCanvas.PointerMoved -= AlphaCanvas_PointerMoved;
}
if (_alphaThumb != null)
{
_alphaThumb.DragDelta -= AlphaThumb_DragDelta;
}
_colorCanvas = e.NameScope.Find<Canvas>("PART_ColorCanvas");
_colorThumb = e.NameScope.Find<Thumb>("PART_ColorThumb");
_hueCanvas = e.NameScope.Find<Canvas>("PART_HueCanvas");
_hueThumb = e.NameScope.Find<Thumb>("PART_HueThumb");
_alphaCanvas = e.NameScope.Find<Canvas>("PART_AlphaCanvas");
_alphaThumb = e.NameScope.Find<Thumb>("PART_AlphaThumb");
_disposable = new CompositeDisposable();
if (_colorCanvas != null)
{
_colorCanvas.PointerPressed += ColorCanvas_PointerPressed;
_colorCanvas.PointerReleased += ColorCanvas_PointerReleased;
_colorCanvas.PointerMoved += ColorCanvas_PointerMoved;
}
if (_colorThumb != null)
{
_colorThumb.DragDelta += ColorThumb_DragDelta;
}
if (_hueCanvas != null)
{
_hueCanvas.PointerPressed += HueCanvas_PointerPressed;
_hueCanvas.PointerReleased += HueCanvas_PointerReleased;
_hueCanvas.PointerMoved += HueCanvas_PointerMoved;
}
if (_hueThumb != null)
{
_hueThumb.DragDelta += HueThumb_DragDelta;
}
if (_alphaCanvas != null)
{
_alphaCanvas.PointerPressed += AlphaCanvas_PointerPressed;
_alphaCanvas.PointerReleased += AlphaCanvas_PointerReleased;
_alphaCanvas.PointerMoved += AlphaCanvas_PointerMoved;
}
if (_alphaThumb != null)
{
_alphaThumb.DragDelta += AlphaThumb_DragDelta;
}
}
private bool IsTemplateValid()
{
return _colorCanvas != null
&& _colorThumb != null
&& _hueCanvas != null
&& _hueThumb != null
&& _alphaCanvas != null
&& _alphaThumb != null;
}
private double Clamp(double val, double min, double max)
{
return Math.Min(Math.Max(val, min), max);
}
private void MoveThumb(Canvas? canvas, Thumb? thumb, double x, double y)
{
if (canvas != null && thumb != null)
{
var left = Clamp(x, 0, canvas.Bounds.Width);
var top = Clamp(y, 0, canvas.Bounds.Height);
Canvas.SetLeft(thumb, left);
Canvas.SetTop(thumb, top);
}
}
private T? Convert<T>(IValueConverter converter, T? value, T? range)
{
return (T?)converter.Convert(value, typeof(T), range, CultureInfo.CurrentCulture);
}
private T? ConvertBack<T>(IValueConverter converter, T? value, T? range)
{
return (T?)converter.ConvertBack(value, typeof(T), range, CultureInfo.CurrentCulture);
}
private double GetValue1Range() => _hueCanvas?.Bounds.Height ?? 0.0;
private double GetValue2Range() => _colorCanvas?.Bounds.Width ?? 0.0;
private double GetValue3Range() => _colorCanvas?.Bounds.Height ?? 0.0;
private double GetValue4Range() => _alphaCanvas?.Bounds.Width ?? 0.0;
private void UpdateThumbsFromColor()
{
ColorPickerHelpers.FromColor(GetColor(), out var h, out var s, out var v, out var a);
var hueY = Convert(_value1Converter, h, GetValue1Range());
var colorX = Convert(_value2Converter, s, GetValue2Range());
var colorY = Convert(_value3Converter, v, GetValue3Range());
var alphaX = Convert(_value4Converter, a, GetValue4Range());
MoveThumb(_hueCanvas, _hueThumb, 0, hueY);
MoveThumb(_colorCanvas, _colorThumb, colorX, colorY);
MoveThumb(_alphaCanvas, _alphaThumb, alphaX, 0);
}
private void UpdateThumbsFromValues()
{
var hueY = Convert(_value1Converter, Value1, GetValue1Range());
var colorX = Convert(_value2Converter, Value2, GetValue2Range());
var colorY = Convert(_value3Converter, Value3, GetValue3Range());
var alphaX = Convert(_value4Converter, Value4, GetValue4Range());
MoveThumb(_hueCanvas, _hueThumb, 0, hueY);
MoveThumb(_colorCanvas, _colorThumb, colorX, colorY);
MoveThumb(_alphaCanvas, _alphaThumb, alphaX, 0);
}
private void UpdateValuesFromThumbs()
{
var hueY = Canvas.GetTop(_hueThumb);
var colorX = Canvas.GetLeft(_colorThumb);
var colorY = Canvas.GetTop(_colorThumb);
var alphaX = Canvas.GetLeft(_alphaThumb);
Value1 = ConvertBack(_value1Converter, hueY, GetValue1Range());
Value2 = ConvertBack(_value2Converter, colorX, GetValue2Range());
Value3 = ConvertBack(_value3Converter, colorY, GetValue3Range());
Value4 = ConvertBack(_value4Converter, alphaX, GetValue4Range());
SetColor(Value1, Value2, Value3, Value4);
}
private void UpdateColorFromThumbs()
{
var hueY = Canvas.GetTop(_hueThumb);
var colorX = Canvas.GetLeft(_colorThumb);
var colorY = Canvas.GetTop(_colorThumb);
var alphaX = Canvas.GetLeft(_alphaThumb);
var h = ConvertBack(_value1Converter, hueY, GetValue1Range());
var s = ConvertBack(_value2Converter, colorX, GetValue2Range());
var v = ConvertBack(_value3Converter, colorY, GetValue3Range());
var a = ConvertBack(_value4Converter, alphaX, GetValue4Range());
SetColor(h, s, v, a);
}
private Color GetColor()
{
return _colorPicker?.Color ?? Avalonia.Media.Colors.Black;
}
private void SetColor(double h, double s, double v, double a)
{
if (_colorPicker is { })
{
_colorPicker.Color = ColorPickerHelpers.FromHSVA(h, s, v, a);
}
}
internal void OnValueChange()
{
if (_updating == false && IsTemplateValid())
{
_updating = true;
UpdateThumbsFromValues();
UpdateValuesFromThumbs();
UpdateColorFromThumbs();
_updating = false;
}
}
internal void OnColorChange()
{
if (_updating == false && IsTemplateValid())
{
_updating = true;
UpdateThumbsFromColor();
UpdateValuesFromThumbs();
UpdateColorFromThumbs();
_updating = false;
}
}
private void ColorCanvas_PointerPressed(object? sender, PointerPressedEventArgs e)
{
var position = e.GetPosition(_colorCanvas);
_updating = true;
MoveThumb(_colorCanvas, _colorThumb, position.X, position.Y);
UpdateValuesFromThumbs();
UpdateColorFromThumbs();
if (_colorCanvas is { } && _colorThumb is { })
{
_colorCanvas.Cursor = new Cursor(StandardCursorType.None);
_colorThumb.Cursor = new Cursor(StandardCursorType.None);
}
_updating = false;
_captured = true;
}
private void ColorCanvas_PointerReleased(object? sender, PointerReleasedEventArgs e)
{
if (_captured)
{
if (_colorCanvas is { } && _colorThumb is { })
{
_colorCanvas.Cursor = Cursor.Default;
_colorThumb.Cursor = Cursor.Default;
}
_captured = false;
}
}
private void ColorCanvas_PointerMoved(object? sender, PointerEventArgs e)
{
if (_captured)
{
var position = e.GetPosition(_colorCanvas);
_updating = true;
MoveThumb(_colorCanvas, _colorThumb, position.X, position.Y);
UpdateValuesFromThumbs();
UpdateColorFromThumbs();
_updating = false;
}
}
private void ColorThumb_DragDelta(object? sender, VectorEventArgs e)
{
var left = Canvas.GetLeft(_colorThumb);
var top = Canvas.GetTop(_colorThumb);
_updating = true;
MoveThumb(_colorCanvas, _colorThumb, left + e.Vector.X, top + e.Vector.Y);
UpdateValuesFromThumbs();
UpdateColorFromThumbs();
_updating = false;
}
private void HueCanvas_PointerPressed(object? sender, PointerPressedEventArgs e)
{
var position = e.GetPosition(_hueCanvas);
_updating = true;
MoveThumb(_hueCanvas, _hueThumb, 0, position.Y);
UpdateValuesFromThumbs();
UpdateColorFromThumbs();
if (_hueCanvas is { } && _hueThumb is { })
{
_hueCanvas.Cursor = new Cursor(StandardCursorType.SizeNorthSouth);
_hueThumb.Cursor = new Cursor(StandardCursorType.SizeNorthSouth);
}
_updating = false;
_captured = true;
}
private void HueCanvas_PointerReleased(object? sender, PointerReleasedEventArgs e)
{
if (_captured)
{
if (_hueCanvas is { } && _hueThumb is { })
{
_hueCanvas.Cursor = Cursor.Default;
_hueThumb.Cursor = Cursor.Default;
}
_captured = false;
}
}
private void HueCanvas_PointerMoved(object? sender, PointerEventArgs e)
{
if (_captured)
{
var position = e.GetPosition(_hueCanvas);
_updating = true;
MoveThumb(_hueCanvas, _hueThumb, 0, position.Y);
UpdateValuesFromThumbs();
UpdateColorFromThumbs();
_updating = false;
}
}
private void HueThumb_DragDelta(object? sender, VectorEventArgs e)
{
var top = Canvas.GetTop(_hueThumb);
_updating = true;
MoveThumb(_hueCanvas, _hueThumb, 0, top + e.Vector.Y);
UpdateValuesFromThumbs();
UpdateColorFromThumbs();
_updating = false;
}
private void AlphaCanvas_PointerPressed(object? sender, PointerPressedEventArgs e)
{
var position = e.GetPosition(_alphaCanvas);
_updating = true;
MoveThumb(_alphaCanvas, _alphaThumb, position.X, 0);
UpdateValuesFromThumbs();
UpdateColorFromThumbs();
if (_alphaCanvas is { } && _alphaThumb is { })
{
_alphaCanvas.Cursor = new Cursor(StandardCursorType.SizeWestEast);
_alphaThumb.Cursor = new Cursor(StandardCursorType.SizeWestEast);
}
_updating = false;
_captured = true;
}
private void AlphaCanvas_PointerReleased(object? sender, PointerReleasedEventArgs e)
{
if (_captured)
{
if (_alphaCanvas is { } && _alphaThumb is { })
{
_alphaCanvas.Cursor = Cursor.Default;
_alphaThumb.Cursor = Cursor.Default;
}
_captured = false;
}
}
private void AlphaCanvas_PointerMoved(object? sender, PointerEventArgs e)
{
if (_captured)
{
var position = e.GetPosition(_alphaCanvas);
_updating = true;
MoveThumb(_alphaCanvas, _alphaThumb, position.X, 0);
UpdateValuesFromThumbs();
UpdateColorFromThumbs();
_updating = false;
}
}
private void AlphaThumb_DragDelta(object? sender, VectorEventArgs e)
{
var left = Canvas.GetLeft(_alphaThumb);
_updating = true;
MoveThumb(_alphaCanvas, _alphaThumb, left + e.Vector.X, 0);
UpdateValuesFromThumbs();
UpdateColorFromThumbs();
_updating = false;
}
}

Просмотреть файл

@ -8,12 +8,12 @@ public abstract class ColorPickerProperties : AvaloniaObject
public static readonly StyledProperty<object?> HeaderProperty =
AvaloniaProperty.Register<ColorPickerProperties, object?>(nameof(Header));
public static readonly StyledProperty<ColorPicker?> ColorPickerProperty =
AvaloniaProperty.Register<ColorPickerProperties, ColorPicker?>(nameof(ColorPicker));
public static readonly StyledProperty<ColorPickerPresenter?> PresenterProperty =
AvaloniaProperty.Register<ColorPickerProperties, ColorPickerPresenter?>(nameof(Presenter));
public ColorPickerProperties()
{
this.GetObservable(ColorPickerProperty).Subscribe(_ => OnColorPickerChange());
this.GetObservable(PresenterProperty).Subscribe(_ => OnColorPickerChange());
}
public object? Header
@ -22,10 +22,10 @@ public abstract class ColorPickerProperties : AvaloniaObject
set => SetValue(HeaderProperty, value);
}
public ColorPicker? ColorPicker
public ColorPickerPresenter? Presenter
{
get => GetValue(ColorPickerProperty);
set => SetValue(ColorPickerProperty, value);
get => GetValue(PresenterProperty);
set => SetValue(PresenterProperty, value);
}
protected abstract void UpdateColorPickerValues();
@ -34,9 +34,9 @@ public abstract class ColorPickerProperties : AvaloniaObject
protected virtual void OnColorPickerChange()
{
ColorPicker?.GetObservable(ColorPicker.Value1Property).Subscribe(_ => UpdatePropertyValues());
ColorPicker?.GetObservable(ColorPicker.Value2Property).Subscribe(_ => UpdatePropertyValues());
ColorPicker?.GetObservable(ColorPicker.Value3Property).Subscribe(_ => UpdatePropertyValues());
ColorPicker?.GetObservable(ColorPicker.Value4Property).Subscribe(_ => UpdatePropertyValues());
Presenter?.GetObservable(ColorPickerPresenter.Value1Property).Subscribe(_ => UpdatePropertyValues());
Presenter?.GetObservable(ColorPickerPresenter.Value2Property).Subscribe(_ => UpdatePropertyValues());
Presenter?.GetObservable(ColorPickerPresenter.Value3Property).Subscribe(_ => UpdatePropertyValues());
Presenter?.GetObservable(ColorPickerPresenter.Value4Property).Subscribe(_ => UpdatePropertyValues());
}
}

Просмотреть файл

@ -33,20 +33,20 @@ public class AlphaProperties : ColorPickerProperties
protected override void UpdateColorPickerValues()
{
if (_updating == false && ColorPicker != null)
if (_updating == false && Presenter != null)
{
_updating = true;
ColorPicker.Value4 = Alpha;
Presenter.Value4 = Alpha;
_updating = false;
}
}
public override void UpdatePropertyValues()
{
if (_updating == false && ColorPicker != null)
if (_updating == false && Presenter != null)
{
_updating = true;
Alpha = ColorPicker.Value4;
Alpha = Presenter.Value4;
_updating = false;
}
}

Просмотреть файл

@ -90,24 +90,24 @@ public class CmykProperties : ColorPickerProperties
protected override void UpdateColorPickerValues()
{
if (_updating == false && ColorPicker != null)
if (_updating == false && Presenter != null)
{
_updating = true;
var cmyk = new CMYK(Cyan, Magenta, Yellow, BlackKey);
var hsv = cmyk.ToHSV();
ColorPicker.Value1 = hsv.H;
ColorPicker.Value2 = hsv.S;
ColorPicker.Value3 = hsv.V;
Presenter.Value1 = hsv.H;
Presenter.Value2 = hsv.S;
Presenter.Value3 = hsv.V;
_updating = false;
}
}
public override void UpdatePropertyValues()
{
if (_updating == false && ColorPicker != null)
if (_updating == false && Presenter != null)
{
_updating = true;
var hsv = new HSV(ColorPicker.Value1, ColorPicker.Value2, ColorPicker.Value3);
var hsv = new HSV(Presenter.Value1, Presenter.Value2, Presenter.Value3);
var cmyk = hsv.ToCMYK();
Cyan = cmyk.C;
Magenta = cmyk.M;

Просмотреть файл

@ -34,25 +34,25 @@ public class HexProperties : ColorPickerProperties
protected override void UpdateColorPickerValues()
{
if (_updating == false && ColorPicker != null)
if (_updating == false && Presenter != null)
{
_updating = true;
var color = Color.Parse(Hex);
ColorPickerHelpers.FromColor(color, out var h, out var s, out var v, out var a);
ColorPicker.Value1 = h;
ColorPicker.Value2 = s;
ColorPicker.Value3 = v;
ColorPicker.Value4 = a;
Presenter.Value1 = h;
Presenter.Value2 = s;
Presenter.Value3 = v;
Presenter.Value4 = a;
_updating = false;
}
}
public override void UpdatePropertyValues()
{
if (_updating == false && ColorPicker != null)
if (_updating == false && Presenter != null)
{
_updating = true;
var color = ColorPickerHelpers.FromHSVA(ColorPicker.Value1, ColorPicker.Value2, ColorPicker.Value3, ColorPicker.Value4);
var color = ColorPickerHelpers.FromHSVA(Presenter.Value1, Presenter.Value2, Presenter.Value3, Presenter.Value4);
Hex = ColorPickerHelpers.ToHexColor(color);
_updating = false;
}

Просмотреть файл

@ -70,24 +70,24 @@ public class HsvProperties : ColorPickerProperties
protected override void UpdateColorPickerValues()
{
if (_updating == false && ColorPicker != null)
if (_updating == false && Presenter != null)
{
_updating = true;
ColorPicker.Value1 = Hue;
ColorPicker.Value2 = Saturation;
ColorPicker.Value3 = Value;
Presenter.Value1 = Hue;
Presenter.Value2 = Saturation;
Presenter.Value3 = Value;
_updating = false;
}
}
public override void UpdatePropertyValues()
{
if (_updating == false && ColorPicker != null)
if (_updating == false && Presenter != null)
{
_updating = true;
Hue = ColorPicker.Value1;
Saturation = ColorPicker.Value2;
Value = ColorPicker.Value3;
Hue = Presenter.Value1;
Saturation = Presenter.Value2;
Value = Presenter.Value3;
_updating = false;
}
}

Просмотреть файл

@ -76,24 +76,24 @@ public class RgbProperties : ColorPickerProperties
protected override void UpdateColorPickerValues()
{
if (_updating == false && ColorPicker != null)
if (_updating == false && Presenter != null)
{
_updating = true;
var rgb = new RGB(Red, Green, Blue);
var hsv = rgb.ToHSV();
ColorPicker.Value1 = hsv.H;
ColorPicker.Value2 = hsv.S;
ColorPicker.Value3 = hsv.V;
Presenter.Value1 = hsv.H;
Presenter.Value2 = hsv.S;
Presenter.Value3 = hsv.V;
_updating = false;
}
}
public override void UpdatePropertyValues()
{
if (_updating == false && ColorPicker != null)
if (_updating == false && Presenter != null)
{
_updating = true;
var hsv = new HSV(ColorPicker.Value1, ColorPicker.Value2, ColorPicker.Value3);
var hsv = new HSV(Presenter.Value1, Presenter.Value2, Presenter.Value3);
var rgb = hsv.ToRGB();
Red = (byte)rgb.R;
Green = (byte)rgb.G;

Просмотреть файл

@ -3,11 +3,13 @@
xmlns:cp="using:ThemeEditor.Controls.ColorPicker"
xmlns:converters="clr-namespace:ThemeEditor.Controls.ColorPicker.Converters"
xmlns:props="clr-namespace:ThemeEditor.Controls.ColorPicker.Props">
<Design.PreviewWith>
<Border Padding="5" Width="400" Height="400">
<cp:ColorPicker Color="#5F1F001F" />
</Border>
</Design.PreviewWith>
<Style Selector="cp|ColorPicker">
<Style.Resources>
<converters:HueToColorConverter x:Key="HueToColorConverter" />
@ -67,6 +69,15 @@
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
<cp:ColorPickerPresenter x:Name="PART_ColorPickerPresenter" />
</DockPanel>
</ControlTemplate>
</Setter>
</Style>
<Style Selector="cp|ColorPickerPresenter">
<Setter Property="Template">
<ControlTemplate>
<Grid x:Name="PART_Picker" ColumnDefinitions="*,3,Auto" RowDefinitions="*,3,Auto">
<Grid Grid.Column="0" Grid.Row="0">
<Grid.Background>
@ -163,12 +174,11 @@
</Canvas>
</Grid>
</Grid>
</DockPanel>
</ControlTemplate>
</Setter>
</Style>
<Style Selector="cp|ColorPicker /template/ Grid#PART_Picker">
<Style Selector="cp|ColorPickerPresenter /template/ Grid#PART_Picker">
<Setter Property="MinHeight" Value="200" />
<Setter Property="MinWidth" Value="200" />
</Style>