Handle tool changes mid press-release operation

Because it's possible for users to change the tool while a
press release operation is mid-way, e.g. by pressing a tool
shortcut key.
This commit is contained in:
Nyall Dawson 2017-07-05 06:59:54 +10:00
parent 3f66520828
commit a346736df2
10 changed files with 52 additions and 14 deletions

View File

@ -55,7 +55,7 @@ class QgsLayoutViewRubberBand
ending ``position`` (in layout coordinate space).
%End
virtual QRectF finish( QPointF position, Qt::KeyboardModifiers modifiers ) = 0;
virtual QRectF finish( QPointF position = QPointF(), Qt::KeyboardModifiers modifiers = 0 ) = 0;
%Docstring
Called when a rubber band use has finished and the rubber
band is no longer required.
@ -116,7 +116,7 @@ class QgsLayoutViewRectangularRubberBand : QgsLayoutViewRubberBand
virtual void update( QPointF position, Qt::KeyboardModifiers modifiers );
virtual QRectF finish( QPointF, Qt::KeyboardModifiers );
virtual QRectF finish( QPointF position = QPointF(), Qt::KeyboardModifiers modifiers = 0 );
};
@ -146,7 +146,7 @@ class QgsLayoutViewEllipticalRubberBand : QgsLayoutViewRubberBand
virtual void update( QPointF position, Qt::KeyboardModifiers modifiers );
virtual QRectF finish( QPointF, Qt::KeyboardModifiers );
virtual QRectF finish( QPointF position = QPointF(), Qt::KeyboardModifiers modifiers = 0 );
};

View File

@ -49,11 +49,19 @@ class QgsLayoutViewTool : QObject
virtual void layoutPressEvent( QgsLayoutViewMouseEvent *event );
%Docstring
Mouse press event for overriding. Default implementation does nothing.
Note that subclasses must ensure that they correctly handle cases
when a layoutPressEvent is called without a corresponding
layoutReleaseEvent (e.g. due to tool being changed mid way
through a press-release operation).
%End
virtual void layoutReleaseEvent( QgsLayoutViewMouseEvent *event );
%Docstring
Mouse release event for overriding. Default implementation does nothing.
Note that subclasses must ensure that they correctly handle cases
when a layoutPressEvent is called without a corresponding
layoutReleaseEvent (e.g. due to tool being changed mid way
through a press-release operation).
%End
virtual void wheelEvent( QWheelEvent *event );

View File

@ -41,6 +41,8 @@ class QgsLayoutViewToolAddItem : QgsLayoutViewTool
virtual void layoutReleaseEvent( QgsLayoutViewMouseEvent *event );
virtual void deactivate();
};

View File

@ -31,6 +31,8 @@ class QgsLayoutViewToolPan : QgsLayoutViewTool
virtual void layoutReleaseEvent( QgsLayoutViewMouseEvent *event );
virtual void deactivate();
};

View File

@ -75,7 +75,7 @@ class GUI_EXPORT QgsLayoutViewRubberBand
* band is no longer required.
* Returns the final bounding box of the rubber band.
*/
virtual QRectF finish( QPointF position, Qt::KeyboardModifiers modifiers ) = 0;
virtual QRectF finish( QPointF position = QPointF(), Qt::KeyboardModifiers modifiers = 0 ) = 0;
/**
* Returns the view associated with the rubber band.
@ -125,7 +125,7 @@ class GUI_EXPORT QgsLayoutViewRectangularRubberBand : public QgsLayoutViewRubber
void start( QPointF position, Qt::KeyboardModifiers modifiers ) override;
void update( QPointF position, Qt::KeyboardModifiers modifiers ) override;
QRectF finish( QPointF, Qt::KeyboardModifiers ) override;
QRectF finish( QPointF position = QPointF(), Qt::KeyboardModifiers modifiers = 0 ) override;
private:
@ -156,7 +156,7 @@ class GUI_EXPORT QgsLayoutViewEllipticalRubberBand : public QgsLayoutViewRubberB
void start( QPointF position, Qt::KeyboardModifiers modifiers ) override;
void update( QPointF position, Qt::KeyboardModifiers modifiers ) override;
QRectF finish( QPointF, Qt::KeyboardModifiers ) override;
QRectF finish( QPointF position = QPointF(), Qt::KeyboardModifiers modifiers = 0 ) override;
private:

View File

@ -72,11 +72,19 @@ class GUI_EXPORT QgsLayoutViewTool : public QObject
/**
* Mouse press event for overriding. Default implementation does nothing.
* Note that subclasses must ensure that they correctly handle cases
* when a layoutPressEvent is called without a corresponding
* layoutReleaseEvent (e.g. due to tool being changed mid way
* through a press-release operation).
*/
virtual void layoutPressEvent( QgsLayoutViewMouseEvent *event );
/**
* Mouse release event for overriding. Default implementation does nothing.
* Note that subclasses must ensure that they correctly handle cases
* when a layoutPressEvent is called without a corresponding
* layoutReleaseEvent (e.g. due to tool being changed mid way
* through a press-release operation).
*/
virtual void layoutReleaseEvent( QgsLayoutViewMouseEvent *event );

