aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorFelix (xq) Queißner <git@mq32.de>2020-06-10 02:01:44 +0200
committerFelix (xq) Queißner <git@mq32.de>2020-06-10 02:01:44 +0200
commita2aaa3c71b8f7e1846a490525001342c6a17f437 (patch)
tree0af23617d02948e3ce28ae13d03107aff1d3dc2a /lib
parent9b93c4d7c5a450607eca0174b1899e56d6a09a48 (diff)
Improves image panning and zoom. Image view is now on a better default and usability.
Diffstat (limited to 'lib')
-rw-r--r--lib/luis-l-gist/interactiveview.cpp133
-rw-r--r--lib/luis-l-gist/interactiveview.hpp47
2 files changed, 180 insertions, 0 deletions
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);
+}
diff --git a/lib/luis-l-gist/interactiveview.hpp b/lib/luis-l-gist/interactiveview.hpp
new file mode 100644
index 0000000..1a0b1f8
--- /dev/null
+++ b/lib/luis-l-gist/interactiveview.hpp
@@ -0,0 +1,47 @@
+#ifndef INTERACTIVE_VIEW_H
+#define INTERACTIVE_VIEW_H
+
+#include <QGraphicsView>
+#include <QWheelEvent>
+#include <QKeyEvent>
+
+class InteractiveView : public QGraphicsView
+{
+public:
+ explicit InteractiveView(QWidget * parent);
+
+ qreal panSpeed;
+ qreal zoomDelta;
+ qreal zoomKey;
+ Qt::MouseButton panButton;
+
+ void pan(QPointF delta);
+ void zoom(float scaleFactor);
+ void zoomIn();
+ void zoomOut();
+
+ qreal getScale() const;
+
+protected:
+
+ void keyPressEvent(QKeyEvent*) override;
+ void keyReleaseEvent(QKeyEvent*) override;
+
+ void mouseMoveEvent(QMouseEvent*) override;
+ void mousePressEvent(QMouseEvent*) override;
+ void mouseReleaseEvent(QMouseEvent*) override;
+ void wheelEvent(QWheelEvent*) override;
+
+private:
+
+ // Flags to determine if zooming or panning should be done.
+ bool _doMousePanning;
+ bool _doKeyZoom;
+
+ QPoint _lastMousePos;
+ qreal _scale;
+
+ void setMaxSize();
+};
+
+#endif // INTERACTIVE_VIEW_H