QGIS API Documentation  3.37.0-Master (a5b4d9743e8)
qgsmaptoolzoom.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmaptoolzoom.cpp - map tool for zooming
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 
17 #include <QRect>
18 #include <QColor>
19 #include <QCursor>
20 #include <QPixmap>
21 
22 #include "qgsmaptoolzoom.h"
23 #include "qgsmapcanvas.h"
24 #include "qgsmaptopixel.h"
25 #include "qgsrubberband.h"
26 #include "qgslogger.h"
27 #include "qgsmapmouseevent.h"
28 #include "qgsapplication.h"
29 
30 
31 
33  : QgsMapTool( canvas )
34  , mZoomOut( zoomOut )
35  , mNativeZoomOut( zoomOut )
36  , mDragging( false )
37  , mZoomOutCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomOut ) )
38  , mZoomInCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomIn ) )
39 
40 {
41  mToolName = tr( "Zoom" );
42  setZoomMode( mNativeZoomOut, true );
43 }
44 
46 {
47  delete mRubberBand;
48 }
49 
51 {
53 }
54 
56 {
57  if ( !( e->buttons() & Qt::LeftButton ) )
58  return;
59 
60  setZoomMode( e->modifiers().testFlag( Qt::AltModifier ) ^ mNativeZoomOut );
61 
62  if ( !mDragging )
63  {
64  mDragging = true;
65  delete mRubberBand;
67  QColor color( Qt::blue );
68  color.setAlpha( 63 );
69  mRubberBand->setColor( color );
70  mZoomRect.setTopLeft( e->pos() );
71  }
72 
73  mZoomRect.setBottomRight( e->pos() );
74  if ( mRubberBand )
75  {
77  mRubberBand->show();
78  }
79 }
80 
81 
83 {
84  if ( e->button() != Qt::LeftButton )
85  return;
86 
87  mZoomRect.setTopLeft( e->pos() );
88  mZoomRect.setBottomRight( e->pos() );
89 }
90 
91 
93 {
94  if ( e->button() != Qt::LeftButton )
95  return;
96 
97  if ( mCanceled )
98  {
99  mCanceled = false;
100  mDragging = false;
101  return;
102  }
103 
104  setZoomMode( e->modifiers().testFlag( Qt::AltModifier ) ^ mNativeZoomOut );
105 
106  // We are not really dragging in this case. This is sometimes caused by
107  // a pen based computer reporting a press, move, and release, all the
108  // one point.
109  const bool tooShort = ( mZoomRect.topLeft() - mZoomRect.bottomRight() ).manhattanLength() < mMinPixelZoom;
110  if ( !mDragging || tooShort )
111  {
112  mDragging = false;
113  delete mRubberBand;
114  mRubberBand = nullptr;
115 
116  // change to zoom in/out by the default multiple
117  mCanvas->zoomWithCenter( e->x(), e->y(), !mZoomOut );
118  }
119  else
120  {
121  mDragging = false;
122  delete mRubberBand;
123  mRubberBand = nullptr;
124 
125  // store the rectangle
126  mZoomRect.setRight( e->pos().x() );
127  mZoomRect.setBottom( e->pos().y() );
128 
129  //account for bottom right -> top left dragging
130  mZoomRect = mZoomRect.normalized();
131 
132  // set center and zoom
133  const QSize &zoomRectSize = mZoomRect.size();
134  const QgsMapSettings &mapSettings = mCanvas->mapSettings();
135  const QSize &canvasSize = mapSettings.outputSize();
136  const double sfx = static_cast<double>( zoomRectSize.width() ) / canvasSize.width();
137  const double sfy = static_cast<double>( zoomRectSize.height() ) / canvasSize.height();
138  const double sf = std::max( sfx, sfy );
139 
140  const QgsMapToPixel *m2p = mCanvas->getCoordinateTransform();
141  const QgsPointXY c = m2p->toMapCoordinates( mZoomRect.center() );
142 
143  mCanvas->zoomByFactor( mZoomOut ? 1.0 / sf : sf, &c );
144 
145  mCanvas->refresh();
146  }
147 }
148 
150 {
151  delete mRubberBand;
152  mRubberBand = nullptr;
153 
155 }
156 
157 void QgsMapToolZoom::setZoomMode( bool zoomOut, bool force )
158 {
159  if ( !force && zoomOut == mZoomOut )
160  return;
161 
162  mZoomOut = zoomOut;
164 }
165 
166 void QgsMapToolZoom::keyPressEvent( QKeyEvent *e )
167 {
168  if ( e->key() == Qt::Key_Alt )
169  {
170  setZoomMode( !mNativeZoomOut );
171  }
172 }
173 
175 {
176  // key press events are not caught wile the mouse is pressed
177  // this is detected in map canvas move event
178 
179  if ( e->key() == Qt::Key_Alt )
180  {
181  setZoomMode( mNativeZoomOut );
182  }
183 
184  if ( e->key() == Qt::Key_Escape && mDragging )
185  {
186  mCanceled = true;
187  delete mRubberBand;
188  mRubberBand = nullptr;
189  }
190 }
@ Polygon
Polygons.
Extends QApplication to provide access to QGIS specific resources such as theme paths,...
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:93
A QgsMapMouseEvent is the result of a user interaction with the mouse on a QgsMapCanvas.
The QgsMapSettings class contains configuration for rendering of the map.
QSize outputSize() const
Returns the size of the resulting map image, in pixels.
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:39
QgsPointXY toMapCoordinates(int x, int y) const
Transforms device coordinates to map (world) coordinates.
~QgsMapToolZoom() override
bool mDragging
Flag to indicate a map canvas drag operation is taking place.
void keyPressEvent(QKeyEvent *e) override
Key event for overriding. Default implementation does nothing.
bool mNativeZoomOut
native tool
QRect mZoomRect
stores actual zoom rect
void canvasPressEvent(QgsMapMouseEvent *e) override
Mouse press event for overriding. Default implementation does nothing.
bool mCanceled
Flag to indicate the user has canceled the current zoom operation.
QgsRubberBand * mRubberBand
Flags flags() const override
Returns the flags for the map tool.
QCursor mZoomOutCursor
void deactivate() override
called when map tool is being deactivated
QCursor mZoomInCursor
void canvasReleaseEvent(QgsMapMouseEvent *e) override
Mouse release event for overriding. Default implementation does nothing.
QgsMapToolZoom(QgsMapCanvas *canvas, bool zoomOut)
constructor
bool mZoomOut
indicates whether we're zooming in or out
void canvasMoveEvent(QgsMapMouseEvent *e) override
Mouse move event for overriding. Default implementation does nothing.
void keyReleaseEvent(QKeyEvent *e) override
Key event for overriding. Default implementation does nothing.
Abstract base class for all map tools.
Definition: qgsmaptool.h:71
QPointer< QgsMapCanvas > mCanvas
The pointer to the map canvas.
Definition: qgsmaptool.h:341
QFlags< Flag > Flags
Definition: qgsmaptool.h:116
virtual void setCursor(const QCursor &cursor)
Sets a user defined cursor.
Definition: qgsmaptool.cpp:166
QString mToolName
The translated name of the map tool.
Definition: qgsmaptool.h:359
@ ShowContextMenu
Show a context menu when right-clicking with the tool (since QGIS 3.14). See populateContextMenu().
Definition: qgsmaptool.h:114
virtual void deactivate()
called when map tool is being deactivated
Definition: qgsmaptool.cpp:110
A class to represent a 2D point.
Definition: qgspointxy.h:60
A class for drawing transient features (e.g.
Definition: qgsrubberband.h:54
void setColor(const QColor &color)
Sets the color for the rubberband.
void setToCanvasRectangle(QRect rect)
Sets this rubber band to a map canvas rectangle.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c