/
qgsmaptoolzoom.cpp
165 lines (135 loc) · 4.49 KB
/
qgsmaptoolzoom.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/***************************************************************************
qgsmaptoolzoom.cpp - map tool for zooming
----------------------
begin : January 2006
copyright : (C) 2006 by Martin Dobias
email : wonder.sk at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include <QRect>
#include <QColor>
#include <QCursor>
#include <QPixmap>
#include "qgsmaptoolzoom.h"
#include "qgsmapcanvas.h"
#include "qgsmaptopixel.h"
#include "qgsrubberband.h"
#include "qgslogger.h"
#include "qgsmapmouseevent.h"
QgsMapToolZoom::QgsMapToolZoom( QgsMapCanvas *canvas, bool zoomOut )
: QgsMapTool( canvas )
, mZoomOut( zoomOut )
, mNativeZoomOut( zoomOut )
, mDragging( false )
, mZoomOutCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomOut ) )
, mZoomInCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomIn ) )
{
mToolName = tr( "Zoom" );
updateCursor();
}
QgsMapToolZoom::~QgsMapToolZoom()
{
delete mRubberBand;
}
void QgsMapToolZoom::canvasMoveEvent( QgsMapMouseEvent *e )
{
if ( !( e->buttons() & Qt::LeftButton ) )
return;
if ( !mDragging )
{
mDragging = true;
delete mRubberBand;
mRubberBand = new QgsRubberBand( mCanvas, QgsWkbTypes::PolygonGeometry );
QColor color( Qt::blue );
color.setAlpha( 63 );
mRubberBand->setColor( color );
mZoomRect.setTopLeft( e->pos() );
}
mZoomRect.setBottomRight( e->pos() );
if ( mRubberBand )
{
mRubberBand->setToCanvasRectangle( mZoomRect );
mRubberBand->show();
}
}
void QgsMapToolZoom::canvasPressEvent( QgsMapMouseEvent *e )
{
if ( e->button() != Qt::LeftButton )
return;
mZoomRect.setRect( 0, 0, 0, 0 );
}
void QgsMapToolZoom::canvasReleaseEvent( QgsMapMouseEvent *e )
{
if ( e->button() != Qt::LeftButton )
return;
// We are not really dragging in this case. This is sometimes caused by
// a pen based computer reporting a press, move, and release, all the
// one point.
bool tooShort = ( mZoomRect.topLeft() - mZoomRect.bottomRight() ).manhattanLength() < mMinPixelZoom;
if ( !mDragging || tooShort )
{
mDragging = false;
delete mRubberBand;
mRubberBand = nullptr;
// change to zoom in/out by the default multiple
mCanvas->zoomWithCenter( e->x(), e->y(), !mZoomOut );
}
else
{
mDragging = false;
delete mRubberBand;
mRubberBand = nullptr;
// store the rectangle
mZoomRect.setRight( e->pos().x() );
mZoomRect.setBottom( e->pos().y() );
//account for bottom right -> top left dragging
mZoomRect = mZoomRect.normalized();
// set center and zoom
const QSize &zoomRectSize = mZoomRect.size();
const QgsMapSettings &mapSettings = mCanvas->mapSettings();
const QSize &canvasSize = mapSettings.outputSize();
double sfx = static_cast<double>( zoomRectSize.width() ) / canvasSize.width();
double sfy = static_cast<double>( zoomRectSize.height() ) / canvasSize.height();
double sf = std::max( sfx, sfy );
const QgsMapToPixel *m2p = mCanvas->getCoordinateTransform();
QgsPointXY c = m2p->toMapCoordinates( mZoomRect.center() );
mCanvas->zoomByFactor( mZoomOut ? 1.0 / sf : sf, &c );
mCanvas->refresh();
}
}
void QgsMapToolZoom::deactivate()
{
delete mRubberBand;
mRubberBand = nullptr;
QgsMapTool::deactivate();
}
void QgsMapToolZoom::updateCursor()
{
setCursor( mZoomOut ? mZoomOutCursor : mZoomInCursor );
}
void QgsMapToolZoom::keyPressEvent( QKeyEvent *e )
{
if ( e->key() == Qt::Key_Alt )
{
mZoomOut = !mZoomOut;
updateCursor();
}
}
void QgsMapToolZoom::keyReleaseEvent( QKeyEvent *e )
{
// key press events are not caught wile the mouse is pressed
// so we can't mess if we are already dragging
// we need to go back to native state, as it cannot be determine
// (since the press event is not detected while mouse is pressed)
if ( e->key() == Qt::Key_Alt )
{
mZoomOut = mNativeZoomOut;
updateCursor();
}
}