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