]> Creatis software - cpPlugins.git/commitdiff
More on graph editor
authorLeonardo Florez-Valencia <florez-l@javeriana.edu.co>
Fri, 11 Dec 2015 22:56:39 +0000 (17:56 -0500)
committerLeonardo Florez-Valencia <florez-l@javeriana.edu.co>
Fri, 11 Dec 2015 22:56:39 +0000 (17:56 -0500)
appli/cpPipelineEditor/Edge.cxx
appli/cpPipelineEditor/Edge.h
appli/cpPipelineEditor/Node.cxx
appli/cpPipelineEditor/Node.h

index 5c515eecd0c65cdc6e98437b1beca478c0457980..5fb9c7cea69c499b5b51af8fccb6ff60638707f9 100644 (file)
@@ -1,18 +1,21 @@
 #include "Edge.h"
 #include "Node.h"
 
+#include <QPainter>
+
 // -------------------------------------------------------------------------
 PipelineEditor::Edge::
-Edge( PipelineEditor::Node* src, PipelineEditor::Node* des )
-  : QGraphicsItem( NULL ),
-    m_ArrowSize( 10 )
+Edge(
+  const Node* nsrc, const Node* ndes,
+  const QRectF* rsrc, const QRectF* rdes
+  )
+  : QGraphicsItem( NULL )
 {
   this->setAcceptedMouseButtons( 0 );
-  this->m_Source = src;
-  this->m_Destination = des;
-  this->m_Source->addEdge( this );
-  this->m_Destination->addEdge( this );
-  // TODO: this->setToolTip( "Edge!!!" );
+  this->m_SrcNode = nsrc;
+  this->m_DesNode = ndes;
+  this->m_SrcRect = rsrc;
+  this->m_DesRect = rdes;
   this->adjust( );
 }
 
@@ -23,63 +26,66 @@ PipelineEditor::Edge::
 }
 
 // -------------------------------------------------------------------------
-PipelineEditor::Node* PipelineEditor::Edge::
-sourceNode( ) const
+const QRectF* PipelineEditor::Edge::
+source( ) const
 {
-  return( this->m_Source );
+  return( this->m_SrcRect );
 }
 
 // -------------------------------------------------------------------------
