Browse Source

initial checkin of new ColorCanvas control. This is an advanced color control that is not within a popup, but acts as a stand alone control that allows you to select colors by using a color canvas, or by setting RGB and Alpha values.

pull/1645/head
brianlagunas_cp 15 years ago
parent
commit
a030fcd934
  1. 413
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ColorCanvas/Implementation/ColorCanvas.cs
  2. 86
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ColorCanvas/Implementation/ColorSpectrumSlider.cs
  3. 234
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ColorCanvas/Themes/Generic.xaml
  4. 70
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ColorPicker/Implementation/ColorPicker.cs
  5. 24
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ColorPicker/Implementation/ColorUtilities.cs
  6. 7
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ColorPicker/Themes/Generic.xaml
  7. 33
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Converters/SolidColorBrushToColorConverter.cs
  8. 18
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/HsvColor.cs
  9. 172
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Utilities/ColorUtilities.cs
  10. 2
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Themes/Generic.xaml
  11. 4
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Themes/Generic.xaml
  12. 10
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj

413
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ColorCanvas/Implementation/ColorCanvas.cs

@ -0,0 +1,413 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using Microsoft.Windows.Controls.Primitives;
using Microsoft.Windows.Controls.Core.Utilities;
namespace Microsoft.Windows.Controls
{
public class ColorCanvas : Control
{
#region Private Members
private TranslateTransform _colorShadeSelectorTransform = new TranslateTransform();
private Canvas _colorShadingCanvas;
private Canvas _colorShadeSelector;
private ColorSpectrumSlider _spectrumSlider;
private Point? _currentColorPosition;
#endregion //Private Members
#region Properties
#region SelectedColor
public static readonly DependencyProperty SelectedColorProperty = DependencyProperty.Register("SelectedColor", typeof(Color), typeof(ColorCanvas), new UIPropertyMetadata(Colors.White, OnSelectedColorChanged));
public Color SelectedColor
{
get { return (Color)GetValue(SelectedColorProperty); }
set { SetValue(SelectedColorProperty, value); }
}
private static void OnSelectedColorChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
ColorCanvas colorCanvas = o as ColorCanvas;
if (colorCanvas != null)
colorCanvas.OnSelectedColorChanged((Color)e.OldValue, (Color)e.NewValue);
}
protected virtual void OnSelectedColorChanged(Color oldValue, Color newValue)
{
UpdateRGBValues(newValue);
}
#endregion //SelectedColor
#region RGB
#region A
public static readonly DependencyProperty AProperty = DependencyProperty.Register("A", typeof(byte), typeof(ColorCanvas), new UIPropertyMetadata((byte)255, new PropertyChangedCallback(OnAChanged), new CoerceValueCallback(OnCoerceA)));
private static object OnCoerceA(DependencyObject o, object value)
{
ColorCanvas colorCanvas = o as ColorCanvas;
if (colorCanvas != null)
return colorCanvas.OnCoerceA((byte)value);
else
return value;
}
private static void OnAChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
ColorCanvas colorCanvas = o as ColorCanvas;
if (colorCanvas != null)
colorCanvas.OnAChanged((byte)e.OldValue, (byte)e.NewValue);
}
protected virtual byte OnCoerceA(byte value)
{
// TODO: Keep the proposed value within the desired range.
return value;
}
protected virtual void OnAChanged(byte oldValue, byte newValue)
{
UpdateRGBColor();
}
public byte A
{
// IMPORTANT: To maintain parity between setting a property in XAML and procedural code, do not touch the getter and setter inside this dependency property!
get
{
return (byte)GetValue(AProperty);
}
set
{
SetValue(AProperty, value);
}
}
#endregion //A
#region R
public static readonly DependencyProperty RProperty = DependencyProperty.Register("R", typeof(byte), typeof(ColorCanvas), new UIPropertyMetadata((byte)255, new PropertyChangedCallback(OnRChanged), new CoerceValueCallback(OnCoerceR)));
private static object OnCoerceR(DependencyObject o, object value)
{
ColorCanvas colorCanvas = o as ColorCanvas;
if (colorCanvas != null)
return colorCanvas.OnCoerceR((byte)value);
else
return value;
}
private static void OnRChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
ColorCanvas colorCanvas = o as ColorCanvas;
if (colorCanvas != null)
colorCanvas.OnRChanged((byte)e.OldValue, (byte)e.NewValue);
}
protected virtual byte OnCoerceR(byte value)
{
// TODO: Keep the proposed value within the desired range.
return value;
}
protected virtual void OnRChanged(byte oldValue, byte newValue)
{
UpdateRGBColor();
}
public byte R
{
// IMPORTANT: To maintain parity between setting a property in XAML and procedural code, do not touch the getter and setter inside this dependency property!
get
{
return (byte)GetValue(RProperty);
}
set
{
SetValue(RProperty, value);
}
}
#endregion //R
#region G
public static readonly DependencyProperty GProperty = DependencyProperty.Register("G", typeof(byte), typeof(ColorCanvas), new UIPropertyMetadata((byte)255, new PropertyChangedCallback(OnGChanged), new CoerceValueCallback(OnCoerceG)));
private static object OnCoerceG(DependencyObject o, object value)
{
ColorCanvas colorCanvas = o as ColorCanvas;
if (colorCanvas != null)
return colorCanvas.OnCoerceG((byte)value);
else
return value;
}
private static void OnGChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
ColorCanvas colorCanvas = o as ColorCanvas;
if (colorCanvas != null)
colorCanvas.OnGChanged((byte)e.OldValue, (byte)e.NewValue);
}
protected virtual byte OnCoerceG(byte value)
{
// TODO: Keep the proposed value within the desired range.
return value;
}
protected virtual void OnGChanged(byte oldValue, byte newValue)
{
UpdateRGBColor();
}
public byte G
{
// IMPORTANT: To maintain parity between setting a property in XAML and procedural code, do not touch the getter and setter inside this dependency property!
get
{
return (byte)GetValue(GProperty);
}
set
{
SetValue(GProperty, value);
}
}
#endregion //G
#region B
public static readonly DependencyProperty BProperty = DependencyProperty.Register("B", typeof(byte), typeof(ColorCanvas), new UIPropertyMetadata((byte)255, new PropertyChangedCallback(OnBChanged), new CoerceValueCallback(OnCoerceB)));
private static object OnCoerceB(DependencyObject o, object value)
{
ColorCanvas colorCanvas = o as ColorCanvas;
if (colorCanvas != null)
return colorCanvas.OnCoerceB((byte)value);
else
return value;
}
private static void OnBChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
ColorCanvas colorCanvas = o as ColorCanvas;
if (colorCanvas != null)
colorCanvas.OnBChanged((byte)e.OldValue, (byte)e.NewValue);
}
protected virtual byte OnCoerceB(byte value)
{
// TODO: Keep the proposed value within the desired range.
return value;
}
protected virtual void OnBChanged(byte oldValue, byte newValue)
{
UpdateRGBColor();
}
public byte B
{
// IMPORTANT: To maintain parity between setting a property in XAML and procedural code, do not touch the getter and setter inside this dependency property!
get
{
return (byte)GetValue(BProperty);
}
set
{
SetValue(BProperty, value);
}
}
#endregion //B
#endregion //RGB
#region HexadecimalString
public static readonly DependencyProperty HexadecimalStringProperty = DependencyProperty.Register("HexadecimalString", typeof(string), typeof(ColorCanvas), new PropertyMetadata("#FFFFFFFF", new PropertyChangedCallback(OnHexadecimalStringPropertyChanged)));
public string HexadecimalString
{
get { return (string)GetValue(HexadecimalStringProperty); }
set { SetValue(HexadecimalStringProperty, value); }
}
private static void OnHexadecimalStringPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
}
#endregion //HexadecimalString
#endregion //Properties
#region Constructors
static ColorCanvas()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorCanvas), new FrameworkPropertyMetadata(typeof(ColorCanvas)));
}
#endregion //Constructors
#region Base Class Overrides
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
_colorShadingCanvas = (Canvas)GetTemplateChild("PART_ColorShadingCanvas");
_colorShadingCanvas.MouseLeftButtonDown += ColorShadingCanvas_MouseLeftButtonDown;
_colorShadingCanvas.MouseMove += ColorShadingCanvas_MouseMove;
_colorShadingCanvas.SizeChanged += ColorShadingCanvas_SizeChanged;
_colorShadeSelector = (Canvas)GetTemplateChild("PART_ColorShadeSelector");
_colorShadeSelector.RenderTransform = _colorShadeSelectorTransform;
_spectrumSlider = (ColorSpectrumSlider)GetTemplateChild("PART_SpectrumSlider");
_spectrumSlider.ValueChanged += SpectrumSlider_ValueChanged;
SetSelectedColorAndPositionSelector(SelectedColor);
}
#endregion //Base Class Overrides
#region Event Handlers
void ColorShadingCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Point p = e.GetPosition(_colorShadingCanvas);
UpdateColorShadeSelectorPositionAndCalculateColor(p, true);
}
void ColorShadingCanvas_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Point p = e.GetPosition(_colorShadingCanvas);
UpdateColorShadeSelectorPositionAndCalculateColor(p, true);
Mouse.Synchronize();
}
}
void ColorShadingCanvas_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (_currentColorPosition != null)
{
Point _newPoint = new Point
{
X = ((Point)_currentColorPosition).X * e.NewSize.Width,
Y = ((Point)_currentColorPosition).Y * e.NewSize.Height
};
UpdateColorShadeSelectorPositionAndCalculateColor(_newPoint, false);
}
}
void SpectrumSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
if (_currentColorPosition != null)
{
CalculateColor((Point)_currentColorPosition);
}
}
#endregion //Event Handlers
#region Methods
private void UpdateRGBColor()
{
SelectedColor = Color.FromArgb(A, R, G, B);
UpdateColorShadeSelectorPosition(SelectedColor);
}
private void UpdateSelectedColor(Color color)
{
SelectedColor = Color.FromArgb(color.A, color.R, color.G, color.B);
}
private void UpdateRGBValues(Color color)
{
A = color.A;
R = color.R;
G = color.G;
B = color.B;
}
private void SetSelectedColorAndPositionSelector(Color color)
{
UpdateSelectedColor(color);
UpdateRGBValues(color);
UpdateColorShadeSelectorPosition(color);
}
private void UpdateColorShadeSelectorPositionAndCalculateColor(Point p, bool calculateColor)
{
if (p.Y < 0)
p.Y = 0;
if (p.X < 0)
p.X = 0;
if (p.X > _colorShadingCanvas.ActualWidth)
p.X = _colorShadingCanvas.ActualWidth;
if (p.Y > _colorShadingCanvas.ActualHeight)
p.Y = _colorShadingCanvas.ActualHeight;
_colorShadeSelectorTransform.X = p.X - (_colorShadeSelector.Width / 2);
_colorShadeSelectorTransform.Y = p.Y - (_colorShadeSelector.Height / 2);
p.X = p.X / _colorShadingCanvas.ActualWidth;
p.Y = p.Y / _colorShadingCanvas.ActualHeight;
_currentColorPosition = p;
if (calculateColor)
CalculateColor(p);
}
private void UpdateColorShadeSelectorPosition(Color color)
{
if (_spectrumSlider == null || _colorShadingCanvas == null)
return;
_currentColorPosition = null;
HsvColor hsv = ColorUtilities.ConvertRgbToHsv(color.R, color.G, color.B);
_spectrumSlider.Value = hsv.H;
Point p = new Point(hsv.S, 1 - hsv.V);
_currentColorPosition = p;
_colorShadeSelectorTransform.X = (p.X * _colorShadingCanvas.Width) - 5;
_colorShadeSelectorTransform.Y = (p.Y * _colorShadingCanvas.Height) - 5;
}
private void CalculateColor(Point p)
{
HsvColor hsv = new HsvColor(360 - _spectrumSlider.Value, 1, 1) { S = p.X, V = 1 - p.Y };
var currentColor = ColorUtilities.ConvertHsvToRgb(hsv.H, hsv.S, hsv.V);
currentColor.A = A;
SelectedColor = currentColor;
HexadecimalString = SelectedColor.ToString();
}
#endregion //Methods
}
}

