Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GrammaticalOptimization/DynamicDataDisplay/Charts/Axes/StackCanvas.cs @ 13749

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

#2283 added GUI and charts; fixed MCTS

File size: 5.8 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.Auxiliary;
10
11namespace Microsoft.Research.DynamicDataDisplay.Charts
12{
13  public class StackCanvas : Panel
14  {
15    public StackCanvas()
16    {
17    }
18
19    #region EndCoordinate attached property
20
21    [AttachedPropertyBrowsableForChildren]
22    public static double GetEndCoordinate(DependencyObject obj)
23    {
24      return (double)obj.GetValue(EndCoordinateProperty);
25    }
26
27    public static void SetEndCoordinate(DependencyObject obj, double value)
28    {
29      obj.SetValue(EndCoordinateProperty, value);
30    }
31
32    public static readonly DependencyProperty EndCoordinateProperty = DependencyProperty.RegisterAttached(
33      "EndCoordinate",
34      typeof(double),
35      typeof(StackCanvas),
36      new PropertyMetadata(Double.NaN, OnCoordinateChanged));
37
38    #endregion
39
40    #region Coordinate attached property
41
42    [AttachedPropertyBrowsableForChildren]
43    public static double GetCoordinate(DependencyObject obj)
44    {
45      return (double)obj.GetValue(CoordinateProperty);
46    }
47
48    public static void SetCoordinate(DependencyObject obj, double value)
49    {
50      obj.SetValue(CoordinateProperty, value);
51    }
52
53    public static readonly DependencyProperty CoordinateProperty = DependencyProperty.RegisterAttached(
54      "Coordinate",
55      typeof(double),
56      typeof(StackCanvas),
57      new PropertyMetadata(0.0, OnCoordinateChanged));
58
59    private static void OnCoordinateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
60    {
61      UIElement reference = d as UIElement;
62      if (reference != null)
63      {
64        StackCanvas parent = VisualTreeHelper.GetParent(reference) as StackCanvas;
65        if (parent != null)
66        {
67          parent.InvalidateArrange();
68        }
69      }
70    }
71    #endregion
72
73    #region AxisPlacement property
74
75    public AxisPlacement Placement
76    {
77      get { return (AxisPlacement)GetValue(PlacementProperty); }
78      set { SetValue(PlacementProperty, value); }
79    }
80
81    public static readonly DependencyProperty PlacementProperty =
82      DependencyProperty.Register(
83        "Placement",
84        typeof(AxisPlacement),
85        typeof(StackCanvas),
86        new FrameworkPropertyMetadata(
87          AxisPlacement.Bottom,
88          FrameworkPropertyMetadataOptions.AffectsArrange));
89
90    #endregion
91
92    private bool IsHorizontal
93    {
94      get { return Placement == AxisPlacement.Top || Placement == AxisPlacement.Bottom; }
95    }
96
97    protected override Size MeasureOverride(Size constraint)
98    {
99      Size availableSize = constraint;
100      Size size = new Size();
101
102      bool isHorizontal = IsHorizontal;
103
104      if (isHorizontal)
105      {
106        availableSize.Width = Double.PositiveInfinity;
107        size.Width = constraint.Width;
108      }
109      else
110      {
111        availableSize.Height = Double.PositiveInfinity;
112        size.Height = constraint.Height;
113      }
114
115      // measuring all children and determining self width and height
116      foreach (UIElement element in base.Children)
117      {
118        if (element != null)
119        {
120          Size childSize = GetChildSize(element, availableSize);
121          element.Measure(childSize);
122          Size desiredSize = element.DesiredSize;
123
124          if (isHorizontal)
125          {
126            size.Height = Math.Max(size.Height, desiredSize.Height);
127          }
128          else
129          {
130            size.Width = Math.Max(size.Width, desiredSize.Width);
131          }
132        }
133      }
134
135      if (Double.IsPositiveInfinity(size.Width)) size.Width = 0;
136      if (Double.IsPositiveInfinity(size.Height)) size.Height = 0;
137
138      return size;
139    }
140
141    private Size GetChildSize(UIElement element, Size availableSize)
142    {
143      var coordinate = GetCoordinate(element);
144      var endCoordinate = GetEndCoordinate(element);
145
146      if (coordinate.IsNotNaN() && endCoordinate.IsNotNaN())
147      {
148        if (Placement.IsBottomOrTop())
149        {
150          availableSize.Width = Math.Abs(endCoordinate - coordinate);
151        }
152        else
153        {
154          availableSize.Height = Math.Abs(endCoordinate - coordinate);
155        }
156      }
157
158      return availableSize;
159    }
160
161    protected override Size ArrangeOverride(Size finalSize)
162    {
163      bool isHorizontal = IsHorizontal;
164
165      foreach (FrameworkElement element in base.Children)
166      {
167        if (element == null)
168        {
169          continue;
170        }
171
172        Size elementSize = element.DesiredSize;
173        double x = 0.0;
174        double y = 0.0;
175
176        switch (Placement)
177        {
178          case AxisPlacement.Left:
179            x = finalSize.Width - elementSize.Width;
180            break;
181          case AxisPlacement.Right:
182            x = 0;
183            break;
184          case AxisPlacement.Top:
185            y = finalSize.Height - elementSize.Height;
186            break;
187          case AxisPlacement.Bottom:
188            y = 0;
189            break;
190          default:
191            break;
192        }
193
194        double coordinate = GetCoordinate(element);
195
196        if (!Double.IsNaN(GetEndCoordinate(element)))
197        {
198          double endCoordinate = GetEndCoordinate(element);
199          double size = endCoordinate - coordinate;
200          if (size < 0)
201          {
202            size = -size;
203            coordinate -= size;
204          }
205          if (isHorizontal)
206            elementSize.Width = size;
207          else
208            elementSize.Height = size;
209        }
210
211
212        // shift for common tick labels, not for major ones.
213        if (isHorizontal)
214        {
215          x = coordinate;
216          if (element.HorizontalAlignment == HorizontalAlignment.Center)
217            x = coordinate - elementSize.Width / 2;
218        }
219        else
220        {
221          y = coordinate;
222          if (element.VerticalAlignment == VerticalAlignment.Center)
223            y = coordinate - elementSize.Height / 2;
224          else if (element.VerticalAlignment == VerticalAlignment.Bottom)
225            y = coordinate - elementSize.Height;
226          else if (element.VerticalAlignment == VerticalAlignment.Top)
227            y = coordinate;
228        }
229
230        Rect bounds = new Rect(new Point(x, y), elementSize);
231        element.Arrange(bounds);
232      }
233
234      return finalSize;
235    }
236  }
237}
Note: See TracBrowser for help on using the repository browser.