QGIS API Documentation  3.21.0-Master (909859188c)
qgsmodelviewtoolzoom.cpp
Go to the documentation of this file.
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 
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 
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 
64 {
65  if ( !mMarqueeZoom )
66  {
67  event->ignore();
68  return;
69  }
70 
71  mRubberBand->update( event->modelPoint(), Qt::KeyboardModifiers() );
72 }
73 
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 
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 
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 
129 {
130  if ( mMarqueeZoom )
131  {
132  mMarqueeZoom = false;
133  mRubberBand->finish();
134  }
136 }
137 
138 void QgsModelViewToolZoom::startMarqueeZoom( QPointF scenePoint )
139 {
140  mMarqueeZoom = true;
141 
142  mRubberBandStartPos = scenePoint;
143  mRubberBand->start( scenePoint, Qt::KeyboardModifiers() );
144 }
static QCursor getThemeCursor(Cursor cursor)
Helper to get a theme cursor.
A QgsModelViewMouseEvent is the result of a user interaction with the mouse on a QgsModelGraphicsView...
QPointF modelPoint() const
Returns the event point location in model coordinates.
QgsModelViewRectangularRubberBand is rectangular rubber band for use within QgsModelGraphicsView widg...
void deactivate() override
Called when tool is deactivated.
void keyReleaseEvent(QKeyEvent *event) override
Key release event for overriding.
void modelPressEvent(QgsModelViewMouseEvent *event) override
Mouse press event for overriding.
void keyPressEvent(QKeyEvent *event) override
Key press event for overriding.
bool mMarqueeZoom
Will be true will marquee zoom operation is in progress.
void modelReleaseEvent(QgsModelViewMouseEvent *event) override
Mouse release event for overriding.
QgsModelViewToolZoom(QgsModelGraphicsView *view)
Constructor for QgsModelViewToolZoom.
void modelMoveEvent(QgsModelViewMouseEvent *event) override
Mouse move event for overriding.
Abstract base class for all model designer view tools.
QgsModelGraphicsView * view() const
Returns the view associated with the tool.
bool isClickAndDrag(QPoint startViewPoint, QPoint endViewPoint) const
Returns true if a mouse press/release operation which started at startViewPoint and ended at endViewP...
void setCursor(const QCursor &cursor)
Sets a user defined cursor for use when the tool is active.
virtual void deactivate()
Called when tool is deactivated.
A rectangle specified with double values.
Definition: qgsrectangle.h:42
void scale(double scaleFactor, const QgsPointXY *c=nullptr)
Scale the rectangle around its center point.
Definition: qgsrectangle.h:256
QRectF toRectF() const
Returns a QRectF with same coordinates as the rectangle.
Definition: qgsrectangle.h:500