Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Implement an ugly workaround due to QGraphicsScene lack of event
propagation
  • Loading branch information
nyalldawson committed Mar 12, 2020
1 parent 86b7363 commit a82bd1d
Show file tree
Hide file tree
Showing 7 changed files with 203 additions and 10 deletions.
Expand Up @@ -48,6 +48,7 @@ for the button. The button will be rendered at the specified ``position`` and ``
virtual void mousePressEvent( QGraphicsSceneMouseEvent *event );



void setPosition( const QPointF &position );
%Docstring
Sets the button's ``position``.
Expand Down
44 changes: 34 additions & 10 deletions src/gui/processing/models/qgsmodelcomponentgraphicitem.cpp
Expand Up @@ -24,6 +24,7 @@
#include "qgsprocessingmodelalgorithm.h"
#include "qgsmodelgraphicsview.h"
#include "qgsmodelviewtool.h"
#include "qgsmodelviewmouseevent.h"

#include <QSvgRenderer>
#include <QPicture>
Expand Down Expand Up @@ -155,6 +156,38 @@ void QgsModelComponentGraphicItem::previewItemRectChange( QRectF rect )
emit updateArrowPaths();
}

void QgsModelComponentGraphicItem::modelHoverEnterEvent( QgsModelViewMouseEvent *event )
{
if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
updateToolTip( mapFromScene( event->modelPoint() ) );
}

void QgsModelComponentGraphicItem::modelHoverMoveEvent( QgsModelViewMouseEvent *event )
{
if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
updateToolTip( mapFromScene( event->modelPoint() ) );
}

void QgsModelComponentGraphicItem::modelHoverLeaveEvent( QgsModelViewMouseEvent * )
{
if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
{
setToolTip( QString() );
if ( mIsHovering )
{
mIsHovering = false;
update();
emit repaintArrows();
}
}
}

void QgsModelComponentGraphicItem::modelDoubleClickEvent( QgsModelViewMouseEvent * )
{
if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
editComponent();
}

