using System.Drawing; using System.Windows.Forms; namespace Netron.Diagramming.Core { // ---------------------------------------------------------------------- /// /// A tool that "pans" the diagram. The 'Origin' of the diagram is /// adjusted when the left mouse button is held down and dragged /// across the canvas. /// // ---------------------------------------------------------------------- public class PanTool : AbstractTool, IMouseListener, IKeyboardListener { // ------------------------------------------------------------------ /// /// The number of times the mouse location has been updated. This is /// used to determine if the cursor is updated. The cursor is only /// updated every 5 times the mouse is moved and then this number is /// reset to 0. The mouse is updated when this number is zero. /// // ------------------------------------------------------------------ int mouseMoveNumber = 0; // ------------------------------------------------------------------ /// /// Set to true when the left mouse buttone is down, set to false /// all other times. /// // ------------------------------------------------------------------ bool isLeftMouseButtonPressed = false; // ------------------------------------------------------------------ /// /// The initial location of the mouse (when the mouse was clicked). /// // ------------------------------------------------------------------ Point initialLocation = Point.Empty; // ------------------------------------------------------------------ /// /// The last location of the mouse. /// // ------------------------------------------------------------------ Point previousMouseLocation = Point.Empty; // ------------------------------------------------------------------ /// /// Constructor. /// /// string: The name of this tool. // ------------------------------------------------------------------ public PanTool(string toolName) : base(toolName) { } // ------------------------------------------------------------------ /// /// Activates the tool and sets the cursor to a hand cursor to provide /// visual feedback that panning is activated. /// // ------------------------------------------------------------------ protected override void OnActivateTool() { base.OnActivateTool(); Cursor = CursorPalette.Pan; } // ------------------------------------------------------------------ /// /// Compares the location specified to the previous location and /// sets the cursor as follows: /// * current x < previous x and curreny y = previous y => pan W /// * current x > previous x and curreny y = previous y => pan E /// * current x = previous x and curreny y < previous y => pan N /// * current x = previous x and curreny y > previous y => pan S /// * current x < previous x and curreny y < previous y => pan NW /// * current x > previous x and curreny y < previous y => pan NE /// * current x < previous x and curreny y > previous y => pan SW /// * current x > previous x and curreny y > previous y => pan SE /// /// Point: The current cursor location. // ------------------------------------------------------------------ protected void UpdateCursor(Point location) { if ((location.X < previousMouseLocation.X) && (location.Y == previousMouseLocation.Y)) { Cursor = Cursors.PanWest; } else if ((location.X > previousMouseLocation.X) && (location.Y == previousMouseLocation.Y)) { Cursor = Cursors.PanEast; } else if ((location.X == previousMouseLocation.X) && (location.Y < previousMouseLocation.Y)) { Cursor = Cursors.PanNorth; } else if ((location.X == previousMouseLocation.X) && (location.Y > previousMouseLocation.Y)) { Cursor = Cursors.PanSouth; } else if ((location.X < previousMouseLocation.X) && (location.Y < previousMouseLocation.Y)) { Cursor = Cursors.PanNW; } else if ((location.X > previousMouseLocation.X) && (location.Y < previousMouseLocation.Y)) { Cursor = Cursors.PanNE; } else if ((location.X < previousMouseLocation.X) && (location.Y > previousMouseLocation.Y)) { Cursor = Cursors.PanSW; } else if ((location.X > previousMouseLocation.X) && (location.Y > previousMouseLocation.Y)) { Cursor = Cursors.PanSE; } } #region IMouseListener Members // ------------------------------------------------------------------ /// /// Starts the panning action if this tool is activated and is not /// suspended. /// /// MouseEventArgs // ------------------------------------------------------------------ public bool MouseDown(MouseEventArgs e) { if ((!IsActive) || (IsSuspended == true)) { this.isLeftMouseButtonPressed = false; this.previousMouseLocation = Point.Empty; return false; } if (e.Button == MouseButtons.Left) { this.isLeftMouseButtonPressed = true; this.previousMouseLocation = Point.Round(Controller.View.WorldToView(e.Location)); this.initialLocation = previousMouseLocation; return true; } else { this.isLeftMouseButtonPressed = false; this.previousMouseLocation = Point.Empty; return false; } } // ------------------------------------------------------------------ /// /// Pans the diagram by the offset amount of the last mouse position /// and the new mouse position divided by 2 (to slow things down a /// bit; otherwise the "distance" panned is too much). /// /// MouseEventArgs // ------------------------------------------------------------------ public void MouseMove(MouseEventArgs e) { Point currentLocation = Point.Round(Controller.View.WorldToView(e.Location)); if ((!IsSuspended) && (IsActive) && (this.isLeftMouseButtonPressed)) { // Change the cursor to indicated which direction we're // panning. if (mouseMoveNumber == 0) { UpdateCursor(currentLocation); } mouseMoveNumber++; if (mouseMoveNumber > 5) { mouseMoveNumber = 0; } IDiagramControl control = Controller.ParentControl; Point origin = Controller.View.Origin; Point offset = new Point( (previousMouseLocation.X - currentLocation.X), (previousMouseLocation.Y - currentLocation.Y)); origin.Offset(offset); // 0,0 is the min scrolling point. if (origin.X < 0) { origin.X = 0; } if (origin.Y < 0) { origin.Y = 0; } control.AutoScrollPosition = origin; Controller.View.Origin = origin; previousMouseLocation = currentLocation; } } // ------------------------------------------------------------------ /// /// Stops the panning action (does not deactivate the tool). /// /// MouseEventArgs // ------------------------------------------------------------------ public void MouseUp(MouseEventArgs e) { if ((IsActive) && (!IsSuspended)) { this.isLeftMouseButtonPressed = false; this.previousMouseLocation = Point.Empty; Cursor = CursorPalette.Pan; } } #endregion #region IKeyboardListener Members // ------------------------------------------------------------------ /// /// Implementation of IKeyboardListener - deactivates this tool when /// the 'escape' key is pressed. /// /// KeyEventArgs // ------------------------------------------------------------------ public void KeyDown(KeyEventArgs e) { if (e.KeyCode == Keys.Escape) DeactivateTool(); else if (e.KeyCode == Keys.Space) ActivateTool(); } // ------------------------------------------------------------------ /// /// Implementation of IKeyboardListener - nothing performed here. /// /// KeyEventArgs // ------------------------------------------------------------------ public void KeyUp(KeyEventArgs e) { if (e.KeyCode == Keys.Space) DeactivateTool(); } // ------------------------------------------------------------------ /// /// Implementation of IKeyboardListener - nothing performed here. /// /// KeyPressEventArgs // ------------------------------------------------------------------ public void KeyPress(KeyPressEventArgs e) { } #endregion } }