Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GrammaticalOptimization/DynamicDataDisplay/Charts/ViewportPanel.cs @ 13072

Last change on this file since 13072 was 12503, checked in by aballeit, 9 years ago

#2283 added GUI and charts; fixed MCTS

File size: 8.1 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.Windows.Controls;
6using System.Windows;
7using System.Windows.Media;
8using System.Diagnostics;
9using Microsoft.Research.DynamicDataDisplay.Common;
10using Microsoft.Research.DynamicDataDisplay.Common.Auxiliary;
11using System.ComponentModel;
12
13namespace Microsoft.Research.DynamicDataDisplay.Charts
14{
15  /// <summary>
16  /// Represents a panel on which elements are arranged in coordinates in viewport space.
17  /// </summary>
18  public partial class ViewportPanel : IndividualArrangePanel
19  {
20    static ViewportPanel()
21    {
22      Type thisType = typeof(ViewportPanel);
23      Plotter.PlotterProperty.OverrideMetadata(thisType, new FrameworkPropertyMetadata { PropertyChangedCallback = OnPlotterChanged });
24    }
25
26    private static void OnPlotterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
27    {
28      ViewportPanel panel = (ViewportPanel)d;
29      panel.OnPlotterChanged((Plotter)e.NewValue, (Plotter)e.OldValue);
30    }
31
32    private void OnPlotterChanged(Plotter currPlotter, Plotter prevPlotter)
33    {
34      if (currPlotter != null)
35      {
36        Plotter2D plotter2d = (Plotter2D)currPlotter;
37        viewport = plotter2d.Viewport;
38      }
39      else
40      {
41        this.viewport = null;
42      }
43    }
44
45    /// <summary>
46    /// Initializes a new instance of the <see cref="ViewportRectPanel"/> class.
47    /// </summary>
48    public ViewportPanel()
49    {
50    }
51
52    #region Panel methods override
53
54    protected override void OnChildDesiredSizeChanged(UIElement child)
55    {
56      base.OnChildDesiredSizeChanged(child);
57
58      InvalidateMeasure();
59    }
60
61    protected internal override void OnChildAdded(FrameworkElement child)
62    {
63      InvalidatePosition(child);
64    }
65
66    protected virtual void InvalidatePosition(FrameworkElement child)
67    {
68      if (viewport == null) return;
69
70      var transform = GetTransform(availableSize);
71
72      Size elementSize = GetElementSize(child, AvailableSize, transform);
73      child.Measure(elementSize);
74
75      Rect bounds = GetElementScreenBounds(transform, child);
76      if (!bounds.IsNaN())
77      {
78        child.Arrange(bounds);
79      }
80    }
81
82    private Size availableSize;
83    protected Size AvailableSize
84    {
85      get { return availableSize; }
86      set { availableSize = value; }
87    }
88
89    protected override Size MeasureOverride(Size availableSize)
90    {
91      this.availableSize = availableSize;
92
93      var transform = GetTransform(availableSize);
94
95      foreach (FrameworkElement child in InternalChildren)
96      {
97        if (child != null)
98        {
99          Size elementSize = GetElementSize(child, availableSize, transform);
100          child.Measure(elementSize);
101        }
102      }
103
104      if (availableSize.Width.IsInfinite())
105        availableSize.Width = 0;
106      if (availableSize.Height.IsInfinite())
107        availableSize.Height = 0;
108      return availableSize;
109    }
110
111    protected virtual Size GetElementSize(FrameworkElement child, Size availableSize, CoordinateTransform transform)
112    {
113      Size result = availableSize;
114
115      DataRect ownViewportBounds = GetViewportBounds(child);
116      if (!ownViewportBounds.IsEmpty)
117      {
118        result = ownViewportBounds.ViewportToScreen(transform).Size;
119      }
120      else
121      {
122        double viewportWidth = GetViewportWidth(child);
123        double viewportHeight = GetViewportHeight(child);
124
125        bool hasViewportWidth = viewportWidth.IsNotNaN();
126        bool hasViewportHeight = viewportHeight.IsNotNaN();
127
128        double minScreenWidth = GetMinScreenWidth(child);
129        bool hasMinScreenWidth = minScreenWidth.IsNotNaN();
130
131        double selfWidth = child.Width.IsNotNaN() ? child.Width : availableSize.Width;
132        double width = hasViewportWidth ? viewportWidth : selfWidth;
133
134        double selfHeight = child.Height.IsNotNaN() ? child.Height : availableSize.Height;
135        double height = hasViewportHeight ? viewportHeight : selfHeight;
136
137        if (width < 0) width = 0;
138        if (height < 0) height = 0;
139
140        DataRect bounds = new DataRect(new Size(width, height));
141        Rect screenBounds = bounds.ViewportToScreen(transform);
142
143        result = new Size(hasViewportWidth ? screenBounds.Width : selfWidth,
144          hasViewportHeight ? screenBounds.Height : selfHeight);
145
146        if (hasMinScreenWidth && result.Width < minScreenWidth)
147        {
148          result.Width = minScreenWidth;
149        }
150      }
151
152      if (result.Width.IsNaN()) result.Width = 0;
153      if (result.Height.IsNaN()) result.Height = 0;
154
155      return result;
156    }
157
158    protected Rect GetElementScreenBounds(CoordinateTransform transform, UIElement child)
159    {
160      Rect screenBounds = GetElementScreenBoundsCore(transform, child);
161
162      DataRect viewportBounds = screenBounds.ScreenToViewport(transform);
163      DataRect prevViewportBounds = GetActualViewportBounds(child);
164
165      SetPrevActualViewportBounds(child, prevViewportBounds);
166      SetActualViewportBounds(child, viewportBounds);
167
168      return screenBounds;
169    }
170
171    protected virtual Rect GetElementScreenBoundsCore(CoordinateTransform transform, UIElement child)
172    {
173      Rect bounds = new Rect(0, 0, 1, 1);
174
175      DataRect ownViewportBounds = GetViewportBounds(child);
176      if (!ownViewportBounds.IsEmpty)
177      {
178        bounds = ownViewportBounds.ViewportToScreen(transform);
179      }
180      else
181      {
182        double viewportX = GetX(child);
183        double viewportY = GetY(child);
184
185        if (viewportX.IsNaN() || viewportY.IsNaN())
186        {
187          //Debug.WriteLine("ViewportRectPanel: Position is not set!");
188
189          return bounds;
190        }
191
192        double viewportWidth = GetViewportWidth(child);
193        if (viewportWidth < 0) viewportWidth = 0;
194        double viewportHeight = GetViewportHeight(child);
195        if (viewportHeight < 0) viewportHeight = 0;
196
197        bool hasViewportWidth = viewportWidth.IsNotNaN();
198        bool hasViewportHeight = viewportHeight.IsNotNaN();
199
200        DataRect r = new DataRect(new Size(hasViewportWidth ? viewportWidth : child.DesiredSize.Width,
201                       hasViewportHeight ? viewportHeight : child.DesiredSize.Height));
202        r = r.ViewportToScreen(transform);
203
204        double screenWidth = hasViewportWidth ? r.Width : child.DesiredSize.Width;
205        double screenHeight = hasViewportHeight ? r.Height : child.DesiredSize.Height;
206
207        double minScreenWidth = GetMinScreenWidth(child);
208        bool hasMinScreemWidth = minScreenWidth.IsNotNaN();
209
210        if (hasViewportWidth && screenWidth < minScreenWidth)
211          screenWidth = minScreenWidth;
212
213        Point location = new Point(viewportX, viewportY).ViewportToScreen(transform);
214
215        double screenX = location.X;
216        double screenY = location.Y;
217
218        HorizontalAlignment horizAlignment = GetViewportHorizontalAlignment(child);
219        switch (horizAlignment)
220        {
221          case HorizontalAlignment.Stretch:
222          case HorizontalAlignment.Center:
223            screenX -= screenWidth / 2;
224            break;
225          case HorizontalAlignment.Left:
226            break;
227          case HorizontalAlignment.Right:
228            screenX -= screenWidth;
229            break;
230        }
231
232        VerticalAlignment vertAlignment = GetViewportVerticalAlignment(child);
233        switch (vertAlignment)
234        {
235          case VerticalAlignment.Bottom:
236            screenY -= screenHeight;
237            break;
238          case VerticalAlignment.Center:
239          case VerticalAlignment.Stretch:
240            screenY -= screenHeight / 2;
241            break;
242          case VerticalAlignment.Top:
243            break;
244          default:
245            break;
246        }
247
248        bounds = new Rect(screenX, screenY, screenWidth, screenHeight);
249      }
250
251      // applying screen offset
252      double screenOffsetX = GetScreenOffsetX(child);
253      if (screenOffsetX.IsNaN()) screenOffsetX = 0;
254      double screenOffsetY = GetScreenOffsetY(child);
255      if (screenOffsetY.IsNaN()) screenOffsetY = 0;
256
257      Vector screenOffset = new Vector(screenOffsetX, screenOffsetY);
258      bounds.Offset(screenOffset);
259
260      return bounds;
261    }
262
263    protected override Size ArrangeOverride(Size finalSize)
264    {
265      var transform = GetTransform(finalSize);
266
267      foreach (UIElement child in InternalChildren)
268      {
269        if (child != null)
270        {
271          Rect bounds = GetElementScreenBounds(transform, child);
272          if (!bounds.IsNaN())
273          {
274            child.Arrange(bounds);
275          }
276        }
277      }
278
279      return finalSize;
280    }
281
282    private CoordinateTransform GetTransform(Size size)
283    {
284      return viewport.Transform.WithRects(ViewportPanel.GetViewportBounds(this), new Rect(size));
285    }
286
287    #endregion
288
289    private Viewport2D viewport;
290  }
291}
Note: See TracBrowser for help on using the repository browser.