void QgsModelComponentGraphicItem::mouseDoubleClickEvent( QGraphicsSceneMouseEvent * )
{
if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
Expand All @@ -175,16 +208,7 @@ void QgsModelComponentGraphicItem::hoverMoveEvent( QGraphicsSceneHoverEvent *eve

void QgsModelComponentGraphicItem::hoverLeaveEvent( QGraphicsSceneHoverEvent * )
{
if ( view() && view()->tool() && view()->tool()->allowItemInteraction() )
{
setToolTip( QString() );
if ( mIsHovering )
{
mIsHovering = false;
update();
emit repaintArrows();
}
}
modelHoverLeaveEvent( nullptr );
}

QVariant QgsModelComponentGraphicItem::itemChange( QGraphicsItem::GraphicsItemChange change, const QVariant &value )
Expand Down
23 changes: 23 additions & 0 deletions src/gui/processing/models/qgsmodelcomponentgraphicitem.h
Expand Up @@ -32,6 +32,7 @@ class QgsProcessingModelAlgorithm;
class QgsModelDesignerFlatButtonGraphicItem;
class QgsModelDesignerFoldButtonGraphicItem;
class QgsModelGraphicsView;
class QgsModelViewMouseEvent;

///@cond NOT_STABLE

Expand Down Expand Up @@ -134,6 +135,28 @@ class GUI_EXPORT QgsModelComponentGraphicItem : public QGraphicsObject
*/
void previewItemRectChange( QRectF rect );

#ifndef SIP_RUN

/**
* Handles a model hover enter \a event.
*/
virtual void modelHoverEnterEvent( QgsModelViewMouseEvent *event );

/**
* Handles a model hover move \a event.
*/
virtual void modelHoverMoveEvent( QgsModelViewMouseEvent *event );

/**
* Handles a model hover leave \a event.
*/
virtual void modelHoverLeaveEvent( QgsModelViewMouseEvent *event );

/**
* Handles a model double click \a event.
*/
virtual void modelDoubleClickEvent( QgsModelViewMouseEvent *event );
#endif
void mouseDoubleClickEvent( QGraphicsSceneMouseEvent *event ) override;
void hoverEnterEvent( QGraphicsSceneHoverEvent *event ) override;
void hoverMoveEvent( QGraphicsSceneHoverEvent *event ) override;
Expand Down
34 changes: 34 additions & 0 deletions src/gui/processing/models/qgsmodelgraphicitem.cpp
Expand Up @@ -18,6 +18,7 @@
#include "qgsmodelgraphicsscene.h"
#include "qgsmodelgraphicsview.h"
#include "qgsmodelviewtool.h"
#include "qgsmodelviewmouseevent.h"
#include <QPainter>
#include <QSvgRenderer>

Expand Down Expand Up @@ -89,6 +90,31 @@ void QgsModelDesignerFlatButtonGraphicItem::mousePressEvent( QGraphicsSceneMouse
emit clicked();
}

void QgsModelDesignerFlatButtonGraphicItem::modelHoverEnterEvent( QgsModelViewMouseEvent * )
{
if ( view()->tool() && !view()->tool()->allowItemInteraction() )
mHoverState = false;
else
mHoverState = true;
update();
}

void QgsModelDesignerFlatButtonGraphicItem::modelHoverLeaveEvent( QgsModelViewMouseEvent * )
{
mHoverState = false;
update();
}

void QgsModelDesignerFlatButtonGraphicItem::modelPressEvent( QgsModelViewMouseEvent *event )
{
if ( view()->tool() && view()->tool()->allowItemInteraction() && event->button() == Qt::LeftButton )
{
QMetaObject::invokeMethod( this, &QgsModelDesignerFlatButtonGraphicItem::clicked, Qt::QueuedConnection );
mHoverState = false;
update();
}
}

void QgsModelDesignerFlatButtonGraphicItem::setPosition( const QPointF &position )
{
mPosition = position;
Expand Down Expand Up @@ -136,5 +162,13 @@ void QgsModelDesignerFoldButtonGraphicItem::mousePressEvent( QGraphicsSceneMouse
QgsModelDesignerFlatButtonGraphicItem::mousePressEvent( event );
}

void QgsModelDesignerFoldButtonGraphicItem::modelPressEvent( QgsModelViewMouseEvent *event )
{
mFolded = !mFolded;
setPicture( mFolded ? mPlusPicture : mMinusPicture );
emit folded( mFolded );
QgsModelDesignerFlatButtonGraphicItem::modelPressEvent( event );
}

///@endcond

22 changes: 22 additions & 0 deletions src/gui/processing/models/qgsmodelgraphicitem.h
Expand Up @@ -22,6 +22,7 @@
#include <QPicture>

class QgsModelGraphicsView;
class QgsModelViewMouseEvent;

///@cond NOT_STABLE

Expand Down Expand Up @@ -52,6 +53,24 @@ class GUI_EXPORT QgsModelDesignerFlatButtonGraphicItem : public QGraphicsObject
void hoverLeaveEvent( QGraphicsSceneHoverEvent *event ) override;
void mousePressEvent( QGraphicsSceneMouseEvent *event ) override;

#ifndef SIP_RUN

/**
* Handles a model hover enter \a event.
*/
virtual void modelHoverEnterEvent( QgsModelViewMouseEvent *event );

/**
* Handles a model hover leave \a event.
*/
virtual void modelHoverLeaveEvent( QgsModelViewMouseEvent *event );

/**
* Handles a model mouse press \a event.
*/
virtual void modelPressEvent( QgsModelViewMouseEvent *event );
#endif

/**
* Sets the button's \a position.
*/
Expand Down Expand Up @@ -108,6 +127,9 @@ class GUI_EXPORT QgsModelDesignerFoldButtonGraphicItem : public QgsModelDesigner
const QSizeF &size = QSizeF( 11, 11 ) );

void mousePressEvent( QGraphicsSceneMouseEvent *event ) override;
#ifndef SIP_RUN
void modelPressEvent( QgsModelViewMouseEvent *event ) override;
#endif

signals:

Expand Down
86 changes: 86 additions & 0 deletions src/gui/processing/models/qgsmodelviewtoolselect.cpp
Expand Up @@ -20,6 +20,7 @@
#include "qgsmodelgraphicsscene.h"
#include "qgsmodelcomponentgraphicitem.h"
#include "qgsmodelviewmousehandles.h"
#include "qgsmodelgraphicitem.h"

QgsModelViewToolSelect::QgsModelViewToolSelect( QgsModelGraphicsView *view )
: QgsModelViewTool( view, tr( "Select" ) )
Expand Down Expand Up @@ -117,6 +118,26 @@ void QgsModelViewToolSelect::modelPressEvent( QgsModelViewMouseEvent *event )
}
event->ignore();
emit itemFocused( selectedItem );

if ( !( event->modifiers() & Qt::ShiftModifier ) )
{
// we need to manually pass this event down to items we want it to go to -- QGraphicsScene doesn't propagate events
// to multiple items
QList< QGraphicsItem * > items = scene()->items( event->modelPoint() );
for ( QGraphicsItem *item : items )
{
if ( QgsModelDesignerFlatButtonGraphicItem *button = dynamic_cast< QgsModelDesignerFlatButtonGraphicItem * >( item ) )
{
// arghhh - if the event happens outside the mouse handles bounding rect, then it's ALREADY passed on!
if ( mMouseHandles->sceneBoundingRect().contains( event->modelPoint() ) )
{
button->modelPressEvent( event );
event->accept();
return;
}
}
}
}
}

