1 | using System;
|
---|
2 | using System.Collections.Generic;
|
---|
3 | using System.Linq;
|
---|
4 | using System.Text;
|
---|
5 | using System.Windows;
|
---|
6 | using System.Windows.Media;
|
---|
7 | using System.Windows.Controls;
|
---|
8 | using System.Windows.Shapes;
|
---|
9 | using System.Windows.Data;
|
---|
10 | using System.Diagnostics.CodeAnalysis;
|
---|
11 |
|
---|
12 | namespace Microsoft.Research.DynamicDataDisplay.Charts
|
---|
13 | {
|
---|
14 | /// <summary>
|
---|
15 | /// Represents rectangle with corners bound to viewport coordinates.
|
---|
16 | /// </summary>
|
---|
17 | [TemplatePart(Name = "PART_LinesPath", Type = typeof(Path))]
|
---|
18 | [TemplatePart(Name = "PART_RectPath", Type = typeof(Path))]
|
---|
19 | public abstract class RangeHighlight : Control, IPlotterElement
|
---|
20 | {
|
---|
21 | /// <summary>
|
---|
22 | /// Initializes a new instance of the <see cref="RangeHighlight"/> class.
|
---|
23 | /// </summary>
|
---|
24 | protected RangeHighlight()
|
---|
25 | {
|
---|
26 | Resources = new ResourceDictionary { Source = new Uri("/DynamicDataDisplay;component/Charts/Shapes/RangeHighlightStyle.xaml", UriKind.Relative) };
|
---|
27 |
|
---|
28 | Style = (Style)FindResource(typeof(RangeHighlight));
|
---|
29 | ApplyTemplate();
|
---|
30 | }
|
---|
31 |
|
---|
32 | bool partsLoaded = false;
|
---|
33 | protected bool PartsLoaded
|
---|
34 | {
|
---|
35 | get { return partsLoaded; }
|
---|
36 | }
|
---|
37 | public override void OnApplyTemplate()
|
---|
38 | {
|
---|
39 | base.OnApplyTemplate();
|
---|
40 |
|
---|
41 | linesPath = (Path)Template.FindName("PART_LinesPath", this);
|
---|
42 | GeometryGroup linesGroup = new GeometryGroup();
|
---|
43 | linesGroup.Children.Add(lineGeometry1);
|
---|
44 | linesGroup.Children.Add(lineGeometry2);
|
---|
45 | linesPath.Data = linesGroup;
|
---|
46 |
|
---|
47 | rectPath = (Path)Template.FindName("PART_RectPath", this);
|
---|
48 | rectPath.Data = rectGeometry;
|
---|
49 |
|
---|
50 | partsLoaded = true;
|
---|
51 | }
|
---|
52 |
|
---|
53 | #region Presentation DPs
|
---|
54 |
|
---|
55 | public static readonly DependencyProperty FillProperty = DependencyProperty.Register(
|
---|
56 | "Fill",
|
---|
57 | typeof(Brush),
|
---|
58 | typeof(RangeHighlight),
|
---|
59 | new PropertyMetadata(Shape.FillProperty.DefaultMetadata.DefaultValue));
|
---|
60 |
|
---|
61 | public Brush Fill
|
---|
62 | {
|
---|
63 | get { return (Brush)GetValue(FillProperty); }
|
---|
64 | set { SetValue(FillProperty, value); }
|
---|
65 | }
|
---|
66 |
|
---|
67 | public static readonly DependencyProperty StrokeProperty = DependencyProperty.Register(
|
---|
68 | "Stroke",
|
---|
69 | typeof(Brush),
|
---|
70 | typeof(RangeHighlight),
|
---|
71 | new PropertyMetadata(Shape.StrokeProperty.DefaultMetadata.DefaultValue));
|
---|
72 |
|
---|
73 | public Brush Stroke
|
---|
74 | {
|
---|
75 | get { return (Brush)GetValue(StrokeProperty); }
|
---|
76 | set { SetValue(StrokeProperty, value); }
|
---|
77 | }
|
---|
78 |
|
---|
79 | public static readonly DependencyProperty StrokeThicknessProperty = DependencyProperty.Register(
|
---|
80 | "StrokeThickness",
|
---|
81 | typeof(double),
|
---|
82 | typeof(RangeHighlight),
|
---|
83 | new PropertyMetadata(Shape.StrokeThicknessProperty.DefaultMetadata.DefaultValue));
|
---|
84 |
|
---|
85 | public double StrokeThickness
|
---|
86 | {
|
---|
87 | get { return (double)GetValue(StrokeThicknessProperty); }
|
---|
88 | set { SetValue(StrokeThicknessProperty, value); }
|
---|
89 | }
|
---|
90 |
|
---|
91 | public static readonly DependencyProperty StrokeStartLineCapProperty = DependencyProperty.Register(
|
---|
92 | "StrokeStartLineCap",
|
---|
93 | typeof(PenLineCap),
|
---|
94 | typeof(RangeHighlight),
|
---|
95 | new PropertyMetadata(Shape.StrokeStartLineCapProperty.DefaultMetadata.DefaultValue));
|
---|
96 |
|
---|
97 | public PenLineCap StrokeStartLineCap
|
---|
98 | {
|
---|
99 | get { return (PenLineCap)GetValue(StrokeStartLineCapProperty); }
|
---|
100 | set { SetValue(StrokeStartLineCapProperty, value); }
|
---|
101 | }
|
---|
102 |
|
---|
103 | public static readonly DependencyProperty StrokeEndLineCapProperty = DependencyProperty.Register(
|
---|
104 | "StrokeEndLineCap",
|
---|
105 | typeof(PenLineCap),
|
---|
106 | typeof(RangeHighlight),
|
---|
107 | new PropertyMetadata(Shape.StrokeEndLineCapProperty.DefaultMetadata.DefaultValue));
|
---|
108 |
|
---|
109 | public PenLineCap StrokeEndLineCap
|
---|
110 | {
|
---|
111 | get { return (PenLineCap)GetValue(StrokeEndLineCapProperty); }
|
---|
112 | set { SetValue(StrokeEndLineCapProperty, value); }
|
---|
113 | }
|
---|
114 |
|
---|
115 | public static readonly DependencyProperty StrokeDashCapProperty = DependencyProperty.Register(
|
---|
116 | "StrokeDashCap",
|
---|
117 | typeof(PenLineCap),
|
---|
118 | typeof(RangeHighlight),
|
---|
119 | new PropertyMetadata(Shape.StrokeDashCapProperty.DefaultMetadata.DefaultValue));
|
---|
120 |
|
---|
121 | public PenLineCap StrokeDashCap
|
---|
122 | {
|
---|
123 | get { return (PenLineCap)GetValue(StrokeDashCapProperty); }
|
---|
124 | set { SetValue(StrokeDashCapProperty, value); }
|
---|
125 | }
|
---|
126 |
|
---|
127 | public static readonly DependencyProperty StrokeLineJoinProperty = DependencyProperty.Register(
|
---|
128 | "StrokeLineJoin",
|
---|
129 | typeof(PenLineJoin),
|
---|
130 | typeof(RangeHighlight),
|
---|
131 | new PropertyMetadata(Shape.StrokeLineJoinProperty.DefaultMetadata.DefaultValue));
|
---|
132 |
|
---|
133 | public PenLineJoin StrokeLineJoin
|
---|
134 | {
|
---|
135 | get { return (PenLineJoin)GetValue(StrokeLineJoinProperty); }
|
---|
136 | set { SetValue(StrokeLineJoinProperty, value); }
|
---|
137 | }
|
---|
138 |
|
---|
139 | public static readonly DependencyProperty StrokeMiterLimitProperty = DependencyProperty.Register(
|
---|
140 | "StrokeMiterLimit",
|
---|
141 | typeof(double),
|
---|
142 | typeof(RangeHighlight),
|
---|
143 | new PropertyMetadata(Shape.StrokeMiterLimitProperty.DefaultMetadata.DefaultValue));
|
---|
144 |
|
---|
145 | public double StrokeMiterLimit
|
---|
146 | {
|
---|
147 | get { return (double)GetValue(StrokeMiterLimitProperty); }
|
---|
148 | set { SetValue(StrokeMiterLimitProperty, value); }
|
---|
149 | }
|
---|
150 |
|
---|
151 | public static readonly DependencyProperty StrokeDashOffsetProperty = DependencyProperty.Register(
|
---|
152 | "StrokeDashOffset",
|
---|
153 | typeof(double),
|
---|
154 | typeof(RangeHighlight),
|
---|
155 | new PropertyMetadata(Shape.StrokeDashOffsetProperty.DefaultMetadata.DefaultValue));
|
---|
156 |
|
---|
157 | public double StrokeDashOffset
|
---|
158 | {
|
---|
159 | get { return (double)GetValue(StrokeDashOffsetProperty); }
|
---|
160 | set { SetValue(StrokeDashOffsetProperty, value); }
|
---|
161 | }
|
---|
162 |
|
---|
163 | public static readonly DependencyProperty StrokeDashArrayProperty = DependencyProperty.Register(
|
---|
164 | "StrokeDashArray",
|
---|
165 | typeof(DoubleCollection),
|
---|
166 | typeof(RangeHighlight),
|
---|
167 | new PropertyMetadata(Shape.StrokeDashArrayProperty.DefaultMetadata.DefaultValue));
|
---|
168 |
|
---|
169 | [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
---|
170 | public DoubleCollection StrokeDashArray
|
---|
171 | {
|
---|
172 | get { return (DoubleCollection)GetValue(StrokeDashArrayProperty); }
|
---|
173 | set { SetValue(StrokeDashArrayProperty, value); }
|
---|
174 | }
|
---|
175 |
|
---|
176 | #endregion
|
---|
177 |
|
---|
178 | #region Values dependency properties
|
---|
179 |
|
---|
180 | /// <summary>
|
---|
181 | /// Gets or sets the first value determining position of rectangle in viewport coordinates.
|
---|
182 | /// </summary>
|
---|
183 | /// <value>The value1.</value>
|
---|
184 | public double Value1
|
---|
185 | {
|
---|
186 | get { return (double)GetValue(Value1Property); }
|
---|
187 | set { SetValue(Value1Property, value); }
|
---|
188 | }
|
---|
189 |
|
---|
190 | public static readonly DependencyProperty Value1Property =
|
---|
191 | DependencyProperty.Register(
|
---|
192 | "Value1",
|
---|
193 | typeof(double),
|
---|
194 | typeof(RangeHighlight),
|
---|
195 | new FrameworkPropertyMetadata(0.0, OnValueChanged));
|
---|
196 |
|
---|
197 | private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
---|
198 | {
|
---|
199 | RangeHighlight r = (RangeHighlight)d;
|
---|
200 | r.OnValueChanged(e);
|
---|
201 | }
|
---|
202 |
|
---|
203 | /// <summary>
|
---|
204 | /// Gets or sets the second value determining position of rectangle in viewport coordinates.
|
---|
205 | /// </summary>
|
---|
206 | /// <value>The value2.</value>
|
---|
207 | public double Value2
|
---|
208 | {
|
---|
209 | get { return (double)GetValue(Value2Property); }
|
---|
210 | set { SetValue(Value2Property, value); }
|
---|
211 | }
|
---|
212 |
|
---|
213 | public static readonly DependencyProperty Value2Property =
|
---|
214 | DependencyProperty.Register(
|
---|
215 | "Value2",
|
---|
216 | typeof(double),
|
---|
217 | typeof(RangeHighlight),
|
---|
218 | new FrameworkPropertyMetadata(0.0, OnValueChanged));
|
---|
219 |
|
---|
220 | private void OnValueChanged(DependencyPropertyChangedEventArgs e)
|
---|
221 | {
|
---|
222 | UpdateUIRepresentation();
|
---|
223 | }
|
---|
224 |
|
---|
225 | #endregion
|
---|
226 |
|
---|
227 | #region Geometry
|
---|
228 |
|
---|
229 | private Path rectPath;
|
---|
230 | private Path linesPath;
|
---|
231 |
|
---|
232 | private readonly RectangleGeometry rectGeometry = new RectangleGeometry();
|
---|
233 | protected RectangleGeometry RectGeometry
|
---|
234 | {
|
---|
235 | get { return rectGeometry; }
|
---|
236 | }
|
---|
237 |
|
---|
238 | private readonly LineGeometry lineGeometry1 = new LineGeometry();
|
---|
239 | protected LineGeometry LineGeometry1
|
---|
240 | {
|
---|
241 | get { return lineGeometry1; }
|
---|
242 | }
|
---|
243 |
|
---|
244 | private readonly LineGeometry lineGeometry2 = new LineGeometry();
|
---|
245 | protected LineGeometry LineGeometry2
|
---|
246 | {
|
---|
247 | get { return lineGeometry2; }
|
---|
248 | }
|
---|
249 |
|
---|
250 | #endregion
|
---|
251 |
|
---|
252 | #region IPlotterElement Members
|
---|
253 |
|
---|
254 | private Plotter2D plotter;
|
---|
255 | void IPlotterElement.OnPlotterAttached(Plotter plotter)
|
---|
256 | {
|
---|
257 | plotter.CentralGrid.Children.Add(this);
|
---|
258 |
|
---|
259 | Plotter2D plotter2d = (Plotter2D)plotter;
|
---|
260 | this.plotter = plotter2d;
|
---|
261 | plotter2d.Viewport.PropertyChanged += Viewport_PropertyChanged;
|
---|
262 |
|
---|
263 | UpdateUIRepresentation();
|
---|
264 | }
|
---|
265 |
|
---|
266 | private void UpdateUIRepresentation()
|
---|
267 | {
|
---|
268 | if (Plotter == null) return;
|
---|
269 |
|
---|
270 | if (partsLoaded)
|
---|
271 | {
|
---|
272 | UpdateUIRepresentationCore();
|
---|
273 | }
|
---|
274 | }
|
---|
275 | protected virtual void UpdateUIRepresentationCore() { }
|
---|
276 |
|
---|
277 | void Viewport_PropertyChanged(object sender, ExtendedPropertyChangedEventArgs e)
|
---|
278 | {
|
---|
279 | UpdateUIRepresentation();
|
---|
280 | }
|
---|
281 |
|
---|
282 | void IPlotterElement.OnPlotterDetaching(Plotter plotter)
|
---|
283 | {
|
---|
284 | Plotter2D plotter2d = (Plotter2D)plotter;
|
---|
285 | plotter2d.Viewport.PropertyChanged -= Viewport_PropertyChanged;
|
---|
286 | plotter.CentralGrid.Children.Remove(this);
|
---|
287 |
|
---|
288 | this.plotter = null;
|
---|
289 | }
|
---|
290 |
|
---|
291 | public Plotter2D Plotter
|
---|
292 | {
|
---|
293 | get { return plotter; }
|
---|
294 | }
|
---|
295 |
|
---|
296 | Plotter IPlotterElement.Plotter
|
---|
297 | {
|
---|
298 | get { return plotter; }
|
---|
299 | }
|
---|
300 |
|
---|
301 | #endregion
|
---|
302 | }
|
---|
303 | }
|
---|