]> 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   if( this->m_Workspace == NULL )
151     return;
152   const QMimeData* mime = event->mimeData( );
153   if( !( mime->hasFormat( "application/x-qabstractitemmodeldatalist" ) ) )
154     return;
155
156   event->acceptProposedAction( );
157   auto tree = dynamic_cast< QTreeWidget* >( event->source( ) );
158   if( tree == NULL )
159     return;
160
161   QList< QTreeWidgetItem* > items = tree->selectedItems( );
162   for( auto iIt = items.begin( ); iIt != items.end( ); ++iIt )
163   {
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 ) );
170
171   } // rof
172 }
173
174 // -------------------------------------------------------------------------
175 void PipelineEditor::QNodesEditorCanvas::
176 _scaleView( qreal scaleFactor )
177 {
178   qreal factor = this->transform( ).
179     scale( scaleFactor, scaleFactor ).
180     mapRect( QRectF( 0, 0, 1, 1 ) ).
181     width( );
182   if( factor < qreal( 0.07 ) || factor > qreal( 100 ) )
183     return;
184   this->scale( scaleFactor, scaleFactor );
185 }
186
187 // -------------------------------------------------------------------------
188 void PipelineEditor::QNodesEditorCanvas::
189 _createBlock( TFilter* f )
190 {
191   if( f == NULL )
192     return;
193
194   // Add block
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 );
198
199   // Add input ports
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( ) );
205
206   // Add output ports
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( ) );
212
213   // Keep a trace of this visual graph
214   this->m_Graph->InsertVertex( f->GetName( ), b );
215
216   // Add vertices and keep track of ports
217   /*
218     std::map< std::string, std::map< std::string, QNEPort* > >
219     in_ports, out_ports;
220     auto vIt = this->m_Workspace->GetGraph( )->BeginVertices( );
221     auto vIt_end = this->m_Workspace->GetGraph( )->EndVertices( );
222     for( ; vIt != vIt_end; ++vIt )
223     {
224     // Add block
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 );
228
229     // Get filter
230     auto f = dynamic_cast< TFilter* >( vIt->second.GetPointer( ) );
231     if( f == NULL )
232     continue;
233
234     // Add input ports
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( ) );
239
240     // Add output ports
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( ) );
245
246     // Keep a trace of this visual graph
247     this->m_Graph->InsertVertex( vIt->first, b );
248
249     } // rof
250   */
251 }
252
253 // eof - $RCSfile$
254
255
256 /*
257
258 // -------------------------------------------------------------------------
259 void GraphWidget::
260 draw( )
261 {
262   if( this->m_Workspace == NULL )
263     return;
264 }
265
266 // -------------------------------------------------------------------------
267 void GraphWidget::itemMoved()
268 {
269   if (!timerId)
270     timerId = startTimer(1000 / 25);
271 }
272
273 void GraphWidget::keyPressEvent(QKeyEvent *event)
274 {
275   switch (event->key()) {
276   case Qt::Key_Up:
277     centerNode->moveBy(0, -20);
278     break;
279   case Qt::Key_Down:
280     centerNode->moveBy(0, 20);
281     break;
282   case Qt::Key_Left:
283     centerNode->moveBy(-20, 0);
284     break;
285   case Qt::Key_Right:
286     centerNode->moveBy(20, 0);
287     break;
288   case Qt::Key_Plus:
289     zoomIn();
290     break;
291   case Qt::Key_Minus:
292     zoomOut();
293     break;
294   case Qt::Key_Space:
295   case Qt::Key_Enter:
296     shuffle();
297     break;
298   default:
299     QGraphicsView::keyPressEvent(event);
300   }
301 }
302
303 void GraphWidget::timerEvent(QTimerEvent *event)
304 {
305   Q_UNUSED(event);
306
307   QList<Node *> nodes;
308   foreach (QGraphicsItem *item, scene()->items()) {
309     if (Node *node = qgraphicsitem_cast<Node *>(item))
310       nodes << node;
311   }
312
313   foreach (Node *node, nodes)
314     node->calculateForces();
315
316   bool itemsMoved = false;
317   foreach (Node *node, nodes) {
318     if (node->advance())
319       itemsMoved = true;
320   }
321
322   if (!itemsMoved) {
323     killTimer(timerId);
324     timerId = 0;
325   }
326 }
327
328 void GraphWidget::wheelEvent(QWheelEvent *event)
329 {
330   scaleView(pow((double)2, -event->delta() / 240.0));
331 }
332
333 void GraphWidget::drawBackground(QPainter *painter, const QRectF &rect)
334 {
335   //Q_UNUSED(rect);
336
337   // Shadow
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);
345
346   // Fill
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);
353
354 #if !defined(Q_OS_SYMBIAN) && !defined(Q_WS_MAEMO_5)
355   // Text
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"));
360
361   QFont font = painter->font();
362   font.setBold(true);
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);
369 #endif
370 }
371
372 void GraphWidget::scaleView(qreal scaleFactor)
373 {
374   qreal factor = transform().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width();
375   if (factor < 0.07 || factor > 100)
376     return;
377
378   scale(scaleFactor, scaleFactor);
379 }
380
381 void GraphWidget::shuffle()
382 {
383   foreach (QGraphicsItem *item, scene()->items()) {
384     if (qgraphicsitem_cast<Node *>(item))
385       item->setPos(-150 + qrand() % 300, -150 + qrand() % 300);
386   }
387 }
388
389 void GraphWidget::zoomIn()
390 {
391   scaleView(qreal(1.2));
392 }
393
394 void GraphWidget::zoomOut()
395 {
396   scaleView(1 / qreal(1.2));
397 }
398
399
400 */