86
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ColorCanvas/Implementation/ColorSpectrumSlider.cs

@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using Microsoft.Windows.Controls.Core.Utilities;
namespace Microsoft.Windows.Controls
{
internal class ColorSpectrumSlider : Slider
{
#region Private Members
private Rectangle _spectrumDisplay;
private LinearGradientBrush _pickerBrush;
#endregion //Private Members
#region Constructors
static ColorSpectrumSlider()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorSpectrumSlider), new FrameworkPropertyMetadata(typeof(ColorSpectrumSlider)));
}
#endregion //Constructors
#region Dependency Properties
public static readonly DependencyProperty SelectedColorProperty = DependencyProperty.Register("SelectedColor", typeof(Color), typeof(ColorSpectrumSlider), new PropertyMetadata(System.Windows.Media.Colors.Transparent));
public Color SelectedColor
{
get { return (Color)GetValue(SelectedColorProperty); }
set { SetValue(SelectedColorProperty, value); }
}
#endregion //Dependency Properties
#region Base Class Overrides
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
_spectrumDisplay = (Rectangle)GetTemplateChild("PART_SpectrumDisplay");
CreateSpectrum();
OnValueChanged(Double.NaN, Value);
}
protected override void OnValueChanged(double oldValue, double newValue)
{
base.OnValueChanged(oldValue, newValue);
Color color = ColorUtilities.ConvertHsvToRgb(360 - newValue, 1, 1);
SelectedColor = color;
}
#endregion //Base Class Overrides
#region Methods
private void CreateSpectrum()
{
_pickerBrush = new LinearGradientBrush();
_pickerBrush.StartPoint = new Point(0.5, 0);
_pickerBrush.EndPoint = new Point(0.5, 1);
_pickerBrush.ColorInterpolationMode = ColorInterpolationMode.SRgbLinearInterpolation;
List<Color> colorsList = ColorUtilities.GenerateHsvSpectrum();
double stopIncrement = (double)1 / colorsList.Count;
int i;
for (i = 0; i < colorsList.Count; i++)
{
_pickerBrush.GradientStops.Add(new GradientStop(colorsList[i], i * stopIncrement));
}
_pickerBrush.GradientStops[i - 1].Offset = 1.0;
_spectrumDisplay.Fill = _pickerBrush;
}
#endregion //Methods
}
}

