Skip to content
Permalink
Browse files

[composer] Fix ctrl modifier not applying to wheel events when in mov…

…e item

content mode, add missing undo merge command for item zoom (refs #7974)
  • Loading branch information
nyalldawson committed Sep 29, 2014
1 parent 583151a commit 8725c2df4b78fd658b9d9cc2efc103a1adb61ce8
@@ -133,6 +133,16 @@ class QgsComposerItem : QgsComposerObject, QGraphicsRectItem
LowerRight
};

/** Modes for zooming item content
*/
enum ZoomMode
{
Zoom = 0, /*< Zoom to center of content */
ZoomRecenter, /*< Zoom and recenter content to point */
ZoomToPoint, /*< Zoom while maintaining relative position of point */
NoZoom /*< No zoom */
};

/**Constructor
@param composition parent composition
@param manageZValue true if the z-Value of this object should be managed by mComposition*/
@@ -183,10 +193,20 @@ class QgsComposerItem : QgsComposerObject, QGraphicsRectItem
virtual void moveContent( double dx, double dy );

/**Zoom content of item. Does nothing per default (but implemented in composer map)
@param delta value from wheel event that describes magnitude and direction (positive /negative number)
@param x x-position of mouse cursor (in item coordinates)
@param y y-position of mouse cursor (in item coordinates)*/
virtual void zoomContent( int delta, double x, double y );
* @param delta value from wheel event that describes direction (positive /negative number)
* @param x x-position of mouse cursor (in item coordinates)
* @param y y-position of mouse cursor (in item coordinates)
* @deprecated use zoomContent( double, QPointF, ZoomMode ) instead
*/
virtual void zoomContent( int delta, double x, double y ) /Deprecated/;

/**Zoom content of item. Does nothing per default (but implemented in composer map)
* @param factor zoom factor, where > 1 results in a zoom in and < 1 results in a zoom out
* @param point item point for zoom center
* @param mode zoom mode
* @note added in QGIS 2.5
*/
virtual void zoomContent( const double factor, const QPointF point, const ZoomMode mode = QgsComposerItem::Zoom );

/**Gets the page the item is currently on.
* @returns page number for item
@@ -130,10 +130,20 @@ class QgsComposerMap : QgsComposerItem
void moveContent( double dx, double dy );

/**Zoom content of map
@param delta value from wheel event that describes magnitude and direction (positive /negative number)
@param x x-coordinate of mouse position in item coordinates
@param y y-coordinate of mouse position in item coordinates*/
void zoomContent( int delta, double x, double y );
* @param delta value from wheel event that describes direction (positive /negative number)
* @param x x-position of mouse cursor (in item coordinates)
* @param y y-position of mouse cursor (in item coordinates)
* @deprecated use zoomContent( double, QPointF, ZoomMode ) instead
*/
void zoomContent( int delta, double x, double y ) /Deprecated/;

/**Zoom content of item. Does nothing per default (but implemented in composer map)
* @param factor zoom factor, where > 1 results in a zoom in and < 1 results in a zoom out
* @param point item point for zoom center
* @param mode zoom mode
* @note added in QGIS 2.5
*/
virtual void zoomContent( const double factor, const QPointF point, const ZoomMode mode = QgsComposerItem::Zoom );

/**Sets new scene rectangle bounds and recalculates hight and extent*/
void setSceneRect( const QRectF& rectangle );
@@ -89,6 +89,18 @@ class CORE_EXPORT QgsComposerItem: public QgsComposerObject, public QGraphicsRec
LowerRight
};

//note - must sync with QgsMapCanvas::WheelAction.
//TODO - QGIS 3.0 move QgsMapCanvas::WheelAction from GUI->CORE and remove this enum
/** Modes for zooming item content
*/
enum ZoomMode
{
Zoom = 0, /*< Zoom to center of content */
ZoomRecenter, /*< Zoom and recenter content to point */
ZoomToPoint, /*< Zoom while maintaining relative position of point */
NoZoom /*< No zoom */
};

/**Constructor
@param composition parent composition
@param manageZValue true if the z-Value of this object should be managed by mComposition*/
@@ -139,10 +151,20 @@ class CORE_EXPORT QgsComposerItem: public QgsComposerObject, public QGraphicsRec
virtual void moveContent( double dx, double dy ) { Q_UNUSED( dx ); Q_UNUSED( dy ); }

