private void autoScrollTimer_Tick(object sender, EventArgs e) { m_autoScrollTimer.Stop(); if (!VisibleClientRectangle.Contains(m_currentPoint)) { if (m_isMultiSelecting) { Rectangle selectionRect = MakeSelectionRect(m_currentPoint, m_firstPoint); ControlPaint.DrawReversibleFrame(selectionRect, BackColor, FrameStyle.Dashed); } const int autoScrollSpeed = 10; Rectangle visibleRect = VisibleClientRectangle; Point scroll = m_scroll; if (m_currentPoint.X < 0) { scroll.X += autoScrollSpeed; } else if (m_currentPoint.X > visibleRect.Width) { scroll.X -= autoScrollSpeed; } if (m_currentPoint.Y < 0) { scroll.Y += autoScrollSpeed; } else if (m_currentPoint.Y > visibleRect.Height) { scroll.Y -= autoScrollSpeed; } Point diff = m_scroll; ScrollPosition = new Point(scroll.X, scroll.Y); diff.X = m_scroll.X - diff.X; diff.Y = m_scroll.Y - diff.Y; // adjust mouse positions m_firstPoint.X += diff.X; m_firstPoint.Y += diff.Y; m_last = m_currentPoint; OnAutoScroll(); base.Update(); // without this, the selection rect doesn't draw correctly if (m_isMultiSelecting) { Rectangle rect = MakeSelectionRect(m_currentPoint, m_firstPoint); ControlPaint.DrawReversibleFrame(rect, BackColor, FrameStyle.Dashed); } m_autoScrollTimer.Start(); } }
/// <summary> /// Raises the <see cref="E:System.Windows.Forms.Control.MouseMove"></see> event</summary> /// <param name="e">A <see cref="T:System.Windows.Forms.MouseEventArgs"></see> that contains the event data</param> protected override void OnMouseMove(MouseEventArgs e) { m_last = m_currentPoint; m_currentPoint = new Point(e.X, e.Y); int xDelta = Math.Abs(m_currentPoint.X - m_firstPoint.X); int yDelta = Math.Abs(m_currentPoint.Y - m_firstPoint.Y); if (m_isDragging && !m_dragOverThreshold && (xDelta > m_dragThreshold || yDelta > m_dragThreshold)) { m_dragOverThreshold = true; if (m_constrain) { m_constrainX = (xDelta < yDelta); } } if (m_constrain) { if (m_constrainX) { m_currentPoint.X = m_firstPoint.X; } else { m_currentPoint.Y = m_firstPoint.Y; } } if (m_dragOverThreshold) { Point delta = DragDelta; // auto scroll if mouse is outside control if (m_autoScroll && !VisibleClientRectangle.Contains(m_currentPoint) && !m_autoScrollTimer.Enabled) { m_autoScrollTimer.Start(); } if (m_isMultiSelecting) { Rectangle rect; rect = MakeSelectionRect(m_last, m_firstPoint); ControlPaint.DrawReversibleFrame(rect, BackColor, FrameStyle.Dashed); rect = MakeSelectionRect(m_currentPoint, m_firstPoint); ControlPaint.DrawReversibleFrame(rect, BackColor, FrameStyle.Dashed); } else if (m_isScrolling) { ScrollPosition = new Point( m_autoScrollPositionStart.X + delta.X, m_autoScrollPositionStart.Y + delta.Y); } else if (m_isZooming) { float xScale = 1 + 2 * delta.X / (float)Width; float yScale = 1 + 2 * delta.Y / (float)Height; if (m_constrain || UniformZoom) { xScale = yScale = Math.Max(xScale, yScale); } SetZoom(m_xZoomStart * xScale, m_yZoomStart * yScale); ScrollPosition = new Point((int)(m_firstPoint.X - m_zoomCenterStart.X * m_xZoom), (int)(m_firstPoint.Y - m_zoomCenterStart.Y * m_yZoom)); } } base.OnMouseMove(e); }