234
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ColorCanvas/Themes/Generic.xaml

@ -0,0 +1,234 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Microsoft.Windows.Controls"
xmlns:coreConverters="clr-namespace:Microsoft.Windows.Controls.Core.Converters">
<coreConverters:ColorToSolidColorBrushConverter x:Key="ColorToSolidColorBrushConverter" />
<LinearGradientBrush x:Key="ColorPickerDarkBorderBrush" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFA3AEB9" Offset="0"/>
<GradientStop Color="#FF8399A9" Offset="0.375"/>
<GradientStop Color="#FF718597" Offset="0.375"/>
<GradientStop Color="#FF617584" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="PopupBackgroundBrush" StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Offset="0" Color="#FFffffff"/>
<GradientStop Offset="1" Color="#FFE8EBED"/>
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<DrawingBrush x:Key="CheckerBrush" Viewport="0,0,10,10" ViewportUnits="Absolute" TileMode="Tile">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="White">
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0 100,100" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="LightGray">
<GeometryDrawing.Geometry>
<GeometryGroup>
<RectangleGeometry Rect="0,0 50,50" />
<RectangleGeometry Rect="50,50 50,50" />
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
<Style TargetType="{x:Type local:ColorCanvas}">
<Setter Property="BorderBrush" Value="{StaticResource ColorPickerDarkBorderBrush}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ColorCanvas}">
<Border BorderThickness="{TemplateBinding BorderThickness}" Background="White" BorderBrush="{TemplateBinding BorderBrush}" Padding="3">
<Grid Margin="2">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions >
<ColumnDefinition Width="200"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<Border BorderThickness="1" BorderBrush="DarkGray" ClipToBounds="True" Background="{StaticResource CheckerBrush}">
<Canvas x:Name="PART_ColorShadingCanvas" Width="200" Height="100" HorizontalAlignment="Left" VerticalAlignment="Top">
<Rectangle x:Name="ColorShadingRectangle" Height="{Binding ElementName=PART_ColorShadingCanvas,Path=Height}" Width="{Binding ElementName=PART_ColorShadingCanvas,Path=Width}"
Fill="{Binding SelectedColor, ElementName=PART_SpectrumSlider, Converter={StaticResource ColorToSolidColorBrushConverter}}" />
<Rectangle x:Name="WhiteGradient" Width="{Binding ElementName=PART_ColorShadingCanvas,Path=Width}" Height="{Binding ElementName=PART_ColorShadingCanvas,Path=Height}" >
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Offset="0" Color="#ffffffff"/>
<GradientStop Offset="1" Color="Transparent"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle x:Name="BlackGradient" Width="{Binding ElementName=PART_ColorShadingCanvas,Path=Width}" Height="{Binding ElementName=PART_ColorShadingCanvas,Path=Height}" >
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,1" EndPoint="0, 0">
<GradientStop Offset="0" Color="#ff000000"/>
<GradientStop Offset="1" Color="#00000000"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Canvas x:Name="PART_ColorShadeSelector" Width="10" Height="10" IsHitTestVisible="False">
<Ellipse Width="10" Height="10" StrokeThickness="3" Stroke="#FFFFFFFF" IsHitTestVisible="False" />
<Ellipse Width="10" Height="10" StrokeThickness="1" Stroke="#FF000000" IsHitTestVisible="False" />
</Canvas>
</Canvas>
</Border>
<Border BorderThickness="0,1,0,0" Grid.Row="1">
<Grid Background="{StaticResource CheckerBrush}">
<Rectangle x:Name="SelectedColor" Fill="{Binding SelectedColor, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource ColorToSolidColorBrushConverter}}" />
</Grid>
</Border>
<Border Grid.Column="1" Grid.RowSpan="2" Margin="4,-8,0,0" ClipToBounds="False">
<local:ColorSpectrumSlider x:Name="PART_SpectrumSlider" VerticalAlignment="Stretch" />
</Border>
</Grid>
<Border MinWidth="180" Grid.Row="1" BorderThickness="1" ClipToBounds="True" Margin="0,10,0,0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="R" />
<Slider x:Name="PART_RSlider" Maximum="255" TickFrequency="1" Grid.Row="0" Grid.Column="1"
Value="{Binding R, RelativeSource={RelativeSource TemplatedParent}}"/>
<TextBox Grid.Row="0" Grid.Column="2" Text="{Binding Value, ElementName=PART_RSlider}" />
<TextBlock Grid.Row="1" Grid.Column="0" Text="G" />
<Slider x:Name="PART_GSlider" Maximum="255" TickFrequency="1" Grid.Row="1" Grid.Column="1"
Value="{Binding G, RelativeSource={RelativeSource TemplatedParent}}"/>
<TextBox Grid.Row="1" Grid.Column="2" Text="{Binding Value, ElementName=PART_GSlider}" />
<TextBlock Grid.Row="2" Grid.Column="0" Text="B" />
<Slider x:Name="PART_BSlider" Maximum="255" TickFrequency="1" Grid.Row="2" Grid.Column="1"
Value="{Binding B, RelativeSource={RelativeSource TemplatedParent}}"/>
<TextBox Grid.Row="2" Grid.Column="3" Text="{Binding Value, ElementName=PART_BSlider}" />
<TextBlock Grid.Row="3" Grid.Column="0" Text="A" />
<Slider x:Name="PART_OpacitySlider" Grid.Row="3" Grid.Column="1" Maximum="255"
Value="{Binding Path=A, RelativeSource={RelativeSource TemplatedParent}}"/>
<TextBox Grid.Row="3" Grid.Column="3" Text="{Binding Value, ElementName=PART_OpacitySlider}" />
</Grid>
</Border>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="SliderRepeatButtonStyle"
TargetType="{x:Type RepeatButton}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Focusable" Value="false"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Border Background="{TemplateBinding Background}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="VerticalSlideThumbStyle" TargetType="{x:Type Thumb}">
<Setter Property="Focusable" Value="false"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Height" Value="12"/>
<Setter Property="Width" Value="11"/>
<Setter Property="Foreground" Value="Gray"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Canvas SnapsToDevicePixels="true">
<Path x:Name="LeftArrow" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FF000000" Data="F1 M 276.761,316L 262.619,307.835L 262.619,324.165L 276.761,316 Z " RenderTransformOrigin="0.5,0.5" Width="6" Height="8" >
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform />
<TranslateTransform Y="6" X="-3"/>
</TransformGroup>
</Path.RenderTransform>
</Path>
<Path x:Name="RightArrow" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FF000000" Data="F1 M 276.761,316L 262.619,307.835L 262.619,324.165L 276.761,316 Z " RenderTransformOrigin="0.5,0.5" Width="6" Height="8" >
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="-180"/>
<TranslateTransform Y="6" X="8"/>
</TransformGroup>
</Path.RenderTransform>
</Path>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type local:ColorSpectrumSlider}">
<Setter Property="Orientation" Value="Vertical"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Minimum" Value="1"/>
<Setter Property="Maximum" Value="360"/>
<Setter Property="TickFrequency" Value="0.001" />
<Setter Property="IsSnapToTickEnabled" Value="True" />
<Setter Property="IsDirectionReversed" Value="False" />
<Setter Property="IsMoveToPointEnabled" Value="True" />
<Setter Property="Value" Value="360" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ColorSpectrumSlider}">
<Grid>
<Border x:Name="PART_TrackBackground" BorderBrush="DarkGray" BorderThickness="1" Width="15" Margin="0,8,0,0" >
<Rectangle x:Name="PART_SpectrumDisplay" Stretch="Fill" VerticalAlignment="Stretch" />
</Border>
<Track Name="PART_Track">
<Track.DecreaseRepeatButton>
<RepeatButton Style="{StaticResource SliderRepeatButtonStyle}" Command="Slider.DecreaseLarge"/>
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton Style="{StaticResource SliderRepeatButtonStyle}" Command="Slider.IncreaseLarge"/>
</Track.IncreaseRepeatButton>
<Track.Thumb>
<Thumb Style="{StaticResource VerticalSlideThumbStyle}" />
</Track.Thumb>
</Track>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

