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