]> Creatis software - cpPlugins.git/blob - appli/cpPipelineEditor/QNodesEditorCanvas.cxx
...
[cpPlugins.git] / appli / cpPipelineEditor / QNodesEditorCanvas.cxx
1 #include "QNodesEditorCanvas.h"
2 #include "QNodesEditor.h"
3 #include "QNEBlock.h"
4 #include "QNEConnection.h"
5 #include "QNEPort.h"
6
7 #include <QDragEnterEvent>
8 #include <QWheelEvent>
9 #include <QTreeWidget>
10
11 // -------------------------------------------------------------------------
12 PipelineEditor::QNodesEditorCanvas::
13 QNodesEditorCanvas( QWidget* parent )
14   : QGraphicsView( parent ),
15     m_Workspace( NULL )
16 {
17   QGraphicsScene* scene = new QGraphicsScene( this );
18   this->setScene( scene );
19   this->setRenderHint( QPainter::Antialiasing );
20   this->setAcceptDrops( true );
21
22   this->m_Editor = new QNodesEditor( this );
23   this->m_Editor->install( scene );
24 }
25
26 // -------------------------------------------------------------------------
27 PipelineEditor::QNodesEditorCanvas::
28 ~QNodesEditorCanvas( )
29 {
30 }
31
32 // -------------------------------------------------------------------------
33 PipelineEditor::QNodesEditorCanvas::
34 TWorkspace* PipelineEditor::QNodesEditorCanvas::
35 workspace( )
36 {
37   return( this->m_Workspace );
38 }
39
40 // -------------------------------------------------------------------------
41 const PipelineEditor::QNodesEditorCanvas::
42 TWorkspace* PipelineEditor::QNodesEditorCanvas::
43 workspace( ) const
44 {
45   return( this->m_Workspace );
46 }
47
48 // -------------------------------------------------------------------------
49 void PipelineEditor::QNodesEditorCanvas::
50 setWorkspace( TWorkspace* ws )
51 {
52   if( this->m_Workspace == ws )
53     return;
54   this->m_Workspace = ws;
55   QGraphicsScene* scene = this->scene( );
56
57   // Create graph
58   this->m_Graph = TGraph::New( );
59
60   // Add vertices and keep track of ports
61   std::map< std::string, std::map< std::string, QNEPort* > >
62     in_ports, out_ports;
63   auto vIt = this->m_Workspace->GetGraph( )->BeginVertices( );
64   auto vIt_end = this->m_Workspace->GetGraph( )->EndVertices( );
65   for( ; vIt != vIt_end; ++vIt )
66   {
67     this->_createBlock( dynamic_cast< TFilter* >( vIt->second.GetPointer( ) ) );
68 #error ACA VOY
69     // Add block
70     QNEBlock* b = new QNEBlock( 0, scene );
71     b->addPort( vIt->second->GetName( ), 0, QNEPort::NamePort );
72     b->addPort( vIt->second->GetClassName( ).c_str( ), 0, QNEPort::TypePort );
73
74     // Get filter
75     if( f == NULL )
76       continue;
77
78     // Add input ports
79     std::set< std::string > inputs;
80     f->GetInputsNames( inputs );
81     for( auto iIt = inputs.begin( ); iIt != inputs.end( ); ++iIt )
82       in_ports[ vIt->first ][ *iIt ] = b->addInputPort( iIt->c_str( ) );
83
84     // Add output ports
85     std::set< std::string > outputs;
86     f->GetOutputsNames( outputs );
87     for( auto oIt = outputs.begin( ); oIt != outputs.end( ); ++oIt )
88       out_ports[ vIt->first ][ *oIt ] = b->addOutputPort( oIt->c_str( ) );
89
90     // Keep a trace of this visual graph
91     this->m_Graph->InsertVertex( vIt->first, b );
92
93   } // rof
94
95   // Add edges
96   /* TODO
97      auto rIt = this->m_Workspace->GetGraph( )->BeginEdgesRows( );
98      auto rIt_end = this->m_Workspace->GetGraph( )->EndEdgesRows( );
99      for( ; rIt != rIt_end; ++rIt )
100      {
101      auto cIt = rIt->second.begin( );
102      for( ; cIt != rIt->second.end( ); ++cIt )
103      {
104      auto eIt = cIt->second.begin( );
105      for( ; eIt != cIt->second.end( ); ++eIt )
106      {
107      QNEPort* p1 = out_ports[ rIt->first ][ eIt->first ];
108      QNEPort* p2 = in_ports[ cIt->first ][ eIt->second ];
109      if( p1 != NULL && p2 != NULL )
110      {
111      QNEConnection* conn = new QNEConnection( 0, scene );
112      conn->setPort1( p1 );
113      conn->setPort2( p2 );
114      this->m_Graph->AddConnection( rIt->first, cIt->first, conn );
115
116      } // fi
117
118      } // rof
119
120      } // rof
121
122      } // rof
123   */
124 }
125
126 // -------------------------------------------------------------------------
127 /* TODO
128    void PipelineEditor::QNodesEditorCanvas::
129    keyPressEvent( QKeyEvent* event )
130    {
131    }
132
133    // -------------------------------------------------------------------------
134    void PipelineEditor::QNodesEditorCanvas::
135    timerEvent( QTimerEvent* event )
136    {
137    }
138 */
139
140 // -------------------------------------------------------------------------
141 void PipelineEditor::QNodesEditorCanvas::
142 wheelEvent( QWheelEvent* event )
143 {
144   this->_scaleView(
145     std::pow( double( 2 ), event->delta( ) / double( 240 ) )
146     );
147 }
148
149 // -------------------------------------------------------------------------
150 void PipelineEditor::QNodesEditorCanvas::
151 dragEnterEvent( QDragEnterEvent* event )
152 {
153   const QMimeData* mime = event->mimeData( );
154   if( mime->hasFormat( "application/x-qabstractitemmodeldatalist" ) )
155     event->acceptProposedAction( );
156 }
157
158 // -------------------------------------------------------------------------
159 void PipelineEditor::QNodesEditorCanvas::
160 dragLeaveEvent( QDragLeaveEvent* event )
161 {
162 }
163
164 // -------------------------------------------------------------------------
165 void PipelineEditor::QNodesEditorCanvas::
166 dragMoveEvent( QDragMoveEvent* event )
167 {
168 }
169
170 // -------------------------------------------------------------------------
171 void PipelineEditor::QNodesEditorCanvas::
172 dropEvent( QDropEvent* event )
173 {
174   if( this->m_Workspace == NULL )
175     return;
176   const QMimeData* mime = event->mimeData( );
177   if( !( mime->hasFormat( "application/x-qabstractitemmodeldatalist" ) ) )
178     return;
179
180   event->acceptProposedAction( );
181   auto tree = dynamic_cast< QTreeWidget* >( event->source( ) );
182   if( tree == NULL )
183     return;
184
185   QList< QTreeWidgetItem* > items = tree->selectedItems( );
186   for( auto iIt = items.begin( ); iIt != items.end( ); ++iIt )
187   {
188     std::string filter = ( *iIt )->text( 0 ).toStdString( );
189     std::string name = filter;
190     if( this->m_Workspace->GetFilter( name ) != NULL )
191       name += std::string( "_" );
192     if( this->m_Workspace->CreateFilter( filter, name ) )
193     {
194     } // fi
195
196   } // rof
197 }
198
199 // -------------------------------------------------------------------------
200 void PipelineEditor::QNodesEditorCanvas::
201 _scaleView( qreal scaleFactor )
202 {
203   qreal factor = this->transform( ).
204     scale( scaleFactor, scaleFactor ).
205     mapRect( QRectF( 0, 0, 1, 1 ) ).
206     width( );
207   if( factor < qreal( 0.07 ) || factor > qreal( 100 ) )
208     return;
209   this->scale( scaleFactor, scaleFactor );
210 }
211
212 // -------------------------------------------------------------------------
213 void PipelineEditor::QNodesEditorCanvas::
214 _createBlock( TFilter* f )
215 {
216   if( f == NULL )
217     return;
218
219   // Add block
220   QNEBlock* b = new QNEBlock( 0, this->scene( ) );
221   b->addPort( f->GetName( ), 0, QNEPort::NamePort );
222   b->addPort( f->GetClassName( ).c_str( ), 0, QNEPort::TypePort );
223
224   // Add input ports
225   std::set< std::string > inputs;
226   f->GetInputsNames( inputs );
227   for( auto iIt = inputs.begin( ); iIt != inputs.end( ); ++iIt )
228     b->addInputPort( iIt->c_str( ) );
229   //in_ports[ vIt->first ][ *iIt ] = b->addInputPort( iIt->c_str( ) );
230
231   // Add output ports
232   std::set< std::string > outputs;
233   f->GetOutputsNames( outputs );
234   for( auto oIt = outputs.begin( ); oIt != outputs.end( ); ++oIt )
235     b->addOutputPort( oIt->c_str( ) );
236   // out_ports[ vIt->first ][ *oIt ] = b->addOutputPort( oIt->c_str( ) );
237
238   // Keep a trace of this visual graph
239   this->m_Graph->InsertVertex( f->GetName( ), b );
240
241   // Add vertices and keep track of ports
242   /*
243     std::map< std::string, std::map< std::string, QNEPort* > >
244     in_ports, out_ports;
245     auto vIt = this->m_Workspace->GetGraph( )->BeginVertices( );
246     auto vIt_end = this->m_Workspace->GetGraph( )->EndVertices( );
247     for( ; vIt != vIt_end; ++vIt )
248     {
249     // Add block
250     QNEBlock* b = new QNEBlock( 0, scene );
251     b->addPort( vIt->second->GetName( ), 0, QNEPort::NamePort );
252     b->addPort( vIt->second->GetClassName( ).c_str( ), 0, QNEPort::TypePort );
253
254     // Get filter
255     auto f = dynamic_cast< TFilter* >( vIt->second.GetPointer( ) );
256     if( f == NULL )
257     continue;
258
259     // Add input ports
260     std::set< std::string > inputs;
261     f->GetInputsNames( inputs );
262     for( auto iIt = inputs.begin( ); iIt != inputs.end( ); ++iIt )
263     in_ports[ vIt->first ][ *iIt ] = b->addInputPort( iIt->c_str( ) );
264
265     // Add output ports
266     std::set< std::string > outputs;
267     f->GetOutputsNames( outputs );
268     for( auto oIt = outputs.begin( ); oIt != outputs.end( ); ++oIt )
269     out_ports[ vIt->first ][ *oIt ] = b->addOutputPort( oIt->c_str( ) );
270
271     // Keep a trace of this visual graph
272     this->m_Graph->InsertVertex( vIt->first, b );
273
274     } // rof
275   */
276 }
277
278 // eof - $RCSfile$
279
280
281 /*
282
283 // -------------------------------------------------------------------------
284 void GraphWidget::
285 draw( )
286 {
287   if( this->m_Workspace == NULL )
288     return;
289 }
290
291 // -------------------------------------------------------------------------
292 void GraphWidget::itemMoved()
293 {
294   if (!timerId)
295     timerId = startTimer(1000 / 25);
296 }
297
298 void GraphWidget::keyPressEvent(QKeyEvent *event)
299 {
300   switch (event->key()) {
301   case Qt::Key_Up:
302     centerNode->moveBy(0, -20);
303     break;
304   case Qt::Key_Down:
305     centerNode->moveBy(0, 20);
306     break;
307   case Qt::Key_Left:
308     centerNode->moveBy(-20, 0);
309     break;
310   case Qt::Key_Right:
311     centerNode->moveBy(20, 0);
312     break;
313   case Qt::Key_Plus:
314     zoomIn();
315     break;
316   case Qt::Key_Minus:
317     zoomOut();
318     break;
319   case Qt::Key_Space:
320   case Qt::Key_Enter:
321     shuffle();
322     break;
323   default:
324     QGraphicsView::keyPressEvent(event);
325   }
326 }
327
328 void GraphWidget::timerEvent(QTimerEvent *event)
329 {
330   Q_UNUSED(event);
331
332   QList<Node *> nodes;
333   foreach (QGraphicsItem *item, scene()->items()) {
334     if (Node *node = qgraphicsitem_cast<Node *>(item))
335       nodes << node;
336   }
337
338   foreach (Node *node, nodes)
339     node->calculateForces();
340
341   bool itemsMoved = false;
342   foreach (Node *node, nodes) {
343     if (node->advance())
344       itemsMoved = true;
345   }
346
347   if (!itemsMoved) {
348     killTimer(timerId);
349     timerId = 0;
350   }
351 }
352
353 void GraphWidget::wheelEvent(QWheelEvent *event)
354 {
355   scaleView(pow((double)2, -event->delta() / 240.0));
356 }
357
358 void GraphWidget::drawBackground(QPainter *painter, const QRectF &rect)
359 {
360   //Q_UNUSED(rect);
361
362   // Shadow
363   QRectF sceneRect = rect;//this->sceneRect();
364   QRectF rightShadow(sceneRect.right(), sceneRect.top() + 5, 5, sceneRect.height());
365   QRectF bottomShadow(sceneRect.left() + 5, sceneRect.bottom(), sceneRect.width(), 5);
366   if (rightShadow.intersects(rect) || rightShadow.contains(rect))
367     painter->fillRect(rightShadow, Qt::darkGray);
368   if (bottomShadow.intersects(rect) || bottomShadow.contains(rect))
369     painter->fillRect(bottomShadow, Qt::darkGray);
370
371   // Fill
372   QLinearGradient gradient(sceneRect.topLeft(), sceneRect.bottomRight());
373   gradient.setColorAt(0, Qt::white);
374   gradient.setColorAt(1, Qt::lightGray);
375   painter->fillRect(rect.intersect(sceneRect), gradient);
376   painter->setBrush(Qt::NoBrush);
377   painter->drawRect(sceneRect);
378
379 #if !defined(Q_OS_SYMBIAN) && !defined(Q_WS_MAEMO_5)
380   // Text
381   QRectF textRect(sceneRect.left() + 4, sceneRect.top() + 4,
382                   sceneRect.width() - 4, sceneRect.height() - 4);
383   QString message(tr("Click and drag the nodes around, and zoom with the mouse "
384                      "wheel or the '+' and '-' keys"));
385
386   QFont font = painter->font();
387   font.setBold(true);
388   font.setPointSize(14);
389   painter->setFont(font);
390   painter->setPen(Qt::lightGray);
391   painter->drawText(textRect.translated(2, 2), message);
392   painter->setPen(Qt::black);
393   painter->drawText(textRect, message);
394 #endif
395 }
396
397 void GraphWidget::scaleView(qreal scaleFactor)
398 {
399   qreal factor = transform().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width();
400   if (factor < 0.07 || factor > 100)
401     return;
402
403   scale(scaleFactor, scaleFactor);
404 }
405
406 void GraphWidget::shuffle()
407 {
408   foreach (QGraphicsItem *item, scene()->items()) {
409     if (qgraphicsitem_cast<Node *>(item))
410       item->setPos(-150 + qrand() % 300, -150 + qrand() % 300);
411   }
412 }
413
414 void GraphWidget::zoomIn()
415 {
416   scaleView(qreal(1.2));
417 }
418
419 void GraphWidget::zoomOut()
420 {
421   scaleView(1 / qreal(1.2));
422 }
423
424
425 */