event->ignore();
Expand All @@ -130,10 +151,75 @@ void QgsModelViewToolSelect::modelMoveEvent( QgsModelViewMouseEvent *event )
}
else
{
// we need to manually pass this event down to items we want it to go to -- QGraphicsScene doesn't propagate events
// to multiple items
QList< QGraphicsItem * > items = scene()->items( event->modelPoint() );
for ( QGraphicsItem *item : items )
{
if ( mHoverEnteredItems.contains( item ) )
{
if ( QgsModelComponentGraphicItem *component = dynamic_cast< QgsModelComponentGraphicItem * >( item ) )
{
component->modelHoverMoveEvent( event );
}
}
else
{
mHoverEnteredItems.append( item );
if ( QgsModelComponentGraphicItem *component = dynamic_cast< QgsModelComponentGraphicItem * >( item ) )
{
component->modelHoverEnterEvent( event );
}
else if ( QgsModelDesignerFlatButtonGraphicItem *button = dynamic_cast<QgsModelDesignerFlatButtonGraphicItem *>( item ) )
{
// arghhh - if the event happens outside the mouse handles bounding rect, then it's ALREADY passed on!
if ( mMouseHandles->sceneBoundingRect().contains( event->modelPoint() ) )
button->modelHoverEnterEvent( event );
}
}
}
const QList< QGraphicsItem * > prevHovered = mHoverEnteredItems;
for ( QGraphicsItem *item : prevHovered )
{
if ( ! items.contains( item ) )
{
mHoverEnteredItems.removeAll( item );
if ( QgsModelComponentGraphicItem *component = dynamic_cast< QgsModelComponentGraphicItem * >( item ) )
{
component->modelHoverLeaveEvent( event );
}
else if ( QgsModelDesignerFlatButtonGraphicItem *button = dynamic_cast<QgsModelDesignerFlatButtonGraphicItem *>( item ) )
{
// arghhh - if the event happens outside the mouse handles bounding rect, then it's ALREADY passed on!
if ( mMouseHandles->sceneBoundingRect().contains( event->modelPoint() ) )
button->modelHoverLeaveEvent( event );
}
}
}

event->ignore();
}
}

void QgsModelViewToolSelect::modelDoubleClickEvent( QgsModelViewMouseEvent *event )
{
if ( !mIsSelecting )
{
// we need to manually pass this event down to items we want it to go to -- QGraphicsScene doesn't propagate events
// to multiple items
QList< QGraphicsItem * > items = scene()->items( event->modelPoint() );
for ( QGraphicsItem *item : items )
{
if ( QgsModelComponentGraphicItem *component = dynamic_cast< QgsModelComponentGraphicItem * >( item ) )
{
scene()->setSelectedItem( component ); // clears existing selection
component->modelDoubleClickEvent( event );
break;
}
}
}
}

void QgsModelViewToolSelect::modelReleaseEvent( QgsModelViewMouseEvent *event )
{
if ( event->button() != Qt::LeftButton && mMouseHandles->shouldBlockEvent( event ) )
Expand Down
3 changes: 3 additions & 0 deletions src/gui/processing/models/qgsmodelviewtoolselect.h
Expand Up @@ -24,6 +24,7 @@
#include <memory>

class QgsModelViewMouseHandles;
class QGraphicsItem;

#define SIP_NO_FILE

Expand All @@ -47,6 +48,7 @@ class GUI_EXPORT QgsModelViewToolSelect : public QgsModelViewTool

void modelPressEvent( QgsModelViewMouseEvent *event ) override;
void modelMoveEvent( QgsModelViewMouseEvent *event ) override;
void modelDoubleClickEvent( QgsModelViewMouseEvent *event ) override;
void modelReleaseEvent( QgsModelViewMouseEvent *event ) override;
void wheelEvent( QWheelEvent *event ) override;
void keyPressEvent( QKeyEvent *event ) override;
Expand Down Expand Up @@ -75,6 +77,7 @@ class GUI_EXPORT QgsModelViewToolSelect : public QgsModelViewTool
QPointF mRubberBandStartPos;

QPointer< QgsModelViewMouseHandles > mMouseHandles; //owned by scene
QList< QGraphicsItem * > mHoverEnteredItems;
};

#endif // QGSMODELVIEWTOOLSELECT_H

0 comments on commit a82bd1d

Please sign in to comment.