1 /***************************************************************************
2 qgsmodelviewtoolzoom.cpp
3 -------------------------
4 Date : March 2020
5 Copyright : (C) 2020 Nyall Dawson
6 Email : nyall dot dawson 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 "qgsmodelviewtoolzoom.h"
17 #include "qgsmodelviewmouseevent.h"
18 #include "qgsmodelgraphicsview.h"
19 #include "qgsmodelviewrubberband.h"
20 #include "qgsrectangle.h"
21 #include "qgsapplication.h"
22 #include <QScrollBar>
23
QgsModelViewToolZoom(QgsModelGraphicsView * view)24 QgsModelViewToolZoom::QgsModelViewToolZoom( QgsModelGraphicsView *view )
25 : QgsModelViewTool( view, tr( "Pan" ) )
26 {
27 setCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomIn ) );
28 mRubberBand.reset( new QgsModelViewRectangularRubberBand( view ) );
29 mRubberBand->setBrush( QBrush( QColor( 70, 50, 255, 25 ) ) );
30 mRubberBand->setPen( QPen( QBrush( QColor( 70, 50, 255, 100 ) ), 0 ) );
31 }
32
modelPressEvent(QgsModelViewMouseEvent * event)33 void QgsModelViewToolZoom::modelPressEvent( QgsModelViewMouseEvent *event )
34 {
35 if ( event->button() != Qt::LeftButton )
36 {
37 event->ignore();
38 return;
39 }
40
41 mMousePressStartPos = event->pos();
42 if ( event->modifiers() & Qt::AltModifier )
43 {
44 //zoom out action, so zoom out and recenter on clicked point
45 const double scaleFactor = 2;
46 //get current visible part of scene
47 const QRect viewportRect( 0, 0, view()->viewport()->width(), view()->viewport()->height() );
48 QgsRectangle visibleRect = QgsRectangle( view()->mapToScene( viewportRect ).boundingRect() );
49
50 visibleRect.scale( scaleFactor, event->modelPoint().x(), event->modelPoint().y() );
51 const QRectF boundsRect = visibleRect.toRectF();
52
53 //zoom view to fit desired bounds
54 view()->fitInView( boundsRect, Qt::KeepAspectRatio );
55 }
56 else
57 {
58 //zoom in action
59 startMarqueeZoom( event->modelPoint() );
60 }
61 }
62
modelMoveEvent(QgsModelViewMouseEvent * event)63 void QgsModelViewToolZoom::modelMoveEvent( QgsModelViewMouseEvent *event )
64 {
65 if ( !mMarqueeZoom )
66 {
67 event->ignore();
68 return;
69 }
70
71 mRubberBand->update( event->modelPoint(), Qt::KeyboardModifiers() );
72 }
73
modelReleaseEvent(QgsModelViewMouseEvent * event)74 void QgsModelViewToolZoom::modelReleaseEvent( QgsModelViewMouseEvent *event )
75 {
76 if ( !mMarqueeZoom || event->button() != Qt::LeftButton )
77 {
78 event->ignore();
79 return;
80 }
81
82 mMarqueeZoom = false;
83 QRectF newBoundsRect = mRubberBand->finish( event->modelPoint() );
84
85 // click? or click-and-drag?
86 if ( !isClickAndDrag( mMousePressStartPos, event->pos() ) )
87 {
88 //just a click, so zoom to clicked point and recenter
89 const double scaleFactor = 0.5;
90 //get current visible part of scene
91 const QRect viewportRect( 0, 0, view()->viewport()->width(), view()->viewport()->height() );
92 QgsRectangle visibleRect = QgsRectangle( view()->mapToScene( viewportRect ).boundingRect() );
93
94 visibleRect.scale( scaleFactor, event->modelPoint().x(), event->modelPoint().y() );
95 newBoundsRect = visibleRect.toRectF();
96 }
97
98 //zoom view to fit desired bounds
99 view()->fitInView( newBoundsRect, Qt::KeepAspectRatio );
100 }
101
keyPressEvent(QKeyEvent * event)102 void QgsModelViewToolZoom::keyPressEvent( QKeyEvent *event )
103 {
104 //respond to changes in the alt key status and update cursor accordingly
105 if ( !event->isAutoRepeat() )
106 {
107
108 view()->viewport()->setCursor( ( event->modifiers() & Qt::AltModifier ) ?
109 QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomOut ) :
110 QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomIn ) );
111 }
112 event->ignore();
113 }
114
keyReleaseEvent(QKeyEvent * event)115 void QgsModelViewToolZoom::keyReleaseEvent( QKeyEvent *event )
116 {
117 //respond to changes in the alt key status and update cursor accordingly
118 if ( !event->isAutoRepeat() )
119 {
120
121 view()->viewport()->setCursor( ( event->modifiers() & Qt::AltModifier ) ?
122 QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomOut ) :
123 QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomIn ) );
124 }
125 event->ignore();
126 }
127
deactivate()128 void QgsModelViewToolZoom::deactivate()
129 {
130 if ( mMarqueeZoom )
131 {
132 mMarqueeZoom = false;
133 mRubberBand->finish();
134 }
135 QgsModelViewTool::deactivate();
136 }
137
startMarqueeZoom(QPointF scenePoint)138 void QgsModelViewToolZoom::startMarqueeZoom( QPointF scenePoint )
139 {
140 mMarqueeZoom = true;
141
142 mRubberBandStartPos = scenePoint;
143 mRubberBand->start( scenePoint, Qt::KeyboardModifiers() );
144 }
145