-PipelineEditor::Node* PipelineEditor::Edge::
-destinationNode( ) const
+const QRectF* PipelineEditor::Edge::
+destination( ) const
 {
-  return( this->m_Destination );
+  return( this->m_DesRect );
 }
 
 // -------------------------------------------------------------------------
 void PipelineEditor::Edge::
 adjust( )
 {
-  if( this->m_Source == NULL || this->m_Destination == NULL )
-    return;
 
-  QLineF line(
-    mapFromItem( this->m_Source, 0, 0 ),
-    mapFromItem( this->m_Destination, 0, 0 )
-    );
-  qreal length = line.length( );
-
-  this->prepareGeometryChange( );
-
-  if( length > qreal( 20 ) )
-  {
-    QPointF edgeOffset(
-      ( line.dx( ) * qreal( 10 ) ) / length,
-      ( line.dy( ) * qreal( 10 ) ) / length
-      );
-    this->m_SourcePoint = line.p1( ) + edgeOffset;
-    this->m_DestinationPoint = line.p2( ) - edgeOffset;
-  }
-  else
-    this->m_SourcePoint = this->m_DestinationPoint = line.p1( );
+  /* TODO
+     if( this->m_Src == NULL || this->m_Des == NULL )
+     return;
+
+     QLineF line(
+     this->mapFromParent( this->m_Src->center( ) ),
+     this->mapFromParent( this->m_Des->center( ) )
+     );
+     // TODO: qreal length = line.length( );
+     this->prepareGeometryChange( );
+     if( length > qreal( 20 ) )
+     {
+     QPointF edgeOffset(
+     ( line.dx( ) * qreal( 10 ) ) / length,
+     ( line.dy( ) * qreal( 10 ) ) / length
+     );
+     this->m_SrcPoint = line.p1( ) + edgeOffset;
+     this->m_DesPoint = line.p2( ) - edgeOffset;
+     }
+     else
+     this->m_SrcPoint = this->m_DesPoint = line.p1( );
+  */
 }
 
 // -------------------------------------------------------------------------
 QRectF PipelineEditor::Edge::
 boundingRect( ) const
 {
-  if( this->m_Source == NULL || this->m_Destination == NULL )
+  if( this->m_SrcRect == NULL || this->m_DesRect == NULL )
     return( QRectF( ) );
 
-  qreal penWidth = 1;
-  qreal extra = ( penWidth + this->m_ArrowSize ) / qreal( 2 );
-
+  /*
+    qreal penWidth = 1;
+    qreal extra = ( penWidth + this->m_ArrowSize ) / qreal( 2 );
+  */
+  qreal extra = qreal( 1 );
   return(
     QRectF(
-      this->m_SourcePoint,
+      this->m_SrcRect->center( ),
       QSizeF(
-        this->m_DestinationPoint.x( ) - this->m_SourcePoint.x( ),
-        this->m_DestinationPoint.y( ) - this->m_SourcePoint.y( )
+        this->m_DesRect->center( ).x( ) - this->m_SrcRect->center( ).x( ),
+        this->m_DesRect->center( ).y( ) - this->m_SrcRect->center( ).y( )
         )
       ).normalized( ).adjusted( -extra, -extra, extra, extra )
     );
@@ -92,36 +98,45 @@ paint(
   )
 {
   /* TODO
-  if (!source || !dest)
-      return;
-
-    QLineF line(sourcePoint, destPoint);
-    if (qFuzzyCompare(line.length(), qreal(0.)))
-        return;
-
-    // Draw the line itself
-    painter->setPen(QPen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
-    painter->drawLine(line);
-
-    // Draw the arrows
-    double angle = ::acos(line.dx() / line.length());
-    if (line.dy() >= 0)
-        angle = TwoPi - angle;
-
-    QPointF destArrowP1 = destPoint + QPointF(
-      sin(angle - Pi / 3) * arrowSize,
-      cos(angle - Pi / 3) * arrowSize
-      );
-    QPointF destArrowP2 = destPoint + QPointF(
-      sin(angle - Pi + Pi / 3) * arrowSize,
-      cos(angle - Pi + Pi / 3) * arrowSize
-      );
-    QPointF center = sourcePoint + destPoint;
-    center /= 2;
-
-    painter->setBrush(Qt::black);
-    painter->drawPolygon(QPolygonF() << line.p2() << destArrowP1 << destArrowP2);
-    painter->drawText( center, "Edge!!!" );
+    if( this->m_Src == NULL || this->m_Des == NULL )
+    return;
+  */
+
+  // TODO: QLineF line( this->m_Src->center( ), this->m_Des->center( ) );
+  QLineF line(
+    this->m_SrcNode->mapToScene( this->m_SrcRect->center( ) ),
+    this->m_DesNode->mapToScene( this->m_DesRect->center( ) )
+    );
+
+  if( qFuzzyCompare( line.length(), qreal( 0 ) ) )
+    return;
+
+  // Draw the line itself
+  painter->setPen(
+    QPen( Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin )
+    );
+  painter->drawLine( line );
+
+  /* TODO
+     // Draw the arrows
+     double angle = ::acos(line.dx() / line.length());
+     if (line.dy() >= 0)
+     angle = TwoPi - angle;
+
+     QPointF destArrowP1 = destPoint + QPointF(
+     sin(angle - Pi / 3) * arrowSize,
+     cos(angle - Pi / 3) * arrowSize
+     );
+     QPointF destArrowP2 = destPoint + QPointF(
+     sin(angle - Pi + Pi / 3) * arrowSize,
+     cos(angle - Pi + Pi / 3) * arrowSize
+     );
+     QPointF center = sourcePoint + destPoint;
+     center /= 2;
+
+     painter->setBrush(Qt::black);
+     painter->drawPolygon(QPolygonF() << line.p2() << destArrowP1 << destArrowP2);
+     painter->drawText( center, "Edge!!!" );
   */
 }
 
index 4968fb3841e68f29be62bb7ca5185e2637b9cd1b..bbaeb1e3f6e68806f1d29952d276b8000858e6b2 100644 (file)
@@ -14,11 +14,14 @@ namespace PipelineEditor
     : public QGraphicsItem
   {
   public:
-    Edge( Node* src, Node* des );
+    Edge(
+      const Node* nsrc, const Node* ndes,
+      const QRectF* rsrc, const QRectF* rdes
+      );
     virtual ~Edge( );
 
-    Node* sourceNode( ) const;
-    Node* destinationNode( ) const;
+    const QRectF* source( ) const;
+    const QRectF* destination( ) const;
     void adjust( );
     QRectF boundingRect( ) const;
     void paint(
@@ -28,12 +31,10 @@ namespace PipelineEditor
       );
 
   private:
-    Node* m_Source;
-    Node* m_Destination;
-
-    QPointF m_SourcePoint;
-    QPointF m_DestinationPoint;
-    qreal m_ArrowSize;
+    const Node* m_SrcNode;
+    const Node* m_DesNode;
+    const QRectF* m_SrcRect;
+    const QRectF* m_DesRect;
   };
 
 } // ecapseman