70
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ColorPicker/Implementation/ColorPicker.cs

@ -5,6 +5,7 @@ using System.Windows.Media;
using System.Windows.Controls.Primitives;
using System.Collections.ObjectModel;
using System.Windows.Input;
using Microsoft.Windows.Controls.Core.Utilities;
namespace Microsoft.Windows.Controls
{
@ -44,6 +45,29 @@ namespace Microsoft.Windows.Controls
#endregion //ButtonStyle
#region DisplayAvailableColors
public static readonly DependencyProperty DisplayAvailableColorsProperty = DependencyProperty.Register("DisplayAvailableColors", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(true, OnDisplayAvailableColorsChanged));
public bool DisplayAvailableColors
{
get { return (bool)GetValue(DisplayAvailableColorsProperty); }
set { SetValue(DisplayAvailableColorsProperty, value); }
}
private static void OnDisplayAvailableColorsChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
ColorPicker colorPicker = o as ColorPicker;
if (colorPicker != null)
colorPicker.OnDisplayAvailableColorsChanged((bool)e.OldValue, (bool)e.NewValue);
}
protected virtual void OnDisplayAvailableColorsChanged(bool oldValue, bool newValue)
{
// TODO: Add your property changed side-effects. Descendants can override as well.
}
#endregion //DisplayAvailableColors
#region DisplayColorAndName
public static readonly DependencyProperty DisplayColorAndNameProperty = DependencyProperty.Register("DisplayColorAndName", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(false));
@ -55,6 +79,52 @@ namespace Microsoft.Windows.Controls
#endregion //DisplayColorAndName
#region DisplayRecentColors
public static readonly DependencyProperty DisplayRecentColorsProperty = DependencyProperty.Register("DisplayRecentColors", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(true, OnDisplayRecentColorsChanged));
public bool DisplayRecentColors
{
get { return (bool)GetValue(DisplayRecentColorsProperty); }
set { SetValue(DisplayRecentColorsProperty, value); }
}
private static void OnDisplayRecentColorsChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
ColorPicker colorPicker = o as ColorPicker;
if (colorPicker != null)
colorPicker.OnDisplayRecentColorsChanged((bool)e.OldValue, (bool)e.NewValue);
}
protected virtual void OnDisplayRecentColorsChanged(bool oldValue, bool newValue)
{
// TODO: Add your property changed side-effects. Descendants can override as well.
}
#endregion //DisplayRecentColors
#region DisplayStandardColors
public static readonly DependencyProperty DisplayStandardColorsProperty = DependencyProperty.Register("DisplayStandardColors", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(true, OnDisplayStandardColorsChanged));
public bool DisplayStandardColors
{
get { return (bool)GetValue(DisplayStandardColorsProperty); }
set { SetValue(DisplayStandardColorsProperty, value); }
}
private static void OnDisplayStandardColorsChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
ColorPicker colorPicker = o as ColorPicker;
if (colorPicker != null)
colorPicker.OnDisplayStandardColorsChanged((bool)e.OldValue, (bool)e.NewValue);
}
protected virtual void OnDisplayStandardColorsChanged(bool oldValue, bool newValue)
{
// TODO: Add your property changed side-effects. Descendants can override as well.
}
#endregion //DisplayStandardColors
#region IsOpen
public static readonly DependencyProperty IsOpenProperty = DependencyProperty.Register("IsOpen", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(false));

