18#include "moc_qgslayoutitemnodeitem.cpp"
26#include <QStyleOptionGraphicsItem>
61 mPolygon = polygon.translated( -topLeft );
64void QgsLayoutNodesItem::init()
68 setCacheMode( QGraphicsItem::NoCache );
78 painter->setPen( Qt::NoPen );
79 painter->setBrush( Qt::NoBrush );
85 if ( mDrawNodes &&
layout()->renderContext().isPreviewRender() )
97 return std::sqrt( std::pow( pt1.x() - pt2.x(), 2 ) + std::pow( pt1.y() - pt2.y(), 2 ) );
101 const bool checkArea,
102 const double radius )
104 const QPointF start = mapFromScene( pt );
105 double minDistance = std::numeric_limits<double>::max();
106 const double maxDistance = ( checkArea ) ? radius : minDistance;
110 for (
int i = 0; i !=
mPolygon.size(); i++ )
113 const QPointF pt1 =
mPolygon.at( i );
119 const double coef = ( pt2.y() - pt1.y() ) / ( pt2.x() - pt1.x() );
120 const double b = pt1.y() - coef * pt1.x();
122 double distance = std::numeric_limits<double>::max();
123 if ( std::isinf( coef ) )
124 distance = std::fabs( pt1.x() - start.x() );
127 const double coef2 = ( -1 / coef );
128 const double b2 = start.y() - coef2 * start.x();
131 if ( std::isinf( coef2 ) )
133 distance = std::fabs( pt1.y() - start.y() );
134 inter.setX( start.x() );
135 inter.setY( pt1.y() );
139 const double interx = ( b - b2 ) / ( coef2 - coef );
140 const double intery = interx * coef2 + b2;
141 inter.setX( interx );
142 inter.setY( intery );
149 const double length4 = length1 + length2;
151 if ( std::fabs( length3 - length4 ) < std::numeric_limits<float>::epsilon() )
155 if ( distance < minDistance && distance < maxDistance )
157 minDistance = distance;
164 rc =
_addNode( idx, start, maxDistance );
178 QVariantMap properties;
179 properties.insert( QStringLiteral(
"name" ), QStringLiteral(
"cross" ) );
180 properties.insert( QStringLiteral(
"color_border" ), QStringLiteral(
"red" ) );
183 symbol->setSize( rectSize );
184 symbol->setAngle( 45 );
187 for (
const QPointF pt : std::as_const(
mPolygon ) )
188 symbol->renderPoint( pt * context.viewScaleFactor(), nullptr, context.renderContext() );
191 if ( mSelectedNode >= 0 && mSelectedNode <
mPolygon.size() )
192 drawSelectedNode( context );
199 QVariantMap properties;
200 properties.insert( QStringLiteral(
"name" ), QStringLiteral(
"square" ) );
201 properties.insert( QStringLiteral(
"color" ), QStringLiteral(
"0, 0, 0, 0" ) );
202 properties.insert( QStringLiteral(
"color_border" ), QStringLiteral(
"blue" ) );
203 properties.insert( QStringLiteral(
"width_border" ), QStringLiteral(
"4" ) );
206 symbol->setSize( rectSize );
214 const bool searchInRadius,
215 const double radius )
const
217 const QPointF pt = mapFromScene( node );
218 double nearestDistance = std::numeric_limits<double>::max();
219 const double maxDistance = ( searchInRadius ) ? radius : nearestDistance;
224 for (
const QPointF polyPt : std::as_const(
mPolygon ) )
227 if ( distance < nearestDistance && distance < maxDistance )
229 nearestDistance = distance;
242 if ( index >= 0 && index <
mPolygon.size() )
244 position = mapToScene(
mPolygon.at( index ) );
266 if ( index >= 0 && index <
mPolygon.size() )
268 const QPointF nodeItem = mapFromScene( pt );
269 mPolygon.replace( index, nodeItem );
282 const QDomElement styleSymbolElem = itemElem.firstChildElement( QStringLiteral(
"symbol" ) );
283 if ( !styleSymbolElem.isNull() )
288 const QDomNodeList nodesList = itemElem.elementsByTagName( QStringLiteral(
"node" ) );
289 for (
int i = 0; i < nodesList.size(); i++ )
291 const QDomElement nodeElem = nodesList.at( i ).toElement();
293 newPt.setX( nodeElem.attribute( QStringLiteral(
"x" ) ).toDouble() );
294 newPt.setY( nodeElem.attribute( QStringLiteral(
"y" ) ).toDouble() );
316 trans = trans.scale( ratioX, ratioY );
325 if ( index >= 0 && index <
mPolygon.size() )
327 mSelectedNode = index;
337 const QRectF br =
mPolygon.boundingRect();
339 const QPointF topLeft = mapToScene( br.topLeft() );
344 mPolygon.translate( -br.topLeft().x(), -br.topLeft().y() );
351 prepareGeometryChange();
364 QDomElement nodesElem = doc.createElement( QStringLiteral(
"nodes" ) );
365 for (
const QPointF pt : std::as_const(
mPolygon ) )
367 QDomElement nodeElem = doc.createElement( QStringLiteral(
"node" ) );
368 nodeElem.setAttribute( QStringLiteral(
"x" ), QString::number( pt.x() ) );
369 nodeElem.setAttribute( QStringLiteral(
"y" ), QString::number( pt.y() ) );
370 nodesElem.appendChild( nodeElem );
372 elem.appendChild( nodesElem );
Contains settings and helpers relating to a render of a QgsLayoutItem.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
double viewScaleFactor() const
Returns the current view zoom (scale factor).
Base class for graphical items within a QgsLayout.
virtual void setFrameEnabled(bool drawFrame)
Sets whether this item has a frame drawn around it or not.
@ FlagDisableSceneCaching
Item should not have QGraphicsItem caching enabled.
void sizePositionChanged()
Emitted when the item's size or position changes.
void clipPathChanged()
Emitted when the item's clipping path has changed.
void attemptSetSceneRect(const QRectF &rect, bool includesFrame=false)
Attempts to update the item's position and size to match the passed rect in layout coordinates.
void setBackgroundEnabled(bool drawBackground)
Sets whether this item has a background drawn under it or not.
QgsLayoutItem::Flags itemFlags() const override
Returns the item's flags, which indicate how the item behaves.
virtual void updateBoundingRect()
Called when the bounding rect of the item should recalculated.
virtual bool _removeNode(int nodeIndex)=0
Method called in removeNode.
QPolygonF nodes() const
Returns the nodes the shape consists of.
double mMaxSymbolBleed
Max symbol bleed.
virtual void _writeXmlStyle(QDomDocument &doc, QDomElement &elmt, const QgsReadWriteContext &context) const =0
Method called in writeXml.
QRectF mCurrentRectangle
Current bounding rectangle of shape.
bool readPropertiesFromElement(const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context) override
Sets item state from a DOM element.
bool setSelectedNode(int index)
Selects a node by index.
bool writePropertiesToElement(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const override
Stores item state within an XML DOM element.
void updateSceneRect()
Update the current scene rectangle for this item.
virtual void _readXmlStyle(const QDomElement &elmt, const QgsReadWriteContext &context)=0
Method called in readXml.
bool removeNode(int index)
Remove a node with specified index from the shape.
QRectF boundingRect() const override
double computeDistance(QPointF pt1, QPointF pt2) const
Compute an euclidean distance between 2 nodes.
bool nodePosition(int index, QPointF &position) const
Gets the position of a node in scene coordinates.
bool addNode(QPointF point, bool checkArea=true, double radius=10)
Add a node in current shape.
bool moveNode(int index, QPointF node)
Moves a node to a new position.
double estimatedFrameBleed() const override
Returns the estimated amount the item's frame bleeds outside the item's actual rectangle.
void draw(QgsLayoutItemRenderContext &context) override
Draws the item's contents using the specified item render context.
virtual void _draw(QgsLayoutItemRenderContext &context, const QStyleOptionGraphicsItem *itemStyle=nullptr)=0
Method called in paint.
QgsLayoutNodesItem(QgsLayout *layout)
Constructor for QgsLayoutNodesItem, attached to the specified layout.
virtual bool _addNode(int nodeIndex, QPointF newNode, double radius)=0
Method called in addNode.
void rescaleToFitBoundingBox()
Rescale the current shape according to the item's bounding box.
void setNodes(const QPolygonF &nodes)
Sets the nodes the shape consists of.
QPolygonF mPolygon
Shape's nodes.
int nodeAtPosition(QPointF point, bool searchInRadius=true, double radius=10) const
Search for the nearest node in the shape within a maximal area.
const QgsLayout * layout() const
Returns the layout the object is attached to.
void changed()
Emitted when the object's properties change.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
static std::unique_ptr< QgsMarkerSymbol > createSimple(const QVariantMap &properties)
Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
A container for the context for various read/write operations on objects.
void setForceVectorOutput(bool force)
Sets whether rendering operations should use vector operations instead of any faster raster shortcuts...
QPainter * painter()
Returns the destination QPainter for the render operation.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)