Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
Vector4Editor.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;
5 using System.Windows.Controls;
6 using System.Windows.Data;
7 
8 using SiliconStudio.Core.Mathematics;
9 
10 namespace SiliconStudio.Presentation.Controls
11 {
12  public class Vector4Editor : Control
13  {
14  private bool interlock;
15 
16  /// <summary>
17  /// Identifies the <see cref="Vector"/> dependency property.
18  /// </summary>
19  public static readonly DependencyProperty VectorProperty = DependencyProperty.Register("Vector", typeof(Vector4), typeof(Vector4Editor), new FrameworkPropertyMetadata(default(Vector4), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnVectorPropertyChanged, null, false, UpdateSourceTrigger.Explicit));
20 
21  /// <summary>
22  /// Identifies the <see cref="X"/> dependency property.
23  /// </summary>
24  public static readonly DependencyProperty XProperty = DependencyProperty.Register("X", typeof(float), typeof(Vector4Editor), new FrameworkPropertyMetadata(.0f, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnCartesianPropertyChanged));
25 
26  /// <summary>
27  /// Identifies the <see cref="Y"/> dependency property.
28  /// </summary>
29  public static readonly DependencyProperty YProperty = DependencyProperty.Register("Y", typeof(float), typeof(Vector4Editor), new FrameworkPropertyMetadata(.0f, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnCartesianPropertyChanged));
30 
31  /// <summary>
32  /// Identifies the <see cref="Z"/> dependency property.
33  /// </summary>
34  public static readonly DependencyProperty ZProperty = DependencyProperty.Register("Z", typeof(float), typeof(Vector4Editor), new FrameworkPropertyMetadata(.0f, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnCartesianPropertyChanged));
35 
36  /// <summary>
37  /// Identifies the <see cref="W"/> dependency property.
38  /// </summary>
39  public static readonly DependencyProperty WProperty = DependencyProperty.Register("W", typeof(float), typeof(Vector4Editor), new FrameworkPropertyMetadata(.0f, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnCartesianPropertyChanged));
40 
41  /// <summary>
42  /// Identifies the <see cref="Length"/> dependency property.
43  /// </summary>
44  public static readonly DependencyProperty LengthProperty = DependencyProperty.Register("Length", typeof(float), typeof(Vector4Editor), new FrameworkPropertyMetadata(0.0f, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnPolarPropertyChanged, CoerceLengthValue));
45 
46  /// <summary>
47  /// The <see cref="Vector4"/> associated to this control.
48  /// </summary>
49  public Vector4 Vector { get { return (Vector4)GetValue(VectorProperty); } set { SetValue(VectorProperty, value); } }
50 
51  /// <summary>
52  /// The X component (in Cartesian coordinate system) of the <see cref="Vector4"/> associated to this control.
53  /// </summary>
54  public float X { get { return (float)GetValue(XProperty); } set { SetValue(XProperty, value); } }
55 
56  /// <summary>
57  /// The Y component (in Cartesian coordinate system) of the <see cref="Vector4"/> associated to this control.
58  /// </summary>
59  public float Y { get { return (float)GetValue(YProperty); } set { SetValue(YProperty, value); } }
60 
61  /// <summary>
62  /// The Y component (in Cartesian coordinate system) of the <see cref="Vector4"/> associated to this control.
63  /// </summary>
64  public float Z { get { return (float)GetValue(ZProperty); } set { SetValue(ZProperty, value); } }
65 
66  /// <summary>
67  /// The Y component (in Cartesian coordinate system) of the <see cref="Vector4"/> associated to this control.
68  /// </summary>
69  public float W { get { return (float)GetValue(WProperty); } set { SetValue(WProperty, value); } }
70 
71  /// <summary>
72  /// The length (in polar coordinate system) of the <see cref="Vector4"/> associated to this control.
73  /// </summary>
74  public float Length { get { return (float)GetValue(LengthProperty); } set { SetValue(LengthProperty, value); } }
75 
76  /// <summary>
77  /// Raised when the <see cref="Vector"/> property is modified.
78  /// </summary>
79  private void OnVectorValueChanged()
80  {
81  if (!interlock)
82  {
83  interlock = true;
84  SetCurrentValue(XProperty, Vector.X);
85  SetCurrentValue(YProperty, Vector.Y);
86  SetCurrentValue(ZProperty, Vector.Z);
87  SetCurrentValue(WProperty, Vector.W);
88  SetCurrentValue(LengthProperty, Vector.Length());
89  interlock = false;
90  }
91 
92  UpdateBinding(VectorProperty);
93  }
94 
95  /// <summary>
96  /// Raised when the <see cref="X"/>, <see cref="Y"/>, <see cref="Z"/> or <see cref="W"/> properties are modified.
97  /// </summary>
98  /// <param name="e">The dependency property that has changed.</param>
99  private void OnCartesianValueChanged(DependencyPropertyChangedEventArgs e)
100  {
101  if (!interlock)
102  {
103  interlock = true;
104  if (e.Property == XProperty)
105  Vector = new Vector4((float)e.NewValue, Vector.Y, Vector.Z, Vector.W);
106  else if (e.Property == YProperty)
107  Vector = new Vector4(Vector.X, (float)e.NewValue, Vector.Z, Vector.W);
108  else if (e.Property == ZProperty)
109  Vector = new Vector4(Vector.X, Vector.Y, (float)e.NewValue, Vector.W);
110  else if (e.Property == WProperty)
111  Vector = new Vector4(Vector.X, Vector.Y, Vector.Z, (float)e.NewValue);
112  else
113  throw new ArgumentException("Property unsupported by method OnCartesianPropertyChanged.");
114 
115  SetCurrentValue(LengthProperty, Vector.Length());
116  interlock = false;
117  }
118 
119  UpdateBinding(e.Property);
120  }
121 
122  /// <summary>
123  /// Raised when the <see cref="Length"/> property is modified.
124  /// </summary>
125  /// <param name="e">The dependency property that has changed.</param>
126  private void OnLengthValueChanged(DependencyPropertyChangedEventArgs e)
127  {
128  if (!interlock)
129  {
130  interlock = true;
131  var vector = Vector;
132  vector.Normalize();
133  vector *= Length;
134  Vector = vector;
135  SetCurrentValue(XProperty, Vector.X);
136  SetCurrentValue(YProperty, Vector.Y);
137  SetCurrentValue(ZProperty, Vector.Z);
138  SetCurrentValue(WProperty, Vector.W);
139  interlock = false;
140  }
141 
142  UpdateBinding(e.Property);
143  }
144 
145  /// <summary>
146  /// Updates the binding of the given dependency property.
147  /// </summary>
148  /// <param name="dependencyProperty">The dependency property.</param>
149  private void UpdateBinding(DependencyProperty dependencyProperty)
150  {
151  BindingExpression expression = GetBindingExpression(dependencyProperty);
152  if (expression != null)
153  expression.UpdateSource();
154  }
155 
156  /// <summary>
157  /// Raised by <see cref="VectorProperty"/> when the <see cref="Vector"/> dependency property is modified.
158  /// </summary>
159  /// <param name="sender">The dependency object where the event handler is attached.</param>
160  /// <param name="e">The event data.</param>
161  private static void OnVectorPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
162  {
163  var editor = (Vector4Editor)sender;
164  editor.OnVectorValueChanged();
165  }
166 
167  /// <summary>
168  /// Raised by <see cref="XProperty"/>, <see cref="YProperty"/>, <see cref="ZProperty"/> or <see cref="WProperty"/>
169  /// when respectively the <see cref="X"/>, <see cref="Y"/>, <see cref="Z"/> or <see cref="W"/> dependency property is modified.
170  /// </summary>
171  /// <param name="sender">The dependency object where the event handler is attached.</param>
172  /// <param name="e">The event data.</param>
173  private static void OnCartesianPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
174  {
175  var editor = (Vector4Editor)sender;
176  editor.OnCartesianValueChanged(e);
177  }
178 
179  /// <summary>
180  /// Raised by <see cref="LengthProperty"/> when the <see cref="Length"/> dependency property is modified.
181  /// </summary>
182  /// <param name="sender">The dependency object where the event handler is attached.</param>
183  /// <param name="e">The event data.</param>
184  private static void OnPolarPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
185  {
186  var editor = (Vector4Editor)sender;
187  editor.OnLengthValueChanged(e);
188  }
189 
190  /// <summary>
191  /// Coerce the value of the Length so it is always positive
192  /// </summary>
193  private static object CoerceLengthValue(DependencyObject sender, object baseValue)
194  {
195  return Math.Max(0.0f, (float)baseValue);
196  }
197  }
198 }
Represents a four dimensional mathematical vector.
Definition: Vector4.cs:42