View File

@ -46,6 +46,7 @@ void QgsLayoutViewToolAddItem::layoutPressEvent( QgsLayoutViewMouseEvent *event
return;
}
mDrawing = true;
mMousePressStartPos = event->pos();
mRubberBand.reset( QgsApplication::layoutItemRegistry()->createItemRubberBand( mItemType, view() ) );
if ( mRubberBand )
@ -56,7 +57,7 @@ void QgsLayoutViewToolAddItem::layoutPressEvent( QgsLayoutViewMouseEvent *event
void QgsLayoutViewToolAddItem::layoutMoveEvent( QgsLayoutViewMouseEvent *event )
{
if ( mRubberBand )
if ( mDrawing && mRubberBand )
{
mRubberBand->update( event->layoutPoint(), event->modifiers() );
}
@ -64,17 +65,13 @@ void QgsLayoutViewToolAddItem::layoutMoveEvent( QgsLayoutViewMouseEvent *event )
void QgsLayoutViewToolAddItem::layoutReleaseEvent( QgsLayoutViewMouseEvent *event )
{
if ( event->button() != Qt::LeftButton )
if ( event->button() != Qt::LeftButton || !mDrawing )
{
return;
}
mDrawing = false;
QRectF rect = QRectF( view()->mapToScene( mMousePressStartPos ),
event->layoutPoint() );
if ( mRubberBand )
{
rect = mRubberBand->finish( event->layoutPoint(), event->modifiers() );
}
QRectF rect = mRubberBand->finish( event->layoutPoint(), event->modifiers() );
// click? or click-and-drag?
QPoint mousePressStopPoint = event->pos();
@ -92,6 +89,17 @@ void QgsLayoutViewToolAddItem::layoutReleaseEvent( QgsLayoutViewMouseEvent *even
layout()->addItem( item );
}
void QgsLayoutViewToolAddItem::deactivate()
{
if ( mDrawing )
{
// canceled mid operation
mRubberBand->finish();
mDrawing = false;
}
QgsLayoutViewTool::deactivate();
}
int QgsLayoutViewToolAddItem::itemType() const
{
return mItemType;

View File

@ -51,9 +51,12 @@ class GUI_EXPORT QgsLayoutViewToolAddItem : public QgsLayoutViewTool
void layoutPressEvent( QgsLayoutViewMouseEvent *event ) override;
void layoutMoveEvent( QgsLayoutViewMouseEvent *event ) override;
void layoutReleaseEvent( QgsLayoutViewMouseEvent *event ) override;
void deactivate() override;
private:
bool mDrawing = false;
int mItemType = 0;
//! Rubber band item

View File

@ -56,3 +56,9 @@ void QgsLayoutViewToolPan::layoutReleaseEvent( QgsLayoutViewMouseEvent *event )
mIsPanning = false;
view()->setCursor( Qt::OpenHandCursor );
}
void QgsLayoutViewToolPan::deactivate()
{
mIsPanning = false;
QgsLayoutViewTool::deactivate();
}

View File

@ -42,6 +42,7 @@ class GUI_EXPORT QgsLayoutViewToolPan : public QgsLayoutViewTool
void layoutPressEvent( QgsLayoutViewMouseEvent *event ) override;
void layoutMoveEvent( QgsLayoutViewMouseEvent *event ) override;
void layoutReleaseEvent( QgsLayoutViewMouseEvent *event ) override;
void deactivate() override;
private: