/Main/src/DynamicDataDisplay/Charts/Navigation/Navigation/MouseNavigation.cs
C# | 235 lines | 188 code | 37 blank | 10 comment | 53 complexity | 9c674772dc6b969ddaa5c98d5655f011 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
- using System;
- using System.Windows;
- using System.Windows.Documents;
- using System.Windows.Input;
-
-
- namespace Microsoft.Research.DynamicDataDisplay.Navigation
- {
- /// <summary>Provides common methods of mouse navigation around viewport</summary>
- public class MouseNavigation : NavigationBase {
- private AdornerLayer adornerLayer;
- protected AdornerLayer AdornerLayer {
- get {
- if (adornerLayer == null) {
- adornerLayer = AdornerLayer.GetAdornerLayer(this);
- if (adornerLayer != null) {
- adornerLayer.IsHitTestVisible = false;
- }
- }
-
- return adornerLayer;
- }
- }
-
- protected override void OnViewportChanged() {
- base.OnViewportChanged();
-
- //Mouse.AddPreviewMouseDownHandler(Parent, (MouseButtonEventHandler)OnMouseDown);
- //Mouse.AddPreviewMouseMoveHandler(Parent, (MouseEventHandler)OnMouseMove);
- //Mouse.AddPreviewMouseUpHandler(Parent, (MouseButtonEventHandler)OnMouseUp);
-
- Mouse.AddMouseDownHandler(Parent, OnMouseDown);
- Mouse.AddMouseMoveHandler(Parent, OnMouseMove);
- Mouse.AddMouseUpHandler(Parent, OnMouseUp);
-
- Mouse.AddMouseWheelHandler(Parent, OnMouseWheel);
- }
-
- private void OnMouseWheel(object sender, MouseWheelEventArgs e) {
- if (!e.Handled) {
- Point mousePos = e.GetPosition(this);
- int delta = -e.Delta;
- MouseWheelZoom(mousePos, delta);
- }
- }
-
- #if DEBUG
- public override string ToString()
- {
- if (!String.IsNullOrEmpty(Name)) {
- return Name;
- }
- return base.ToString();
- }
- #endif
-
- bool adornerAdded;
- RectangleSelectionAdorner selectionAdorner;
- private void AddSelectionAdorner() {
- if (!adornerAdded) {
- AdornerLayer layer = AdornerLayer;
- if (layer != null) {
- selectionAdorner = new RectangleSelectionAdorner(this) { Border = zoomRect };
-
- layer.Add(selectionAdorner);
- adornerAdded = true;
- }
- }
- }
-
- private void RemoveSelectionAdorner() {
- AdornerLayer layer = AdornerLayer;
- if (layer != null) {
- layer.Remove(selectionAdorner);
- adornerAdded = false;
- }
- }
-
- private void UpdateSelectionAdorner() {
- selectionAdorner.Border = zoomRect;
- selectionAdorner.InvalidateVisual();
- }
-
- Rect? zoomRect = null;
- private const double wheelZoomSpeed = 1.2;
- private bool shouldKeepRatioWhileZooming;
- private bool isZooming;
- private bool isDragging;
- private Point dragStartPointInVisible;
- private Point zoomStartPoint;
-
- private static bool IsShiftOrCtrl {
- get {
- ModifierKeys currKeys = Keyboard.Modifiers;
- return (currKeys | ModifierKeys.Shift) == currKeys ||
- (currKeys | ModifierKeys.Control) == currKeys;
- }
- }
-
- private void OnMouseDown(object sender, MouseButtonEventArgs e) {
- // dragging
- bool shouldStartDrag = e.ChangedButton == MouseButton.Left && Keyboard.Modifiers == ModifierKeys.None;
-
- if (shouldStartDrag) {
- Point dragStartPointInOutput = e.GetPosition(this);
- dragStartPointInVisible = dragStartPointInOutput.Transform(Viewport.Output, Viewport.Visible);
-
- isDragging = true;
- CaptureMouse();
- }
-
- bool shouldStartZoom = e.ChangedButton == MouseButton.Left && IsShiftOrCtrl;
- if (shouldStartZoom) {
- // zooming
-
- zoomStartPoint = e.GetPosition(this);
- if (Viewport.Output.Contains(zoomStartPoint)) {
- isZooming = true;
- AddSelectionAdorner();
- CaptureMouse();
- shouldKeepRatioWhileZooming = Keyboard.Modifiers == ModifierKeys.Shift;
- }
- }
-
- ((IInputElement) Parent).Focus();
- }
-
- private void OnMouseMove(object sender, MouseEventArgs e) {
- if (!isDragging && !isZooming) return;
-
- // dragging
- if (isDragging && e.LeftButton == MouseButtonState.Pressed) {
- Point endPoint = e.GetPosition(this).Transform(Viewport.Output, Viewport.Visible);
-
- Point loc = Viewport.Visible.Location;
- Vector shift = dragStartPointInVisible - endPoint;
- loc += shift;
-
- if (shift.X != 0 || shift.Y != 0) {
- Rect visible = Viewport.Visible;
-
- visible.Location = loc;
- Viewport.Visible = visible;
- }
- }
- // zooming
- else if (isZooming && e.LeftButton == MouseButtonState.Pressed) {
- Point zoomEndPoint = e.GetPosition(this);
- UpdateZoomRect(zoomEndPoint);
- }
- }
-
- private static bool IsShiftPressed() {
- return Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift);
- }
-
- private void UpdateZoomRect(Point zoomEndPoint) {
- Rect output = Viewport.Output;
- Rect tmpZoomRect = new Rect(zoomStartPoint, zoomEndPoint);
- tmpZoomRect = Rect.Intersect(tmpZoomRect, output);
-
- shouldKeepRatioWhileZooming = IsShiftPressed();
- if (shouldKeepRatioWhileZooming) {
- double currZoomRatio = tmpZoomRect.Width / tmpZoomRect.Height;
- double zoomRatio = output.Width / output.Height;
- if (currZoomRatio < zoomRatio) {
- double oldHeight = tmpZoomRect.Height;
- double height = tmpZoomRect.Width / zoomRatio;
- tmpZoomRect.Height = height;
- if (!tmpZoomRect.Contains(zoomStartPoint)) {
- tmpZoomRect.Offset(0, oldHeight - height);
- }
- }
- else {
- double oldWidth = tmpZoomRect.Width;
- double width = tmpZoomRect.Height * zoomRatio;
- tmpZoomRect.Width = width;
- if (!tmpZoomRect.Contains(zoomStartPoint)) {
- tmpZoomRect.Offset(oldWidth - width, 0);
- }
- }
- }
-
- zoomRect = tmpZoomRect;
- UpdateSelectionAdorner();
- }
-
- private void OnMouseUp(object sender, MouseButtonEventArgs e) {
- if (isDragging && e.ChangedButton == MouseButton.Left) {
- isDragging = false;
- ReleaseMouseCapture();
- Point endPoint = e.GetPosition(this).Transform(Viewport.Output, Viewport.Visible);
-
- // focusing on LMB click
- if (endPoint == dragStartPointInVisible) {
- //Keyboard.Focus(Parent as IInputElement);
- }
- }
- else if (isZooming && e.ChangedButton == MouseButton.Left) {
- isZooming = false;
- if (zoomRect.HasValue) {
- Rect output = Viewport.Output;
-
- Point p1 = zoomRect.Value.TopLeft.Transform(output, Viewport.Visible);
- Point p2 = zoomRect.Value.BottomRight.Transform(output, Viewport.Visible);
- Rect newVisible = new Rect(p1, p2);
- Viewport.Visible = newVisible;
-
- zoomRect = null;
- ReleaseMouseCapture();
- RemoveSelectionAdorner();
- }
- }
- }
-
- protected override void OnLostFocus(RoutedEventArgs e) {
- if (isZooming) {
- RemoveSelectionAdorner();
- }
- ReleaseMouseCapture();
- base.OnLostFocus(e);
- }
-
- private void MouseWheelZoom(Point mousePos, int wheelRotationDelta) {
- Point zoomTo = mousePos.Transform(Viewport.Output, Viewport.Visible);
-
- double zoomSpeed = Math.Abs(wheelRotationDelta / Mouse.MouseWheelDeltaForOneLine);
- zoomSpeed *= wheelZoomSpeed;
- if (wheelRotationDelta < 0) {
- zoomSpeed = 1 / zoomSpeed;
- }
- Viewport.Visible = Viewport.Visible.Zoom(zoomTo, zoomSpeed);
- }
- }
- }