Skip to content

Commit

Permalink
Temporary rubberband
Browse files Browse the repository at this point in the history
  • Loading branch information
YoannQDQ committed Nov 22, 2024
1 parent 41aa984 commit 997fdd7
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ should be created. The default behavior is to create a rectangular rubber band.
.. seealso:: :py:func:`createNodeRubberBand`
%End

virtual QAbstractGraphicsShapeItem *createNodeRubberBand( QgsLayoutView *view ) /TransferBack/;
virtual QGraphicsItem *createNodeRubberBand( QgsLayoutView *view ) /TransferBack/;
%Docstring
Creates a rubber band for use when creating layout node based items of this type. Can return ``None`` if no rubber band
should be created. The default behavior is to return ``None``.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ should be created. The default behavior is to create a rectangular rubber band.
.. seealso:: :py:func:`createNodeRubberBand`
%End

virtual QAbstractGraphicsShapeItem *createNodeRubberBand( QgsLayoutView *view ) /TransferBack/;
virtual QGraphicsItem *createNodeRubberBand( QgsLayoutView *view ) /TransferBack/;
%Docstring
Creates a rubber band for use when creating layout node based items of this type. Can return ``None`` if no rubber band
should be created. The default behavior is to return ``None``.
Expand Down
36 changes: 26 additions & 10 deletions src/gui/layout/qgslayoutguiutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -372,10 +372,15 @@ void QgsLayoutGuiUtils::registerGuiForKnownItemTypes( QgsMapCanvas *mapCanvas )
arrow->setEndMarker( QgsLayoutItemPolyline::ArrowHead );
return arrow.release();
} );
arrowMetadata->setNodeRubberBandCreationFunction( []( QgsLayoutView * )->QGraphicsPathItem*
arrowMetadata->setNodeRubberBandCreationFunction( []( QgsLayoutView * )->QGraphicsItemGroup*
{
std::unique_ptr< QGraphicsPathItem > band = std::make_unique< QGraphicsPathItem >();
band->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0 ) );
std::unique_ptr< QGraphicsItemGroup > band = std::make_unique< QGraphicsItemGroup >();
QGraphicsPathItem *poly = new QGraphicsPathItem( band.get() );
poly->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0 ) );

QGraphicsPathItem *tempPoly = new QGraphicsPathItem( band.get() );
tempPoly->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0, Qt::DotLine ) );

band->setZValue( QgsLayout::ZViewTool );
return band.release();
} );
Expand All @@ -389,11 +394,17 @@ void QgsLayoutGuiUtils::registerGuiForKnownItemTypes( QgsMapCanvas *mapCanvas )
{
return new QgsLayoutPolygonWidget( qobject_cast< QgsLayoutItemPolygon * >( item ) );
}, createRubberBand, QStringLiteral( "nodes" ), true );
polygonMetadata->setNodeRubberBandCreationFunction( []( QgsLayoutView * )->QGraphicsPolygonItem*
polygonMetadata->setNodeRubberBandCreationFunction( []( QgsLayoutView * )->QGraphicsItemGroup*
{
std::unique_ptr< QGraphicsPolygonItem > band = std::make_unique< QGraphicsPolygonItem >();
band->setBrush( Qt::NoBrush );
band->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0 ) );
std::unique_ptr< QGraphicsItemGroup > band = std::make_unique< QGraphicsItemGroup >();
QGraphicsPolygonItem *poly = new QGraphicsPolygonItem( band.get() );
poly->setBrush( QBrush( QColor( 227, 22, 22, 20 ) ) );
poly->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0 ) );

QGraphicsPolygonItem *tempPoly = new QGraphicsPolygonItem( band.get() );
tempPoly->setBrush( Qt::NoBrush );
tempPoly->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0, Qt::DotLine ) );