24
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ColorPicker/Implementation/ColorUtilities.cs

@ -1,24 +0,0 @@
using System;
using System.Linq;
using System.Windows.Media;
using System.Reflection;
using System.Collections.Generic;
namespace Microsoft.Windows.Controls
{
static class ColorUtilities
{
public static readonly Dictionary<string, Color> KnownColors = GetKnownColors();
public static string GetColorName(this Color color)
{
return KnownColors.Where(kvp => kvp.Value.Equals(color)).Select(kvp => kvp.Key).FirstOrDefault();
}
private static Dictionary<string, Color> GetKnownColors()
{
var colorProperties = typeof(Colors).GetProperties(BindingFlags.Static | BindingFlags.Public);
return colorProperties.ToDictionary(p => p.Name, p => (Color)p.GetValue(null, null));
}
}
}

7
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ColorPicker/Themes/Generic.xaml

@ -14,6 +14,7 @@
<!-- ColorPicker -->
<!-- =============================================================================== -->
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<coreConverters:ColorToSolidColorBrushConverter x:Key="ColorToSolidColorBrushConverter" />
<LinearGradientBrush x:Key="ColorPickerDarkBorderBrush" EndPoint="0.5,1" StartPoint="0.5,0">
@ -196,7 +197,7 @@
</Grid.RowDefinitions>
<!-- Available Colors -->
<Grid Grid.Row="1">
<Grid Grid.Row="1" Visibility="{TemplateBinding DisplayAvailableColors, Converter={StaticResource BooleanToVisibilityConverter}}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
@ -217,7 +218,7 @@
</Grid>
<!-- Standard Colors-->
<Grid Grid.Row="2">
<Grid Grid.Row="2" Visibility="{TemplateBinding DisplayStandardColors, Converter={StaticResource BooleanToVisibilityConverter}}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
@ -238,7 +239,7 @@
</Grid>
<!-- Recent Colors-->
<Grid Grid.Row="3" Margin="0,1,0,1">
<Grid Grid.Row="3" Margin="0,1,0,1" Visibility="{TemplateBinding DisplayRecentColors, Converter={StaticResource BooleanToVisibilityConverter}}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />

33
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Converters/SolidColorBrushToColorConverter.cs

@ -0,0 +1,33 @@
using System;
using System.Windows.Data;
using System.Windows.Media;
namespace Microsoft.Windows.Controls.Core.Converters
{
public class SolidColorBrushToColorConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
SolidColorBrush brush = value as SolidColorBrush;
if (brush != null)
return brush.Color;
return default(Color);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value != null)
{
Color color = (Color)value;
return new SolidColorBrush(color);
}
return default(SolidColorBrush);
}
#endregion
}
}

18
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/HsvColor.cs

@ -0,0 +1,18 @@
using System;
namespace Microsoft.Windows.Controls.Primitives
{
internal struct HsvColor
{
public double H;
public double S;
public double V;
public HsvColor(double h, double s, double v)
{
H = h;
S = s;
V = v;
}
}
}

172
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Utilities/ColorUtilities.cs

@ -0,0 +1,172 @@
using System;
using System.Linq;
using System.Windows.Media;
using System.Reflection;
using System.Collections.Generic;
using Microsoft.Windows.Controls.Primitives;
namespace Microsoft.Windows.Controls.Core.Utilities
{
static class ColorUtilities
{
public static readonly Dictionary<string, Color> KnownColors = GetKnownColors();
public static string GetColorName(this Color color)
{
return KnownColors.Where(kvp => kvp.Value.Equals(color)).Select(kvp => kvp.Key).FirstOrDefault();
}
private static Dictionary<string, Color> GetKnownColors()
{
var colorProperties = typeof(Colors).GetProperties(BindingFlags.Static | BindingFlags.Public);
return colorProperties.ToDictionary(p => p.Name, p => (Color)p.GetValue(null, null));
}
/// <summary>
/// Converts an RGB color to an HSV color.
/// </summary>
/// <param name="r"></param>
/// <param name="b"></param>
/// <param name="g"></param>
/// <returns></returns>
public static HsvColor ConvertRgbToHsv(int r, int b, int g)
{
double delta, min;
double h = 0, s, v;
min = Math.Min(Math.Min(r, g), b);
v = Math.Max(Math.Max(r, g), b);
delta = v - min;
if (v == 0.0)
{
s = 0;
}
else
s = delta / v;
if (s == 0)
h = 0.0;
else
{
if (r == v)
h = (g - b) / delta;
else if (g == v)
h = 2 + (b - r) / delta;
else if (b == v)
h = 4 + (r - g) / delta;
h *= 60;
if (h < 0.0)
h = h + 360;
}
return new HsvColor { H = h, S = s, V = v / 255 };
}
/// <summary>
/// Converts an HSV color to an RGB color.
/// </summary>
/// <param name="h"></param>
/// <param name="s"></param>
/// <param name="v"></param>
/// <returns></returns>
public static Color ConvertHsvToRgb(double h, double s, double v)
{
double r = 0, g = 0, b = 0;
if (s == 0)
{
r = v;
g = v;
b = v;
}
else
{
int i;
double f, p, q, t;
if (h == 360)
h = 0;
else
h = h / 60;
i = (int)Math.Truncate(h);
f = h - i;
p = v * (1.0 - s);
q = v * (1.0 - (s * f));
t = v * (1.0 - (s * (1.0 - f)));
switch (i)
{
case 0:
{
r = v;
g = t;
b = p;
break;
}
case 1:
{
r = q;
g = v;
b = p;
break;
}
case 2:
{
r = p;
g = v;
b = t;
break;
}
case 3:
{
r = p;
g = q;
b = v;
break;
}
case 4:
{
r = t;
g = p;
b = v;
break;
}
default:
{
r = v;
g = p;
b = q;
break;
}
}
}
return Color.FromArgb(255, (byte)(r * 255), (byte)(g * 255), (byte)(b * 255));
}
/// <summary>
/// Generates a list of colors with hues ranging from 0 360 and a saturation and value of 1.
/// </summary>
/// <returns></returns>
public static List<Color> GenerateHsvSpectrum()
{
List<Color> colorsList = new List<Color>(8);
for (int i = 0; i < 29; i++)
{
colorsList.Add(ColorUtilities.ConvertHsvToRgb(i * 12, 1, 1));
}
colorsList.Add(ColorUtilities.ConvertHsvToRgb(0, 1, 1));
return colorsList;
}
}
}