index a1026dc6260e211eeb1255c13a13a2fd6901bc89..34c4d96fddc1f314503331b54f1dc7a0d0303fdb 100644 (file)
@@ -7,9 +7,10 @@
 #include <QGraphicsSceneHoverEvent>
 
 #include <cpPlugins/Interface/Object.h>
+#include <cpPlugins/Interface/DataObject.h>
 #include <cpPlugins/Interface/ProcessObject.h>
 
-#define PORT_SIZE 10
+#define PORT_SIZE 15
 
 // -------------------------------------------------------------------------
 PipelineEditor::Node::
@@ -17,14 +18,16 @@ Node( GraphCanvas* canvas, cpPlugins::Interface::Object* object )
   : QGraphicsItem( NULL ),
     m_Canvas( canvas ),
     m_Object( object ),
-    m_UpdatedBounds( false )
+    m_SelectedPort( NULL ),
+    m_DraggingPort( false )
 {
-  this->setFlag( QGraphicsItem::ItemIsMovable );
-  this->setFlag( QGraphicsItem::ItemSendsGeometryChanges );
+  this->setFlag( QGraphicsItem::ItemIsMovable, true );
+  this->setFlag( QGraphicsItem::ItemSendsGeometryChanges, true );
   this->setCacheMode( QGraphicsItem::DeviceCoordinateCache );
   this->setAcceptHoverEvents( true );
+  this->setAcceptDrops( true );
   this->setZValue( -1 );
-  this->setToolTip( this->m_Object->GetName( ) );
+  this->updateRepresentation( );
 }
 
 // -------------------------------------------------------------------------
@@ -49,49 +52,95 @@ edges( ) const
 }
 
 // -------------------------------------------------------------------------