band->setZValue( QgsLayout::ZViewTool );
return band.release();
} );
Expand All @@ -405,10 +416,15 @@ void QgsLayoutGuiUtils::registerGuiForKnownItemTypes( QgsMapCanvas *mapCanvas )
{
return new QgsLayoutPolylineWidget( qobject_cast< QgsLayoutItemPolyline * >( item ) );
}, createRubberBand, QStringLiteral( "nodes" ), true );
polylineMetadata->setNodeRubberBandCreationFunction( []( QgsLayoutView * )->QGraphicsPathItem*
polylineMetadata->setNodeRubberBandCreationFunction( []( QgsLayoutView * )->QGraphicsItemGroup*
{
std::unique_ptr< QGraphicsPathItem > band = std::make_unique< QGraphicsPathItem >();
band->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0 ) );
std::unique_ptr< QGraphicsItemGroup > band = std::make_unique< QGraphicsItemGroup >();
QGraphicsPathItem *poly = new QGraphicsPathItem( band.get() );
poly->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0 ) );

QGraphicsPathItem *tempPoly = new QGraphicsPathItem( band.get() );
tempPoly->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0, Qt::DotLine ) );

band->setZValue( QgsLayout::ZViewTool );
return band.release();
} );
Expand Down
4 changes: 2 additions & 2 deletions src/gui/layout/qgslayoutitemguiregistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ QgsLayoutViewRubberBand *QgsLayoutItemAbstractGuiMetadata::createRubberBand( Qgs
return new QgsLayoutViewRectangularRubberBand( view );
}

QAbstractGraphicsShapeItem *QgsLayoutItemAbstractGuiMetadata::createNodeRubberBand( QgsLayoutView * )
QGraphicsItem *QgsLayoutItemAbstractGuiMetadata::createNodeRubberBand( QgsLayoutView * )
{
return nullptr;
}
Expand Down Expand Up @@ -150,7 +150,7 @@ QgsLayoutViewRubberBand *QgsLayoutItemGuiRegistry::createItemRubberBand( int met
return mMetadata[metadataId]->createRubberBand( view );
}

