Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
ColorPicker.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.Windows.Controls;
5 using System.Windows;
6 using System.Windows.Data;
7 using System.Windows.Media;
8 using SiliconStudio.Core.Mathematics;
9 
10 using System.Windows.Media.Imaging;
11 using System.Windows.Input;
12 using SiliconStudio.Presentation.Extensions;
13 
17 
18 namespace SiliconStudio.Presentation.Controls
19 {
20  /// <summary>
21  /// Represents a color picker control.
22  /// </summary>
23  [TemplatePart(Name = "PART_ColorPickerSelector", Type = typeof(Canvas))]
24  [TemplatePart(Name = "PART_ColorPickerRenderSurface", Type = typeof(Rectangle))]
25  [TemplatePart(Name = "PART_ColorPreviewRenderSurface", Type = typeof(Rectangle))]
26  [TemplatePart(Name = "PART_HuePickerSelector", Type = typeof(FrameworkElement))]
27  [TemplatePart(Name = "PART_HuePickerRenderSurface", Type = typeof(Rectangle))]
28  public sealed class ColorPicker : Control
29  {
30  static ColorPicker()
31  {
32  DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorPicker), new FrameworkPropertyMetadata(typeof(ColorPicker)));
33  }
34 
35  private Canvas colorPickerSelector;
36  private Rectangle colorPickerRenderSurface;
37  private Rectangle colorPreviewRenderSurface;
38  private FrameworkElement huePickerRenderSurface;
39  private Rectangle huePickerSelector;
40  private bool interlock;
41  private ColorHSV internalColor;
42  private bool suspendBindingUpdates;
43  private bool templateApplied;
44  private DependencyProperty initializingProperty;
45 
46  /// <summary>
47  /// Identifies the <see cref="Color"/> dependency property.
48  /// </summary>
49  public static readonly DependencyProperty ColorProperty = DependencyProperty.Register("Color", typeof(Color4), typeof(ColorPicker), new FrameworkPropertyMetadata(default(Color4), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnColorPropertyChanged, CoreceColorValue, false, UpdateSourceTrigger.Explicit));
50 
51  /// <summary>
52  /// Identifies the <see cref="Hue"/> dependency property.
53  /// </summary>
54  public static readonly DependencyProperty HueProperty = DependencyProperty.Register("Hue", typeof(float), typeof(ColorPicker), new FrameworkPropertyMetadata(0.0f, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnHSVPropertyChanged, CoerceHueValue));
55 
56  /// <summary>
57  /// Identifies the <see cref="Saturation"/> dependency property.
58  /// </summary>
59  public static readonly DependencyProperty SaturationProperty = DependencyProperty.Register("Saturation", typeof(float), typeof(ColorPicker), new FrameworkPropertyMetadata(0.0f, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnHSVPropertyChanged, CoercePercentageValue));
60 
61  /// <summary>
62  /// Identifies the <see cref="Brightness"/> dependency property.
63  /// </summary>
64  public static readonly DependencyProperty BrightnessProperty = DependencyProperty.Register("Brightness", typeof(float), typeof(ColorPicker), new FrameworkPropertyMetadata(0.0f, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnHSVPropertyChanged, CoercePercentageValue));
65 
66  /// <summary>
67  /// Identifies the <see cref="Red"/> dependency property.
68  /// </summary>
69  public static readonly DependencyProperty RedProperty = DependencyProperty.Register("Red", typeof(byte), typeof(ColorPicker), new FrameworkPropertyMetadata((byte)0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnRGBAPropertyChanged));
70 
71  /// <summary>
72  /// Identifies the <see cref="Green"/> dependency property.
73  /// </summary>
74  public static readonly DependencyProperty GreenProperty = DependencyProperty.Register("Green", typeof(byte), typeof(ColorPicker), new FrameworkPropertyMetadata((byte)0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnRGBAPropertyChanged));
75 
76  /// <summary>
77  /// Identifies the <see cref="Blue"/> dependency property.
78  /// </summary>
79  public static readonly DependencyProperty BlueProperty = DependencyProperty.Register("Blue", typeof(byte), typeof(ColorPicker), new FrameworkPropertyMetadata((byte)0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnRGBAPropertyChanged));
80 
81  /// <summary>
82  /// Identifies the <see cref="Alpha"/> dependency property.
83  /// </summary>
84  public static readonly DependencyProperty AlphaProperty = DependencyProperty.Register("Alpha", typeof(byte), typeof(ColorPicker), new FrameworkPropertyMetadata((byte)0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnRGBAPropertyChanged));
85 
86  /// <summary>
87  /// The color associated to this color picker.
88  /// </summary>
89  /// <remarks>The float values of each component of the color are always equals to the float conversion of a <see cref="byte"/> value divided by <b>255</b>.</remarks>
90  public Color4 Color { get { return (Color4)GetValue(ColorProperty); } set { SetValue(ColorProperty, value); } }
91 
92  /// <summary>
93  /// The hue of the color associated to this color picker.
94  /// </summary>
95  public float Hue { get { return (float)GetValue(HueProperty); } set { SetValue(HueProperty, value); } }
96 
97  /// <summary>
98  /// The saturation of the color associated to this color picker.
99  /// </summary>
100  public float Saturation { get { return (float)GetValue(SaturationProperty); } set { SetValue(SaturationProperty, value); } }
101 
102  /// <summary>
103  /// The brightness of the color associated to this color picker.
104  /// </summary>
105  public float Brightness { get { return (float)GetValue(BrightnessProperty); } set { SetValue(BrightnessProperty, value); } }
106 
107  /// <summary>
108  /// The red component of the color associated to this color picker.
109  /// </summary>
110  public byte Red { get { return (byte)GetValue(RedProperty); } set { SetValue(RedProperty, value); } }
111 
112  /// <summary>
113  /// The green component of the color associated to this color picker.
114  /// </summary>
115  public byte Green { get { return (byte)GetValue(GreenProperty); } set { SetValue(GreenProperty, value); } }
116 
117  /// <summary>
118  /// The blue component of the color associated to this color picker.
119  /// </summary>
120  public byte Blue { get { return (byte)GetValue(BlueProperty); } set { SetValue(BlueProperty, value); } }
121 
122  /// <summary>
123  /// The alpha component of the color associated to this color picker.
124  /// </summary>
125  public byte Alpha { get { return (byte)GetValue(AlphaProperty); } set { SetValue(AlphaProperty, value); } }
126 
127  /// <summary>
128  /// An internal representation of the color associated to this color picker. Its value never rounded to match a byte division by 255.
129  /// </summary>
130  private ColorHSV InternalColor { get { return internalColor; } set { internalColor = value; var prev = interlock; interlock = true; Color = value.ToColor(); interlock = prev; } }
131 
132  /// <inheritdoc/>
133  public override void OnApplyTemplate()
134  {
135  templateApplied = false;
136  base.OnApplyTemplate();
137 
138  if (colorPickerRenderSurface != null)
139  {
140  colorPickerRenderSurface.MouseDown -= OnColorPickerRenderSurfaceMouseDown;
141  colorPickerRenderSurface.MouseUp -= OnColorPickerRenderSurfaceMouseUp;
142  colorPickerRenderSurface.MouseMove -= OnColorPickerRenderSurfaceMouseMove;
143  }
144 
145  if (huePickerRenderSurface != null)
146  {
147  huePickerRenderSurface.MouseDown -= OnHuePickerRenderSurfaceMouseDown;
148  huePickerRenderSurface.MouseUp -= OnHuePickerRenderSurfaceMouseUp;
149  huePickerRenderSurface.MouseMove -= OnHuePickerRenderSurfaceMouseMove;
150 
151  }
152 
153  colorPickerRenderSurface = FrameworkElementExtensions.CheckTemplatePart<Rectangle>(GetTemplateChild("PART_ColorPickerRenderSurface"));
154  colorPreviewRenderSurface = FrameworkElementExtensions.CheckTemplatePart<Rectangle>(GetTemplateChild("PART_ColorPreviewRenderSurface"));
155  colorPickerSelector = FrameworkElementExtensions.CheckTemplatePart<Canvas>(GetTemplateChild("PART_ColorPickerSelector"));
156  huePickerSelector = FrameworkElementExtensions.CheckTemplatePart<Rectangle>(GetTemplateChild("PART_HuePickerSelector"));
157  huePickerRenderSurface = FrameworkElementExtensions.CheckTemplatePart<FrameworkElement>(GetTemplateChild("PART_HuePickerRenderSurface"));
158 
159  if (colorPickerRenderSurface != null)
160  {
161  colorPickerRenderSurface.MouseDown += OnColorPickerRenderSurfaceMouseDown;
162  colorPickerRenderSurface.MouseUp += OnColorPickerRenderSurfaceMouseUp;
163  colorPickerRenderSurface.MouseMove += OnColorPickerRenderSurfaceMouseMove;
164  }
165 
166  if (huePickerRenderSurface != null)
167  {
168  huePickerRenderSurface.MouseDown += OnHuePickerRenderSurfaceMouseDown;
169  huePickerRenderSurface.MouseUp += OnHuePickerRenderSurfaceMouseUp;
170  huePickerRenderSurface.MouseMove += OnHuePickerRenderSurfaceMouseMove;
171  }
172 
173  RenderColorPickerSurface();
174 
175  if (colorPickerSelector != null && colorPickerRenderSurface != null)
176  {
177  Canvas.SetLeft(colorPickerSelector, Saturation * colorPickerRenderSurface.Width / 100.0);
178  Canvas.SetTop(colorPickerSelector, Brightness * colorPickerRenderSurface.Height / 100.0);
179  }
180  if (huePickerSelector != null && huePickerRenderSurface != null)
181  {
182  Canvas.SetLeft(huePickerSelector, Hue * huePickerRenderSurface.Width / 360.0);
183  }
184  templateApplied = true;
185  }
186 
187  /// <summary>
188  /// Handles the <see cref="Rectangle.MouseDown"/> event of the color surface.
189  /// </summary>
190  /// <param name="sender">The object where the event handler is attached.</param>
191  /// <param name="e">The event data.</param>
192  private void OnColorPickerRenderSurfaceMouseDown(object sender, MouseButtonEventArgs e)
193  {
194  if (e.LeftButton == MouseButtonState.Pressed)
195  {
196  colorPickerRenderSurface.CaptureMouse();
197  suspendBindingUpdates = true;
198  UpdateColorPickerFromMouse(e.GetPosition(colorPickerRenderSurface));
199  }
200  }
201 
202  /// <summary>
203  /// Handles the <see cref="Rectangle.MouseUp"/> event of the color surface.
204  /// </summary>
205  /// <param name="sender">The object where the event handler is attached.</param>
206  /// <param name="e">The event data.</param>
207  private void OnColorPickerRenderSurfaceMouseUp(object sender, MouseButtonEventArgs e)
208  {
209  if (e.LeftButton == MouseButtonState.Released)
210  {
211  colorPickerRenderSurface.ReleaseMouseCapture();
212  suspendBindingUpdates = false;
213  UpdateAllBindings();
214  }
215  }
216 
217  /// <summary>
218  /// Handles the <see cref="Rectangle.MouseMove"/> event of the color surface.
219  /// </summary>
220  /// <param name="sender">The object where the event handler is attached.</param>
221  /// <param name="e">The event data.</param>
222  private void OnColorPickerRenderSurfaceMouseMove(object sender, MouseEventArgs e)
223  {
224  if (e.LeftButton == MouseButtonState.Pressed && colorPickerRenderSurface.IsMouseCaptured)
225  {
226  UpdateColorPickerFromMouse(e.GetPosition(colorPickerRenderSurface));
227  }
228  }
229 
230  /// <summary>
231  /// Updates the <see cref="Color"/> value from the given position in the color surface.
232  /// </summary>
233  /// <param name="position">The position of the cursor in the color surface.</param>
234  private void UpdateColorPickerFromMouse(Point position)
235  {
236  Canvas.SetLeft(colorPickerSelector, MathUtil.Clamp(position.X, 0.0f, colorPickerRenderSurface.Width));
237  Canvas.SetTop(colorPickerSelector, MathUtil.Clamp(position.Y, 0.0f, colorPickerRenderSurface.Height));
238  var x = (float)(position.X / colorPickerRenderSurface.Width);
239  var y = (float)(position.Y / colorPickerRenderSurface.Height);
240  x = MathUtil.Clamp(x, 0.0f, 1.0f);
241  y = MathUtil.Clamp(y, 0.0f, 1.0f);
242  var colorHSV = new ColorHSV(Hue, x, y, Alpha / 255.0f);
243  //SetCurrentValue(ColorProperty, colorHSV.ToColor());
244  SetCurrentValue(SaturationProperty, colorHSV.S * 100.0f);
245  SetCurrentValue(BrightnessProperty, colorHSV.V * 100.0f);
246  }
247 
248 
249  /// <summary>
250  /// Handles the <see cref="Rectangle.MouseDown"/> event of the hue surface.
251  /// </summary>
252  /// <param name="sender">The object where the event handler is attached.</param>
253  /// <param name="e">The event data.</param>
254  private void OnHuePickerRenderSurfaceMouseDown(object sender, MouseButtonEventArgs e)
255  {
256  if (e.LeftButton == MouseButtonState.Pressed)
257  {
258  huePickerRenderSurface.CaptureMouse();
259  suspendBindingUpdates = true;
260  UpdateHuePickerFromMouse(e.GetPosition(huePickerRenderSurface));
261  }
262  }
263 
264  /// <summary>
265  /// Handles the <see cref="Rectangle.MouseUp"/> event of the hue surface.
266  /// </summary>
267  /// <param name="sender">The object where the event handler is attached.</param>
268  /// <param name="e">The event data.</param>
269  private void OnHuePickerRenderSurfaceMouseUp(object sender, MouseButtonEventArgs e)
270  {
271  if (e.LeftButton == MouseButtonState.Released)
272  {
273  huePickerRenderSurface.ReleaseMouseCapture();
274  suspendBindingUpdates = false;
275  UpdateAllBindings();
276  }
277  }
278 
279  /// <summary>
280  /// Handles the <see cref="Rectangle.MouseMove"/> event of the hue surface.
281  /// </summary>
282  /// <param name="sender">The object where the event handler is attached.</param>
283  /// <param name="e">The event data.</param>
284  private void OnHuePickerRenderSurfaceMouseMove(object sender, MouseEventArgs e)
285  {
286  if (e.LeftButton == MouseButtonState.Pressed && huePickerRenderSurface.IsMouseCaptured)
287  {
288  UpdateHuePickerFromMouse(e.GetPosition(huePickerRenderSurface));
289  }
290  }
291 
292  /// <summary>
293  /// Updates the <see cref="Color"/> value from the given position in the hue surface.
294  /// </summary>
295  /// <param name="position">The position of the cursor in the hue surface.</param>
296  private void UpdateHuePickerFromMouse(Point position)
297  {
298  Canvas.SetLeft(huePickerSelector, MathUtil.Clamp(position.X, 0.0f, huePickerRenderSurface.Width));
299  var x = (float)(position.X / huePickerRenderSurface.Width);
300  x = (float)(360.0 * MathUtil.Clamp(x, 0.0f, 1.0f));
301  //var colorHSV = new ColorHSV(x, Saturation / 100.0f, Brightness / 100.0f, Alpha / 255.0f);
302  //SetCurrentValue(ColorProperty, colorHSV.ToColor());
303  SetCurrentValue(HueProperty, x);
304  }
305 
306  /// <summary>
307  /// Update the color surface brush according to the current <see cref="Hue"/> value.
308  /// </summary>
309  private void RenderColorPickerSurface()
310  {
311  if (colorPreviewRenderSurface != null)
312  {
313  colorPreviewRenderSurface.Fill = new SolidColorBrush(Color.ToSystemColor());
314  }
315  if (colorPickerRenderSurface != null)
316  {
317  // Ensure the color picker is loaded
318  if (!double.IsNaN(colorPickerRenderSurface.Width) && !double.IsNaN(colorPickerRenderSurface.Height))
319  {
320  var width = (int)colorPickerRenderSurface.Width;
321  var height = (int)colorPickerRenderSurface.Height;
322 
323  PixelFormat pf = PixelFormats.Bgr32;
324  int rawStride = (width * pf.BitsPerPixel + 7) / 8;
325  var rawImage = new byte[rawStride * height];
326 
327  for (int j = 0; j < height; ++j)
328  {
329  float y = j / (float)(height - 1);
330 
331  for (int i = 0; i < width; ++i)
332  {
333  float x = i / (float)(width - 1);
334 
335  System.Windows.Media.Color color = new ColorHSV(Hue, x, y, 1.0f).ToSystemColor();
336  rawImage[(i + j * width) * 4 + 0] = color.B;
337  rawImage[(i + j * width) * 4 + 1] = color.G;
338  rawImage[(i + j * width) * 4 + 2] = color.R;
339  }
340  }
341 
342  colorPickerRenderSurface.Fill = new DrawingBrush(new ImageDrawing(BitmapSource.Create(width, height, 96, 96, pf, null, rawImage, rawStride), new Rect(0.0f, 0.0f, width, height)));
343  }
344  }
345  }
346 
347  /// <summary>
348  /// Raised when the <see cref="Color"/> property is modified.
349  /// </summary>
350  private void OnColorChanged()
351  {
352  bool isInitializing = !templateApplied && initializingProperty == null;
353  if (isInitializing)
354  initializingProperty = ColorProperty;
355 
356  if (!interlock)
357  {
358  InternalColor = ColorHSV.FromColor(Color);
359  var colorRGBA = InternalColor.ToColor();
360  interlock = true;
361 
362  SetCurrentValue(RedProperty, (byte)(Math.Round(colorRGBA.R * 255.0f)));
363  SetCurrentValue(GreenProperty, (byte)(Math.Round(colorRGBA.G * 255.0f)));
364  SetCurrentValue(BlueProperty, (byte)(Math.Round(colorRGBA.B * 255.0f)));
365  SetCurrentValue(AlphaProperty, (byte)(Math.Round(colorRGBA.A * 255.0f)));
366 
367  SetCurrentValue(HueProperty, InternalColor.H);
368  SetCurrentValue(SaturationProperty, InternalColor.S * 100.0f);
369  SetCurrentValue(BrightnessProperty, InternalColor.V * 100.0f);
370  interlock = false;
371  }
372 
373  if (!suspendBindingUpdates)
374  {
375  RenderColorPickerSurface();
376  }
377  else if (colorPreviewRenderSurface != null)
378  {
379  colorPreviewRenderSurface.Fill = new SolidColorBrush(Color.ToSystemColor());
380  }
381  UpdateBinding(ColorProperty);
382 
383  if (isInitializing)
384  initializingProperty = null;
385  }
386 
387  /// <summary>
388  /// Raised when the <see cref="Red"/>, <see cref="Green"/>, <see cref="Blue"/> or <see cref="Alpha"/> properties are modified.
389  /// </summary>
390  /// <param name="e">The dependency property that has changed.</param>
391  private void OnRGBAValueChanged(DependencyPropertyChangedEventArgs e)
392  {
393  bool isInitializing = !templateApplied && initializingProperty == null;
394  if (isInitializing)
395  initializingProperty = e.Property;
396 
397  if (!interlock)
398  {
399  Color4 colorRGBA;
400  if (e.Property == RedProperty)
401  colorRGBA = new Color4((byte)e.NewValue / 255.0f, Green / 255.0f, Blue / 255.0f, Alpha / 255.0f);
402  else if (e.Property == GreenProperty)
403  colorRGBA = new Color4(Red / 255.0f, (byte)e.NewValue / 255.0f, Blue / 255.0f, Alpha / 255.0f);
404  else if (e.Property == BlueProperty)
405  colorRGBA = new Color4(Red / 255.0f, Green / 255.0f, (byte)e.NewValue / 255.0f, Alpha / 255.0f);
406  else if (e.Property == AlphaProperty)
407  colorRGBA = new Color4(Red / 255.0f, Green / 255.0f, Blue / 255.0f, (byte)e.NewValue / 255.0f);
408  else
409  throw new ArgumentException("Property unsupported by method OnRGBAValueChanged.");
410 
411  interlock = true;
412  InternalColor = ColorHSV.FromColor(colorRGBA);
413  SetCurrentValue(HueProperty, InternalColor.H);
414  SetCurrentValue(SaturationProperty, InternalColor.S * 100.0f);
415  SetCurrentValue(BrightnessProperty, InternalColor.V * 100.0f);
416  interlock = false;
417  }
418 
419  UpdateBinding(e.Property);
420  if (isInitializing)
421  initializingProperty = null;
422  }
423 
424  /// <summary>
425  /// Raised when the <see cref="Hue"/>, <see cref="Saturation"/>, or <see cref="Brightness"/> properties are modified.
426  /// </summary>
427  /// <param name="e">The dependency property that has changed.</param>
428  private void OnHSVValueChanged(DependencyPropertyChangedEventArgs e)
429  {
430  bool isInitializing = !templateApplied && initializingProperty == null;
431  if (isInitializing)
432  initializingProperty = e.Property;
433 
434  if (!interlock)
435  {
436  if (e.Property == HueProperty)
437  {
438  InternalColor = new ColorHSV((float)e.NewValue, Saturation / 100.0f, Brightness / 100.0f, Alpha / 255.0f);
439  RenderColorPickerSurface();
440  }
441  else if (e.Property == SaturationProperty)
442  InternalColor = new ColorHSV(Hue, (float)e.NewValue / 100.0f, Brightness / 100.0f, Alpha / 255.0f);
443  else if (e.Property == BrightnessProperty)
444  InternalColor = new ColorHSV(Hue, Saturation / 100.0f, (float)e.NewValue / 100.0f, Alpha / 255.0f);
445  else
446  throw new ArgumentException("Property unsupported by method OnHSVValueChanged.");
447 
448  var colorRGBA = InternalColor.ToColor();
449  interlock = true;
450  SetCurrentValue(RedProperty, (byte)(Math.Round(colorRGBA.R * 255.0f)));
451  SetCurrentValue(GreenProperty, (byte)(Math.Round(colorRGBA.G * 255.0f)));
452  SetCurrentValue(BlueProperty, (byte)(Math.Round(colorRGBA.B * 255.0f)));
453  SetCurrentValue(AlphaProperty, (byte)(Math.Round(colorRGBA.A * 255.0f)));
454  interlock = false;
455  }
456 
457  UpdateBinding(e.Property);
458 
459  if (colorPickerSelector != null && colorPickerRenderSurface != null && !suspendBindingUpdates)
460  {
461  Canvas.SetLeft(colorPickerSelector, Saturation * colorPickerRenderSurface.Width / 100.0);
462  Canvas.SetTop(colorPickerSelector, Brightness * colorPickerRenderSurface.Height / 100.0);
463  }
464  if (huePickerSelector != null && huePickerRenderSurface != null && !suspendBindingUpdates)
465  {
466  Canvas.SetLeft(huePickerSelector, Hue * huePickerRenderSurface.Width / 360.0);
467  }
468 
469  if (isInitializing)
470  initializingProperty = null;
471  }
472 
473  /// <summary>
474  /// Updates the binding of the given dependency property, if binding updates are not currently suspended by user actions.
475  /// </summary>
476  /// <param name="dependencyProperty">The dependency property.</param>
477  private void UpdateBinding(DependencyProperty dependencyProperty)
478  {
479  if (!suspendBindingUpdates && dependencyProperty != initializingProperty)
480  {
481  BindingExpression expression = GetBindingExpression(dependencyProperty);
482  if (expression != null)
483  expression.UpdateSource();
484  }
485  }
486 
487  /// <summary>
488  /// Updates the bindings of all dependency properties, if binding updates are not currently suspended by user actions.
489  /// </summary>
490  private void UpdateAllBindings()
491  {
492  UpdateBinding(ColorProperty);
493  UpdateBinding(RedProperty);
494  UpdateBinding(GreenProperty);
495  UpdateBinding(BlueProperty);
496  UpdateBinding(AlphaProperty);
497  UpdateBinding(HueProperty);
498  UpdateBinding(SaturationProperty);
499  UpdateBinding(BrightnessProperty);
500  }
501 
502  /// <summary>
503  /// Raised by <see cref="ColorProperty"/> when the <see cref="Color"/> dependency property is modified.
504  /// </summary>
505  /// <param name="sender">The dependency object where the event handler is attached.</param>
506  /// <param name="e">The event data.</param>
507  private static void OnColorPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
508  {
509  var colorPicker = (ColorPicker)sender;
510  colorPicker.OnColorChanged();
511  }
512 
513  /// <summary>
514  /// Raised by <see cref="HueProperty"/>, <see cref="SaturationProperty"/> or <see cref="BrightnessProperty"/> when respectively the
515  /// <see cref="Hue"/>, <see cref="Saturation"/> or <see cref="Brightness"/> dependency property is modified.
516  /// </summary>
517  /// <param name="sender">The dependency object where the event handler is attached.</param>
518  /// <param name="e">The event data.</param>
519  private static void OnHSVPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
520  {
521  var colorPicker = (ColorPicker)sender;
522  colorPicker.OnHSVValueChanged(e);
523  }
524 
525  /// <summary>
526  /// Raised by <see cref="RedProperty"/>, <see cref="GreenProperty"/>, <see cref="BlueProperty"/> or <see cref="AlphaProperty"/> when respectively the
527  /// <see cref="Red"/>, <see cref="Green"/>, <see cref="Blue"/> or <see cref="Alpha"/> dependency property is modified.
528  /// </summary>
529  /// <param name="sender">The dependency object where the event handler is attached.</param>
530  /// <param name="e">The event data.</param>
531  private static void OnRGBAPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
532  {
533  var colorPicker = (ColorPicker)sender;
534  colorPicker.OnRGBAValueChanged(e);
535  }
536 
537  /// <summary>
538  /// Coerce the value of the Color so its components are always equals to the float value of a byte divided by 255.
539  /// </summary>
540  private static object CoreceColorValue(DependencyObject sender, object baseValue)
541  {
542  return new Color(((Color4)baseValue).ToArray()).ToColor4();
543  }
544 
545  /// <summary>
546  /// Coerce the value of the Hue so it is always contained in the -360, +360 interval
547  /// </summary>
548  private static object CoerceHueValue(DependencyObject sender, object baseValue)
549  {
550  return ((float)baseValue + 360.0f) % 360.0f;
551  }
552 
553  /// <summary>
554  /// Coerce the saturation and brightness values so they are always contained between 0 and 100
555  /// </summary>
556  private static object CoercePercentageValue(DependencyObject sender, object baseValue)
557  {
558  return MathUtil.Clamp((float)baseValue, 0.0f, 100.0f);
559  }
560  }
561 }
Hue effect from the two textures.
_In_ size_t _In_ DXGI_FORMAT _In_ size_t _In_ float size_t y
Definition: DirectXTexP.h:191
Represents a color picker control.
Definition: ColorPicker.cs:28
Represents a color in the form of rgba.
Definition: Color4.cs:42
Saturation effect from the two textures.
static float Clamp(float value, float min, float max)
Clamps the specified value.
Definition: MathUtil.cs:276
Structure using the same layout than System.Drawing.Point.
Definition: Point.cs:35
SiliconStudio.Core.Mathematics.Color Color
Definition: ColorPicker.cs:14
Represents a 32-bit color (4 bytes) in the form of RGBA (in byte order: R, G, B, A).
Definition: Color.cs:16
System.Windows.Shapes.Rectangle Rectangle
Definition: ColorPicker.cs:16
Structure using the same layout than System.Drawing.Rectangle
Definition: Rectangle.cs:35
PixelFormat
Defines various types of pixel formats.
Definition: PixelFormat.cs:32
System.Windows.Point Point
Definition: ColorPicker.cs:15
Represents a color in the form of Hue, Saturation, Value, Alpha.
Definition: ColorHSV.cs:15