using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Signum.Windows.ColorUtils
{
/// <summary>
/// Interaction logic for ColorSelector.xaml
/// </summary>
public partial class ColorSelector : UserControl
{
private TranslateTransform markerTransform = new TranslateTransform();
private Point m_ColorPosition;
public ColorSelector()
{
InitializeComponent();
PART_ColorMarker.RenderTransform = markerTransform;
updateMarkerPosition(SelectedColor);
}
#region Public Properties
public static readonly DependencyProperty SelectedColorProperty =
DependencyProperty.Register
("SelectedColor", typeof(Color), typeof(ColorSelector),
new FrameworkPropertyMetadata(Colors.Black, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
(o, e) => ((ColorSelector)o).SelectedColorChanging(e)));
// Gets or sets the selected color.
public Color SelectedColor
{
get
{
return (Color)GetValue(SelectedColorProperty);
}
set
{
SetValue(SelectedColorProperty, value);
}
}
#endregion
#region Public Events
public static readonly RoutedEvent SelectedColorChangedEvent = EventManager.RegisterRoutedEvent(
"SelectedColorChanged",
RoutingStrategy.Bubble,
typeof(RoutedPropertyChangedEventHandler<Color>),
typeof(ColorSelector)
);
public event RoutedPropertyChangedEventHandler<Color> SelectedColorChanged
{
add { AddHandler(SelectedColorChangedEvent, value); }
remove { RemoveHandler(SelectedColorChangedEvent, value); }
}
#endregion
#region Property Changed Callbacks
private void SelectedColorChanging(DependencyPropertyChangedEventArgs e)
{
Color newC = (Color)e.NewValue;
updateMarkerPosition(newC);
OnSelectedColorChanged((Color)e.OldValue, newC);
}
protected virtual void OnSelectedColorChanged(Color oldColor, Color newColor)
{
RaiseEvent(new RoutedPropertyChangedEventArgs<Color>(oldColor, newColor, ColorSelector.SelectedColorChangedEvent));
}
#endregion
#region Color Resolution Helpers
private void setMarkerPosition(Point p)
{
m_ColorPosition = new Point(
Math.Min(Math.Max(0, p.X / PART_ColorDetail.ActualWidth), 1),
Math.Min(Math.Max(0, p.Y / PART_ColorDetail.ActualHeight), 1)
);
updateTransform();
determineColor();
}
private void updateTransform()
{
markerTransform.X = m_ColorPosition.X * PART_ColorDetail.ActualWidth;
markerTransform.Y = m_ColorPosition.Y * PART_ColorDetail.ActualHeight;
}
bool updating = false;
private void updateMarkerPosition(Color theColor)
{
if (updating) return;
try
{
updating = true;
opacitySlider.Value = theColor.ScA;
HsvColor hsv = HsvColor.FromColor(theColor);
PART_ColorSlider.Value = hsv.H;
Point p = new Point(hsv.S, 1 - hsv.V);
m_ColorPosition = p;
updateTransform();
}
finally
{
updating = false;
}
}
private void determineColor()
{
if (updating) return;
Point p = m_ColorPosition;
HsvColor hsv = new HsvColor(PART_ColorSlider.Value, 1, 1);
hsv.S = p.X;
hsv.V = 1 - p.Y;
Color color = hsv.ToColor();
SelectedColor = Color.FromArgb((byte)(255 * opacitySlider.Value), color.R, color.G, color.B);
}
#endregion
private void opacitySlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
determineColor();
}
private void PART_ColorSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
determineColor();
}
private void PART_ColorDetail_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Mouse.Capture(PART_ColorDetail);
Point p = e.GetPosition(PART_ColorDetail);
setMarkerPosition(p);
}
private void PART_ColorDetail_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Point p = e.GetPosition(PART_ColorDetail);
setMarkerPosition(p);
Mouse.Synchronize();
}
}
private void PART_ColorDetail_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
Mouse.Capture(null);
}
}
}