/**Zoom content of item. Does nothing per default (but implemented in composer map)
@param delta value from wheel event that describes magnitude and direction (positive /negative number)
@param x x-position of mouse cursor (in item coordinates)
@param y y-position of mouse cursor (in item coordinates)*/
virtual void zoomContent( int delta, double x, double y ) { Q_UNUSED( delta ); Q_UNUSED( x ); Q_UNUSED( y ); }
* @param delta value from wheel event that describes direction (positive /negative number)
* @param x x-position of mouse cursor (in item coordinates)
* @param y y-position of mouse cursor (in item coordinates)
* @deprecated use zoomContent( double, QPointF, ZoomMode ) instead
*/
Q_DECL_DEPRECATED virtual void zoomContent( int delta, double x, double y ) { Q_UNUSED( delta ); Q_UNUSED( x ); Q_UNUSED( y ); }

/**Zoom content of item. Does nothing per default (but implemented in composer map)
* @param factor zoom factor, where > 1 results in a zoom in and < 1 results in a zoom out
* @param point item point for zoom center
* @param mode zoom mode
* @note added in QGIS 2.5
*/
virtual void zoomContent( const double factor, const QPointF point, const ZoomMode mode = QgsComposerItem::Zoom ) { Q_UNUSED( factor ); Q_UNUSED( point ); Q_UNUSED( mode ); }

/**Gets the page the item is currently on.
* @returns page number for item
@@ -119,7 +119,8 @@ class CORE_EXPORT QgsComposerMergeCommand: public QgsComposerItemCommand
ItemOutlineWidth,
ItemMove,
ItemRotation,
ItemTransparency
ItemTransparency,
ItemZoomContent
};

QgsComposerMergeCommand( Context c, QgsComposerItem* item, const QString& text );
@@ -605,55 +605,63 @@ void QgsComposerMap::moveContent( double dx, double dy )

void QgsComposerMap::zoomContent( int delta, double x, double y )
{
if ( mDrawing )
QSettings settings;

//read zoom mode
QgsComposerItem::ZoomMode zoomMode = ( QgsComposerItem::ZoomMode )settings.value( "/qgis/wheel_action", 2 ).toInt();
if ( zoomMode == QgsComposerItem::NoZoom )
{
//do nothing
return;
}

QSettings settings;
double zoomFactor = settings.value( "/qgis/zoom_factor", 2.0 ).toDouble();
zoomFactor = delta > 0 ? zoomFactor : 1 / zoomFactor;

//read zoom mode
//0: zoom, 1: zoom and recenter, 2: zoom to cursor, 3: nothing
int zoomMode = settings.value( "/qgis/wheel_action", 2 ).toInt();
if ( zoomMode == 3 ) //do nothing
zoomContent( zoomFactor, QPointF( x, y ), zoomMode );
}

void QgsComposerMap::zoomContent( const double factor, const QPointF point, const ZoomMode mode )
{
if ( mDrawing )
{
return;
}

double zoomFactor = settings.value( "/qgis/zoom_factor", 2.0 ).toDouble();
if ( mode == QgsComposerItem::NoZoom )
{
//do nothing
return;
}

//find out map coordinates of position
double mapX = currentMapExtent()->xMinimum() + ( point.x() / rect().width() ) * ( currentMapExtent()->xMaximum() - currentMapExtent()->xMinimum() );
double mapY = currentMapExtent()->yMinimum() + ( 1 - ( point.y() / rect().height() ) ) * ( currentMapExtent()->yMaximum() - currentMapExtent()->yMinimum() );

//find out new center point
double centerX = ( currentMapExtent()->xMaximum() + currentMapExtent()->xMinimum() ) / 2;
double centerY = ( currentMapExtent()->yMaximum() + currentMapExtent()->yMinimum() ) / 2;

if ( zoomMode != 0 )
if ( mode != QgsComposerItem::Zoom )
{
//find out map coordinates of mouse position
double mapMouseX = currentMapExtent()->xMinimum() + ( x / rect().width() ) * ( currentMapExtent()->xMaximum() - currentMapExtent()->xMinimum() );
double mapMouseY = currentMapExtent()->yMinimum() + ( 1 - ( y / rect().height() ) ) * ( currentMapExtent()->yMaximum() - currentMapExtent()->yMinimum() );
if ( zoomMode == 1 ) //zoom and recenter
if ( mode == QgsComposerItem::ZoomRecenter )
{
centerX = mapMouseX;
centerY = mapMouseY;
centerX = mapX;
centerY = mapY;
}
else if ( zoomMode == 2 ) //zoom to cursor
else if ( mode == QgsComposerItem::ZoomToPoint )
{
centerX = mapMouseX + ( centerX - mapMouseX ) * ( 1.0 / zoomFactor );
centerY = mapMouseY + ( centerY - mapMouseY ) * ( 1.0 / zoomFactor );
centerX = mapX + ( centerX - mapX ) * ( 1.0 / factor );
centerY = mapY + ( centerY - mapY ) * ( 1.0 / factor );
}
}

double newIntervalX, newIntervalY;

if ( delta > 0 )
{
newIntervalX = ( currentMapExtent()->xMaximum() - currentMapExtent()->xMinimum() ) / zoomFactor;
newIntervalY = ( currentMapExtent()->yMaximum() - currentMapExtent()->yMinimum() ) / zoomFactor;
}
else if ( delta < 0 )
if ( factor > 0 )
{
newIntervalX = ( currentMapExtent()->xMaximum() - currentMapExtent()->xMinimum() ) * zoomFactor;
newIntervalY = ( currentMapExtent()->yMaximum() - currentMapExtent()->yMinimum() ) * zoomFactor;
newIntervalX = ( currentMapExtent()->xMaximum() - currentMapExtent()->xMinimum() ) / factor;
newIntervalY = ( currentMapExtent()->yMaximum() - currentMapExtent()->yMinimum() ) / factor;
}
else //no need to zoom
{
@@ -170,10 +170,20 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
void moveContent( double dx, double dy );

/**Zoom content of map
@param delta value from wheel event that describes magnitude and direction (positive /negative number)
@param x x-coordinate of mouse position in item coordinates
@param y y-coordinate of mouse position in item coordinates*/
void zoomContent( int delta, double x, double y );
* @param delta value from wheel event that describes direction (positive /negative number)
* @param x x-position of mouse cursor (in item coordinates)
* @param y y-position of mouse cursor (in item coordinates)
* @deprecated use zoomContent( double, QPointF, ZoomMode ) instead
*/
Q_DECL_DEPRECATED void zoomContent( int delta, double x, double y );

