File indexing completed on 2024-04-21 05:43:54

0001 /***************************************************************************
0002  *   Copyright (C) 2003-2005 by David Saxton                               *
0003  *   david@bluehaze.org                                                    *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  ***************************************************************************/
0010 
0011 #ifndef CONNECTOR_H
0012 #define CONNECTOR_H
0013 
0014 //#include <canvas.h> // 2018.10.16 - not needed
0015 #include "canvasitems.h"
0016 #include <QPointer>
0017 // #include <q3valuevector.h>
0018 
0019 class Cell;
0020 class ConnectorData;
0021 class ConnectorLine;
0022 class ConRouter;
0023 class CNItem;
0024 class ICNDocument;
0025 class Node;
0026 class NodeGroup;
0027 class Wire;
0028 
0029 typedef QList<ConnectorLine *> ConnectorLineList;
0030 typedef QList<QPoint> QPointList;
0031 typedef QVector<QPointer<Wire>> WireVector;
0032 
0033 /**
0034 @short Represents a connection between two Nodes on a ICNDocument
0035 @author David Saxton
0036 */
0037 
0038 class Connector : /* public QObject, */ public KtlQCanvasPolygon
0039 {
0040     Q_OBJECT
0041 
0042 public:
0043     Connector(Node *startNode, Node *endNode, ICNDocument *_ICNDocument, QString *id = nullptr);
0044     ~Connector() override;
0045 
0046     /**
0047      * Node at start of connector (which refers to this as the output connector)
0048      */
0049     virtual Node *startNode() const = 0;
0050 
0051     /**
0052      * Node at end of connector (which refers to this as the input connector)
0053      */
0054     virtual Node *endNode() const = 0;
0055 
0056     /**
0057      * @returns connector data describing this connector
0058      */
0059     ConnectorData connectorData() const;
0060 
0061     /**
0062      * Restore the state of the connector (route, etc) from the saved data
0063      */
0064     void restoreFromConnectorData(const ConnectorData &connectorData);
0065 
0066     /**
0067      * If selected, will be drawn in a different colour
0068      */
0069     void setSelected(bool yes) override;
0070 
0071     /**
0072      * Connected id
0073      */
0074     QString id() const
0075     {
0076         return m_id;
0077     }
0078 
0079     /**
0080      * Update the list of lines and connetion-points that the connector uses for
0081      * drawing.
0082      */
0083     void updateDrawList();
0084 
0085     /**
0086      * Tells the connector that it is under the control of a NodeGroup. When
0087      * the connector is under the control of a NodeGroup, all requests for
0088      * connection rerouting will be passed onto that NodeGroup
0089      */
0090     void setNodeGroup(NodeGroup *nodeGroup)
0091     {
0092         p_nodeGroup = nodeGroup;
0093     }
0094 
0095     /**
0096      * Returns the NodeGroup that the connector is under the control of (if any)
0097      */
0098     NodeGroup *nodeGroup() const
0099     {
0100         return p_nodeGroup;
0101     }
0102 
0103     /**
0104      * ICNDocument needs to know what 'cells' a connector is present in,
0105      * so that connection mapping can be done to avoid connectors.
0106      * This function will add the hit penalty to the cells pointed to
0107      * by ICNDocument::cells()
0108      */
0109     void updateConnectorPoints(bool add);
0110 
0111     /**
0112      * Sets the canvas points that the connector should route itself along.
0113      * This is used for manual routing. The cells points are absolute positions
0114      * (unlike the points stored internally in this class, which are the cell poisition
0115      * @param setManual if true then the connector will change to a manual route one
0116      * @param checkEndPoints if true then will  check to see if the end points are at the nodes, and adds them if not
0117      */
0118     void setRoutePoints(QPointList pointList, bool setManual, bool checkEndPoints = false);
0119 
0120     /**
0121      * Call this function (e.g. when moving a CNItem connected to the connector)
0122      * to make the connector partially hidden - probably grayed out - if semiHidden
0123      * is true.
0124      */
0125     void setSemiHidden(bool semiHidden);
0126 
0127     /**
0128      * Sets the container parent (i.e. the container of the parent item)
0129      */
0130     void setParentContainer(const QString &cnItemId);
0131 
0132     /**
0133      * Returns a pointer to the parent item container
0134      */
0135     CNItem *parentContainer() const
0136     {
0137         return p_parentContainer;
0138     }
0139 
0140     /**
0141      * @returns whether the points have been set by the user manually defining them
0142      */
0143     bool usesManualPoints() const
0144     {
0145         return b_manualPoints;
0146     }
0147 
0148     /**
0149      * Returns two sets of points (in canvas-reference) that define the connector
0150      * from start to finish, when it is split at the given point (in canvas-reference)
0151      */
0152     QList<QPointList> splitConnectorPoints(const QPoint &pos) const;
0153 
0154     /**
0155      * @returns pointer to ICNDocument that this connector is a member of
0156      */
0157     ICNDocument *icnDocument() const
0158     {
0159         return p_icnDocument;
0160     }
0161 
0162     /**
0163      * Looks at the set of canvas points and tries to determine whether they are
0164      * in the reverse order from start to end node
0165      */
0166     bool pointsAreReverse(const QPointList &pointList) const;
0167 
0168     /**
0169      * Returns the points, given in canvas-reference, in order of start node to
0170      * end node if reverse is false
0171      * @param reverse whether or not to reverse the points from start node to end node
0172      */
0173     QPointList connectorPoints(bool reverse = false) const;
0174 
0175     /**
0176      * Reroute the connector. Note that if this connector is controlled by a
0177      * NodeGroup, it will do nothing (other than print out a warning)
0178      */
0179     void rerouteConnector();
0180 
0181     /**
0182      * Translates the route by the given amoumt. No checking is done to see if
0183      * the translation is useful, etc.
0184      */
0185     void translateRoute(int dx, int dy);
0186     void setVisible(bool yes) override;
0187 
0188     /**
0189     Methods relating to wire lists
0190     */
0191     WireVector wires() const
0192     {
0193         return m_wires;
0194     }
0195     unsigned numWires() const
0196     {
0197         return m_wires.size();
0198     }
0199     Wire *wire(unsigned num = 0) const;
0200 
0201     void updateConnectorLines(bool forceRedraw = false);
0202 
0203     /**
0204      * Modular offset of moving dots in connector, indicating current (in
0205      * pixels).
0206      */
0207     double currentAnimationOffset() const
0208     {
0209         return m_currentAnimationOffset;
0210     }
0211 
0212     /**
0213      * Increases the currentAnimationOffset according to the current flowing in
0214      * the connector and deltaTime.
0215      */
0216     void incrementCurrentAnimation(double deltaTime);
0217 
0218 signals:
0219     void removed(Connector *connector);
0220     void selected(bool yes);
0221     void numWiresChanged(unsigned newNum);
0222 
0223 public slots:
0224     void removeConnectorNoArg();
0225     void removeConnectorNodeArg(Node *);
0226     void removeConnector(Node *);
0227 
0228     // protected:
0229     //  bool m_bIsSyncingWires;
0230 
0231 protected:
0232     WireVector m_wires;
0233 
0234 private:
0235     bool b_semiHidden;
0236     bool b_deleted;
0237     bool b_manualPoints;
0238     bool b_pointsAdded;
0239 
0240     double m_currentAnimationOffset;
0241 
0242     NodeGroup *p_nodeGroup;
0243     CNItem *p_parentContainer;
0244     ICNDocument *p_icnDocument;
0245     ConRouter *m_conRouter;
0246 
0247     QString m_id;
0248     QRect m_oldBoundRect;
0249 
0250     ConnectorLineList m_connectorLineList;
0251 };
0252 
0253 typedef QList<QPointer<Connector>> ConnectorList;
0254 
0255 // BEGIN ConnectorLine things
0256 
0257 class ConnectorLine : /* public QObject, */ public KtlQCanvasLine
0258 {
0259 public:
0260     /**
0261      * @param pixelOffset the number of pixels between the start of the
0262      * parent connector and the start of this wire. Used in current
0263      * animation.
0264      */
0265     ConnectorLine(Connector *connector, int pixelOffset);
0266     Connector *parent() const
0267     {
0268         return m_pConnector;
0269     }
0270 
0271     void setAnimateCurrent(bool animateCurrent)
0272     {
0273         m_bAnimateCurrent = animateCurrent;
0274     }
0275 
0276 protected:
0277     void drawShape(QPainter &p) override;
0278 
0279     Connector *m_pConnector;
0280     int m_pixelOffset;
0281     bool m_bAnimateCurrent;
0282 };
0283 
0284 // END ConnectorLine things
0285 
0286 #endif