fpnode.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2003-2005 by David Saxton                               *
00003  *   david@bluehaze.org                                                    *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  ***************************************************************************/
00010 
00011 #include "icndocument.h"
00012 #include "connector.h"
00013 #include "flowpart.h"
00014 #include "fpnode.h"
00015 
00016 #include <kdebug.h>
00017 #include <qpainter.h>
00018 
00019 FPNode::FPNode( ICNDocument *icnDocument, Node::node_type type, node_dir dir, const QPoint &pos, QString *id )
00020         : Node( icnDocument, type, dir, pos, id )
00021 {
00022         icnDocument->registerItem(this);
00023 }
00024 
00025 
00026 FPNode::~FPNode()
00027 {
00028 }
00029 
00030 
00031 FlowPart *FPNode::outputFlowPart() const
00032 {
00033         FlowPart *flowPart = dynamic_cast<FlowPart*>(parentItem());
00034         
00035         if ( type() == fp_in )
00036                 return flowPart;
00037         
00038         if ( m_outputConnectorList.size() > 1 )
00039                 kdError() << "FpNode::outputFlowPart(): outputConnectorList() size is greater than 1"<<endl;
00040         
00041         else if ( m_outputConnectorList.size() < 1 )
00042                 return 0;
00043         
00044         ConnectorList::const_iterator it = m_outputConnectorList.begin();
00045         if ( it == m_outputConnectorList.end() || !*it || !(*it)->endNode()  )
00046                 return 0;
00047         
00048         return (dynamic_cast<FPNode*>((*it)->endNode()))->outputFlowPart();
00049 }
00050 
00051 
00052 FlowPartList FPNode::inputFlowParts() const
00053 {
00054         FlowPartList list;
00055         FlowPart *flowPart = dynamic_cast<FlowPart*>(parentItem());
00056         if ( type() != fp_in && flowPart )
00057         {
00058                 list.append(flowPart);
00059                 return list;
00060         }
00061         const ConnectorList::const_iterator end = m_inputConnectorList.end();
00062         for ( ConnectorList::const_iterator it = m_inputConnectorList.begin(); it != end; ++it )
00063         {
00064                 if (*it)
00065                 {
00066                         Node *startNode = (*it)->startNode();
00067                         FlowPart *flowPart = startNode ? dynamic_cast<FlowPart*>(startNode->parentItem()) : 0;
00068                         if (flowPart)
00069                                 list.append(flowPart);
00070                 }
00071         }
00072         return list;
00073 }
00074 
00075 
00076 inline QPointArray arrowPoints( Node::node_dir dir )
00077 {
00078         QPointArray pa(3);
00079         switch (dir)
00080         {
00081                 case Node::dir_right:
00082                         pa[0] = QPoint( 3, 0 );
00083                         pa[1] = QPoint( 0, 2 );
00084                         pa[2] = QPoint( 0, -2 );
00085                         break;
00086                 case Node::dir_left:
00087                         pa[0] = QPoint( -3, 0 );
00088                         pa[1] = QPoint( 0, 2 );
00089                         pa[2] = QPoint( 0, -2 );
00090                         break;
00091                 case Node::dir_down:
00092                         pa[0] = QPoint( 2, 0 );
00093                         pa[1] = QPoint( -2, 0 );
00094                         pa[2] = QPoint( 0, 3 );
00095                         break;
00096                 case Node::dir_up:
00097                         pa[0] = QPoint( 2, 0 );
00098                         pa[1] = QPoint( -2, 0 );
00099                         pa[2] = QPoint( 0, -3 );
00100                         break;
00101         };
00102         return pa;
00103 }
00104 
00105 
00106 void FPNode::drawShape( QPainter &p )
00107 {
00108         const int _x = (int)x();
00109         const int _y = (int)y();
00110         
00111         if ( type() == fp_junction && !m_inputConnectorList.isEmpty() )
00112         {
00113                 const ConnectorList::iterator end = m_inputConnectorList.end();
00114                 for ( ConnectorList::iterator it = m_inputConnectorList.begin(); it != end; ++ it)
00115                 {
00116                         Connector * connector = *it;
00117                         if (!connector)
00118                                 continue;
00119                 
00120                         // Work out the direction of the connector
00121                         const QPointList points = connector->connectorPoints(false);
00122                 
00123                         const int count = points.size();
00124                         if ( count < 2 )
00125                                 continue;
00126                 
00127                         QPoint end_0 = points[count-1];
00128                         QPoint end_1 = points[count-2];
00129                 
00130                         QPointArray pa;
00131                         if ( end_0.x() < end_1.x() )
00132                         {
00133                                 pa = arrowPoints( Node::dir_left );
00134                                 pa.translate( 4, 0 );
00135                         }
00136                         else if ( end_0.x() > end_1.x() )
00137                         {
00138                                 pa = arrowPoints( Node::dir_right );
00139                                 pa.translate( -4, 0 );
00140                         }
00141                         else if ( end_0.y() < end_1.y() )
00142                         {
00143                                 pa = arrowPoints( Node::dir_up );
00144                                 pa.translate( 0, 4 );
00145                         }
00146                         else if ( end_0.y() > end_1.y() )
00147                         {
00148                                 pa = arrowPoints( Node::dir_down );
00149                                 pa.translate( 0, -4 );
00150                         }
00151                         else
00152                                 continue;
00153                         
00154                         pa.translate( _x, _y );
00155                         p.setPen( connector->isSelected() ? m_selectedColor : Qt::black );
00156                         p.drawPolygon(pa);
00157                 }
00158                 return;
00159         }
00160         
00161         if              ( m_dir == Node::dir_right )    p.drawLine( _x, _y, _x-8, _y );
00162         else if ( m_dir == Node::dir_down )             p.drawLine( _x, _y, _x, _y-8 );
00163         else if ( m_dir == Node::dir_left )             p.drawLine( _x, _y, _x+8, _y );
00164         else if ( m_dir == Node::dir_up )               p.drawLine( _x, _y, _x, _y+8 );
00165         
00166         QPointArray pa(3);      
00167         
00168         // Right facing arrow
00169         if ( (type() == fp_out && m_dir == Node::dir_right) ||
00170                          (type() == fp_in && m_dir == Node::dir_left ) )
00171                 pa = arrowPoints( Node::dir_right );
00172         
00173         // Left facing arrow
00174         else if ( (type() == fp_out && m_dir == Node::dir_left) ||
00175                                   (type() == fp_in && m_dir == Node::dir_right) )
00176                 pa = arrowPoints( Node::dir_left );
00177         
00178         // Down facing arrow
00179         else if ( (type() == fp_out && m_dir == Node::dir_down) ||
00180                                   (type() == fp_in && m_dir == Node::dir_up) )
00181                 pa = arrowPoints( Node::dir_down );
00182         
00183         // Up facing arrow
00184         else
00185                 pa = arrowPoints( Node::dir_up );
00186         
00187         
00188         // Note: I have not tested the positioning of the arrows for all combinations.
00189         // In fact, most almost definitely do not work. So feel free to change the code
00190         // as you see fit if necessary.
00191         
00192         if ( type() == fp_out )
00193         {
00194                 if              ( m_dir == Node::dir_right ) pa.translate( -5, 0 );
00195                 else if ( m_dir == Node::dir_down ) pa.translate( 0, -5 );
00196                 else if ( m_dir == Node::dir_left ) pa.translate( 5, 0 );
00197                 else if ( m_dir == Node::dir_up ) pa.translate( 0, 5 );
00198         }
00199         else if ( type() == fp_in )
00200         {
00201                 if              ( m_dir == Node::dir_right );
00202                 else if ( m_dir == Node::dir_down );
00203                 else if ( m_dir == Node::dir_left ) pa.translate( 3, 0 );
00204                 else if ( m_dir == Node::dir_up ) pa.translate( 0, 3 );
00205         }
00206         else return;
00207         
00208         pa.translate( _x, _y );
00209         p.drawPolygon(pa);
00210 }
00211 
00212 #include "fpnode.moc"

Generated on Tue May 8 17:05:30 2007 for KTechLab by  doxygen 1.5.1