33#include <QGraphicsRectItem>
37#include "moc_qgslayoutviewtooladdnodeitem.cpp"
48 mItemMetadataId = metadataId;
53 if ( event->button() == Qt::LeftButton )
60 layout()->addItem( mRubberBand.get() );
72 else if ( event->button() == Qt::RightButton && mRubberBand )
77 mPolygon.remove( mPolygon.count() - 1 );
83 if (
QgsLayoutNodesItem *nodesItem = qobject_cast<QgsLayoutNodesItem *>( item.get() ) )
85 nodesItem->setNodes( mPolygon );
86 if ( !nodesItem->isValid() )
108 moveTemporaryNode( event->
snappedPoint(), event->modifiers() );
127 if ( !mRubberBand || event->isAutoRepeat() )
133 if ( event->key() == Qt::Key_Delete || event->key() == Qt::Key_Backspace )
135 if ( mPolygon.size() > 2 )
139 setRubberBandNodes();
140 moveTemporaryNode(
view()->mapToScene(
view()->mapFromGlobal( QCursor::pos() ) ), event->modifiers() );
148 else if ( event->key() == Qt::Key_Escape )
168void QgsLayoutViewToolAddNodeItem::addNode( QPointF scenePoint )
170 mPolygon.append( scenePoint );
172 if ( mPolygon.size() == 1 )
173 mPolygon.append( scenePoint );
175 setRubberBandNodes();
178void QgsLayoutViewToolAddNodeItem::moveTemporaryNode( QPointF scenePoint, Qt::KeyboardModifiers modifiers )
180 if ( mPolygon.isEmpty() )
183 if ( mPolygon.size() > 1 && ( modifiers & Qt::ShiftModifier ) )
185 const QPointF start = mPolygon.at( mPolygon.size() - 2 );
186 QLineF newLine = QLineF( start, scenePoint );
190 newLine.setAngle( angle );
191 scenePoint = newLine.p2();
194 mPolygon.replace( mPolygon.size() - 1, scenePoint );
195 setRubberBandNodes();
198void QgsLayoutViewToolAddNodeItem::setRubberBandNodes()
200 QList<QGraphicsItem *> items = mRubberBand->childItems();
205 if ( items.isEmpty() )
207 items << mRubberBand.get();
210 if ( QGraphicsPolygonItem *polygonItem =
dynamic_cast<QGraphicsPolygonItem *
>( items[0] ) )
213 if ( items.size() == 2 &&
dynamic_cast<QGraphicsPolygonItem *
>( items[1] ) !=
nullptr )
215 if ( mPolygon.size() > 3 )
217 polygonItem->setPolygon( QPolygonF( mPolygon.mid( 0, mPolygon.size() - 1 ) ) );
221 polygonItem->setPolygon( QPolygonF() );
223 dynamic_cast<QGraphicsPolygonItem *
>( items[1] )->setPolygon( mPolygon );
228 polygonItem->setPolygon( mPolygon );
231 else if ( QGraphicsPathItem *polylineItem =
dynamic_cast<QGraphicsPathItem *
>( items[0] ) )
234 if ( items.size() == 2 &&
dynamic_cast<QGraphicsPathItem *
>( items[1] ) !=
nullptr )
236 if ( mPolygon.size() > 2 )
239 path.addPolygon( QPolygonF( mPolygon.mid( 0, mPolygon.size() - 1 ) ) );
240 polylineItem->setPath( path );
244 polylineItem->setPath( QPainterPath() );
246 if ( mPolygon.size() > 1 )
249 path.addPolygon( mPolygon.mid( mPolygon.size() - 2 ) );
250 dynamic_cast<QGraphicsPathItem *
>( items[1] )->setPath( path );
258 path.addPolygon( mPolygon );
259 polylineItem->setPath( path );
266 return mItemMetadataId;
static QgsLayoutItemGuiRegistry * layoutItemGuiRegistry()
Returns the global layout item GUI registry, used for registering the GUI behavior of layout items.
Base class for graphical items within a QgsLayout.
An abstract layout item that provides generic methods for node based shapes such as polygon or polyli...
static double snappedAngle(double angle)
Snaps an angle (in degrees) to its closest 45 degree angle.
A mouse event which is the result of a user interaction with a QgsLayoutView.
QPointF snappedPoint() const
Returns the snapped event point location in layout coordinates.
A graphical widget to display and interact with QgsLayouts.
void deselectAll()
Deselects all items in the view.
void setSelectedItem(QgsLayoutItem *item)
Clears any selected items and sets item as the current selection.
void addLayoutItem(QgsLayoutItem *item)
Adds an item to the layout.
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored).