Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GrammaticalOptimization/DynamicDataDisplay/Charts/Shapes/PivotSegmentEditor.cs @ 12747

Last change on this file since 12747 was 12503, checked in by aballeit, 10 years ago

#2283 added GUI and charts; fixed MCTS

File size: 10.3 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.Windows.Markup;
6using System.Windows;
7using System.Windows.Data;
8using Microsoft.Research.DynamicDataDisplay.Common.Auxiliary;
9using System.Windows.Threading;
10using Microsoft.Research.DynamicDataDisplay.Converters;
11using System.Globalization;
12using System.Windows.Controls;
13using System.Diagnostics.Contracts;
14using System.Windows.Shapes;
15using System.Windows.Media;
16using System.Diagnostics;
17using System.ComponentModel;
18
19namespace Microsoft.Research.DynamicDataDisplay.Charts.Shapes
20{
21  public class PivotSegmentEditor : FrameworkElement, IPlotterElement, INotifyPropertyChanged
22  {
23    private Plotter2D plotter = null;
24    private ViewportHostPanel panel = new ViewportHostPanel();
25    private Segment segment;
26    private DraggablePoint startThumb;
27    private DraggablePoint endThumb;
28    private Func<double, string> xMapping = d => d.ToString("F");
29    private readonly ViewportRay leftRay;
30    private readonly ViewportRay rightRay;
31
32    /// <summary>
33    /// Initializes a new instance of the <see cref="PivotSegmentEditor"/> class.
34    /// </summary>
35    public PivotSegmentEditor()
36    {
37      ResourceDictionary resources = new ResourceDictionary
38      {
39        Source = new Uri("/DynamicDataDisplay;component/Charts/Shapes/PivotSegmentEditor.xaml", UriKind.Relative)
40      };
41
42      panel.BeginBatchAdd();
43
44      ControlTemplate segmentTemplate = (ControlTemplate)resources["segment"];
45      segment = (Segment)segmentTemplate.LoadContent();
46      segment.DataContext = this;
47
48      ControlTemplate startThumbTemplate = (ControlTemplate)resources["leftThumb"];
49      startThumb = (DraggablePoint)startThumbTemplate.LoadContent();
50      startThumb.DataContext = this;
51
52      ControlTemplate endThumbTemplate = (ControlTemplate)resources["rightThumb"];
53      endThumb = (DraggablePoint)endThumbTemplate.LoadContent();
54      endThumb.DataContext = this;
55
56      ControlTemplate leftRayTemplate = (ControlTemplate)resources["leftRay"];
57      leftRay = (ViewportRay)leftRayTemplate.LoadContent();
58      leftRay.DataContext = this;
59
60      ControlTemplate rightRayTemplate = (ControlTemplate)resources["rightRay"];
61      rightRay = (ViewportRay)rightRayTemplate.LoadContent();
62      rightRay.DataContext = this;
63
64      ControlTemplate mTextTemplate = (ControlTemplate)resources["mText"];
65      TextBlock mText = (TextBlock)mTextTemplate.LoadContent();
66      panel.Children.Add(mText);
67      mText.DataContext = this;
68
69      ControlTemplate leftPointGridTemplate = (ControlTemplate)resources["leftPointGrid"];
70      Panel leftPointGrid = (Panel)leftPointGridTemplate.LoadContent();
71      panel.Children.Add(leftPointGrid);
72      leftPointGrid.DataContext = this;
73
74      ControlTemplate rightPointGridTemplate = (ControlTemplate)resources["rightPointGrid"];
75      Panel rightPointGrid = (Panel)rightPointGridTemplate.LoadContent();
76      panel.Children.Add(rightPointGrid);
77      rightPointGrid.DataContext = this;
78
79      ControlTemplate leftTextTemplate = (ControlTemplate)resources["leftText"];
80      FrameworkElement leftBorder = (FrameworkElement)leftTextTemplate.LoadContent();
81      panel.Children.Add(leftBorder);
82      leftBorder.DataContext = this;
83
84      ControlTemplate rightTextTemplate = (ControlTemplate)resources["rightText"];
85      FrameworkElement rightBorder = (FrameworkElement)rightTextTemplate.LoadContent();
86      panel.Children.Add(rightBorder);
87      rightBorder.DataContext = this;
88    }
89
90    #region Properties
91
92    #region XMapping property
93
94    [NotNull]
95    public Func<double, string> XMapping
96    {
97      get { return xMapping; }
98      set
99      {
100        Contract.Assert(value != null);
101
102        xMapping = value;
103        PropertyChanged.Raise(this, "");
104      }
105    }
106
107    #endregion
108
109    #region Point1 property
110
111    public Point Point1
112    {
113      get { return (Point)GetValue(Point1Property); }
114      set { SetValue(Point1Property, value); }
115    }
116
117    public static readonly DependencyProperty Point1Property = DependencyProperty.Register(
118      "Point1",
119      typeof(Point),
120      typeof(PivotSegmentEditor),
121      new FrameworkPropertyMetadata(new Point(0, 0), OnPointChanged));
122
123    private static void OnPointChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
124    {
125      PivotSegmentEditor owner = (PivotSegmentEditor)d;
126      owner.CoerceValue(LeftYProperty);
127      owner.CoerceValue(RightYProperty);
128      owner.OnPointChanged();
129    }
130
131    private void OnPointChanged()
132    {
133      PropertyChanged.Raise(this, "");
134    }
135
136    #endregion
137
138    #region Point2 property
139
140    public Point Point2
141    {
142      get { return (Point)GetValue(Point2Property); }
143      set { SetValue(Point2Property, value); }
144    }
145
146    public static readonly DependencyProperty Point2Property = DependencyProperty.Register(
147      "Point2",
148      typeof(Point),
149      typeof(PivotSegmentEditor),
150      new FrameworkPropertyMetadata(new Point(1, 1), OnPointChanged));
151
152    #endregion
153
154    #region LineStroke property
155
156    public Brush LineStroke
157    {
158      get { return (Brush)GetValue(LineStrokeProperty); }
159      set { SetValue(LineStrokeProperty, value); }
160    }
161
162    public static readonly DependencyProperty LineStrokeProperty = DependencyProperty.Register(
163      "LineStroke",
164      typeof(Brush),
165      typeof(PivotSegmentEditor),
166      new FrameworkPropertyMetadata(Brushes.Black));
167
168    #endregion
169
170    #region LineThickness property
171
172    public double LineThickness
173    {
174      get { return (double)GetValue(LineThicknessProperty); }
175      set { SetValue(LineThicknessProperty, value); }
176    }
177
178    public static readonly DependencyProperty LineThicknessProperty = DependencyProperty.Register(
179      "LineThickbess",
180      typeof(double),
181      typeof(PivotSegmentEditor),
182      new FrameworkPropertyMetadata(2.0));
183
184    #endregion
185
186    #region LeftY property
187
188    public double LeftY
189    {
190      get { return (double)GetValue(LeftYProperty); }
191    }
192
193    private static readonly DependencyPropertyKey LeftYPropertyKey = DependencyProperty.RegisterReadOnly(
194      "LeftY",
195      typeof(double),
196      typeof(PivotSegmentEditor),
197      new FrameworkPropertyMetadata(null, OnLeftYCoerce));
198
199    public static readonly DependencyProperty LeftYProperty = LeftYPropertyKey.DependencyProperty;
200
201    private Func<double, double> GetLineFunc()
202    {
203      Viewport2D viewport = plotter.Viewport;
204      double deltaX = Point1.X - Point2.X;
205      double deltaY = Point1.Y - Point2.Y;
206      double m = deltaY / deltaX;
207      double b = Point1.Y - Point1.X * deltaY / deltaX;
208
209      Func<double, double> func = x => m * x + b;
210
211      return func;
212    }
213
214    private static object OnLeftYCoerce(DependencyObject source, object value)
215    {
216      PivotSegmentEditor editor = (PivotSegmentEditor)source;
217      if (editor.plotter == null)
218        return value;
219
220      Func<double, double> func = editor.GetLineFunc();
221      double xmin = editor.plotter.Viewport.Visible.XMin;
222      double result = func(xmin);
223
224      return result;
225    }
226
227    #endregion
228
229    #region RightY property
230
231    public double RightY
232    {
233      get { return (double)GetValue(RightYProperty); }
234    }
235
236    private static readonly DependencyPropertyKey RightYPropertyKey = DependencyProperty.RegisterReadOnly(
237      "RightY",
238      typeof(double),
239      typeof(PivotSegmentEditor),
240      new FrameworkPropertyMetadata(null, OnRightYCoerce));
241
242    public static readonly DependencyProperty RightYProperty = RightYPropertyKey.DependencyProperty;
243
244    private static object OnRightYCoerce(DependencyObject source, object value)
245    {
246      PivotSegmentEditor editor = (PivotSegmentEditor)source;
247      if (editor.plotter == null)
248        return value;
249
250      Func<double, double> func = editor.GetLineFunc();
251      double xmax = editor.plotter.Viewport.Visible.XMax;
252      double result = func(xmax);
253
254      return result;
255    }
256    #endregion
257
258    public double M
259    {
260      get { return (Point1.Y - Point2.Y) / (Point1.X - Point2.X); }
261      set { Debug.WriteLine("M set = " + value.ToString()); }
262    }
263
264    public string LeftName
265    {
266      get
267      {
268        return String.Format("({0}, {1:F})", xMapping(Point1.X), Point1.Y);
269      }
270    }
271
272    public string RightName
273    {
274      get
275      {
276        return String.Format("({0}, {1:F})", xMapping(Point2.X), Point2.Y);
277      }
278    }
279
280    public Point Center
281    {
282      get
283      {
284        return Point1 + (Point2 - Point1) / 2;
285      }
286    }
287
288    #endregion
289
290    #region IPlotterElement Members
291
292    public void OnPlotterAttached(Plotter plotter)
293    {
294      this.plotter = (Plotter2D)plotter;
295
296      this.plotter.Viewport.PropertyChanged += OnViewport_PropertyChanged;
297
298      plotter.Dispatcher.BeginInvoke(() =>
299      {
300        plotter.Children.AddMany(
301          segment,
302          startThumb,
303          endThumb,
304          panel,
305          leftRay,
306          rightRay);
307
308        CoerceValue(LeftYProperty);
309        CoerceValue(RightYProperty);
310
311        PropertyChanged.Raise(this, "");
312      }, DispatcherPriority.Normal);
313    }
314
315    private void OnViewport_PropertyChanged(object sender, ExtendedPropertyChangedEventArgs e)
316    {
317      CoerceValue(LeftYProperty);
318      CoerceValue(RightYProperty);
319    }
320
321    public void OnPlotterDetaching(Plotter plotter)
322    {
323      this.plotter.Viewport.PropertyChanged -= OnViewport_PropertyChanged;
324
325      plotter.Dispatcher.BeginInvoke(() =>
326      {
327        plotter.Children.RemoveAll(
328          segment,
329          startThumb,
330          endThumb,
331          panel,
332          leftRay,
333          rightRay);
334      }, DispatcherPriority.Normal);
335
336      this.plotter = null;
337    }
338
339    public Plotter2D Plotter
340    {
341      get { return plotter; }
342    }
343
344    Plotter IPlotterElement.Plotter
345    {
346      get { return plotter; }
347    }
348
349    #endregion
350
351    #region INotifyPropertyChanged Members
352
353    public event PropertyChangedEventHandler PropertyChanged;
354
355    #endregion
356  }
357
358  public sealed class MToVerticalOffsetConverter : GenericValueConverter<double>
359  {
360    public override object ConvertCore(double value, Type targetType, object parameter, CultureInfo culture)
361    {
362      if (value > 0)
363        return 2.0;
364      else
365        return -2.0;
366    }
367  }
368
369  public sealed class MToVerticalAlignmentInvertedConverter : GenericValueConverter<double>
370  {
371    public override object ConvertCore(double value, Type targetType, object parameter, CultureInfo culture)
372    {
373      if (value > 0)
374        return VerticalAlignment.Bottom;
375      else
376        return VerticalAlignment.Top;
377    }
378  }
379
380  public sealed class MToVerticalAlignmentConverter : GenericValueConverter<double>
381  {
382    public override object ConvertCore(double value, Type targetType, object parameter, CultureInfo culture)
383    {
384      if (value > 0)
385        return VerticalAlignment.Top;
386      else
387        return VerticalAlignment.Bottom;
388    }
389  }
390}
391
Note: See TracBrowser for help on using the repository browser.