From 573b027e72bfeda604f3585851df38373c52447a Mon Sep 17 00:00:00 2001 From: Lukáš Lalinský Date: Thu, 3 Sep 2009 12:17:44 +0200 Subject: Implement auto-scrolling of the diagram view --- src/diagramview.cpp | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++- src/diagramview.h | 10 ++++++ 2 files changed, 103 insertions(+), 1 deletion(-) diff --git a/src/diagramview.cpp b/src/diagramview.cpp index e2a5779..cb958e4 100644 --- a/src/diagramview.cpp +++ b/src/diagramview.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "diagramview.h" #include "diagramdocument.h" @@ -24,12 +25,17 @@ using namespace std; DiagramView::DiagramView(QWidget *parent) - : QGraphicsView(parent), m_handScrolling(false) + : QGraphicsView(parent), + m_handScrolling(false), + m_autoScrollCount(0), + m_autoScrollMargin(16) { setAlignment(Qt::AlignLeft | Qt::AlignTop); setRenderHint(QPainter::Antialiasing); setDragMode(QGraphicsView::RubberBandDrag); setRubberBandSelectionMode(Qt::ContainsItemBoundingRect); + m_autoScrollTimer = new QTimer(this); + connect(m_autoScrollTimer, SIGNAL(timeout()), SLOT(doAutoScroll())); } DiagramDocument * @@ -80,6 +86,10 @@ DiagramView::mouseMoveEvent(QMouseEvent *event) return; } QGraphicsView::mouseMoveEvent(event); + + if (event->buttons() && !isAutoScrolling() && shouldAutoScroll(event->pos())) { + startAutoScroll(); + } } void @@ -138,3 +148,85 @@ DiagramView::drawGrid(QPainter *painter, const QRectF &rect) } painter->restore(); } + +static QRect +clipRect(QWidget *w) +{ + if (!w->isVisible()) + return QRect(); + QRect r = w->rect(); + int ox = 0; + int oy = 0; + while (w + && w->isVisible() + && !w->isWindow() + && w->parentWidget()) { + ox -= w->x(); + oy -= w->y(); + w = w->parentWidget(); + r &= QRect(ox, oy, w->width(), w->height()); + } + return r; +} + +void +DiagramView::startAutoScroll() +{ + m_autoScrollTimer->start(50); + m_autoScrollCount = 0; +} + +void +DiagramView::stopAutoScroll() +{ + m_autoScrollTimer->stop(); + m_autoScrollCount = 0; +} + +bool +DiagramView::isAutoScrolling() const +{ + return m_autoScrollTimer->isActive(); +} + +bool +DiagramView::shouldAutoScroll(const QPoint &pos) const +{ + QRect area = clipRect(viewport()); + return (pos.y() - area.top() < m_autoScrollMargin) + || (area.bottom() - pos.y() < m_autoScrollMargin) + || (pos.x() - area.left() < m_autoScrollMargin) + || (area.right() - pos.x() < m_autoScrollMargin); +} + +void +DiagramView::doAutoScroll() +{ + int verticalStep = verticalScrollBar()->pageStep(); + int horizontalStep = horizontalScrollBar()->pageStep(); + if (m_autoScrollCount < qMax(verticalStep, horizontalStep)) + ++m_autoScrollCount; + + int verticalValue = verticalScrollBar()->value(); + int horizontalValue = horizontalScrollBar()->value(); + + QPoint pos = viewport()->mapFromGlobal(QCursor::pos()); + QRect area = clipRect(viewport()); + + if (pos.y() - area.top() < m_autoScrollMargin) + verticalScrollBar()->setValue(verticalValue - m_autoScrollCount); + else if (area.bottom() - pos.y() < m_autoScrollMargin) + verticalScrollBar()->setValue(verticalValue + m_autoScrollCount); + if (pos.x() - area.left() < m_autoScrollMargin) + horizontalScrollBar()->setValue(horizontalValue - m_autoScrollCount); + else if (area.right() - pos.x() < m_autoScrollMargin) + horizontalScrollBar()->setValue(horizontalValue + m_autoScrollCount); + + bool verticalUnchanged = (verticalValue == verticalScrollBar()->value()); + bool horizontalUnchanged = (horizontalValue == horizontalScrollBar()->value()); + if (verticalUnchanged && horizontalUnchanged) { + stopAutoScroll(); + } else { + viewport()->update(); + } +} diff --git a/src/diagramview.h b/src/diagramview.h index 9e57c36..1a16f6b 100644 --- a/src/diagramview.h +++ b/src/diagramview.h @@ -19,6 +19,7 @@ #include class DiagramDocument; +class QTimer; class DiagramView : public QGraphicsView { @@ -41,13 +42,22 @@ protected: protected slots: void updateSceneRect2(const QRectF &rect); + void doAutoScroll(); private: + void startAutoScroll(); + void stopAutoScroll(); + bool isAutoScrolling() const; + bool shouldAutoScroll(const QPoint &pos) const; + bool m_handScrolling; QPoint m_handScrollingOrigin; QCursor m_savedCursor; int m_handScrollingValueX; int m_handScrollingValueY; + QTimer *m_autoScrollTimer; + int m_autoScrollCount; + int m_autoScrollMargin; }; #endif -- cgit v1.2.3-54-g00ecf