From 1e5b18d86ada0caaeb23bc2a2883ba370a21ffae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Thu, 28 Apr 2022 21:54:00 +0200 Subject: [PATCH] Added support for pinch zoom --- src/GUI/mapview.cpp | 49 +++++++++++++++++++++++++++++++++++++++++---- src/GUI/mapview.h | 10 ++++++++- 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/src/GUI/mapview.cpp b/src/GUI/mapview.cpp index face9e9a..266be4b3 100644 --- a/src/GUI/mapview.cpp +++ b/src/GUI/mapview.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +50,8 @@ MapView::MapView(Map *map, POI *poi, QGeoPositionInfoSource *source, setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); setResizeAnchor(QGraphicsView::AnchorViewCenter); setAcceptDrops(false); + viewport()->setAttribute(Qt::WA_AcceptTouchEvents); + grabGesture(Qt::PinchGesture); _mapScale = new ScaleItem(); _mapScale->setZValue(2.0); @@ -125,6 +128,8 @@ MapView::MapView(Map *map, POI *poi, QGeoPositionInfoSource *source, _opengl = false; _plot = false; _digitalZoom = 0; + _pinchZoom = 0; + _wheelDelta = 0; _res = _map->resolution(_map->bounds()); _scene->setSceneRect(_map->bounds()); @@ -617,19 +622,40 @@ void MapView::zoom(int zoom, const QPoint &pos, bool shift) } } +void MapView::pinchGesture(QPinchGesture *gesture) +{ + QPinchGesture::ChangeFlags changeFlags = gesture->changeFlags(); + qreal scaleFactor = gesture->totalScaleFactor(); + + if (changeFlags & QPinchGesture::ScaleFactorChanged) { + int z = 0; + + for (qreal sc = scaleFactor; sc > 1.25; sc *= 0.8) + z += 1; + for (qreal sc = scaleFactor; sc < 0.8; sc *= 1.25) + z -= 1; + + if (_pinchZoom != z) { + zoom(z - _pinchZoom, gesture->centerPoint().toPoint(), false); + _pinchZoom = z; + } + } + if (gesture->state() == Qt::GestureFinished) + _pinchZoom = 0; +} + void MapView::wheelEvent(QWheelEvent *event) { - static int deg8 = 0; bool shift = (event->modifiers() & MODIFIER) ? true : false; // Shift inverts the wheel axis on OS X, so use scrolling in both axes for // the zoom. int delta = event->angleDelta().y() ? event->angleDelta().y() : event->angleDelta().x(); - deg8 += delta; - if (qAbs(deg8) < (15 * 8)) + _wheelDelta += delta; + if (qAbs(_wheelDelta) < (15 * 8)) return; - deg8 = deg8 % (15 * 8); + _wheelDelta = _wheelDelta % (15 * 8); #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) zoom((delta > 0) ? 1 : -1, event->pos(), shift); @@ -1186,6 +1212,21 @@ void MapView::leaveEvent(QEvent *event) QGraphicsView::leaveEvent(event); } +bool MapView::event(QEvent *event) +{ + if (event->type() == QEvent::Gesture) + return gestureEvent(static_cast(event)); + return QWidget::event(event); +} + +bool MapView::gestureEvent(QGestureEvent *event) +{ + if (QGesture *pinch = event->gesture(Qt::PinchGesture)) + pinchGesture(static_cast(pinch)); + + return true; +} + void MapView::useOpenGL(bool use) { _opengl = use; diff --git a/src/GUI/mapview.h b/src/GUI/mapview.h index 956aed1a..e1e1ec92 100644 --- a/src/GUI/mapview.h +++ b/src/GUI/mapview.h @@ -19,6 +19,8 @@ class QGeoPositionInfoSource; class QGeoPositionInfo; +class QGestureEvent; +class QPinchGesture; class Data; class POI; class Map; @@ -147,6 +149,8 @@ private: void zoom(int zoom, const QPoint &pos, bool shift); void digitalZoom(int zoom); void updatePOIVisibility(); + bool gestureEvent(QGestureEvent *event); + void pinchGesture(QPinchGesture *gesture); void skipColor() {_palette.nextColor();} void mouseMoveEvent(QMouseEvent *event); @@ -157,8 +161,9 @@ private: void keyReleaseEvent(QKeyEvent *event); void drawBackground(QPainter *painter, const QRectF &rect); void paintEvent(QPaintEvent *event); - void scrollContentsBy(int dx, int dy); void leaveEvent(QEvent *event); + bool event(QEvent *event); + void scrollContentsBy(int dx, int dy); GraphicsScene *_scene; ScaleItem *_mapScale; @@ -201,6 +206,9 @@ private: qreal _deviceRatio; qreal _mapRatio; bool _opengl; + + int _pinchZoom; + int _wheelDelta; }; #endif // MAPVIEW_H