summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukáš Lalinský <lalinsky@gmail.com>2009-09-03 12:17:44 +0200
committerLukáš Lalinský <lalinsky@gmail.com>2009-09-03 12:17:44 +0200
commit573b027e72bfeda604f3585851df38373c52447a (patch)
tree6c0f212b90781515d48b8051b7c78daadc677d8c
parent68d7ce96113bb59292332d9907b6adc95915e98e (diff)
downloaddbmodel-573b027e72bfeda604f3585851df38373c52447a.tar.gz
dbmodel-573b027e72bfeda604f3585851df38373c52447a.tar.bz2
Implement auto-scrolling of the diagram view
-rw-r--r--src/diagramview.cpp94
-rw-r--r--src/diagramview.h10
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