1 #include "QNodesEditorCanvas.h"
2 #include "QNodesEditor.h"
4 #include "QNEConnection.h"
7 #include <QDragEnterEvent>
11 // -------------------------------------------------------------------------
12 PipelineEditor::QNodesEditorCanvas::
13 QNodesEditorCanvas( QWidget* parent )
14 : QGraphicsView( parent ),
17 QGraphicsScene* scene = new QGraphicsScene( this );
18 this->setScene( scene );
19 this->setRenderHint( QPainter::Antialiasing );
20 this->setAcceptDrops( true );
22 this->m_Editor = new QNodesEditor( this );
23 this->m_Editor->install( scene );
26 // -------------------------------------------------------------------------
27 PipelineEditor::QNodesEditorCanvas::
28 ~QNodesEditorCanvas( )
32 // -------------------------------------------------------------------------
33 PipelineEditor::QNodesEditorCanvas::
34 TWorkspace* PipelineEditor::QNodesEditorCanvas::
37 return( this->m_Workspace );
40 // -------------------------------------------------------------------------
41 const PipelineEditor::QNodesEditorCanvas::
42 TWorkspace* PipelineEditor::QNodesEditorCanvas::
45 return( this->m_Workspace );
48 // -------------------------------------------------------------------------
49 void PipelineEditor::QNodesEditorCanvas::
50 setWorkspace( TWorkspace* ws )
52 if( this->m_Workspace == ws )
54 this->m_Workspace = ws;
55 this->m_Graph = TGraph::New( );
58 QGraphicsScene* scene = this->scene( );
59 // Add vertices and keep track of ports
60 std::map< std::string, std::map< std::string, QNEPort* > >
62 auto vIt = this->m_Workspace->GetGraph( )->BeginVertices( );
63 auto vIt_end = this->m_Workspace->GetGraph( )->EndVertices( );
64 for( ; vIt != vIt_end; ++vIt )
66 this->_createBlock( dynamic_cast< TFilter* >( vIt->second.GetPointer( ) ) );
73 auto rIt = this->m_Workspace->GetGraph( )->BeginEdgesRows( );
74 auto rIt_end = this->m_Workspace->GetGraph( )->EndEdgesRows( );
75 for( ; rIt != rIt_end; ++rIt )
77 auto cIt = rIt->second.begin( );
78 for( ; cIt != rIt->second.end( ); ++cIt )
80 auto eIt = cIt->second.begin( );
81 for( ; eIt != cIt->second.end( ); ++eIt )
83 QNEPort* p1 = out_ports[ rIt->first ][ eIt->first ];
84 QNEPort* p2 = in_ports[ cIt->first ][ eIt->second ];
85 if( p1 != NULL && p2 != NULL )
87 QNEConnection* conn = new QNEConnection( 0, scene );
90 this->m_Graph->AddConnection( rIt->first, cIt->first, conn );
102 // -------------------------------------------------------------------------
104 void PipelineEditor::QNodesEditorCanvas::
105 keyPressEvent( QKeyEvent* event )
109 // -------------------------------------------------------------------------
110 void PipelineEditor::QNodesEditorCanvas::
111 timerEvent( QTimerEvent* event )
116 // -------------------------------------------------------------------------
117 void PipelineEditor::QNodesEditorCanvas::
118 wheelEvent( QWheelEvent* event )
121 std::pow( double( 2 ), event->delta( ) / double( 240 ) )
125 // -------------------------------------------------------------------------
126 void PipelineEditor::QNodesEditorCanvas::
127 dragEnterEvent( QDragEnterEvent* event )
129 const QMimeData* mime = event->mimeData( );
130 if( mime->hasFormat( "application/x-qabstractitemmodeldatalist" ) )
131 event->acceptProposedAction( );
134 // -------------------------------------------------------------------------
135 void PipelineEditor::QNodesEditorCanvas::
136 dragLeaveEvent( QDragLeaveEvent* event )
140 // -------------------------------------------------------------------------
141 void PipelineEditor::QNodesEditorCanvas::
142 dragMoveEvent( QDragMoveEvent* event )
146 // -------------------------------------------------------------------------
147 void PipelineEditor::QNodesEditorCanvas::
148 dropEvent( QDropEvent* event )
150 if( this->m_Workspace == NULL )
152 const QMimeData* mime = event->mimeData( );
153 if( !( mime->hasFormat( "application/x-qabstractitemmodeldatalist" ) ) )
156 event->acceptProposedAction( );
157 auto tree = dynamic_cast< QTreeWidget* >( event->source( ) );
161 QList< QTreeWidgetItem* > items = tree->selectedItems( );
162 for( auto iIt = items.begin( ); iIt != items.end( ); ++iIt )
164 std::string filter = ( *iIt )->text( 0 ).toStdString( );
165 std::string name = filter;
166 while( this->m_Workspace->HasFilter( name ) )
167 name += std::string( "_" );
168 if( this->m_Workspace->CreateFilter( filter, name ) )
169 this->_createBlock( this->m_Workspace->GetFilter( name ) );
174 // -------------------------------------------------------------------------
175 void PipelineEditor::QNodesEditorCanvas::
176 _scaleView( qreal scaleFactor )
178 qreal factor = this->transform( ).
179 scale( scaleFactor, scaleFactor ).
180 mapRect( QRectF( 0, 0, 1, 1 ) ).
182 if( factor < qreal( 0.07 ) || factor > qreal( 100 ) )
184 this->scale( scaleFactor, scaleFactor );
187 // -------------------------------------------------------------------------
188 void PipelineEditor::QNodesEditorCanvas::
189 _createBlock( TFilter* f )
195 QNEBlock* b = new QNEBlock( 0, this->scene( ) );
196 b->addPort( f->GetName( ), 0, QNEPort::NamePort );
197 b->addPort( f->GetClassName( ).c_str( ), 0, QNEPort::TypePort );
200 std::set< std::string > inputs;
201 f->GetInputsNames( inputs );
202 for( auto iIt = inputs.begin( ); iIt != inputs.end( ); ++iIt )
203 b->addInputPort( iIt->c_str( ) );
204 //in_ports[ vIt->first ][ *iIt ] = b->addInputPort( iIt->c_str( ) );
207 std::set< std::string > outputs;
208 f->GetOutputsNames( outputs );
209 for( auto oIt = outputs.begin( ); oIt != outputs.end( ); ++oIt )
210 b->addOutputPort( oIt->c_str( ) );
211 // out_ports[ vIt->first ][ *oIt ] = b->addOutputPort( oIt->c_str( ) );
213 // Keep a trace of this visual graph
214 this->m_Graph->InsertVertex( f->GetName( ), b );
216 // Add vertices and keep track of ports
218 std::map< std::string, std::map< std::string, QNEPort* > >
220 auto vIt = this->m_Workspace->GetGraph( )->BeginVertices( );
221 auto vIt_end = this->m_Workspace->GetGraph( )->EndVertices( );
222 for( ; vIt != vIt_end; ++vIt )
225 QNEBlock* b = new QNEBlock( 0, scene );
226 b->addPort( vIt->second->GetName( ), 0, QNEPort::NamePort );
227 b->addPort( vIt->second->GetClassName( ).c_str( ), 0, QNEPort::TypePort );
230 auto f = dynamic_cast< TFilter* >( vIt->second.GetPointer( ) );
235 std::set< std::string > inputs;
236 f->GetInputsNames( inputs );
237 for( auto iIt = inputs.begin( ); iIt != inputs.end( ); ++iIt )
238 in_ports[ vIt->first ][ *iIt ] = b->addInputPort( iIt->c_str( ) );
241 std::set< std::string > outputs;
242 f->GetOutputsNames( outputs );
243 for( auto oIt = outputs.begin( ); oIt != outputs.end( ); ++oIt )
244 out_ports[ vIt->first ][ *oIt ] = b->addOutputPort( oIt->c_str( ) );
246 // Keep a trace of this visual graph
247 this->m_Graph->InsertVertex( vIt->first, b );
258 // -------------------------------------------------------------------------
262 if( this->m_Workspace == NULL )
266 // -------------------------------------------------------------------------
267 void GraphWidget::itemMoved()
270 timerId = startTimer(1000 / 25);
273 void GraphWidget::keyPressEvent(QKeyEvent *event)
275 switch (event->key()) {
277 centerNode->moveBy(0, -20);
280 centerNode->moveBy(0, 20);
283 centerNode->moveBy(-20, 0);
286 centerNode->moveBy(20, 0);
299 QGraphicsView::keyPressEvent(event);
303 void GraphWidget::timerEvent(QTimerEvent *event)
308 foreach (QGraphicsItem *item, scene()->items()) {
309 if (Node *node = qgraphicsitem_cast<Node *>(item))
313 foreach (Node *node, nodes)
314 node->calculateForces();
316 bool itemsMoved = false;
317 foreach (Node *node, nodes) {
328 void GraphWidget::wheelEvent(QWheelEvent *event)
330 scaleView(pow((double)2, -event->delta() / 240.0));
333 void GraphWidget::drawBackground(QPainter *painter, const QRectF &rect)
338 QRectF sceneRect = rect;//this->sceneRect();
339 QRectF rightShadow(sceneRect.right(), sceneRect.top() + 5, 5, sceneRect.height());
340 QRectF bottomShadow(sceneRect.left() + 5, sceneRect.bottom(), sceneRect.width(), 5);
341 if (rightShadow.intersects(rect) || rightShadow.contains(rect))
342 painter->fillRect(rightShadow, Qt::darkGray);
343 if (bottomShadow.intersects(rect) || bottomShadow.contains(rect))
344 painter->fillRect(bottomShadow, Qt::darkGray);
347 QLinearGradient gradient(sceneRect.topLeft(), sceneRect.bottomRight());
348 gradient.setColorAt(0, Qt::white);
349 gradient.setColorAt(1, Qt::lightGray);
350 painter->fillRect(rect.intersect(sceneRect), gradient);
351 painter->setBrush(Qt::NoBrush);
352 painter->drawRect(sceneRect);
354 #if !defined(Q_OS_SYMBIAN) && !defined(Q_WS_MAEMO_5)
356 QRectF textRect(sceneRect.left() + 4, sceneRect.top() + 4,
357 sceneRect.width() - 4, sceneRect.height() - 4);
358 QString message(tr("Click and drag the nodes around, and zoom with the mouse "
359 "wheel or the '+' and '-' keys"));
361 QFont font = painter->font();
363 font.setPointSize(14);
364 painter->setFont(font);
365 painter->setPen(Qt::lightGray);
366 painter->drawText(textRect.translated(2, 2), message);
367 painter->setPen(Qt::black);
368 painter->drawText(textRect, message);
372 void GraphWidget::scaleView(qreal scaleFactor)
374 qreal factor = transform().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width();
375 if (factor < 0.07 || factor > 100)
378 scale(scaleFactor, scaleFactor);
381 void GraphWidget::shuffle()
383 foreach (QGraphicsItem *item, scene()->items()) {
384 if (qgraphicsitem_cast<Node *>(item))
385 item->setPos(-150 + qrand() % 300, -150 + qrand() % 300);
389 void GraphWidget::zoomIn()
391 scaleView(qreal(1.2));
394 void GraphWidget::zoomOut()
396 scaleView(1 / qreal(1.2));