2
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Themes/Generic.xaml

@ -317,7 +317,7 @@
<Grid Background="#BCC7D8" Margin="4">
<StackPanel Orientation="Horizontal" Margin="1" >
<RadioButton IsChecked="{Binding IsCategorized, RelativeSource={RelativeSource TemplatedParent}}" VerticalAlignment="Center"
Style="{StaticResource OptionsToggleButtonStyle}" ToolTip="Categorize">
Style="{StaticResource OptionsToggleButtonStyle}" ToolTip="Categorized">
<Image Source="/WPFToolkit.Extended;component/PropertyGrid/Images/Categorize16.png" Width="16" Height="16" />
</RadioButton>
<RadioButton IsChecked="{Binding IsCategorized, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource InverseBoolConverter}, Mode=OneWay}" VerticalAlignment="Center"

4
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Themes/Generic.xaml

@ -5,7 +5,8 @@
<ResourceDictionary Source="/WPFToolkit.Extended;component/BusyIndicator/Themes/Generic.xaml" />
<ResourceDictionary Source="/WPFToolkit.Extended;component/ButtonSpinner/Themes/Generic.xaml" />
<ResourceDictionary Source="/WPFToolkit.Extended;component/ChildWindow/Themes/Generic.xaml" />
<ResourceDictionary Source="/WPFToolkit.Extended;component/ColorPicker/Themes/Generic.xaml" />
<ResourceDictionary Source="/WPFToolkit.Extended;component/ColorCanvas/Themes/Generic.xaml" />
<ResourceDictionary Source="/WPFToolkit.Extended;component/ColorPicker/Themes/Generic.xaml" />
<ResourceDictionary Source="/WPFToolkit.Extended;component/Magnifier/Themes/Generic.xaml" />
<ResourceDictionary Source="/WPFToolkit.Extended;component/MaskedTextBox/Themes/Generic.xaml" />
<ResourceDictionary Source="/WPFToolkit.Extended;component/MessageBox/Themes/Generic.xaml" />
@ -15,5 +16,4 @@
<ResourceDictionary Source="/WPFToolkit.Extended;component/PropertyGrid/Themes/Generic.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

