File indexing completed on 2024-12-01 11:20:31

0001 //
0002 // C++ Implementation: inputflownode
0003 //
0004 // Description:
0005 //
0006 //
0007 //
0008 // Copyright: See COPYING file that comes with this distribution
0009 //
0010 //
0011 #include "inputflownode.h"
0012 #include "connector.h"
0013 #include "flowconnector.h"
0014 #include "flowpart.h"
0015 
0016 #include <QPainter>
0017 
0018 #include <ktechlab_debug.h>
0019 
0020 InputFlowNode::InputFlowNode(ICNDocument *icnDocument, int dir, const QPoint &pos, QString *id)
0021     : FPNode(icnDocument, Node::fp_in, dir, pos, id)
0022 {
0023 }
0024 
0025 InputFlowNode::~InputFlowNode()
0026 {
0027 }
0028 
0029 FlowPart *InputFlowNode::outputFlowPart() const
0030 {
0031     return dynamic_cast<FlowPart *>(parentItem());
0032 }
0033 
0034 FlowPartList InputFlowNode::inputFlowParts() const
0035 {
0036     FlowPartList list;
0037 
0038     const FlowConnectorList::const_iterator end = m_inFlowConnList.end();
0039     for (FlowConnectorList::const_iterator it = m_inFlowConnList.begin(); it != end; ++it) {
0040         if (*it) {
0041             Node *startNode = (*it)->startNode();
0042             FlowPart *flowPart = startNode ? dynamic_cast<FlowPart *>(startNode->parentItem()) : nullptr;
0043             if (flowPart)
0044                 list.append(flowPart);
0045         }
0046     }
0047 
0048     return list;
0049 }
0050 
0051 bool InputFlowNode::acceptInput() const
0052 {
0053     return true;
0054 }
0055 
0056 bool InputFlowNode::acceptOutput() const
0057 {
0058     return false;
0059 }
0060 
0061 void InputFlowNode::addOutputConnector(Connector *const /*connector*/)
0062 {
0063     qCCritical(KTL_LOG) << "BUG: adding output connector to an input node";
0064 }
0065 
0066 inline QPolygon arrowPoints(int dir)
0067 {
0068     QPolygon pa(3);
0069     switch (dir) {
0070     case 0:
0071         pa[0] = QPoint(3, 0);
0072         pa[1] = QPoint(0, 2);
0073         pa[2] = QPoint(0, -2);
0074         break;
0075     case 180:
0076         pa[0] = QPoint(-3, 0);
0077         pa[1] = QPoint(0, 2);
0078         pa[2] = QPoint(0, -2);
0079         break;
0080     case 90:
0081         pa[0] = QPoint(2, 0);
0082         pa[1] = QPoint(-2, 0);
0083         pa[2] = QPoint(0, 3);
0084         break;
0085     case 270:
0086         pa[0] = QPoint(2, 0);
0087         pa[1] = QPoint(-2, 0);
0088         pa[2] = QPoint(0, -3);
0089         break;
0090     };
0091     return pa;
0092 }
0093 
0094 void InputFlowNode::drawShape(QPainter &p)
0095 {
0096     const int _x = int(x());
0097     const int _y = int(y());
0098 
0099     if (m_dir == 0)
0100         p.drawLine(_x, _y, _x - 8, _y);
0101     else if (m_dir == 90)
0102         p.drawLine(_x, _y, _x, _y - 8);
0103     else if (m_dir == 180)
0104         p.drawLine(_x, _y, _x + 8, _y);
0105     else if (m_dir == 270)
0106         p.drawLine(_x, _y, _x, _y + 8);
0107 
0108     QPolygon pa(3);
0109 
0110     switch (m_dir) {
0111     case 180: // right
0112         pa = arrowPoints(0);
0113         break;
0114     case 0: // left
0115         pa = arrowPoints(180);
0116         break;
0117     case 270: // down
0118         pa = arrowPoints(90);
0119         break;
0120     case 90: // up
0121         pa = arrowPoints(270);
0122         break;
0123     default:
0124         qCCritical(KTL_LOG) << "BUG: m_dir = " << m_dir;
0125     }
0126 
0127     // Note: I have not tested the positioning of the arrows for all combinations.
0128     // In fact, most almost definitely do not work. So feel free to change the code
0129     // as you see fit if necessary.
0130 
0131     if (m_dir == 0)
0132         ;
0133     else if (m_dir == 90)
0134         ;
0135     else if (m_dir == 180)
0136         pa.translate(3, 0);
0137     else if (m_dir == 270)
0138         pa.translate(0, 3);
0139 
0140     pa.translate(_x, _y);
0141     p.drawPolygon(pa);
0142 }