From a2aaa3c71b8f7e1846a490525001342c6a17f437 Mon Sep 17 00:00:00 2001 From: "Felix (xq) Queißner" Date: Wed, 10 Jun 2020 02:01:44 +0200 Subject: Improves image panning and zoom. Image view is now on a better default and usability. --- lib/luis-l-gist/interactiveview.cpp | 133 ++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 lib/luis-l-gist/interactiveview.cpp (limited to 'lib/luis-l-gist/interactiveview.cpp') diff --git a/lib/luis-l-gist/interactiveview.cpp b/lib/luis-l-gist/interactiveview.cpp new file mode 100644 index 0000000..2707352 --- /dev/null +++ b/lib/luis-l-gist/interactiveview.cpp @@ -0,0 +1,133 @@ +#include "interactiveview.hpp" + +#define VIEW_CENTER viewport()->rect().center() +#define VIEW_WIDTH viewport()->rect().width() +#define VIEW_HEIGHT viewport()->rect().height() + +InteractiveView::InteractiveView(QWidget * parent) : + QGraphicsView(parent) +{ + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + setMaxSize(); + centerOn(0, 0); + + zoomDelta = 0.1; + panSpeed = 4; + _doMousePanning = false; + _doKeyZoom = false; + _scale = 1.0; + + panButton = Qt::MiddleButton; + zoomKey = Qt::Key_Z; +} + +qreal InteractiveView::getScale() const +{ + return _scale; +} + +void InteractiveView::keyPressEvent(QKeyEvent * event) +{ + qint32 key = event->key(); + + if(key == zoomKey){ + _doKeyZoom = true; + } + + if (_doKeyZoom){ + if (key == Qt::Key_Up) + zoomIn(); + + else if (key == Qt::Key_Down) + zoomOut(); + } + + else{ + QGraphicsView::keyPressEvent(event); + } +} + +void InteractiveView::keyReleaseEvent(QKeyEvent * event) +{ + if (event->key() == zoomKey){ + _doKeyZoom = false; + } + + QGraphicsView::keyReleaseEvent(event); +} + +void InteractiveView::mouseMoveEvent(QMouseEvent * event) +{ + if (_doMousePanning){ + QPointF mouseDelta = mapToScene(event->pos()) - mapToScene(_lastMousePos); + pan(mouseDelta); + } + + QGraphicsView::mouseMoveEvent(event); + _lastMousePos = event->pos(); +} + +void InteractiveView::mousePressEvent(QMouseEvent * event) +{ + if (event->button() == panButton){ + _lastMousePos = event->pos(); + _doMousePanning = true; + } + + QGraphicsView::mousePressEvent(event); +} + +void InteractiveView::mouseReleaseEvent(QMouseEvent * event) +{ + if (event->button() == panButton){ + _doMousePanning = false; + } + + QGraphicsView::mouseReleaseEvent(event); +} + +void InteractiveView::wheelEvent(QWheelEvent *event) +{ + QPoint scrollAmount = event->angleDelta(); + + // Apply zoom. + scrollAmount.y() > 0 ? zoomIn() : zoomOut(); +} + +void InteractiveView::setMaxSize() +{ + setSceneRect(INT_MIN/2, INT_MIN/2, INT_MAX, INT_MAX); +} + +void InteractiveView::zoom(float scaleFactor) +{ + scale(scaleFactor, scaleFactor); + _scale *= scaleFactor; +} + +void InteractiveView::zoomIn() +{ + zoom(1 + zoomDelta); +} + +void InteractiveView::zoomOut() +{ + zoom (1 - zoomDelta); +} + +void InteractiveView::pan(QPointF delta) +{ + // Scale the pan amount by the current zoom. + delta *= _scale; + delta *= panSpeed; + + // Have panning be anchored from the mouse. + setTransformationAnchor(QGraphicsView::AnchorUnderMouse); + QPoint newCenter(VIEW_WIDTH / 2 - delta.x(), VIEW_HEIGHT / 2 - delta.y()); + centerOn(mapToScene(newCenter)); + + // For zooming to anchor from the view center. + setTransformationAnchor(QGraphicsView::AnchorViewCenter); +} -- cgit v1.2.3