You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ktechlab/src/fpnode.cpp

213 lines
5.6 KiB

/***************************************************************************
* Copyright (C) 2003-2005 by David Saxton *
* david@bluehaze.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
***************************************************************************/
#include "icndocument.h"
#include "connector.h"
#include "flowpart.h"
#include "fpnode.h"
#include <kdebug.h>
#include <tqpainter.h>
FPNode::FPNode( ICNDocument *icnDocument, Node::node_type type, node_dir dir, const TQPoint &pos, TQString *id )
: Node( icnDocument, type, dir, pos, id )
{
icnDocument->registerItem(this);
}
FPNode::~FPNode()
{
}
FlowPart *FPNode::outputFlowPart() const
{
FlowPart *flowPart = dynamic_cast<FlowPart*>(parentItem());
if ( type() == fp_in )
return flowPart;
if ( m_outputConnectorList.size() > 1 )
kdError() << "FpNode::outputFlowPart(): outputConnectorList() size is greater than 1"<<endl;
else if ( m_outputConnectorList.size() < 1 )
return 0l;
ConnectorList::const_iterator it = m_outputConnectorList.begin();
if ( it == m_outputConnectorList.end() || !*it || !(*it)->endNode() )
return 0L;
return (dynamic_cast<FPNode*>((*it)->endNode()))->outputFlowPart();
}
FlowPartList FPNode::inputFlowParts() const
{
FlowPartList list;
FlowPart *flowPart = dynamic_cast<FlowPart*>(parentItem());
if ( type() != fp_in && flowPart )
{
list.append(flowPart);
return list;
}
const ConnectorList::const_iterator end = m_inputConnectorList.end();
for ( ConnectorList::const_iterator it = m_inputConnectorList.begin(); it != end; ++it )
{
if (*it)
{
Node *startNode = (*it)->startNode();
FlowPart *flowPart = startNode ? dynamic_cast<FlowPart*>(startNode->parentItem()) : 0l;
if (flowPart)
list.append(flowPart);
}
}
return list;
}
inline TQPointArray arrowPoints( Node::node_dir dir )
{
TQPointArray pa(3);
switch (dir)
{
case Node::dir_right:
pa[0] = TQPoint( 3, 0 );
pa[1] = TQPoint( 0, 2 );
pa[2] = TQPoint( 0, -2 );
break;
case Node::dir_left:
pa[0] = TQPoint( -3, 0 );
pa[1] = TQPoint( 0, 2 );
pa[2] = TQPoint( 0, -2 );
break;
case Node::dir_down:
pa[0] = TQPoint( 2, 0 );
pa[1] = TQPoint( -2, 0 );
pa[2] = TQPoint( 0, 3 );
break;
case Node::dir_up:
pa[0] = TQPoint( 2, 0 );
pa[1] = TQPoint( -2, 0 );
pa[2] = TQPoint( 0, -3 );
break;
};
return pa;
}
void FPNode::drawShape( TQPainter &p )
{
const int _x = (int)x();
const int _y = (int)y();
if ( type() == fp_junction && !m_inputConnectorList.isEmpty() )
{
const ConnectorList::iterator end = m_inputConnectorList.end();
for ( ConnectorList::iterator it = m_inputConnectorList.begin(); it != end; ++ it)
{
Connector * connector = *it;
if (!connector)
continue;
// Work out the direction of the connector
const TQPointList points = connector->connectorPoints(false);
const int count = points.size();
if ( count < 2 )
continue;
TQPoint end_0 = points[count-1];
TQPoint end_1 = points[count-2];
TQPointArray pa;
if ( end_0.x() < end_1.x() )
{
pa = arrowPoints( Node::dir_left );
pa.translate( 4, 0 );
}
else if ( end_0.x() > end_1.x() )
{
pa = arrowPoints( Node::dir_right );
pa.translate( -4, 0 );
}
else if ( end_0.y() < end_1.y() )
{
pa = arrowPoints( Node::dir_up );
pa.translate( 0, 4 );
}
else if ( end_0.y() > end_1.y() )
{
pa = arrowPoints( Node::dir_down );
pa.translate( 0, -4 );
}
else
continue;
pa.translate( _x, _y );
p.setPen( connector->isSelected() ? m_selectedColor : TQt::black );
p.drawPolygon(pa);
}
return;
}
if ( m_dir == Node::dir_right ) p.drawLine( _x, _y, _x-8, _y );
else if ( m_dir == Node::dir_down ) p.drawLine( _x, _y, _x, _y-8 );
else if ( m_dir == Node::dir_left ) p.drawLine( _x, _y, _x+8, _y );
else if ( m_dir == Node::dir_up ) p.drawLine( _x, _y, _x, _y+8 );
TQPointArray pa(3);
// Right facing arrow
if ( (type() == fp_out && m_dir == Node::dir_right) ||
(type() == fp_in && m_dir == Node::dir_left ) )
pa = arrowPoints( Node::dir_right );
// Left facing arrow
else if ( (type() == fp_out && m_dir == Node::dir_left) ||
(type() == fp_in && m_dir == Node::dir_right) )
pa = arrowPoints( Node::dir_left );
// Down facing arrow
else if ( (type() == fp_out && m_dir == Node::dir_down) ||
(type() == fp_in && m_dir == Node::dir_up) )
pa = arrowPoints( Node::dir_down );
// Up facing arrow
else
pa = arrowPoints( Node::dir_up );
// Note: I have not tested the positioning of the arrows for all combinations.
// In fact, most almost definitely do not work. So feel free to change the code
// as you see fit if necessary.
if ( type() == fp_out )
{
if ( m_dir == Node::dir_right ) pa.translate( -5, 0 );
else if ( m_dir == Node::dir_down ) pa.translate( 0, -5 );
else if ( m_dir == Node::dir_left ) pa.translate( 5, 0 );
else if ( m_dir == Node::dir_up ) pa.translate( 0, 5 );
}
else if ( type() == fp_in )
{
if ( m_dir == Node::dir_right );
else if ( m_dir == Node::dir_down );
else if ( m_dir == Node::dir_left ) pa.translate( 3, 0 );
else if ( m_dir == Node::dir_up ) pa.translate( 0, 3 );
}
else return;
pa.translate( _x, _y );
p.drawPolygon(pa);
}
#include "fpnode.moc"