QGIS API Documentation  3.21.0-Master (5b68dc587e)
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 
50 QgsMapTool::Flags QgsMapToolZoom::flags() const
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.setRect( 0, 0, 0, 0 );
88 }
89 
90 
92 {
93  if ( e->button() != Qt::LeftButton )
94  return;
95 
96  setZoomMode( e->modifiers().testFlag( Qt::AltModifier ) ^ mNativeZoomOut );
97 
98  // We are not really dragging in this case. This is sometimes caused by
99  // a pen based computer reporting a press, move, and release, all the
100  // one point.
101  const bool tooShort = ( mZoomRect.topLeft() - mZoomRect.bottomRight() ).manhattanLength() < mMinPixelZoom;
102  if ( !mDragging || tooShort )
103  {
104  mDragging = false;
105  delete mRubberBand;
106  mRubberBand = nullptr;
107 
108  // change to zoom in/out by the default multiple
109  mCanvas->zoomWithCenter( e->x(), e->y(), !mZoomOut );
110  }
111  else
112  {
113  mDragging = false;
114  delete mRubberBand;
115  mRubberBand = nullptr;
116 
117  // store the rectangle
118  mZoomRect.setRight( e->pos().x() );
119  mZoomRect.setBottom( e->pos().y() );
120 
121  //account for bottom right -> top left dragging
122  mZoomRect = mZoomRect.normalized();
123 
124  // set center and zoom
125  const QSize &zoomRectSize = mZoomRect.size();
126  const QgsMapSettings &mapSettings = mCanvas->mapSettings();
127  const QSize &canvasSize = mapSettings.outputSize();
128  const double sfx = static_cast<double>( zoomRectSize.width() ) / canvasSize.width();
129  const double sfy = static_cast<double>( zoomRectSize.height() ) / canvasSize.height();
130  const double sf = std::max( sfx, sfy );
131 
133  const QgsPointXY c = m2p->toMapCoordinates( mZoomRect.center() );
134 
135  mCanvas->zoomByFactor( mZoomOut ? 1.0 / sf : sf, &c );
136 
137  mCanvas->refresh();
138  }
139 }
140 
142 {
143  delete mRubberBand;
144  mRubberBand = nullptr;
145 
147 }
148 
149 void QgsMapToolZoom::setZoomMode( bool zoomOut, bool force )
150 {
151  if ( !force && zoomOut == mZoomOut )
152  return;
153 
154  mZoomOut = zoomOut;
156 }
157 
158 void QgsMapToolZoom::keyPressEvent( QKeyEvent *e )
159 {
160  if ( e->key() == Qt::Key_Alt )
161  {
162  setZoomMode( !mNativeZoomOut );
163  }
164 }
165 
167 {
168  // key press events are not caught wile the mouse is pressed
169  // this is detected in map canvas move event
170 
171  if ( e->key() == Qt::Key_Alt )
172  {
173  setZoomMode( mNativeZoomOut );
174  }
175 }
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:88
void zoomWithCenter(int x, int y, bool zoomIn)
Zooms in/out with a given center.
void zoomByFactor(double scaleFactor, const QgsPointXY *center=nullptr, bool ignoreScaleLock=false)
Zoom with the factor supplied.
const QgsMapToPixel * getCoordinateTransform()
Gets the current coordinate transform.
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
void refresh()
Repaints the canvas map.
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.
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:66
QgsMapCanvas * mCanvas
The pointer to the map canvas.
Definition: qgsmaptool.h:304
virtual void setCursor(const QCursor &cursor)
Sets a user defined cursor.
Definition: qgsmaptool.cpp:150
QString mToolName
The translated name of the map tool.
Definition: qgsmaptool.h:322
@ ShowContextMenu
Show a context menu when right-clicking with the tool (since QGIS 3.14). See populateContextMenu().
Definition: qgsmaptool.h:100
virtual void deactivate()
called when map tool is being deactivated
Definition: qgsmaptool.cpp:100
A class to represent a 2D point.
Definition: qgspointxy.h:59
A class for drawing transient features (e.g.
Definition: qgsrubberband.h:52
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