/**Zoom content of item. Does nothing per default (but implemented in composer map)
* @param factor zoom factor, where > 1 results in a zoom in and < 1 results in a zoom out
* @param point item point for zoom center
* @param mode zoom mode
* @note added in QGIS 2.5
*/
virtual void zoomContent( const double factor, const QPointF point, const ZoomMode mode = QgsComposerItem::Zoom );

/**Sets new scene rectangle bounds and recalculates hight and extent*/
void setSceneRect( const QRectF& rectangle );
@@ -1558,9 +1558,26 @@ void QgsComposerView::wheelEvent( QWheelEvent* event )
{
if ( theItem->isSelected() )
{
QSettings settings;
//read zoom mode
QgsComposerItem::ZoomMode zoomMode = ( QgsComposerItem::ZoomMode )settings.value( "/qgis/wheel_action", 2 ).toInt();
if ( zoomMode == QgsComposerItem::NoZoom )
{
//do nothing
return;
}

double zoomFactor = settings.value( "/qgis/zoom_factor", 2.0 ).toDouble();
if ( event->modifiers() & Qt::ControlModifier )
{
//holding ctrl while wheel zooming results in a finer zoom
zoomFactor = 1.0 + ( zoomFactor - 1.0 ) / 20.0;
}
zoomFactor = event->delta() > 0 ? zoomFactor : 1 / zoomFactor;

QPointF itemPoint = theItem->mapFromScene( scenePoint );
theItem->beginCommand( tr( "Zoom item content" ) );
theItem->zoomContent( event->delta(), itemPoint.x(), itemPoint.y() );
theItem->beginCommand( tr( "Zoom item content" ), QgsComposerMergeCommand::ItemZoomContent );
theItem->zoomContent( zoomFactor, itemPoint, zoomMode );
theItem->endCommand();
}
}

0 comments on commit 8725c2d

Please sign in to comment.
You can’t perform that action at this time.