ui: Use update loop in graph panning and zooming for smooth interaction

This commit is contained in:
Eberhard Graether
2016-03-16 15:03:57 +01:00
parent 2d0700cd06
commit a78e7b85d1
3 changed files with 146 additions and 77 deletions
+124 -70
View File
@@ -1,15 +1,23 @@
#include "qt/graphics/QtGraphicsView.h"
#include <QPropertyAnimation>
#include <QScrollBar>
#include <QMouseEvent>
#include <QScrollBar>
#include <QTimer>
QtGraphicsView::QtGraphicsView(QWidget* parent)
: QGraphicsView(parent)
, m_zoomFactor(1.0f)
, m_appZoomFactor(1.0f)
, m_up(false)
, m_down(false)
, m_left(false)
, m_right(false)
, m_shift(false)
{
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
m_timer = std::make_shared<QTimer>(this);
connect(m_timer.get(), SIGNAL(timeout()), this, SLOT(update()));
}
float QtGraphicsView::getZoomFactor() const
@@ -23,17 +31,6 @@ void QtGraphicsView::setAppZoomFactor(float appZoomFactor)
updateTransform();
}
qreal QtGraphicsView::zoom() const
{
return m_zoomFactor;
}
void QtGraphicsView::setZoom(qreal zoom)
{
m_zoomFactor = qBound(0.1, zoom, 100.0);
updateTransform();
}
void QtGraphicsView::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton && !itemAt(event->pos()))
@@ -57,58 +54,63 @@ void QtGraphicsView::mouseReleaseEvent(QMouseEvent *event)
void QtGraphicsView::keyPressEvent(QKeyEvent* event)
{
float delta = 150;
float x = 0.0f;
float y = 0.0f;
if (event->key() == Qt::Key_W)
switch (event->key())
{
if (event->modifiers() == Qt::ShiftModifier)
{
updateZoom(200.0f, true);
case Qt::Key_W:
m_up = true;
break;
case Qt::Key_A:
m_left = true;
break;
case Qt::Key_S:
m_down = true;
break;
case Qt::Key_D:
m_right = true;
break;
case Qt::Key_0:
m_zoomFactor = 1.0f;
updateTransform();
break;
case Qt::Key_Shift:
m_shift = true;
break;
default:
return;
}
}
y -= delta;
}
else if (event->key() == Qt::Key_A)
if (moves())
{
x -= delta;
m_timer->start(20);
}
else if (event->key() == Qt::Key_S)
}
void QtGraphicsView::keyReleaseEvent(QKeyEvent* event)
{
switch (event->key())
{
if (event->modifiers() == Qt::ShiftModifier)
{
updateZoom(-200.0f, true);
case Qt::Key_W:
m_up = false;
break;
case Qt::Key_A:
m_left = false;
break;
case Qt::Key_S:
m_down = false;
break;
case Qt::Key_D:
m_right = false;
break;
case Qt::Key_Shift:
m_shift = false;
break;
default:
return;
}
y += delta;
}
else if (event->key() == Qt::Key_D)
{
x += delta;
}
else
{
return;
}
if (x != 0)
if (!moves())
{
QPropertyAnimation* anim = new QPropertyAnimation(horizontalScrollBar(), "value");
anim->setDuration(100);
anim->setStartValue(horizontalScrollBar()->value());
anim->setEndValue(horizontalScrollBar()->value() + x);
anim->start();
}
if (y != 0)
{
QPropertyAnimation* anim = new QPropertyAnimation(verticalScrollBar(), "value");
anim->setDuration(100);
anim->setStartValue(verticalScrollBar()->value());
anim->setEndValue(verticalScrollBar()->value() + y);
anim->start();
m_timer->stop();
}
}
@@ -116,20 +118,82 @@ void QtGraphicsView::wheelEvent(QWheelEvent* event)
{
if (event->modifiers() == Qt::ShiftModifier && event->delta() != 0.0f)
{
updateZoom(event->delta(), false);
updateZoom(event->delta());
return;
}
QGraphicsView::wheelEvent(event);
}
void QtGraphicsView::update()
{
float ds = 25.0f;
float dz = 50.0f;
float x = 0.0f;
float y = 0.0f;
float z = 0.0f;
if (m_shift)
{
if (m_up)
{
z += dz;
}
else if (m_down)
{
z -= dz;
}
}
else
{
if (m_up)
{
y -= ds;
}
else if (m_down)
{
y += ds;
}
if (m_left)
{
x -= ds;
}
else if (m_right)
{
x += ds;
}
}
if (x != 0)
{
horizontalScrollBar()->setValue(horizontalScrollBar()->value() + x);
}
if (y != 0)
{
verticalScrollBar()->setValue(verticalScrollBar()->value() + y);
}
if (z != 0)
{
updateZoom(z);
}
}
bool QtGraphicsView::moves() const
{
return m_up || m_down || m_left || m_right;
}
void QtGraphicsView::updateTransform()
{
float zoomFactor = m_appZoomFactor * m_zoomFactor;
setTransform(QTransform(zoomFactor, 0, 0, zoomFactor, 0, 0));
}
void QtGraphicsView::updateZoom(float delta, bool animate)
void QtGraphicsView::updateZoom(float delta)
{
float factor = 1.0f + 0.001 * delta;
@@ -138,18 +202,8 @@ void QtGraphicsView::updateZoom(float delta, bool animate)
factor = 0.000001;
}
float newZoom = m_zoomFactor * factor;
double newZoom = m_zoomFactor * factor;
m_zoomFactor = qBound(0.1, newZoom, 100.0);
if (animate)
{
QPropertyAnimation* anim = new QPropertyAnimation(this, "zoom");
anim->setDuration(100);
anim->setStartValue(m_zoomFactor);
anim->setEndValue(newZoom);
anim->start();
}
else
{
setZoom(newZoom);
}
updateTransform();
}
+19 -5
View File
@@ -3,11 +3,12 @@
#include <QGraphicsView>
class QTimer;
class QtGraphicsView
: public QGraphicsView
{
Q_OBJECT
Q_PROPERTY(qreal zoom READ zoom WRITE setZoom)
public:
QtGraphicsView(QWidget* parent);
@@ -15,26 +16,39 @@ public:
float getZoomFactor() const;
void setAppZoomFactor(float appZoomFactor);
qreal zoom() const;
void setZoom(qreal zoom);
protected:
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void keyPressEvent(QKeyEvent* event);
void keyReleaseEvent(QKeyEvent* event);
void wheelEvent(QWheelEvent* event);
signals:
void emptySpaceClicked();
private slots:
void update();
private:
bool moves() const;
void updateTransform();
void updateZoom(float delta, bool animate);
void updateZoom(float delta);
QPoint m_last;
float m_zoomFactor;
float m_appZoomFactor;
bool m_up;
bool m_down;
bool m_left;
bool m_right;
bool m_shift;
std::shared_ptr<QTimer> m_timer;
};
#endif // QT_GRAPHICS_VIEW_H
+3 -2
View File
@@ -976,12 +976,13 @@
<ul>
<li>Drag the background area with the mouse.</li>
<li>Scroll left-right and up-down on the mouse pad.</li>
<li>Use the keys <kbd>WASD</kbd>.</li>
<li>Use the keys <kbd>W</kbd> <kbd>A</kbd> <kbd>S</kbd> <kbd>D</kbd>.</li>
</ul>
<strong>Zooming:</strong>
<ul>
<li>Hold <kbd>Shift</kbd> and scroll with mouse wheel or mouse pad.</li>
<li>Press <kbd>Shift + WS</kbd>.</li>
<li>Press <kbd>Shift + W</kbd> or <kbd>Shift + S</kbd>.</li>
<li>Press <kbd>0</kbd> to reset zoom.</li>
</ul>
<h3>Nodes</h3>