PageRenderTime 45ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/Main/src/DynamicDataDisplay/Charts/Shapes/PositionalViewportUIContainer.cs

#
C# | 194 lines | 156 code | 30 blank | 8 comment | 16 complexity | e057e96f363cdeebe923e200c81d548f MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. #define old
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Windows.Controls;
  7. using System.Windows;
  8. using Microsoft.Research.DynamicDataDisplay;
  9. using System.Windows.Threading;
  10. using System.Diagnostics;
  11. using System.Windows.Markup;
  12. using System.Collections.ObjectModel;
  13. using Microsoft.Research.DynamicDataDisplay.Common;
  14. using Microsoft.Research.DynamicDataDisplay.Common.Auxiliary;
  15. using System.Windows.Data;
  16. namespace Microsoft.Research.DynamicDataDisplay.Charts
  17. {
  18. public sealed class PositionChangedEventArgs : EventArgs
  19. {
  20. public Point Position { get; internal set; }
  21. public Point PreviousPosition { get; internal set; }
  22. }
  23. public delegate Point PositionCoerceCallback(PositionalViewportUIContainer container, Point position);
  24. public class PositionalViewportUIContainer : ContentControl, IPlotterElement
  25. {
  26. static PositionalViewportUIContainer()
  27. {
  28. Type type = typeof(PositionalViewportUIContainer);
  29. // todo subscribe for properties changes
  30. HorizontalContentAlignmentProperty.AddOwner(
  31. type, new FrameworkPropertyMetadata(HorizontalAlignment.Center));
  32. VerticalContentAlignmentProperty.AddOwner(
  33. type, new FrameworkPropertyMetadata(VerticalAlignment.Center));
  34. }
  35. public PositionalViewportUIContainer()
  36. {
  37. PlotterEvents.PlotterChangedEvent.Subscribe(this, OnPlotterChanged);
  38. //SetBinding(ViewportPanel.XProperty, new Binding("Position.X") { Source = this, Mode = BindingMode.TwoWay });
  39. //SetBinding(ViewportPanel.YProperty, new Binding("Position.Y") { Source = this, Mode = BindingMode.TwoWay });
  40. }
  41. protected virtual void OnPlotterChanged(object sender, PlotterChangedEventArgs e)
  42. {
  43. if (e.CurrentPlotter != null)
  44. OnPlotterAttached(e.CurrentPlotter);
  45. else if (e.PreviousPlotter != null)
  46. OnPlotterDetaching(e.PreviousPlotter);
  47. }
  48. public Point Position
  49. {
  50. get { return (Point)GetValue(PositionProperty); }
  51. set { SetValue(PositionProperty, value); }
  52. }
  53. public static readonly DependencyProperty PositionProperty =
  54. DependencyProperty.Register(
  55. "Position",
  56. typeof(Point),
  57. typeof(PositionalViewportUIContainer),
  58. new FrameworkPropertyMetadata(new Point(0, 0), OnPositionChanged, CoercePosition));
  59. private static object CoercePosition(DependencyObject d, object value)
  60. {
  61. PositionalViewportUIContainer owner = (PositionalViewportUIContainer)d;
  62. if (owner.positionCoerceCallbacks.Count > 0)
  63. {
  64. Point position = (Point)value;
  65. foreach (var callback in owner.positionCoerceCallbacks)
  66. {
  67. position = callback(owner, position);
  68. }
  69. value = position;
  70. }
  71. return value;
  72. }
  73. private readonly ObservableCollection<PositionCoerceCallback> positionCoerceCallbacks = new ObservableCollection<PositionCoerceCallback>();
  74. /// <summary>
  75. /// Gets the list of callbacks which are called every time Position changes to coerce it.
  76. /// </summary>
  77. /// <value>The position coerce callbacks.</value>
  78. public ObservableCollection<PositionCoerceCallback> PositionCoerceCallbacks
  79. {
  80. get { return positionCoerceCallbacks; }
  81. }
  82. private static void OnPositionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  83. {
  84. PositionalViewportUIContainer container = (PositionalViewportUIContainer)d;
  85. container.OnPositionChanged(e);
  86. }
  87. public event EventHandler<PositionChangedEventArgs> PositionChanged;
  88. private void OnPositionChanged(DependencyPropertyChangedEventArgs e)
  89. {
  90. PositionChanged.Raise(this, new PositionChangedEventArgs { Position = (Point)e.NewValue, PreviousPosition = (Point)e.OldValue });
  91. ViewportPanel.SetX(this, Position.X);
  92. ViewportPanel.SetY(this, Position.Y);
  93. }
  94. #region IPlotterElement Members
  95. private const string canvasName = "ViewportUIContainer_Canvas";
  96. private ViewportHostPanel hostPanel;
  97. private Plotter2D plotter;
  98. public void OnPlotterAttached(Plotter plotter)
  99. {
  100. if (Parent == null)
  101. {
  102. hostPanel = new ViewportHostPanel();
  103. Viewport2D.SetIsContentBoundsHost(hostPanel, false);
  104. hostPanel.Children.Add(this);
  105. plotter.Dispatcher.BeginInvoke(() =>
  106. {
  107. plotter.Children.Add(hostPanel);
  108. }, DispatcherPriority.Send);
  109. }
  110. #if !old
  111. Canvas hostCanvas = (Canvas)hostPanel.FindName(canvasName);
  112. if (hostCanvas == null)
  113. {
  114. hostCanvas = new Canvas { ClipToBounds = true };
  115. Panel.SetZIndex(hostCanvas, 1);
  116. INameScope nameScope = NameScope.GetNameScope(hostPanel);
  117. if (nameScope == null)
  118. {
  119. nameScope = new NameScope();
  120. NameScope.SetNameScope(hostPanel, nameScope);
  121. }
  122. hostPanel.RegisterName(canvasName, hostCanvas);
  123. hostPanel.Children.Add(hostCanvas);
  124. }
  125. hostCanvas.Children.Add(this);
  126. #else
  127. #endif
  128. Plotter2D plotter2d = (Plotter2D)plotter;
  129. this.plotter = plotter2d;
  130. }
  131. public void OnPlotterDetaching(Plotter plotter)
  132. {
  133. Plotter2D plotter2d = (Plotter2D)plotter;
  134. #if !old
  135. Canvas hostCanvas = (Canvas)hostPanel.FindName(canvasName);
  136. if (hostCanvas.Children.Count == 1)
  137. {
  138. // only this ViewportUIContainer left
  139. hostPanel.Children.Remove(hostCanvas);
  140. }
  141. hostCanvas.Children.Remove(this);
  142. #else
  143. if (hostPanel != null)
  144. {
  145. hostPanel.Children.Remove(this);
  146. }
  147. plotter.Dispatcher.BeginInvoke(() =>
  148. {
  149. plotter.Children.Remove(hostPanel);
  150. }, DispatcherPriority.Send);
  151. #endif
  152. this.plotter = null;
  153. }
  154. public Plotter2D Plotter
  155. {
  156. get { return plotter; }
  157. }
  158. Plotter IPlotterElement.Plotter
  159. {
  160. get { return plotter; }
  161. }
  162. #endregion
  163. }
  164. }