File indexing completed on 2024-05-05 03:50:40
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2014 Calin Cruceru <crucerucalincristian@gmail.com> 0004 // 0005 0006 #ifndef POLYLINEANNOTATION_H 0007 #define POLYLINEANNOTATION_H 0008 0009 #include <QColor> 0010 #include <QPointer> 0011 0012 #include "SceneGraphicsItem.h" 0013 #include "GeoDataCoordinates.h" 0014 0015 0016 namespace Marble 0017 { 0018 0019 class PolylineNode; 0020 class MergingPolylineNodesAnimation; 0021 0022 class PolylineAnnotation : public SceneGraphicsItem 0023 { 0024 friend class MergingPolylineNodesAnimation; 0025 0026 public: 0027 explicit PolylineAnnotation( GeoDataPlacemark *placemark ); 0028 ~PolylineAnnotation() override; 0029 0030 /** 0031 * @brief Paints the nodes on the screen and updates the regions which correspond 0032 * to each node using the given GeoPainter. 0033 */ 0034 void paint( GeoPainter *painter, const ViewportParams *viewport, const QString &layer , int tileZoomLevel) override; 0035 0036 /** 0037 * @brief Returns true if either the polyline's associated region or one of its nodes 0038 * contains the given QPoint. Note that the return value depends on the state. 0039 */ 0040 bool containsPoint( const QPoint &eventPos ) const override; 0041 0042 /** 0043 * @brief It is used so far to remove the hover effect while being in the 0044 * AddingPolylineNodes state (@see SceneGraphicsItem::dealWithItemChange documentation). 0045 */ 0046 void dealWithItemChange( const SceneGraphicsItem *other ) override; 0047 0048 /** 0049 * @brief Moves the whole polyline to the destination point. 0050 */ 0051 void move( const GeoDataCoordinates &source, const GeoDataCoordinates &destination ) override; 0052 0053 /** 0054 * @brief Changes the busy state of the object according to @p enabled. It is mostly used 0055 * by Annotate Plugin to not send events to this object anymore but is different than the 0056 * focus property (you can have a focused polyline which does not accept events because is 0057 * busy). 0058 */ 0059 void setBusy( bool enabled ); 0060 0061 /** 0062 * @brief Returns whether the annotation is 'busy' or not - this usually means that something 0063 * is being performed and it does not accept events anymore. 0064 */ 0065 bool isBusy() const; 0066 0067 /** 0068 * @brief Iterates through all nodes which form the polyline and sets the IsSelected flag to 0069 * false. 0070 */ 0071 void deselectAllNodes(); 0072 0073 /** 0074 * @brief Iterates through all nodes which form the polyline and deletes the selected ones. 0075 */ 0076 void deleteAllSelectedNodes(); 0077 0078 /** 0079 * @brief Deletes the last clicked node while being in the Editing state. 0080 */ 0081 void deleteClickedNode(); 0082 0083 /** 0084 * @brief If the last clicked node is selected, set its IsSelected flag to false and 0085 * vice versa. 0086 */ 0087 void changeClickedNodeSelection(); 0088 0089 /** 0090 * @brief Tests if there are any selected nodes. 0091 */ 0092 bool hasNodesSelected() const; 0093 0094 /** 0095 * @brief Tests if the last clicked node is selected. 0096 */ 0097 bool clickedNodeIsSelected() const; 0098 0099 /** 0100 * @brief Returns the animation to be handled by a QObject which can connect signals 0101 * and slots. 0102 */ 0103 QPointer<MergingPolylineNodesAnimation> animation(); 0104 0105 /** 0106 * @brief Provides information for downcasting a SceneGraphicsItem. 0107 */ 0108 const char *graphicType() const override; 0109 0110 protected: 0111 /** 0112 * @brief Protected methods which handle mouse events and are called by 0113 * SceneGraphicsItem::sceneEvent() (@see Template Method pattern). Each of these 0114 * event handlers are structured according to the state. 0115 */ 0116 bool mousePressEvent( QMouseEvent *event ) override; 0117 bool mouseMoveEvent( QMouseEvent *event ) override; 0118 bool mouseReleaseEvent( QMouseEvent *event ) override; 0119 0120 void dealWithStateChange( SceneGraphicsItem::ActionState previousState ) override; 0121 0122 private: 0123 /** 0124 * @brief It is called when the ::paint method is called for the first time. It 0125 * initializes the m_nodesList by creating the PolylineNodes. 0126 * @see updateRegions() method for more detailed explanation. 0127 */ 0128 void setupRegionsLists( GeoPainter *painter ); 0129 0130 /** 0131 * @brief As briefly mentioned above, the PolylineNodes instances are not created at 0132 * each ::paint call, but only at its first call. Every time the ::paint method is 0133 * called after that, each node from the lists of PolylineNodes gets its setRegion() 0134 * method called. We need the GeoPainter for doing this because we have to get the 0135 * ellipse around the GeoDataCoordinates. 0136 */ 0137 void updateRegions( GeoPainter *painter ); 0138 0139 /** 0140 * @brief It iterates through all nodes and paints them on the map. It takes into 0141 * consideration the active flags of each PolylineNode. 0142 */ 0143 void drawNodes( GeoPainter *painter ); 0144 0145 /** 0146 * @brief Tests if the polyline's nodes contain the given point and in case they do, it 0147 * returns the index of the first one. 0148 */ 0149 int nodeContains( const QPoint &point ) const; 0150 0151 /** 0152 * @brief Tests if the polyline's virtual nodes contain the given point and in case they 0153 * do, it returns the index of the first one. 0154 */ 0155 int virtualNodeContains( const QPoint &point ) const; 0156 0157 /** 0158 * @brief Returns true/false on how the polyline (its 'lines' excepting its nodes) contain 0159 * the given point or not. 0160 */ 0161 bool polylineContains( const QPoint &point ) const; 0162 0163 /** 0164 * @brief It is called from processOnMove functions and deals with polylines 0165 * hovering. 0166 */ 0167 bool dealWithHovering( QMouseEvent *mouseEvent ); 0168 0169 /** 0170 * @brief Each state has its corresponding event handler, since in each state the 0171 * item may behave differently. These are the event handlers for the Editing state. 0172 */ 0173 bool processEditingOnPress( QMouseEvent *mouseEvent ); 0174 bool processEditingOnMove( QMouseEvent *mouseEvent ); 0175 bool processEditingOnRelease( QMouseEvent *mouseEvent ); 0176 0177 /** 0178 * @brief These are the event handlers for the MergingPolylineNodes state. 0179 */ 0180 bool processMergingOnPress( QMouseEvent *mouseEvent ); 0181 bool processMergingOnMove( QMouseEvent *mouseEvent ); 0182 static bool processMergingOnRelease(QMouseEvent *mouseEvent); 0183 0184 /** 0185 * @brief These are the event handlers for the AddingPolylineNodes state. 0186 */ 0187 bool processAddingNodesOnPress( QMouseEvent *mouseEvent ); 0188 bool processAddingNodesOnMove( QMouseEvent *mouseEvent ); 0189 bool processAddingNodesOnRelease( QMouseEvent *mouseEvent ); 0190 0191 0192 0193 /** 0194 * @brief Since they are used in many functions, the size and color of nodes for each 0195 * state are static and have class scope. 0196 */ 0197 static const int regularDim; 0198 static const int selectedDim; 0199 static const int mergedDim; 0200 static const int hoveredDim; 0201 static const QColor regularColor; 0202 static const QColor mergedColor; 0203 0204 const ViewportParams *m_viewport; 0205 bool m_regionsInitialized; 0206 bool m_busy; 0207 0208 QVector<PolylineNode> m_nodesList; 0209 QVector<PolylineNode> m_virtualNodesList; 0210 QRegion m_polylineRegion; 0211 0212 // Used in Editing state 0213 enum EditingInteractingObject { 0214 InteractingNothing, // e.g. when hovering 0215 InteractingNode, 0216 InteractingPolyline 0217 }; 0218 EditingInteractingObject m_interactingObj; 0219 GeoDataCoordinates m_movedPointCoords; 0220 int m_clickedNodeIndex; 0221 int m_hoveredNodeIndex; 0222 0223 // Used in Merging Nodes state 0224 QPointer<MergingPolylineNodesAnimation> m_animation; 0225 int m_firstMergedNode; 0226 int m_secondMergedNode; 0227 0228 // Used in Adding Nodes state 0229 int m_virtualHoveredNode; 0230 int m_adjustedNode; 0231 }; 0232 0233 } 0234 0235 #endif