using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Research.DynamicDataDisplay.Navigation; using System.Windows.Input; using System.Diagnostics; using System.Windows; using System.Windows.Media.Animation; using System.Windows.Threading; namespace Microsoft.Research.DynamicDataDisplay.Charts.Navigation { public class PhysicalNavigation : IPlotterElement { private readonly DispatcherTimer timer; public PhysicalNavigation() { timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(30) }; timer.Tick += timer_Tick; } DateTime startTime; private void timer_Tick(object sender, EventArgs e) { TimeSpan time = DateTime.Now - startTime; animation.UseMouse = isMouseDown; if (!isMouseDown) { animation.LiquidFrictionQuadraticCoeff = 1; } plotter.Viewport.Visible = animation.GetValue(time); if (animation.IsFinished && !isMouseDown) { timer.Stop(); } } private bool isMouseDown = false; private PhysicalRectAnimation animation; private Point clickPos; private void OnMouseDown(object sender, MouseButtonEventArgs e) { if (e.ChangedButton == MouseButton.Left) { clickPos = e.GetPosition(plotter.CentralGrid); isMouseDown = true; startTime = DateTime.Now; animation = new PhysicalRectAnimation( plotter.Viewport, e.GetPosition(plotter.ViewportPanel)); timer.Start(); } } private void OnMouseUp(object sender, MouseButtonEventArgs e) { if (e.ChangedButton == MouseButton.Left) { isMouseDown = false; if (clickPos == e.GetPosition(plotter.CentralGrid)) { timer.Stop(); animation = null; } else { if (animation.IsFinished) { timer.Stop(); animation = null; } else { animation.UseMouse = false; animation.LiquidFrictionQuadraticCoeff = 1; } } } } #region IPlotterElement Members private Plotter2D plotter; void IPlotterElement.OnPlotterAttached(Plotter plotter) { this.plotter = (Plotter2D)plotter; Mouse.AddPreviewMouseDownHandler(plotter.CentralGrid, OnMouseDown); Mouse.AddPreviewMouseUpHandler(plotter.CentralGrid, OnMouseUp); plotter.CentralGrid.MouseLeave += CentralGrid_MouseLeave; } private void CentralGrid_MouseLeave(object sender, MouseEventArgs e) { isMouseDown = false; } void IPlotterElement.OnPlotterDetaching(Plotter plotter) { plotter.CentralGrid.MouseLeave -= CentralGrid_MouseLeave; Mouse.RemovePreviewMouseDownHandler(plotter.CentralGrid, OnMouseDown); Mouse.RemovePreviewMouseUpHandler(plotter.CentralGrid, OnMouseUp); this.plotter = null; } Plotter IPlotterElement.Plotter { get { return plotter; } } #endregion } }