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 );
 
   87  if ( mDrawNodes && 
layout()->renderContext().isPreviewRender() )
 
 
   99  return std::sqrt( std::pow( pt1.x() - pt2.x(), 2 ) + std::pow( pt1.y() - pt2.y(), 2 ) );
 
 
  103                                  const bool checkArea,
 
  104                                  const double radius )
 
  106  const QPointF start = mapFromScene( pt );
 
  107  double minDistance = std::numeric_limits<double>::max();
 
  108  const double maxDistance = ( checkArea ) ? radius : minDistance;
 
  112  for ( 
int i = 0; i != 
mPolygon.size(); i++ )
 
  115    const QPointF pt1 = 
mPolygon.at( i );
 
  121    const double coef = ( pt2.y() - pt1.y() ) / ( pt2.x() - pt1.x() );
 
  122    const double b = pt1.y() - coef * pt1.x();
 
  124    double distance = std::numeric_limits<double>::max();
 
  125    if ( std::isinf( coef ) )
 
  126      distance = std::fabs( pt1.x() - start.x() );
 
  129      const double coef2 = ( -1 / coef );
 
  130      const double b2 = start.y() - coef2 * start.x();
 
  133      if ( std::isinf( coef2 ) )
 
  135        distance = std::fabs( pt1.y() - start.y() );
 
  136        inter.setX( start.x() );
 
  137        inter.setY( pt1.y() );
 
  141        const double interx = ( b - b2 ) / ( coef2 - coef );
 
  142        const double intery = interx * coef2 + b2;
 
  143        inter.setX( interx );
 
  144        inter.setY( intery );
 
  151      const double length4 = length1 + length2;
 
  153      if ( std::fabs( length3 - length4 ) < std::numeric_limits<float>::epsilon() )
 
  157    if ( distance < minDistance && distance < maxDistance )
 
  159      minDistance = distance;
 
  166    rc = 
_addNode( idx, start, maxDistance );
 
 
  180  QVariantMap properties;
 
  181  properties.insert( QStringLiteral( 
"name" ), QStringLiteral( 
"cross" ) );
 
  182  properties.insert( QStringLiteral( 
"color_border" ), QStringLiteral( 
"red" ) );
 
  185  symbol->setSize( rectSize );
 
  186  symbol->setAngle( 45 );
 
  189  for ( 
const QPointF pt : std::as_const( 
mPolygon ) )
 
  190    symbol->renderPoint( pt * context.viewScaleFactor(), nullptr, context.renderContext() );
 
  193  if ( mSelectedNode >= 0 && mSelectedNode < 
mPolygon.size() )
 
  194    drawSelectedNode( context );
 
  201  QVariantMap properties;
 
  202  properties.insert( QStringLiteral( 
"name" ), QStringLiteral( 
"square" ) );
 
  203  properties.insert( QStringLiteral( 
"color" ), QStringLiteral( 
"0, 0, 0, 0" ) );
 
  204  properties.insert( QStringLiteral( 
"color_border" ), QStringLiteral( 
"blue" ) );
 
  205  properties.insert( QStringLiteral( 
"width_border" ), QStringLiteral( 
"4" ) );
 
  208  symbol->setSize( rectSize );
 
  216                                        const bool searchInRadius,
 
  217                                        const double radius )
 const 
  219  const QPointF pt = mapFromScene( node );
 
  220  double nearestDistance = std::numeric_limits<double>::max();
 
  221  const double maxDistance = ( searchInRadius ) ? radius : nearestDistance;
 
  226  for ( 
const QPointF polyPt : std::as_const( 
mPolygon ) )
 
  229    if ( distance < nearestDistance && distance < maxDistance )
 
  231      nearestDistance = distance;
 
 
  244  if ( index >= 0 && index < 
mPolygon.size() )
 
  246    position = mapToScene( 
mPolygon.at( index ) );
 
 
  268  if ( index >= 0 && index < 
mPolygon.size() )
 
  270    const QPointF nodeItem = mapFromScene( pt );
 
  271    mPolygon.replace( index, nodeItem );
 
 
  284  const QDomElement styleSymbolElem = itemElem.firstChildElement( QStringLiteral( 
"symbol" ) );
 
  285  if ( !styleSymbolElem.isNull() )
 
  290  const QDomNodeList nodesList = itemElem.elementsByTagName( QStringLiteral( 
"node" ) );
 
  291  for ( 
int i = 0; i < nodesList.size(); i++ )
 
  293    const QDomElement nodeElem = nodesList.at( i ).toElement();
 
  295    newPt.setX( nodeElem.attribute( QStringLiteral( 
"x" ) ).toDouble() );
 
  296    newPt.setY( nodeElem.attribute( QStringLiteral( 
"y" ) ).toDouble() );
 
 
  318  trans = trans.scale( ratioX, ratioY );
 
 
  327  if ( index >= 0 && index < 
mPolygon.size() )
 
  329    mSelectedNode = index;
 
 
  339  const QRectF br = 
mPolygon.boundingRect();
 
  341  const QPointF topLeft = mapToScene( br.topLeft() );
 
  346  mPolygon.translate( -br.topLeft().x(), -br.topLeft().y() );
 
 
  353  prepareGeometryChange();
 
 
  366  QDomElement nodesElem = doc.createElement( QStringLiteral( 
"nodes" ) );
 
  367  for ( 
const QPointF pt : std::as_const( 
mPolygon ) )
 
  369    QDomElement nodeElem = doc.createElement( QStringLiteral( 
"node" ) );
 
  370    nodeElem.setAttribute( QStringLiteral( 
"x" ), QString::number( pt.x() ) );
 
  371    nodeElem.setAttribute( QStringLiteral( 
"y" ), QString::number( pt.y() ) );
 
  372    nodesElem.appendChild( nodeElem );
 
  374  elem.appendChild( nodesElem );
 
 
@ Default
Allow raster-based rendering in situations where it is required for correct rendering or where it wil...
 
@ PreferVector
Prefer vector-based rendering, when the result will still be visually near-identical to a raster-base...
 
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.
 
QPainter * painter()
Returns the destination QPainter for the render operation.
 
void setRasterizedRenderingPolicy(Qgis::RasterizedRenderingPolicy policy)
Sets the policy controlling when rasterisation of content during renders is permitted.
 
Qgis::RasterizedRenderingPolicy rasterizedRenderingPolicy() const
Returns the policy controlling when rasterisation of content during renders is permitted.
 
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)