-QRectF PipelineEditor::Node::
-boundingRect( ) const
+void PipelineEditor::Node::
+updateRepresentation( )
 {
+  typedef cpPlugins::Interface::DataObject    _TData;
   typedef cpPlugins::Interface::ProcessObject _TFilter;
-  if( !this->m_UpdatedBounds )
+
+  if( this->m_Object == NULL )
+    return;
+
+  // Try to infere type
+  _TData* d = dynamic_cast< _TData* >( this->m_Object );
+  _TFilter* f = dynamic_cast< _TFilter* >( this->m_Object );
+  if( d == NULL && f == NULL )
+    return;
+
+  // Label and its bounds
+  QFontMetricsF fm( this->m_Canvas->font( ) );
+  this->m_Label  = this->m_Object->GetName( );
+  this->m_Label += "\n";
+  this->m_Label += this->m_Object->GetClassName( ).c_str( );
+  this->m_Bounds = fm.boundingRect( this->m_Label );
+
+  // Create ports representation
+  this->m_Inputs.clear( );
+  this->m_Outputs.clear( );
+  this->m_InputPorts.clear( );
+  this->m_OutputPorts.clear( );
+  if( f != NULL )
   {
-    // Text bounding box
-    QFontMetricsF fm( this->m_Canvas->font( ) );
-    this->m_Label = this->m_Object->GetName( );
-    this->m_Label += "\n";
-    this->m_Label += this->m_Object->GetClassName( ).c_str( );
-
-    // Ports
-    this->m_Bounds = fm.boundingRect( this->m_Label );
-    const _TFilter* f = dynamic_cast< const _TFilter* >( this->m_Object );
-    if( f != NULL )
+    // Get filter's inputs and outputs
+    f->GetInputsNames( this->m_Inputs );
+    f->GetOutputsNames( this->m_Outputs );
+
+    // Correct height
+    unsigned int nIn = this->m_Inputs.size( );
+    unsigned int nOut = this->m_Outputs.size( );
+    qreal n =
+      qreal( ( ( ( ( nIn > nOut )? nIn: nOut ) << 1 ) + 1 ) * PORT_SIZE );
+    qreal h = this->m_Bounds.height( );
+    if( n > h )
+      this->m_Bounds.setHeight( n );
+
+    // Get bounds values
+    qreal rt = this->m_Bounds.top( ) - qreal( PORT_SIZE );
+    qreal rb = this->m_Bounds.bottom( ) + qreal( PORT_SIZE );
+    qreal rl = this->m_Bounds.left( ) - qreal( PORT_SIZE );
+    qreal rr = this->m_Bounds.right( ) + qreal( PORT_SIZE );
+
+    // Add some space to the geometry
+    this->m_Bounds.setTop( rt );
+    this->m_Bounds.setBottom( rb );
+    this->m_Bounds.setLeft( rl );
+    this->m_Bounds.setRight( rr );
+    qreal rh = this->m_Bounds.height( );
+
+    // Create ports
+    QSizeF ps( qreal( PORT_SIZE ), qreal( PORT_SIZE ) );
+    std::set< std::string >* ports[] =
+      { &( this->m_Inputs ), &( this->m_Outputs ) };
+    for( unsigned int pId = 0; pId < 2; ++pId )
     {
-      unsigned int nIn = f->GetNumberOfInputs( );
-      unsigned int nOut = f->GetNumberOfOutputs( );
-      qreal n =
-        qreal( ( ( ( ( nIn > nOut )? nIn: nOut ) << 1 ) + 1 ) * PORT_SIZE );
-      qreal h = this->m_Bounds.height( );
-      if( n > h )
-        this->m_Bounds.setHeight( n );
-
-      // Let some space for ports
-      this->m_Bounds.setLeft(
-        this->m_Bounds.left( ) - qreal( PORT_SIZE )
-        );
-      this->m_Bounds.setTop(
-        this->m_Bounds.top( ) - qreal( PORT_SIZE )
-        );
-      this->m_Bounds.setRight(
-        this->m_Bounds.right( ) + qreal( PORT_SIZE )
-        );
-      this->m_Bounds.setBottom(
-        this->m_Bounds.bottom( ) + qreal( PORT_SIZE )
-        );
+      qreal h = qreal( ( ( ports[ pId ]->size( ) << 1 ) + 1 ) * PORT_SIZE );
+      qreal off = qreal( PORT_SIZE );
+      if( rh > h )
+        off += ( rh - h ) / qreal( 2 );
+      for( auto i = ports[ pId ]->begin( ); i != ports[ pId ]->end( ); ++i )
+      {
+        if( pId == 0 )
+          this->m_InputPorts[ *i ] =
+            QRectF( QPointF( rl, rt + off ), ps );
+        else
+          this->m_OutputPorts[ *i ] =
+            QRectF( QPointF( rr - qreal( PORT_SIZE ), rt + off ), ps );
+        off += qreal( PORT_SIZE < 1 );
+
+      } // rof
 
-    } // fi
-    this->m_UpdatedBounds = true;
+    } // rof
 
   } // fi
+
+  // Some other initializations
+  this->m_SelectedPort = NULL;
+}
+
+// -------------------------------------------------------------------------
+QRectF PipelineEditor::Node::
+boundingRect( ) const
+{
   return( this->m_Bounds );
 }
 
@@ -100,7 +149,7 @@ QPainterPath PipelineEditor::Node::
 shape( ) const
 {
   QPainterPath path;
-  path.addRect( this->boundingRect( ) );
+  path.addRect( this->m_Bounds );
   return( path );
 }
 