QAbstractGraphicsShapeItem *QgsLayoutItemGuiRegistry::createNodeItemRubberBand( int metadataId, QgsLayoutView *view )
QGraphicsItem *QgsLayoutItemGuiRegistry::createNodeItemRubberBand( int metadataId, QgsLayoutView *view )
{
if ( !mMetadata.contains( metadataId ) )
return nullptr;
Expand Down
8 changes: 4 additions & 4 deletions src/gui/layout/qgslayoutitemguiregistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ class GUI_EXPORT QgsLayoutItemAbstractGuiMetadata
* should be created. The default behavior is to return NULLPTR.
* \see createRubberBand()
*/
virtual QAbstractGraphicsShapeItem *createNodeRubberBand( QgsLayoutView *view ) SIP_TRANSFERBACK;
virtual QGraphicsItem *createNodeRubberBand( QgsLayoutView *view ) SIP_TRANSFERBACK;

/**
* Creates an instance of the corresponding item type.
Expand Down Expand Up @@ -166,7 +166,7 @@ typedef std::function<QgsLayoutItemBaseWidget *( QgsLayoutItem * )> QgsLayoutIte
typedef std::function<QgsLayoutViewRubberBand *( QgsLayoutView * )> QgsLayoutItemRubberBandFunc SIP_SKIP;

//! Layout node based rubber band creation function
typedef std::function<QAbstractGraphicsShapeItem *( QgsLayoutView * )> QgsLayoutNodeItemRubberBandFunc SIP_SKIP;
typedef std::function<QGraphicsItem *( QgsLayoutView * )> QgsLayoutNodeItemRubberBandFunc SIP_SKIP;

//! Layout item added to layout callback
typedef std::function<void ( QgsLayoutItem *, const QVariantMap & )> QgsLayoutItemAddedToLayoutFunc SIP_SKIP;
Expand Down Expand Up @@ -269,7 +269,7 @@ class GUI_EXPORT QgsLayoutItemGuiMetadata : public QgsLayoutItemAbstractGuiMetad
QIcon creationIcon() const override { return mIcon.isNull() ? QgsLayoutItemAbstractGuiMetadata::creationIcon() : mIcon; }
QgsLayoutItemBaseWidget *createItemWidget( QgsLayoutItem *item ) override { return mWidgetFunc ? mWidgetFunc( item ) : nullptr; }
QgsLayoutViewRubberBand *createRubberBand( QgsLayoutView *view ) override { return mRubberBandFunc ? mRubberBandFunc( view ) : nullptr; }
QAbstractGraphicsShapeItem *createNodeRubberBand( QgsLayoutView *view ) override { return mNodeRubberBandFunc ? mNodeRubberBandFunc( view ) : nullptr; }
QGraphicsItem *createNodeRubberBand( QgsLayoutView *view ) override { return mNodeRubberBandFunc ? mNodeRubberBandFunc( view ) : nullptr; }

QgsLayoutItem *createItem( QgsLayout *layout ) override;
void newItemAddedToLayout( QgsLayoutItem *item ) override;
Expand Down Expand Up @@ -476,7 +476,7 @@ class GUI_EXPORT QgsLayoutItemGuiRegistry : public QObject
* \see createItemRubberBand()
* \note not available from Python bindings
*/
QAbstractGraphicsShapeItem *createNodeItemRubberBand( int metadataId, QgsLayoutView *view ) SIP_SKIP;
QGraphicsItem *createNodeItemRubberBand( int metadataId, QgsLayoutView *view ) SIP_SKIP;

/**
* Returns a list of available item metadata ids handled by the registry.
Expand Down
59 changes: 52 additions & 7 deletions src/gui/layout/qgslayoutviewtooladdnodeitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,16 +192,61 @@ void QgsLayoutViewToolAddNodeItem::moveTemporaryNode( QPointF scenePoint, Qt::Ke

void QgsLayoutViewToolAddNodeItem::setRubberBandNodes()
{
if ( QGraphicsPolygonItem *polygonItem = dynamic_cast< QGraphicsPolygonItem *>( mRubberBand.get() ) )
QList<QGraphicsItem *> items = mRubberBand->childItems();
if ( items.isEmpty() )
return;

if ( QGraphicsPolygonItem *polygonItem = dynamic_cast< QGraphicsPolygonItem *>( items[0] ) )
{
polygonItem->setPolygon( mPolygon );
// The group contains two polygons
if ( items.size() == 2 && dynamic_cast< QGraphicsPolygonItem *>( items[1] ) != nullptr )
{
if ( mPolygon.size() > 3 )
{
polygonItem->setPolygon( QPolygonF( mPolygon.mid( 0, mPolygon.size() - 1 ) ) );
}
else
{
polygonItem->setPolygon( QPolygonF() );
}
dynamic_cast< QGraphicsPolygonItem *>( items[1] )->setPolygon( mPolygon );
}
// The group contains a single QGraphicsPolygonItem as rubberband
else
{
polygonItem->setPolygon( mPolygon );
}
}
else if ( QGraphicsPathItem *polylineItem = dynamic_cast< QGraphicsPathItem *>( mRubberBand.get() ) )
else if ( QGraphicsPathItem *polylineItem = dynamic_cast< QGraphicsPathItem *>( items[0] ) )
{
// rebuild a new qpainter path
QPainterPath path;
path.addPolygon( mPolygon );
polylineItem->setPath( path );
// The group contains two polylines
if ( items.size() == 2 && dynamic_cast< QGraphicsPathItem *>( items[1] ) != nullptr )
{
if ( mPolygon.size() > 2 )
{
QPainterPath path;
path.addPolygon( QPolygonF( mPolygon.mid( 0, mPolygon.size() - 1 ) ) );
polylineItem->setPath( path );
}
else
{
polylineItem->setPath( QPainterPath() );
}
if ( mPolygon.size() > 1 )
{
QPainterPath path;
path.addPolygon( mPolygon.mid( mPolygon.size() - 2 ) );
dynamic_cast< QGraphicsPathItem *>( items[1] )->setPath( path );
}
}
// The group contains a single QGraphicsPathItem as rubberband
else
{
// rebuild a new qpainter path
QPainterPath path;
path.addPolygon( mPolygon );
polylineItem->setPath( path );
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/gui/layout/qgslayoutviewtooladdnodeitem.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class GUI_EXPORT QgsLayoutViewToolAddNodeItem : public QgsLayoutViewTool
int mItemMetadataId = -1;

//! Rubber band item
std::unique_ptr< QAbstractGraphicsShapeItem > mRubberBand;
std::unique_ptr< QGraphicsItem > mRubberBand;

QPolygonF mPolygon;

Expand Down

0 comments on commit 997fdd7

Please sign in to comment.