Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GrammaticalOptimization/DynamicDataDisplay/Charts/Navigation/AxisNavigation.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.0 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.Windows;
6using System.Windows.Input;
7using System.Windows.Controls;
8using System.Windows.Media;
9using Microsoft.Research.DynamicDataDisplay.Charts.Axes;
10using Microsoft.Research.DynamicDataDisplay.Common.Auxiliary;
11using System.Diagnostics;
12
13namespace Microsoft.Research.DynamicDataDisplay.Charts.Navigation
14{
15  public class AxisNavigation : DependencyObject, IPlotterElement
16  {
17    public AxisPlacement Placement
18    {
19      get { return (AxisPlacement)GetValue(PlacementProperty); }
20      set { SetValue(PlacementProperty, value); }
21    }
22
23    public static readonly DependencyProperty PlacementProperty = DependencyProperty.Register(
24      "Placement",
25      typeof(AxisPlacement),
26      typeof(AxisNavigation),
27      new FrameworkPropertyMetadata(AxisPlacement.Left, OnPlacementChanged));
28
29    private static void OnPlacementChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
30    {
31      AxisNavigation navigation = (AxisNavigation)d;
32      navigation.OnPlacementChanged();
33    }
34
35    private Panel listeningPanel;
36    protected Panel ListeningPanel
37    {
38      get { return listeningPanel; }
39    }
40
41    private void OnPlacementChanged()
42    {
43      SetListeningPanel();
44    }
45
46    private void SetListeningPanel()
47    {
48      if (plotter == null) return;
49
50      AxisPlacement placement = Placement;
51      switch (placement)
52      {
53        case AxisPlacement.Left:
54          listeningPanel = plotter.LeftPanel;
55          break;
56        case AxisPlacement.Right:
57          listeningPanel = plotter.RightPanel;
58          break;
59        case AxisPlacement.Top:
60          listeningPanel = plotter.TopPanel;
61          break;
62        case AxisPlacement.Bottom:
63          listeningPanel = plotter.BottomPanel;
64          break;
65        default:
66          break;
67      }
68    }
69
70    private CoordinateTransform Transform
71    {
72      get { return plotter.Viewport.Transform; }
73    }
74
75    private Panel hostPanel;
76
77    #region IPlotterElement Members
78
79    void IPlotterElement.OnPlotterAttached(Plotter plotter)
80    {
81      this.plotter = (Plotter2D)plotter;
82
83      hostPanel = plotter.MainGrid;
84
85      //hostPanel.Background = Brushes.Pink;
86
87      SetListeningPanel();
88
89      if (hostPanel != null)
90      {
91        hostPanel.MouseLeftButtonUp += OnMouseLeftButtonUp;
92        hostPanel.MouseLeftButtonDown += OnMouseLeftButtonDown;
93        hostPanel.MouseMove += OnMouseMove;
94        hostPanel.MouseWheel += OnMouseWheel;
95
96        hostPanel.MouseRightButtonDown += OnMouseRightButtonDown;
97        hostPanel.MouseRightButtonUp += OnMouseRightButtonUp;
98        hostPanel.LostFocus += OnLostFocus;
99      }
100    }
101
102    private void OnLostFocus(object sender, RoutedEventArgs e)
103    {
104      //Debug.WriteLine("Lost Focus");
105      RevertChanges();
106      rmbPressed = false;
107      lmbPressed = false;
108
109      e.Handled = true;
110    }
111
112    #region Right button down
113
114    DataRect rmbDragStartRect;
115    private void OnMouseRightButtonDown(object sender, MouseButtonEventArgs e)
116    {
117      OnMouseRightButtonDown(e);
118    }
119
120    protected virtual void OnMouseRightButtonDown(MouseButtonEventArgs e)
121    {
122      rmbInitialPosition = e.GetPosition(listeningPanel);
123
124      var foundActivePlotter = UpdateActivePlotter(e);
125      if (foundActivePlotter)
126      {
127        rmbPressed = true;
128        dragStartInViewport = rmbInitialPosition.ScreenToViewport(activePlotter.Transform);
129        rmbDragStartRect = activePlotter.Visible;
130
131        listeningPanel.Background = fillBrush;
132        listeningPanel.CaptureMouse();
133
134        //e.Handled = true;
135      }
136    }
137
138    #endregion
139
140    #region Right button up
141
142    private void OnMouseRightButtonUp(object sender, MouseButtonEventArgs e)
143    {
144      OnMouseRightButtonUp(e);
145    }
146
147    protected virtual void OnMouseRightButtonUp(MouseButtonEventArgs e)
148    {
149      if (rmbPressed)
150      {
151        rmbPressed = false;
152        RevertChanges();
153
154        //e.Handled = true;
155      }
156    }
157
158    #endregion
159
160    private void RevertChanges()
161    {
162      listeningPanel.ClearValue(Panel.CursorProperty);
163      listeningPanel.Background = Brushes.Transparent;
164      listeningPanel.ReleaseMouseCapture();
165    }
166
167    private const double wheelZoomSpeed = 1.2;
168    private void OnMouseWheel(object sender, MouseWheelEventArgs e)
169    {
170      Point mousePos = e.GetPosition(listeningPanel);
171
172      Rect listeningPanelBounds = new Rect(listeningPanel.RenderSize);
173      if (!listeningPanelBounds.Contains(mousePos))
174        return;
175
176      var foundActivePlotter = UpdateActivePlotter(e);
177      if (!foundActivePlotter) return;
178
179      int delta = -e.Delta;
180
181      Point zoomTo = mousePos.ScreenToViewport(activePlotter.Transform);
182
183      double zoomSpeed = Math.Abs(delta / Mouse.MouseWheelDeltaForOneLine);
184      zoomSpeed *= wheelZoomSpeed;
185      if (delta < 0)
186      {
187        zoomSpeed = 1 / zoomSpeed;
188      }
189
190      DataRect visible = activePlotter.Viewport.Visible.Zoom(zoomTo, zoomSpeed);
191      DataRect oldVisible = activePlotter.Viewport.Visible;
192      if (Placement.IsBottomOrTop())
193      {
194        visible.YMin = oldVisible.YMin;
195        visible.Height = oldVisible.Height;
196      }
197      else
198      {
199        visible.XMin = oldVisible.XMin;
200        visible.Width = oldVisible.Width;
201      }
202
203      activePlotter.Viewport.SetChangeType(Placement.GetZoomChangeType());
204      activePlotter.Viewport.Visible = visible;
205      activePlotter.Viewport.SetChangeType(ChangeType.None);
206
207      e.Handled = true;
208    }
209
210    private const int RmbZoomScale = 200;
211    private void OnMouseMove(object sender, MouseEventArgs e)
212    {
213      if (lmbPressed)
214      {
215        // panning:
216        if (e.LeftButton == MouseButtonState.Released)
217        {
218          lmbPressed = false;
219          RevertChanges();
220          return;
221        }
222
223        Point screenMousePos = e.GetPosition(listeningPanel);
224        Point dataMousePos = screenMousePos.ScreenToViewport(activePlotter.Transform);
225        DataRect visible = activePlotter.Viewport.Visible;
226        double delta;
227        if (Placement.IsBottomOrTop())
228        {
229          delta = (dataMousePos - dragStartInViewport).X;
230          visible.XMin -= delta;
231        }
232        else
233        {
234          delta = (dataMousePos - dragStartInViewport).Y;
235          visible.YMin -= delta;
236        }
237
238        if (screenMousePos != lmbInitialPosition)
239        {
240          listeningPanel.Cursor = Placement.IsBottomOrTop() ? Cursors.ScrollWE : Cursors.ScrollNS;
241        }
242
243        activePlotter.Viewport.SetChangeType(Placement.GetPanChangeType());
244        activePlotter.Viewport.Visible = visible;
245        activePlotter.Viewport.SetChangeType();
246
247        e.Handled = true;
248      }
249      else if (rmbPressed)
250      {
251        // one direction zooming:
252        if (e.RightButton == MouseButtonState.Released)
253        {
254          rmbPressed = false;
255          RevertChanges();
256          return;
257        }
258
259        Point screenMousePos = e.GetPosition(listeningPanel);
260        DataRect visible = activePlotter.Viewport.Visible;
261        double delta;
262
263        bool isHorizontal = Placement.IsBottomOrTop();
264        if (isHorizontal)
265        {
266          delta = (screenMousePos - rmbInitialPosition).X;
267        }
268        else
269        {
270          delta = (screenMousePos - rmbInitialPosition).Y;
271        }
272
273        if (delta < 0)
274          delta = 1 / Math.Exp(-delta / RmbZoomScale);
275        else
276          delta = Math.Exp(delta / RmbZoomScale);
277
278        Point center = dragStartInViewport;
279
280        if (isHorizontal)
281        {
282          visible = rmbDragStartRect.ZoomX(center, delta);
283        }
284        else
285        {
286          visible = rmbDragStartRect.ZoomY(center, delta);
287        }
288
289        if (screenMousePos != lmbInitialPosition)
290        {
291          listeningPanel.Cursor = Placement.IsBottomOrTop() ? Cursors.ScrollWE : Cursors.ScrollNS;
292        }
293
294        activePlotter.Viewport.SetChangeType(Placement.GetZoomChangeType());
295        activePlotter.Viewport.Visible = visible;
296        activePlotter.Viewport.SetChangeType();
297
298        //e.Handled = true;
299      }
300    }
301
302    private Point lmbInitialPosition;
303    protected Point LmbInitialPosition
304    {
305      get { return lmbInitialPosition; }
306    }
307
308    private Point rmbInitialPosition;
309    private readonly SolidColorBrush fillBrush = new SolidColorBrush(Color.FromRgb(255, 228, 209)).MakeTransparent(0.2);
310    private bool lmbPressed;
311    private bool rmbPressed;
312    private Point dragStartInViewport;
313    private Plotter2D activePlotter;
314
315    #region Left button down
316
317    private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
318    {
319      OnMouseLeftButtonDown(e);
320    }
321
322    protected virtual void OnMouseLeftButtonDown(MouseButtonEventArgs e)
323    {
324      lmbInitialPosition = e.GetPosition(listeningPanel);
325
326      var foundActivePlotter = UpdateActivePlotter(e);
327      if (foundActivePlotter)
328      {
329        lmbPressed = true;
330        dragStartInViewport = lmbInitialPosition.ScreenToViewport(activePlotter.Transform);
331
332        listeningPanel.Background = fillBrush;
333        listeningPanel.CaptureMouse();
334
335        e.Handled = true;
336      }
337    }
338
339    #endregion
340
341    private bool UpdateActivePlotter(MouseEventArgs e)
342    {
343      var axes = listeningPanel.Children.OfType<GeneralAxis>();
344
345      foreach (var axis in axes)
346      {
347        var positionInAxis = e.GetPosition(axis);
348        Rect axisBounds = new Rect(axis.RenderSize);
349        if (axisBounds.Contains(positionInAxis))
350        {
351          activePlotter = axis.Plotter;
352
353          return true;
354        }
355      }
356
357      return false;
358    }
359
360    #region Left button up
361
362    private void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
363    {
364      OnMouseLeftButtonUp(e);
365    }
366
367    protected virtual void OnMouseLeftButtonUp(MouseButtonEventArgs e)
368    {
369      if (lmbPressed)
370      {
371        lmbPressed = false;
372        RevertChanges();
373
374        e.Handled = true;
375      }
376    }
377
378    #endregion
379
380    public void OnPlotterDetaching(Plotter plotter)
381    {
382      if (plotter.MainGrid != null)
383      {
384        hostPanel.MouseLeftButtonUp -= OnMouseLeftButtonUp;
385        hostPanel.MouseLeftButtonDown -= OnMouseLeftButtonDown;
386        hostPanel.MouseMove -= OnMouseMove;
387        hostPanel.MouseWheel -= OnMouseWheel;
388
389        hostPanel.MouseRightButtonDown -= OnMouseRightButtonDown;
390        hostPanel.MouseRightButtonUp -= OnMouseRightButtonUp;
391       
392        hostPanel.LostFocus -= OnLostFocus;
393      }
394      listeningPanel = null;
395      this.plotter = null;
396    }
397
398    private Plotter2D plotter;
399    Plotter IPlotterElement.Plotter
400    {
401      get { return plotter; }
402    }
403
404    #endregion
405
406    public override string ToString()
407    {
408      return "AxisNavigation: " + Placement;
409    }
410  }
411}
Note: See TracBrowser for help on using the repository browser.