1 /***************************************************************************
2 qgsmaptoolpan.h - map tool for panning in map canvas
3 ---------------------
4 begin : January 2006
5 copyright : (C) 2006 by Martin Dobias
6 email : wonder.sk at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16 #include <QBitmap>
17 #include <QCursor>
18 #include "qgsmaptoolpan.h"
19 #include "qgsmapcanvas.h"
20 #include "qgsmaptopixel.h"
21 #include "qgsmapmouseevent.h"
22 #include "qgsproject.h"
23 #include "qgslogger.h"
24
25
QgsMapToolPan(QgsMapCanvas * canvas)26 QgsMapToolPan::QgsMapToolPan( QgsMapCanvas *canvas )
27 : QgsMapTool( canvas )
28 , mDragging( false )
29 {
30 mToolName = tr( "Pan" );
31 // set cursor
32 mCursor = QCursor( Qt::OpenHandCursor );
33 }
34
~QgsMapToolPan()35 QgsMapToolPan::~QgsMapToolPan()
36 {
37 mCanvas->ungrabGesture( Qt::PinchGesture );
38 }
39
activate()40 void QgsMapToolPan::activate()
41 {
42 mCanvas->grabGesture( Qt::PinchGesture );
43 QgsMapTool::activate();
44 }
45
deactivate()46 void QgsMapToolPan::deactivate()
47 {
48 mCanvas->ungrabGesture( Qt::PinchGesture );
49 QgsMapTool::deactivate();
50 }
51
flags() const52 QgsMapTool::Flags QgsMapToolPan::flags() const
53 {
54 return QgsMapTool::Transient | QgsMapTool::AllowZoomRect | QgsMapTool::ShowContextMenu;
55 }
56
canvasPressEvent(QgsMapMouseEvent * e)57 void QgsMapToolPan::canvasPressEvent( QgsMapMouseEvent *e )
58 {
59 if ( e->button() == Qt::LeftButton )
60 {
61 mCanvas->setCursor( QCursor( Qt::ClosedHandCursor ) );
62 mCanvas->panActionStart( e->pos() );
63 }
64 }
65
66
canvasMoveEvent(QgsMapMouseEvent * e)67 void QgsMapToolPan::canvasMoveEvent( QgsMapMouseEvent *e )
68 {
69 if ( !mPinching )
70 {
71 if ( ( e->buttons() & Qt::LeftButton ) )
72 {
73 mDragging = true;
74 // move map and other canvas items
75 mCanvas->panAction( e );
76 }
77 }
78 }
79
canvasReleaseEvent(QgsMapMouseEvent * e)80 void QgsMapToolPan::canvasReleaseEvent( QgsMapMouseEvent *e )
81 {
82 if ( !mPinching )
83 {
84 if ( e->button() == Qt::LeftButton )
85 {
86 if ( mDragging )
87 {
88 mCanvas->panActionEnd( e->pos() );
89 mDragging = false;
90 }
91 else // add pan to mouse cursor
92 {
93 if ( mCanvas->allowInteraction( QgsMapCanvasInteractionBlocker::Interaction::MapPanOnSingleClick ) )
94 {
95 // transform the mouse pos to map coordinates
96 const QgsPointXY prevCenter = mCanvas->center();
97 QgsPointXY center = mCanvas->getCoordinateTransform()->toMapCoordinates( e->x(), e->y() );
98 mCanvas->setCenter( center );
99 mCanvas->refresh();
100
101 QgsDistanceArea da;
102 da.setEllipsoid( QgsProject::instance()->ellipsoid() );
103 da.setSourceCrs( mCanvas->mapSettings().destinationCrs(), QgsProject::instance()->transformContext() );
104 emit panDistanceBearingChanged( da.measureLine( center, prevCenter ), da.lengthUnits(), da.bearing( center, prevCenter ) * 180 / M_PI );
105 }
106 }
107 }
108 }
109 mCanvas->setCursor( mCursor );
110 }
111
canvasDoubleClickEvent(QgsMapMouseEvent * e)112 void QgsMapToolPan::canvasDoubleClickEvent( QgsMapMouseEvent *e )
113 {
114 if ( !QTouchDevice::devices().isEmpty() && !mPinching )
115 {
116 mCanvas->zoomWithCenter( e->x(), e->y(), true );
117 }
118 }
119
gestureEvent(QGestureEvent * event)120 bool QgsMapToolPan::gestureEvent( QGestureEvent *event )
121 {
122 if ( QTouchDevice::devices().isEmpty() )
123 return true; // no touch support
124
125 if ( QGesture *gesture = event->gesture( Qt::PinchGesture ) )
126 {
127 mPinching = true;
128 pinchTriggered( static_cast<QPinchGesture *>( gesture ) );
129 }
130 return true;
131 }
132
pinchTriggered(QPinchGesture * gesture)133 void QgsMapToolPan::pinchTriggered( QPinchGesture *gesture )
134 {
135 if ( gesture->state() == Qt::GestureFinished )
136 {
137 //a very small totalScaleFactor indicates a two finger tap (pinch gesture without pinching)
138 if ( 0.98 < gesture->totalScaleFactor() && gesture->totalScaleFactor() < 1.02 )
139 {
140 mCanvas->zoomOut();
141 }
142 else
143 {
144 //Transfor global coordinates to widget coordinates
145 QPoint pos = gesture->centerPoint().toPoint();
146 pos = mCanvas->mapFromGlobal( pos );
147 // transform the mouse pos to map coordinates
148 QgsPointXY center = mCanvas->getCoordinateTransform()->toMapCoordinates( pos.x(), pos.y() );
149 QgsRectangle r = mCanvas->extent();
150 r.scale( 1 / gesture->totalScaleFactor(), ¢er );
151 mCanvas->setExtent( r );
152 mCanvas->refresh();
153 }
154 mPinching = false;
155 }
156 }
157