@@ -110,49 +159,23 @@ paint(
   QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget
   )
 {
-  typedef cpPlugins::Interface::ProcessObject _TFilter;
-
+  // Draw main box
   QRectF rect = this->boundingRect( );
   painter->drawRect( rect );
   painter->drawText( rect, Qt::AlignCenter, this->m_Label );
 
-  // Show ports
-  const _TFilter* f = dynamic_cast< const _TFilter* >( this->m_Object );
-  if( f != NULL )
-  {
-    QSizeF port_size( qreal( PORT_SIZE ), qreal( PORT_SIZE ) );
-    qreal rh = rect.height( );
-    qreal rt = rect.top( );
-    qreal rl = rect.left( );
-    qreal rr = rect.right( );
-
-    std::set< std::string > inputs, outputs;
-    f->GetInputsNames( inputs );
-    f->GetOutputsNames( outputs );
-
-    qreal oh = qreal( ( ( inputs.size( ) << 1 ) + 1 ) * PORT_SIZE );
-    qreal off = qreal( PORT_SIZE );
-    if( rh > oh )
-      off += ( rh - oh ) / qreal( 2 );
-    for( auto it = inputs.begin( ); it != inputs.end( ); ++it )
-    {
-      painter->drawRect( QRectF( QPointF( rl, rt + off ), port_size ) );
-      off += qreal( PORT_SIZE < 1 );
+  // Draw ports
+  std::map< std::string, QRectF >* ports[] =
+    { &( this->m_InputPorts ), &( this->m_OutputPorts ) };
+  for( unsigned int pId = 0; pId < 2; ++pId )
+    for( auto i = ports[ pId ]->begin( ); i != ports[ pId ]->end( ); ++i )
+      painter->drawRect( i->second );
 
-    } // rof
-
-    oh = qreal( ( ( outputs.size( ) << 1 ) + 1 ) * PORT_SIZE );
-    off = qreal( PORT_SIZE );
-    if( rh > oh )
-      off += ( rh - oh ) / qreal( 2 );
-    for( auto it = outputs.begin( ); it != outputs.end( ); ++it )
-    {
-      painter->drawRect(
-        QRectF( QPointF( rr - qreal( PORT_SIZE ), rt + off ), port_size )
-        );
-      off += qreal( PORT_SIZE < 1 );
-
-    } // rof
+  // Draw clicked port
+  if( this->m_SelectedPort != NULL )
+  {
+    painter->setBrush( Qt::green );
+    painter->drawEllipse( *( this->m_SelectedPort ) );
 
   } // fi
 }
@@ -161,18 +184,16 @@ paint(
 QVariant PipelineEditor::Node::
 itemChange( GraphicsItemChange change, const QVariant& value )
 {
-  /* TODO
-     switch( change )
-     {
-     case QGraphicsItem::ItemPositionHasChanged:
-     foreach( Edge* edge, this->m_Edges )
-     edge->adjust( );
-     this->m_Canvas->itemMoved( );
-     break;
-     default:
-     break;
-     } // hctiws
-  */
+  switch( change )
+  {
+  case QGraphicsItem::ItemPositionHasChanged:
+    foreach( Edge* edge, this->m_Edges )
+      edge->update( );
+    this->m_Canvas->itemMoved( );
+    break;
+  default:
+    break;
+  } // hctiws
   return( this->QGraphicsItem::itemChange( change, value ) );
 }
 
@@ -180,6 +201,54 @@ itemChange( GraphicsItemChange change, const QVariant& value )
 void PipelineEditor::Node::
 mousePressEvent( QGraphicsSceneMouseEvent* event )
 {
+  if( this->m_SelectedPort != NULL && this->m_Canvas != NULL )
+  {
+    if( event->button( ) == Qt::LeftButton )
+    {
+      QDrag* drag = new QDrag( this->m_Canvas );
+      QMimeData* mimeData = new QMimeData( );
+
+      // mimeData->setText( "drag_data" );
+      qulonglong address = reinterpret_cast< qulonglong >( this );
+      QByteArray ba;
+      ba.setNum( address );
+      mimeData->setData( "source_node", ba );
+      drag->setMimeData( mimeData );
+      // TODO: drag->setPixmap( iconPixmap );
+
+      this->m_DraggingPort = true;
+      Qt::DropAction dropAction = drag->exec( );
+      this->m_DraggingPort = false;
+
+    } // fi
+  }
+  else
+  {
+  } // fi
+
+  /* TODO
+     Qt::MouseButton btn = event->button( );
+     if( btn == Qt::LeftButton )
+     {
+     std::string name = this->toolTip( ).toStdString( );
+     if( name != this->m_Object->GetName( ) )
+     {
+     // Get clicked port, if any
+     QPointF pos = event->buttonDownPos( btn );
+     auto iIt = this->m_InputPorts.find( name );
+     auto oIt = this->m_OutputPorts.find( name );
+     this->m_SelectedPort = NULL;
+     if( iIt != this->m_InputPorts.end( ) )
+     if( iIt->second.contains( pos ) )
+     this->m_SelectedPort = &( iIt->second );
+      if( this->m_SelectedPort == NULL && oIt != this->m_OutputPorts.end( ) )
+      if( oIt->second.contains( pos ) )
+      this->m_SelectedPort = &( oIt->second );
+
+      } // fi
+
+      } // fi
+  */
   this->update( );
   this->QGraphicsItem::mousePressEvent( event );
 }
@@ -202,51 +271,121 @@ mouseDoubleClickEvent( QGraphicsSceneMouseEvent* event )
 void PipelineEditor::Node::
 hoverMoveEvent( QGraphicsSceneHoverEvent* event )
 {
-  QPointF pos = event->pos( );
+  this->_selectPort( event->pos( ) );
 }
 
-/* TODO
-   private:
-   GraphCanvas*   m_Canvas;
-   QList< Edge* > m_Edges;
-   std::string    m_Label;
-   };
-
-   } // ecapseman
-
-   #endif // __PIPELINEEDITOR__NODE__H__
-*/
+// -------------------------------------------------------------------------
+void PipelineEditor::Node::
+hoverLeaveEvent( QGraphicsSceneHoverEvent* event )
+{
+  this->_deselectPort( );
+}
 
-// eof - $RCSfile$
+// -------------------------------------------------------------------------
+void PipelineEditor::Node::
+dragMoveEvent( QGraphicsSceneDragDropEvent* event )
+{
+  this->_selectPort( event->pos( ) );
+}
 
+// -------------------------------------------------------------------------
+void PipelineEditor::Node::
+dragLeaveEvent( QGraphicsSceneDragDropEvent* event )
+{
+  this->_deselectPort( );
+}
 
-/*
-QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value)
+// -------------------------------------------------------------------------
+void PipelineEditor::Node::
+dropEvent( QGraphicsSceneDragDropEvent* event )
 {
-  switch (change) {
-  case ItemPositionHasChanged:
-    foreach (Edge *edge, edgeList)
-      edge->adjust();
-    graph->itemMoved();
-    break;
-  default:
-    break;
-  };
+  // Get vertices and directionality
+  bool ok;
+  qulonglong address =
+    event->mimeData( )->data( "source_node" ).toULongLong( &ok );
+  Node* src = reinterpret_cast< Node* >( address );
+  if( src == NULL )
+    return;
+  Node* des = this;
+  if( src->m_SelectedPortIsInput )
+  {
+    des = src;
+    src = this;
+
+  } // fi
 
-  return QGraphicsItem::itemChange(change, value);
+  // Discard if a loop is detected
+  if( src == des )
+    return;
+
+  // Get edge data
+  const QRectF* srcPort = src->m_SelectedPort;
+  const QRectF* desPort = des->m_SelectedPort;
+  std::string srcName = src->m_Object->GetName( );
+  std::string desName = des->m_Object->GetName( );
+  std::string srcPortName = src->toolTip( ).toStdString( );
+  std::string desPortName = des->toolTip( ).toStdString( );
+
+  Edge* e = new Edge( src, des, srcPort, desPort );
+  src->addEdge( e );
+  des->addEdge( e );
+  if( this->m_Canvas != NULL )
+    this->m_Canvas->scene( )->addItem( e );
 }
 
-void Node::mousePressEvent(QGraphicsSceneMouseEvent *event)
+// -------------------------------------------------------------------------
+void PipelineEditor::Node::
+_selectPort( const QPointF& pos )
 {
-  update();
-  QGraphicsItem::mousePressEvent(event);
+  if( this->m_DraggingPort )
+    return;
+
+  const QRectF* prevPort = this->m_SelectedPort;
+
+  // Check ports
+  std::map< std::string, QRectF >* ports[] =
+    { &( this->m_InputPorts ), &( this->m_OutputPorts ) };
+  bool found = false;
+  for( unsigned int pId = 0; pId < 2 && !found; ++pId )
+  {
+    for(
+      auto i = ports[ pId ]->begin( );
+      i != ports[ pId ]->end( ) && !found;
+      ++i
+      )
+    {
+      if( i->second.contains( pos ) )
+      {
+        this->setToolTip( i->first.c_str( ) );
+        this->m_SelectedPort = &( i->second );
+        this->m_SelectedPortIsInput = ( pId == 0 );
+        found = true;
+
+      } // fi
+
+    } // rof
+
+  } // rof
+  if( !found )
+  {
+    this->setToolTip( this->m_Object->GetName( ) );
+    this->m_SelectedPort = NULL;
+
+  } // fi
+  if( prevPort != this->m_SelectedPort )
+    this->update( );
 }
 
-void Node::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+// -------------------------------------------------------------------------
+void PipelineEditor::Node::
+_deselectPort( )
 {
-  update();
-  QGraphicsItem::mouseReleaseEvent(event);
+  if( !( this->m_DraggingPort ) )
+  {
+    this->m_SelectedPort = NULL;
+    this->update( );
+
+  } // fi
 }
 
 // eof - $RCSfile$
-*/
index 8dc526a9aceae4b1543057e501cbc8de885f1dd3..41a68c35c0e5cbb0ef6ba1d477847568bca9f309 100644 (file)
@@ -1,9 +1,16 @@
 #ifndef __PIPELINEEDITOR__NODE__H__
 #define __PIPELINEEDITOR__NODE__H__
 
+#include <map>
+#include <set>
+
 #include <QGraphicsItem>
 #include <QList>
 
+
+#include <iostream>
+
+
 // Some forward declarations
 class QGraphicsSceneMouseEvent;
 class QGraphicsSceneHoverEvent;
@@ -35,6 +42,8 @@ namespace PipelineEditor
     void addEdge( Edge* edge );
     QList< Edge* > edges( ) const;
 
+    void updateRepresentation( );
+
     QRectF boundingRect( ) const;
     QPainterPath shape( ) const;
     void paint(
@@ -42,6 +51,11 @@ namespace PipelineEditor
       const QStyleOptionGraphicsItem* option,
       QWidget* widget
       );
+    void moveBy(qreal dx, qreal dy)
+      {
+        std::cout << "move: " << dx << " " << dy << std::endl;
+        this->QGraphicsItem::moveBy( dx, dy );
+      }
 
   protected:
     QVariant itemChange( GraphicsItemChange change, const QVariant& value );
@@ -50,14 +64,31 @@ namespace PipelineEditor
     void mouseReleaseEvent( QGraphicsSceneMouseEvent* event );
     void mouseDoubleClickEvent( QGraphicsSceneMouseEvent* event );
     void hoverMoveEvent( QGraphicsSceneHoverEvent* event );
+    void hoverLeaveEvent( QGraphicsSceneHoverEvent* event );
+    void dragMoveEvent( QGraphicsSceneDragDropEvent* event );
+    void dragLeaveEvent( QGraphicsSceneDragDropEvent* event );
+    void dropEvent( QGraphicsSceneDragDropEvent* event );
+
+    void _selectPort( const QPointF& pos );
+    void _deselectPort( );
 
   private:
     GraphCanvas*   m_Canvas;
     QList< Edge* > m_Edges;
     cpPlugins::Interface::Object* m_Object;
-    mutable QString m_Label;
-    mutable QRectF m_Bounds;
-    mutable bool m_UpdatedBounds;
+
+    // Graphical objects
+    QString m_Label;
+    QRectF m_Bounds;
+    std::set< std::string > m_Inputs;
+    std::set< std::string > m_Outputs;
+    std::map< std::string, QRectF > m_InputPorts;
+    std::map< std::string, QRectF > m_OutputPorts;
+
+    // Interaction objects
+    const QRectF* m_SelectedPort;
+    bool m_SelectedPortIsInput;
+    bool m_DraggingPort;
   };
 
 } // ecapseman