1 /* Copyright (c) 2012, STANISLAW ADASZEWSKI
\r
4 Redistribution and use in source and binary forms, with or without
\r
5 modification, are permitted provided that the following conditions are met:
\r
6 * Redistributions of source code must retain the above copyright
\r
7 notice, this list of conditions and the following disclaimer.
\r
8 * Redistributions in binary form must reproduce the above copyright
\r
9 notice, this list of conditions and the following disclaimer in the
\r
10 documentation and/or other materials provided with the distribution.
\r
11 * Neither the name of STANISLAW ADASZEWSKI nor the
\r
12 names of its contributors may be used to endorse or promote products
\r
13 derived from this software without specific prior written permission.
\r
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
\r
16 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
\r
17 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
\r
18 DISCLAIMED. IN NO EVENT SHALL STANISLAW ADASZEWSKI BE LIABLE FOR ANY
\r
19 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
\r
20 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
\r
21 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
\r
22 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
\r
23 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
\r
24 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
27 #include "QNodesEditor.h"
\r
29 #include <QGraphicsScene>
\r
31 #include <QGraphicsSceneContextMenuEvent>
\r
32 #include <QGraphicsSceneDragDropEvent>
\r
33 #include <QGraphicsSceneHelpEvent>
\r
34 #include <QGraphicsSceneHoverEvent>
\r
35 #include <QGraphicsSceneMouseEvent>
\r
36 #include <QGraphicsSceneMoveEvent>
\r
37 #include <QGraphicsSceneResizeEvent>
\r
38 #include <QGraphicsSceneWheelEvent>
\r
40 #include "QNEPort.h"
\r
41 #include "QNEConnection.h"
\r
42 #include "QNEBlock.h"
\r
44 // -------------------------------------------------------------------------
\r
45 PipelineEditor::QNodesEditor::
\r
46 QNodesEditor( QObject* parent )
\r
47 : Superclass( parent ),
\r
53 // -------------------------------------------------------------------------
\r
54 PipelineEditor::QNodesEditor::
\r
59 // -------------------------------------------------------------------------
\r
60 PipelineEditor::QNodesEditor::
\r
61 TWorkspace* PipelineEditor::QNodesEditor::
\r
64 return( this->m_Workspace );
\r
67 // -------------------------------------------------------------------------
\r
68 const PipelineEditor::QNodesEditor::
\r
69 TWorkspace* PipelineEditor::QNodesEditor::
\r
72 return( this->m_Workspace );
\r
75 // -------------------------------------------------------------------------
\r
76 void PipelineEditor::QNodesEditor::
\r
77 setWorkspace( TWorkspace* ws )
\r
79 if( this->m_Workspace == ws )
\r
81 this->m_Workspace = ws;
\r
82 this->m_Graph = TGraph::New( );
\r
85 QGraphicsScene* scene = this->scene( );
\r
86 // Add vertices and keep track of ports
\r
87 std::map< std::string, std::map< std::string, QNEPort* > >
\r
88 in_ports, out_ports;
\r
89 auto vIt = this->m_Workspace->GetGraph( )->BeginVertices( );
\r
90 auto vIt_end = this->m_Workspace->GetGraph( )->EndVertices( );
\r
91 for( ; vIt != vIt_end; ++vIt )
\r
93 this->_createBlock( dynamic_cast< TFilter* >( vIt->second.GetPointer( ) ) );
\r
100 auto rIt = this->m_Workspace->GetGraph( )->BeginEdgesRows( );
\r
101 auto rIt_end = this->m_Workspace->GetGraph( )->EndEdgesRows( );
\r
102 for( ; rIt != rIt_end; ++rIt )
\r
104 auto cIt = rIt->second.begin( );
\r
105 for( ; cIt != rIt->second.end( ); ++cIt )
\r
107 auto eIt = cIt->second.begin( );
\r
108 for( ; eIt != cIt->second.end( ); ++eIt )
\r
110 QNEPort* p1 = out_ports[ rIt->first ][ eIt->first ];
\r
111 QNEPort* p2 = in_ports[ cIt->first ][ eIt->second ];
\r
112 if( p1 != NULL && p2 != NULL )
\r
114 QNEConnection* conn = new QNEConnection( 0, scene );
\r
115 conn->setPort1( p1 );
\r
116 conn->setPort2( p2 );
\r
117 this->m_Graph->AddConnection( rIt->first, cIt->first, conn );
\r
129 // -------------------------------------------------------------------------
\r
130 std::string PipelineEditor::QNodesEditor::
\r
131 createFilter( const std::string& filter, const QPointF& pnt )
\r
133 std::string name = filter;
\r
134 while( this->m_Workspace->HasFilter( name ) )
\r
135 name += std::string( "_" );
\r
136 if( this->m_Workspace->CreateFilter( filter, name ) )
\r
138 this->_CreateBlock( this->m_Workspace->GetFilter( name ), pnt );
\r
145 // -------------------------------------------------------------------------
\r
146 void PipelineEditor::QNodesEditor::
\r
147 install( QGraphicsScene* s )
\r
149 s->installEventFilter( this );
\r
153 // -------------------------------------------------------------------------
\r
154 QGraphicsItem* PipelineEditor::QNodesEditor::
\r
155 itemAt( const QPointF& pos )
\r
157 QList< QGraphicsItem* > items =
\r
158 this->m_Scene->items( QRectF( pos - QPointF( 1, 1 ), QSize( 3, 3 ) ) );
\r
160 foreach( QGraphicsItem* item, items )
\r
161 if( item->type( ) > QGraphicsItem::UserType )
\r
166 #include <iostream>
\r
168 // -------------------------------------------------------------------------
\r
169 void PipelineEditor::QNodesEditor::
\r
170 _CreateBlock( TFilter* f, const QPointF& pnt )
\r
176 QNEBlock* b = new QNEBlock( 0, this->m_Scene );
\r
177 b->setNamePort( f->GetName( ) );
\r
178 b->setTypePort( f->GetClassName( ).c_str( ) );
\r
179 // TODO: b->setScenePos( pnt );
\r
182 std::set< std::string > inputs;
\r
183 f->GetInputsNames( inputs );
\r
184 for( auto iIt = inputs.begin( ); iIt != inputs.end( ); ++iIt )
\r
185 b->addInputPort( iIt->c_str( ) );
\r
187 // Add output ports
\r
188 std::set< std::string > outputs;
\r
189 f->GetOutputsNames( outputs );
\r
190 for( auto oIt = outputs.begin( ); oIt != outputs.end( ); ++oIt )
\r
191 b->addOutputPort( oIt->c_str( ) );
\r
193 // Keep a trace of this visual graph
\r
194 this->m_Graph->InsertVertex( f->GetName( ), b );
\r
197 // -------------------------------------------------------------------------
\r
198 void PipelineEditor::QNodesEditor::
\r
199 _DoubleClick( QGraphicsSceneMouseEvent* evt, QGraphicsItem* item )
\r
201 switch( evt->button( ) )
\r
203 case Qt::LeftButton:
\r
205 QNEBlock* block = dynamic_cast< QNEBlock* >( item );
\r
206 QNEPort* port = dynamic_cast< QNEPort* >( item );
\r
207 QNEConnection* conn = dynamic_cast< QNEConnection* >( item );
\r
209 if( block != NULL )
\r
212 auto ports = block->ports( );
\r
213 std::string name = "";
\r
215 auto pIt = ports.begin( );
\r
216 pIt != ports.end( ) && name == "";
\r
220 ( *pIt )->portFlags( ) && QNEPort::NamePort == QNEPort::NamePort
\r
222 name = ( *pIt )->portName( ).toStdString( );
\r
225 TFilter* filter = this->m_Workspace->GetFilter( name );
\r
226 if( filter != NULL )
\r
231 else if( port != NULL )
\r
234 else if( conn != NULL )
\r
240 case Qt::RightButton:
\r
244 case Qt::MiddleButton:
\r
254 // -------------------------------------------------------------------------
\r
255 bool PipelineEditor::QNodesEditor::
\r
256 eventFilter( QObject* o, QEvent* e )
\r
259 switch( int( e->type( ) ) )
\r
261 case QEvent::GraphicsSceneContextMenu:
\r
263 QGraphicsSceneContextMenuEvent* evt =
\r
264 dynamic_cast< QGraphicsSceneContextMenuEvent* >( e );
\r
270 case QEvent::GraphicsSceneDragEnter:
\r
272 QGraphicsSceneDragDropEvent* evt =
\r
273 dynamic_cast< QGraphicsSceneDragDropEvent* >( e );
\r
279 case QEvent::GraphicsSceneDragLeave:
\r
281 QGraphicsSceneDragDropEvent* evt =
\r
282 dynamic_cast< QGraphicsSceneDragDropEvent* >( e );
\r
288 case QEvent::GraphicsSceneDragMove:
\r
290 QGraphicsSceneDragDropEvent* evt =
\r
291 dynamic_cast< QGraphicsSceneDragDropEvent* >( e );
\r
297 case QEvent::GraphicsSceneDrop:
\r
299 QGraphicsSceneDragDropEvent* evt =
\r
300 dynamic_cast< QGraphicsSceneDragDropEvent* >( e );
\r
306 case QEvent::GraphicsSceneHelp:
\r
308 QGraphicsSceneHelpEvent* evt =
\r
309 dynamic_cast< QGraphicsSceneHelpEvent* >( e );
\r
315 case QEvent::GraphicsSceneHoverEnter:
\r
317 QGraphicsSceneHoverEvent* evt =
\r
318 dynamic_cast< QGraphicsSceneHoverEvent* >( e );
\r
324 case QEvent::GraphicsSceneHoverLeave:
\r
326 QGraphicsSceneHoverEvent* evt =
\r
327 dynamic_cast< QGraphicsSceneHoverEvent* >( e );
\r
333 case QEvent::GraphicsSceneHoverMove:
\r
335 QGraphicsSceneHoverEvent* evt =
\r
336 dynamic_cast< QGraphicsSceneHoverEvent* >( e );
\r
342 case QEvent::GraphicsSceneMouseDoubleClick:
\r
344 QGraphicsSceneMouseEvent* evt =
\r
345 dynamic_cast< QGraphicsSceneMouseEvent* >( e );
\r
348 QGraphicsItem* item = this->itemAt( evt->scenePos( ) );
\r
351 this->_DoubleClick( evt, item );
\r
359 case QEvent::GraphicsSceneMouseMove:
\r
361 QGraphicsSceneMouseEvent* evt =
\r
362 dynamic_cast< QGraphicsSceneMouseEvent* >( e );
\r
367 this->m_Conn->setPos2( evt->scenePos( ) );
\r
368 this->m_Conn->updatePath( );
\r
376 case QEvent::GraphicsSceneMousePress:
\r
378 QGraphicsSceneMouseEvent* evt =
\r
379 dynamic_cast< QGraphicsSceneMouseEvent* >( e );
\r
382 switch( evt->button( ) )
\r
384 case Qt::LeftButton:
\r
386 QNEOutputPort* port =
\r
387 dynamic_cast< QNEOutputPort* >( this->itemAt( evt->scenePos( ) ) );
\r
390 this->m_Conn = new QNEConnection( 0, this->m_Scene );
\r
391 this->m_Conn->setPort1( port );
\r
392 this->m_Conn->setPos1( port->scenePos( ) );
\r
393 this->m_Conn->setPos2( evt->scenePos( ) );
\r
394 this->m_Conn->updatePath( );
\r
408 case QEvent::GraphicsSceneMouseRelease:
\r
410 QGraphicsSceneMouseEvent* evt =
\r
411 dynamic_cast< QGraphicsSceneMouseEvent* >( e );
\r
414 if( this->m_Conn != NULL && evt->button( ) == Qt::LeftButton )
\r
416 QNEInputPort* port2 =
\r
417 dynamic_cast< QNEInputPort* >( this->itemAt( evt->scenePos( ) ) );
\r
418 if( port2 != NULL )
\r
420 QNEOutputPort* port1 =
\r
421 dynamic_cast< QNEOutputPort* >( this->m_Conn->port1( ) );
\r
422 if( port1 != NULL )
\r
425 port1->block( ) != port2->block( ) &&
\r
426 !port2->hasConnection( ) &&
\r
427 !port1->isConnected( port2 )
\r
430 this->m_Conn->setPos2( port2->scenePos( ) );
\r
431 this->m_Conn->setPort2( port2 );
\r
432 this->m_Conn->updatePath( );
\r
434 this->m_Workspace->Connect(
\r
435 port1->block( )->namePort( )->name( ).toStdString( ),
\r
436 port2->block( )->namePort( )->name( ).toStdString( ),
\r
437 port1->name( ).toStdString( ),
\r
438 port2->name( ).toStdString( )
\r
440 this->m_Graph->AddConnection(
\r
441 port1->block( )->namePort( )->name( ).toStdString( ),
\r
442 port2->block( )->namePort( )->name( ).toStdString( ),
\r
446 this->m_Conn = NULL;
\r
454 delete this->m_Conn;
\r
455 this->m_Conn = NULL;
\r
463 case QEvent::GraphicsSceneMove:
\r
465 QGraphicsSceneMoveEvent* evt =
\r
466 dynamic_cast< QGraphicsSceneMoveEvent* >( e );
\r
472 case QEvent::GraphicsSceneResize:
\r
474 QGraphicsSceneResizeEvent* evt =
\r
475 dynamic_cast< QGraphicsSceneResizeEvent* >( e );
\r
481 case QEvent::GraphicsSceneWheel:
\r
483 QGraphicsSceneWheelEvent* evt =
\r
484 dynamic_cast< QGraphicsSceneWheelEvent* >( e );
\r
496 QGraphicsSceneMouseEvent* me =
\r
497 dynamic_cast< QGraphicsSceneMouseEvent* >( e );
\r
504 switch( ( int ) e->type( ) )
\r
506 case QEvent::GraphicsSceneMouseMove:
\r
510 this->m_Conn->setPos2( me->scenePos( ) );
\r
511 this->m_Conn->updatePath( );
\r
516 case QEvent::GraphicsSceneMouseRelease:
\r
518 if( this->m_Conn && me->button( ) == Qt::LeftButton )
\r
520 QGraphicsItem* item = itemAt( me->scenePos( ) );
\r
521 if( item && item->type( ) == QNEPort::Type )
\r
523 QNEPort* port1 = this->m_Conn->port1( );
\r
524 QNEPort* port2 = ( QNEPort* ) item;
\r
525 if( port1->block( ) != port2->block( ) && port1->isOutput( ) != port2->isOutput( ) && !port1->isConnected( port2 ) )
\r
527 this->m_Conn->setPos2( port2->scenePos( ) );
\r
528 this->m_Conn->setPort2( port2 );
\r
529 this->m_Conn->updatePath( );
\r
530 this->m_Conn = NULL;
\r
535 delete this->m_Conn;
\r
536 this->m_Conn = NULL;
\r
544 return( this->Superclass::eventFilter( o, e ) );
\r