From 49ccd98bd1a735c6cf787853addb4ff2a2bfd2e1 Mon Sep 17 00:00:00 2001 From: Leonardo Florez-Valencia Date: Fri, 11 Dec 2015 17:56:39 -0500 Subject: [PATCH] More on graph editor --- appli/cpPipelineEditor/Edge.cxx | 159 +++++++------ appli/cpPipelineEditor/Edge.h | 19 +- appli/cpPipelineEditor/Node.cxx | 387 ++++++++++++++++++++++---------- appli/cpPipelineEditor/Node.h | 37 ++- 4 files changed, 394 insertions(+), 208 deletions(-) diff --git a/appli/cpPipelineEditor/Edge.cxx b/appli/cpPipelineEditor/Edge.cxx index 5c515ee..5fb9c7c 100644 --- a/appli/cpPipelineEditor/Edge.cxx +++ b/appli/cpPipelineEditor/Edge.cxx @@ -1,18 +1,21 @@ #include "Edge.h" #include "Node.h" +#include + // ------------------------------------------------------------------------- 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!!!" ); */ } diff --git a/appli/cpPipelineEditor/Edge.h b/appli/cpPipelineEditor/Edge.h index 4968fb3..bbaeb1e 100644 --- a/appli/cpPipelineEditor/Edge.h +++ b/appli/cpPipelineEditor/Edge.h @@ -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 diff --git a/appli/cpPipelineEditor/Node.cxx b/appli/cpPipelineEditor/Node.cxx index a1026dc..34c4d96 100644 --- a/appli/cpPipelineEditor/Node.cxx +++ b/appli/cpPipelineEditor/Node.cxx @@ -7,9 +7,10 @@ #include #include +#include #include -#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$ -*/ diff --git a/appli/cpPipelineEditor/Node.h b/appli/cpPipelineEditor/Node.h index 8dc526a..41a68c3 100644 --- a/appli/cpPipelineEditor/Node.h +++ b/appli/cpPipelineEditor/Node.h @@ -1,9 +1,16 @@ #ifndef __PIPELINEEDITOR__NODE__H__ #define __PIPELINEEDITOR__NODE__H__ +#include +#include + #include #include + +#include + + // 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 -- 2.47.1