10
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj

@ -75,6 +75,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="ColorCanvas\Themes\Generic.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="ColorPicker\Themes\Generic.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@ -132,11 +136,15 @@
<Compile Include="ButtonSpinner\Implementation\Spinner.cs" />
<Compile Include="ButtonSpinner\Implementation\ValidSpinDirections.cs" />
<Compile Include="Chromes\Implementation\ButtonChrome.cs" />
<Compile Include="ColorCanvas\Implementation\ColorCanvas.cs" />
<Compile Include="Core\Primitives\HsvColor.cs" />
<Compile Include="ColorPicker\Implementation\ColorItem.cs" />
<Compile Include="ColorPicker\Implementation\ColorPicker.cs" />
<Compile Include="ColorPicker\Implementation\ColorUtilities.cs" />
<Compile Include="Core\Utilities\ColorUtilities.cs" />
<Compile Include="ColorCanvas\Implementation\ColorSpectrumSlider.cs" />
<Compile Include="Core\Converters\ColorToSolidColorBrushConverter.cs" />
<Compile Include="Core\Converters\InverseBoolConverter.cs" />
<Compile Include="Core\Converters\SolidColorBrushToColorConverter.cs" />
<Compile Include="Core\Utilities\ContextMenuUtilities.cs" />
<Compile Include="DateTimeUpDown\Implementation\DateTimeFormat.cs" />
<Compile Include="DateTimeUpDown\Implementation\DateTimeInfo.cs" />

Loading…
Cancel
Save