Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgslayoutitemnodeitem.h 3 : : begin : March 2016 4 : : copyright : (C) 2016 Paul Blottiere, Oslandia 5 : : email : paul dot blottiere at oslandia dot com 6 : : ***************************************************************************/ 7 : : 8 : : /*************************************************************************** 9 : : * * 10 : : * This program is free software; you can redistribute it and/or modify * 11 : : * it under the terms of the GNU General Public License as published by * 12 : : * the Free Software Foundation; either version 2 of the License, or * 13 : : * (at your option) any later version. * 14 : : * * 15 : : ***************************************************************************/ 16 : : 17 : : #ifndef QGSLAYOUTITEMNODEITEM_H 18 : : #define QGSLAYOUTITEMNODEITEM_H 19 : : 20 : : #include "qgis_core.h" 21 : : #include "qgslayoutitem.h" 22 : : 23 : : /** 24 : : * \ingroup core 25 : : * \brief An abstract layout item that provides generic methods for node based 26 : : * shapes such as polygon or polylines. 27 : : * \since QGIS 3.0 28 : : */ 29 : 0 : class CORE_EXPORT QgsLayoutNodesItem: public QgsLayoutItem 30 : : { 31 : : Q_OBJECT 32 : : 33 : : public: 34 : : 35 : : /** 36 : : * Sets the \a nodes the shape consists of. 37 : : * \see nodes() 38 : : */ 39 : : void setNodes( const QPolygonF &nodes ); 40 : : 41 : : /** 42 : : * Returns the nodes the shape consists of. 43 : : * \see setNodes() 44 : : */ 45 : : QPolygonF nodes() const { return mPolygon; } 46 : : 47 : : /** 48 : : * Add a node in current shape. 49 : : * \param point is the location of the new node (in scene coordinates) 50 : : * \param checkArea is a flag to indicate if there's a space constraint. 51 : : * \param radius is the space contraint and is used only if checkArea is 52 : : * TRUE. Typically, if this flag is TRUE, the new node has to be nearer 53 : : * than radius to the shape to be added. 54 : : */ 55 : : bool addNode( QPointF point, bool checkArea = true, double radius = 10 ); 56 : : 57 : : /** 58 : : * Set whether the item's nodes should be displayed. 59 : : */ 60 : : void setDisplayNodes( bool display = true ) { mDrawNodes = display; } 61 : : 62 : : /** 63 : : * Moves a node to a new position. 64 : : * \param index the index of the node to move 65 : : * \param node is the new position in scene coordinate 66 : : */ 67 : : bool moveNode( int index, QPointF node ); 68 : : 69 : : /** 70 : : * Search for the nearest node in the shape within a maximal area. Returns the 71 : : * index of the nearest node or -1 if no node was found. 72 : : * \param point is the location to search for nodes from (in scene coordinates) 73 : : * \param searchInRadius is a flag to indicate if the area of research is 74 : : * limited in space. 75 : : * \param radius is only used if searchInRadius is TRUE 76 : : */ 77 : : int nodeAtPosition( QPointF point, bool searchInRadius = true, double radius = 10 ) const; 78 : : 79 : : /** 80 : : * Gets the position of a node in scene coordinates. 81 : : * \param index of the node 82 : : * \param position the position of the node 83 : : * \returns TRUE if the index is valid and the position is set, FALSE otherwise 84 : : */ 85 : : bool nodePosition( int index, QPointF &position ) const; 86 : : 87 : : /** 88 : : * Remove a node with specified \a index from the shape. 89 : : */ 90 : : bool removeNode( int index ); 91 : : 92 : : //! Returns the number of nodes in the shape. 93 : : int nodesSize() const { return mPolygon.size(); } 94 : : 95 : : /** 96 : : * Selects a node by \a index. 97 : : */ 98 : : bool setSelectedNode( int index ); 99 : : 100 : : /** 101 : : * Returns the currently selected node, or -1 if no node is selected. 102 : : */ 103 : : int selectedNode() const { return mSelectedNode; } 104 : : 105 : : /** 106 : : * Deselects any selected nodes. 107 : : */ 108 : : void deselectNode() { mSelectedNode = -1; } 109 : : 110 : : // Depending on the symbol style, the bounding rectangle can be larger than the shape 111 : : QRectF boundingRect() const override; 112 : : 113 : : // Reimplement estimatedFrameBleed, since frames on shapes are drawn using symbology 114 : : // rather than the item's pen 115 : : double estimatedFrameBleed() const override; 116 : : 117 : : protected: 118 : : 119 : : /** 120 : : * Constructor for QgsLayoutNodesItem, attached to the specified \a layout. 121 : : */ 122 : : QgsLayoutNodesItem( QgsLayout *layout ); 123 : : 124 : : /** 125 : : * Constructor for a QgsLayoutNodesItem with the given \a polygon nodes, attached to the specified \a layout. 126 : : */ 127 : : QgsLayoutNodesItem( const QPolygonF &polygon, QgsLayout *layout ); 128 : : 129 : : void draw( QgsLayoutItemRenderContext &context ) override; 130 : : 131 : : bool writePropertiesToElement( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const override; 132 : : bool readPropertiesFromElement( const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context ) override; 133 : : 134 : : //! Shape's nodes. 135 : : QPolygonF mPolygon; 136 : : 137 : : //! Max symbol bleed 138 : : double mMaxSymbolBleed = 0.0; 139 : : 140 : : //! Method called in addNode. 141 : : virtual bool _addNode( int nodeIndex, QPointF newNode, double radius ) = 0; 142 : : 143 : : //! Method called in removeNode. 144 : : virtual bool _removeNode( int nodeIndex ) = 0; 145 : : 146 : : //! Method called in paint. 147 : : virtual void _draw( QgsLayoutItemRenderContext &context, const QStyleOptionGraphicsItem *itemStyle = nullptr ) = 0; 148 : : 149 : : //! Method called in readXml. 150 : : virtual void _readXmlStyle( const QDomElement &elmt, const QgsReadWriteContext &context ) = 0; 151 : : 152 : : //! Method called in writeXml. 153 : : virtual void _writeXmlStyle( QDomDocument &doc, QDomElement &elmt, const QgsReadWriteContext &context ) const = 0; 154 : : 155 : : /** 156 : : * Rescale the current shape according to the item's bounding box. Useful when 157 : : * the shape is resized thanks to the rubber band. 158 : : */ 159 : : void rescaleToFitBoundingBox(); 160 : : 161 : : //! Compute an euclidean distance between 2 nodes. 162 : : double computeDistance( QPointF pt1, QPointF pt2 ) const; 163 : : 164 : : //! Update the current scene rectangle for this item. 165 : : void updateSceneRect(); 166 : : 167 : : //! Current bounding rectangle of shape 168 : : QRectF mCurrentRectangle; 169 : : 170 : : protected slots: 171 : : 172 : : /** 173 : : * Called when the bounding rect of the item should recalculated. Subclasses should update 174 : : * currentRectangle in their implementations. 175 : : */ 176 : : virtual void updateBoundingRect(); 177 : : 178 : : private: 179 : : 180 : : void init(); 181 : : 182 : : //! The index of the node currently selected. 183 : : int mSelectedNode = -1; 184 : : 185 : : /** 186 : : * This tag is used to indicate if we have to draw nodes or not during 187 : : * the painting. 188 : : */ 189 : : bool mDrawNodes = false; 190 : : 191 : : //! Draw nodes 192 : : void drawNodes( QgsLayoutItemRenderContext &context ) const; 193 : : void drawSelectedNode( QgsLayoutItemRenderContext &context ) const; 194 : : 195 : : }; 196 : : 197 : : #endif // QGSLAYOUTITEMNODEITEM_H