PageRenderTime 49ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/Main/src/DynamicDataDisplay/Charts/ViewportHostPanel.cs

#
C# | 330 lines | 248 code | 57 blank | 25 comment | 51 complexity | 50f1819e5c982265f6f99805e5a85d49 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Windows.Media;
  6. using System.Windows;
  7. using System.Windows.Controls;
  8. using System.Diagnostics;
  9. using Microsoft.Research.DynamicDataDisplay.Common.Auxiliary;
  10. using System.Windows.Threading;
  11. using d3 = Microsoft.Research.DynamicDataDisplay;
  12. using Microsoft.Research.DynamicDataDisplay.Common;
  13. namespace Microsoft.Research.DynamicDataDisplay.Charts
  14. {
  15. public class ViewportHostPanel : ViewportPanel, IPlotterElement
  16. {
  17. static ViewportHostPanel()
  18. {
  19. //EventManager.RegisterClassHandler(typeof(ViewportHostPanel), d3.Plotter.PlotterChangedEvent, new PlotterChangedEventHandler(OnPlotterChanged));
  20. }
  21. public ViewportHostPanel()
  22. {
  23. #if false
  24. // for debug purposes
  25. Width = 100;
  26. Height = 100;
  27. Background = Brushes.PaleGreen.MakeTransparent(0.2);
  28. #endif
  29. }
  30. private static void OnPlotterChanged(object sender, PlotterChangedEventArgs e)
  31. {
  32. ViewportHostPanel owner = (ViewportHostPanel)sender;
  33. if (owner.plotter != null && e.PreviousPlotter != null)
  34. {
  35. owner.viewport.PropertyChanged -= owner.Viewport_PropertyChanged;
  36. owner.viewport = null;
  37. owner.plotter = null;
  38. }
  39. if (owner.plotter == null && e.CurrentPlotter != null)
  40. {
  41. owner.plotter = (Plotter2D)e.CurrentPlotter;
  42. owner.viewport = owner.plotter.Viewport;
  43. owner.viewport.PropertyChanged += owner.Viewport_PropertyChanged;
  44. }
  45. }
  46. private Canvas hostingCanvas = new Canvas();
  47. internal Canvas HostingCanvas
  48. {
  49. get { return hostingCanvas; }
  50. }
  51. #region IPlotterElement Members
  52. private Plotter2D plotter;
  53. public Plotter2D Plotter
  54. {
  55. get { return plotter; }
  56. }
  57. Viewport2D viewport;
  58. public virtual void OnPlotterAttached(Plotter plotter)
  59. {
  60. this.plotter = (Plotter2D)plotter;
  61. viewport = this.plotter.Viewport;
  62. if (!IsMarkersHost)
  63. {
  64. plotter.CentralGrid.Children.Add(hostingCanvas);
  65. }
  66. if (Parent == null)
  67. {
  68. hostingCanvas.Children.Add(this);
  69. }
  70. this.plotter.Viewport.PropertyChanged += Viewport_PropertyChanged;
  71. }
  72. public virtual void OnPlotterDetaching(Plotter plotter)
  73. {
  74. this.plotter.Viewport.PropertyChanged -= Viewport_PropertyChanged;
  75. if (!IsMarkersHost)
  76. {
  77. plotter.CentralGrid.Children.Remove(hostingCanvas);
  78. }
  79. hostingCanvas.Children.Remove(this);
  80. this.plotter = null;
  81. }
  82. Plotter IPlotterElement.Plotter
  83. {
  84. get { return plotter; }
  85. }
  86. protected override void OnChildDesiredSizeChanged(UIElement child)
  87. {
  88. base.OnChildDesiredSizeChanged(child);
  89. InvalidatePosition((FrameworkElement)child);
  90. }
  91. Vector prevVisualOffset;
  92. bool sizeChanged = true;
  93. DataRect visibleWhileCreation;
  94. protected virtual void Viewport_PropertyChanged(object sender, ExtendedPropertyChangedEventArgs e)
  95. {
  96. if (e.PropertyName == Viewport2D.VisiblePropertyName)
  97. {
  98. DataRect visible = (DataRect)e.NewValue;
  99. DataRect prevVisible = (DataRect)e.OldValue;
  100. InvalidateMeasure();
  101. // todo previous way
  102. // if (prevVisible.Size.EqualsApproximately(visible.Size) && !sizeChanged)
  103. // {
  104. // var transform = viewport.Transform;
  105. // Point prevLocation = prevVisible.Location.ViewportToScreen(transform);
  106. // Point location = visible.Location.ViewportToScreen(transform);
  107. // Vector offset = prevLocation - location;
  108. // // todo was true
  109. //#if false
  110. // translateTransform.X += offset.X;
  111. // translateTransform.Y += offset.Y;
  112. //#else
  113. // InvalidateMeasure();
  114. //#endif
  115. // }
  116. // else
  117. // {
  118. // visibleWhileCreation = visible;
  119. // translateTransform.X = 0;
  120. // translateTransform.Y = 0;
  121. // InvalidateMeasure();
  122. // }
  123. sizeChanged = false;
  124. }
  125. else if (e.PropertyName == "Output")
  126. {
  127. sizeChanged = true;
  128. InvalidateMeasure();
  129. }
  130. prevVisualOffset = VisualOffset;
  131. }
  132. #endregion
  133. protected internal override void OnChildAdded(FrameworkElement child)
  134. {
  135. if (plotter == null) return;
  136. InvalidatePosition(child);
  137. //Dispatcher.BeginInvoke(((Action)(()=> InvalidatePosition(child))), DispatcherPriority.ApplicationIdle);
  138. }
  139. private DataRect overallViewportBounds = DataRect.Empty;
  140. internal DataRect OverallViewportBounds
  141. {
  142. get { return overallViewportBounds; }
  143. set { overallViewportBounds = value; }
  144. }
  145. private BoundsUnionMode boundsUnionMode;
  146. internal BoundsUnionMode BoundsUnionMode
  147. {
  148. get { return boundsUnionMode; }
  149. set { boundsUnionMode = value; }
  150. }
  151. protected override void InvalidatePosition(FrameworkElement child)
  152. {
  153. invalidatePositionCalls++;
  154. if (viewport == null) return;
  155. if (child.Visibility != Visibility.Visible)
  156. return;
  157. var transform = viewport.Transform;
  158. Size elementSize = GetElementSize(child, AvailableSize, transform);
  159. child.Measure(elementSize);
  160. Rect bounds = GetElementScreenBounds(transform, child);
  161. child.Arrange(bounds);
  162. var viewportBounds = Viewport2D.GetContentBounds(this);
  163. if (!viewportBounds.IsEmpty)
  164. overallViewportBounds = viewportBounds;
  165. UniteWithBounds(transform, bounds);
  166. if (!InBatchAdd)
  167. {
  168. Viewport2D.SetContentBounds(this, overallViewportBounds);
  169. ContentBoundsChanged.Raise(this);
  170. }
  171. }
  172. private void UniteWithBounds(CoordinateTransform transform, Rect bounds)
  173. {
  174. var childViewportBounds = bounds.ScreenToViewport(transform);
  175. if (boundsUnionMode == BoundsUnionMode.Bounds)
  176. overallViewportBounds.Union(childViewportBounds);
  177. else
  178. {
  179. overallViewportBounds.Union(childViewportBounds.GetCenter());
  180. }
  181. }
  182. int invalidatePositionCalls = 0;
  183. public override void BeginBatchAdd()
  184. {
  185. base.BeginBatchAdd();
  186. invalidatePositionCalls = 0;
  187. }
  188. public override void EndBatchAdd()
  189. {
  190. base.EndBatchAdd();
  191. if (plotter == null) return;
  192. UpdateContentBounds(Children.Count > 0 && invalidatePositionCalls == 0);
  193. }
  194. public void UpdateContentBounds()
  195. {
  196. UpdateContentBounds(true);
  197. }
  198. private void UpdateContentBounds(bool recalculate)
  199. {
  200. if (recalculate)
  201. {
  202. var transform = plotter.Viewport.Transform;
  203. overallViewportBounds = DataRect.Empty;
  204. foreach (FrameworkElement child in Children)
  205. {
  206. if (child != null)
  207. {
  208. if (child.Visibility != Visibility.Visible)
  209. continue;
  210. Rect bounds = GetElementScreenBounds(transform, child);
  211. UniteWithBounds(transform, bounds);
  212. }
  213. }
  214. }
  215. Viewport2D.SetContentBounds(this, overallViewportBounds);
  216. ContentBoundsChanged.Raise(this);
  217. }
  218. protected override Size ArrangeOverride(Size finalSize)
  219. {
  220. if (plotter == null)
  221. return finalSize;
  222. var transform = plotter.Viewport.Transform;
  223. overallViewportBounds = DataRect.Empty;
  224. foreach (UIElement child in InternalChildren)
  225. {
  226. if (child != null)
  227. {
  228. if (child.Visibility != Visibility.Visible)
  229. continue;
  230. Rect bounds = GetElementScreenBounds(transform, child);
  231. child.Arrange(bounds);
  232. UniteWithBounds(transform, bounds);
  233. }
  234. }
  235. if (!InBatchAdd)
  236. {
  237. Viewport2D.SetContentBounds(this, overallViewportBounds);
  238. ContentBoundsChanged.Raise(this);
  239. }
  240. return finalSize;
  241. }
  242. public event EventHandler ContentBoundsChanged;
  243. protected override Size MeasureOverride(Size availableSize)
  244. {
  245. AvailableSize = availableSize;
  246. if (plotter == null)
  247. {
  248. if (availableSize.Width.IsInfinite() || availableSize.Height.IsInfinite())
  249. return new Size();
  250. return availableSize;
  251. }
  252. var transform = plotter.Viewport.Transform;
  253. foreach (FrameworkElement child in InternalChildren)
  254. {
  255. if (child != null)
  256. {
  257. Size elementSize = GetElementSize(child, availableSize, transform);
  258. child.Measure(elementSize);
  259. }
  260. }
  261. if (availableSize.Width.IsInfinite())
  262. availableSize.Width = 0;
  263. if (availableSize.Height.IsInfinite())
  264. availableSize.Height = 0;
  265. return availableSize;
  266. }
  267. }
  268. public enum BoundsUnionMode
  269. {
  270. Center,
  271. Bounds
  272. }
  273. }