diff options
author | Lukáš Lalinský <lalinsky@gmail.com> | 2009-09-03 12:17:44 +0200 |
---|---|---|
committer | Lukáš Lalinský <lalinsky@gmail.com> | 2009-09-03 12:17:44 +0200 |
commit | 573b027e72bfeda604f3585851df38373c52447a (patch) | |
tree | 6c0f212b90781515d48b8051b7c78daadc677d8c /src | |
parent | 68d7ce96113bb59292332d9907b6adc95915e98e (diff) | |
download | dbmodel-573b027e72bfeda604f3585851df38373c52447a.tar.xz |
Implement auto-scrolling of the diagram view
Diffstat (limited to 'src')
-rw-r--r-- | src/diagramview.cpp | 94 | ||||
-rw-r--r-- | src/diagramview.h | 10 |
2 files changed, 103 insertions, 1 deletions
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 <cmath> #include <QMouseEvent> #include <QScrollBar> +#include <QTimer> #include <QDebug> #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 <QGraphicsView> 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 |