File indexing completed on 2024-05-26 04:38:39

0001 /* This file is part of the TikZKit project.
0002  *
0003  * Copyright (C) 2013-2014 Dominik Haumann <dhaumann@kde.org>
0004  *
0005  * This library is free software; you can redistribute it and/or modify
0006  * it under the terms of the GNU Library General Public License as published
0007  * by the Free Software Foundation, either version 2 of the License, or
0008  * (at your option) any later version.
0009  *
0010  * This library is distributed in the hope that it will be useful,
0011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013  * GNU Library General Public License for more details.
0014  *
0015  * You should have received a copy of the GNU Library General Public License
0016  * along with this library; see the file COPYING.LIB.  If not, see
0017  * <http://www.gnu.org/licenses/>.
0018  */
0019 
0020 #ifndef TIKZ_UI_EDGE_PATH_ITEM_H
0021 #define TIKZ_UI_EDGE_PATH_ITEM_H
0022 
0023 #include "PathItem.h"
0024 
0025 #include <QPointer>
0026 
0027 class QPainter;
0028 
0029 class AbstractArrow;
0030 
0031 namespace tikz {
0032 namespace core {
0033     class EdgePath;
0034     class Node;
0035 }
0036 namespace ui {
0037 
0038 class DocumentPrivate;
0039 class NodeItem;
0040 
0041 class EdgePathItem :  public PathItem
0042 {
0043     Q_OBJECT
0044 
0045     public:
0046         /**
0047          * Constructor for @p edge and parent @p parent.
0048          */
0049         EdgePathItem(tikz::core::Path * path, QGraphicsItem * parent = nullptr);
0050 
0051         /**
0052          * Destructor
0053          */
0054         virtual ~EdgePathItem();
0055 
0056         /**
0057          * Returns the tikz::core::Path object, casted to tikz::core::EdgePath
0058          */
0059         tikz::core::EdgePath * edgePath() const;
0060 
0061         /**
0062          * Set the start node to @p start.
0063          * @param start start node of the edge. 0 is allows.
0064          */
0065         void setStartNode(NodeItem* start);
0066 
0067         /**
0068          * Set the end node to @p end.
0069          * @param end end node of the edge. 0 is allows.
0070          */
0071         void setEndNode(NodeItem* end);
0072 
0073         /**
0074          * Get the start node.
0075          * @return the start node or 0, if the start of the edge is not connected.
0076          */
0077         NodeItem* startNode() const;
0078 
0079         /**
0080          * Get the end node.
0081          * @return the end node or 0, if the end of the edge is not connected.
0082          */
0083         NodeItem* endNode() const;
0084 
0085         /**
0086          * Get the position of the start of the edge.
0087          * @return the position in item coordinates
0088          */
0089         QPointF startPos() const;
0090 
0091         /**
0092          * Get the position of the start of the edge for the specified angle @p rad.
0093          * @return the position in item coordinates
0094          */
0095         QPointF startPos(qreal rad) const;
0096 
0097         /**
0098          * Get the position of the end of the edge.
0099          * @return the position in item coordinates
0100          */
0101         QPointF endPos() const;
0102 
0103         /**
0104          * Get the position of the end of the edge for the specified angle @p rad.
0105          * @return the position in item coordinates
0106          */
0107         QPointF endPos(qreal rad) const;
0108 
0109     //
0110     // anchor methods
0111     //
0112     public:
0113         /**
0114          * Get the anchor of the start of the edge.
0115          */
0116         QString startAnchor() const;
0117 
0118         /**
0119          * Get the anchor of the end of the edge.
0120          */
0121         QString endAnchor() const;
0122 
0123     public Q_SLOTS:
0124         /**
0125          * Set the anchor of the head of the edge to @p anchor.
0126          */
0127         void setStartAnchor(const QString & anchor);
0128         /**
0129          * Set the anchor of the tail of the edge to @p anchor.
0130          */
0131         void setEndAnchor(const QString & anchor);
0132 
0133     //
0134     // catch when start or end node of the model changes
0135     //
0136     protected Q_SLOTS:
0137         /**
0138          * This function is called whenever the tikz::core::Node::setStartNode()
0139          * changes. This is required, since otherwise the model is updated,
0140          * without the EdgePathItem being notified.
0141          */
0142         void updateStartNode(tikz::core::Node * node);
0143 
0144         /**
0145          * This function is called whenever the tikz::core::Node::setEndNode()
0146          * changes. This is required, since otherwise the model is updated,
0147          * without the EdgePathItem being notified.
0148          */
0149         void updateEndNode(tikz::core::Node * node);
0150 
0151     //
0152     // angles
0153     //
0154     protected:
0155         /**
0156          * Return the angle between from start to end. If no Node%s are set, the
0157          * base angle is defined by the angle of the start coordinate to the end coordinate.
0158          * If start or end Node%s are set, the base angle takes the anchors into account.
0159          */
0160         qreal baseAngle() const;
0161 
0162         /**
0163          * Returns the angle under with this edge "leaves" the start Node.
0164          * The default implementation returns baseAngle().
0165          */
0166         virtual qreal startAngle() const;
0167 
0168         /**
0169          * Returns the angle under with this edge "arrives" the end Node.
0170          * The default implementation returns baseAngle() - M_PI.
0171          */
0172         virtual qreal endAngle() const;
0173 
0174     //
0175     // arrow head and tail
0176     //
0177     protected:
0178 
0179     //
0180     // reimplemented from QGraphicsItem
0181     //
0182     public:
0183         /**
0184          * Paint this item.
0185          */
0186         void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
0187 
0188         /**
0189          * Returns the bounding rect of this item.
0190          */
0191         QRectF boundingRect() const override;
0192 
0193         /**
0194          * Returns an exact shape as painter path
0195          */
0196         QPainterPath shape() const override;
0197 
0198         /**
0199          * Returns @p true, if @p point is contained in the edge.
0200          */
0201         bool contains(const QPointF & point) const override;
0202 
0203     private Q_SLOTS:
0204         void slotUpdate();
0205 
0206         /**
0207          * Recalculate all paths here.
0208          */
0209         virtual void updateCache();
0210 
0211     //
0212     // internal
0213     //
0214     private:
0215         /**
0216          * Private default constructor, not implemented
0217          */
0218         EdgePathItem();
0219 
0220     private:
0221         bool m_dirty;
0222 
0223         QPointer<NodeItem> m_startNode;
0224         QPointer<NodeItem> m_endNode;
0225 
0226         // Cached start and end position of the edge.
0227         // These positions include the rightExtend() of arrows as well as
0228         // the shortening of lines. Therefore, these positions are NOT
0229         // equal to startPos() and endPos().
0230         QPointF m_startAnchor;
0231         QPointF m_endAnchor;
0232 
0233         // cached edge paths
0234         QPainterPath m_edgePath;
0235         QPainterPath m_hoverPath;
0236         QPainterPath m_shapePath;
0237 
0238         // cached arrows
0239         QPainterPath m_headPath;
0240         QPainterPath m_tailPath;
0241 
0242         // Arrow tail and arrow head
0243         AbstractArrow * m_arrowTail;
0244         AbstractArrow * m_arrowHead;
0245 };
0246 
0247 }
0248 }
0249 
0250 #endif // TIKZ_UI_EDGE_PATH_ITEM_H
0251 
0252 // kate: indent-width 4; replace-tabs on;