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