aboutsummaryrefslogtreecommitdiff
path: root/lib/luis-l-gist/interactiveview.cpp
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/luis-l-gist/interactiveview.cpp
parent9b93c4d7c5a450607eca0174b1899e56d6a09a48 (diff)
downloadkristall-a2aaa3c71b8f7e1846a490525001342c6a17f437.tar.gz
Improves image panning and zoom. Image view is now on a better default and usability.
Diffstat (limited to 'lib/luis-l-gist/interactiveview.cpp')
-rw-r--r--lib/luis-l-gist/interactiveview.cpp133
1 files changed, 133 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);
+}