From: Leonardo Florez-Valencia Date: Tue, 15 Dec 2015 22:54:08 +0000 (-0500) Subject: More on graph editor X-Git-Tag: v0.1~283 X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=ef8b6e12859181d3faa8019ce7319c539c0f86ec;p=cpPlugins.git More on graph editor --- diff --git a/appli/cpPipelineEditor/CMakeLists.txt b/appli/cpPipelineEditor/CMakeLists.txt index 002e6e2..b978bcd 100644 --- a/appli/cpPipelineEditor/CMakeLists.txt +++ b/appli/cpPipelineEditor/CMakeLists.txt @@ -10,10 +10,15 @@ IF(USE_QT4) SET( App_QT_SOURCES - Edge.cxx - GraphCanvas.cxx - Node.cxx - cpPipelineEditor.cxx + QNEBlock.cxx + QNEConnection.cxx + QNEPort.cxx + QNodesEditor.cxx + QNEMainWindow.cxx + #Edge.cxx + #GraphCanvas.cxx + #Node.cxx + #cpPipelineEditor.cxx ) SET( App_SOURCES @@ -21,8 +26,10 @@ IF(USE_QT4) ) SET( App_QT_HEADERS - GraphCanvas.h - cpPipelineEditor.h + QNodesEditor.h + QNEMainWindow.h + #GraphCanvas.h + #cpPipelineEditor.h ) SET( App_HEADERS diff --git a/appli/cpPipelineEditor/QNEBlock.cxx b/appli/cpPipelineEditor/QNEBlock.cxx new file mode 100644 index 0000000..d1e0109 --- /dev/null +++ b/appli/cpPipelineEditor/QNEBlock.cxx @@ -0,0 +1,260 @@ +/* Copyright (c) 2012, STANISLAW ADASZEWSKI + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of STANISLAW ADASZEWSKI nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL STANISLAW ADASZEWSKI BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "QNEBlock.h" + +#include +#include +#include +#include +#include + +#include "QNEPort.h" + +// ------------------------------------------------------------------------- +PipelineEditor::QNEBlock:: +QNEBlock( QGraphicsItem* parent, QGraphicsScene* scene ) + : Superclass( parent, scene ), + m_HorzMargin( 20 ), + m_VertMargin( 5 ) +{ + QPainterPath p; + p.addRoundedRect( -50, -15, 100, 30, 5, 5 ); + this->setPath( p ); + this->setPen( QPen( Qt::darkGreen ) ); + this->setBrush( Qt::green ); + this->setFlag( QGraphicsItem::ItemIsMovable ); + this->setFlag( QGraphicsItem::ItemIsSelectable ); + this->m_Width = this->m_HorzMargin; + this->m_Height = this->m_VertMargin; +} + +// ------------------------------------------------------------------------- +PipelineEditor::QNEBlock:: +~QNEBlock( ) +{ +} + +// ------------------------------------------------------------------------- +PipelineEditor::QNEPort* PipelineEditor::QNEBlock:: +addPort( const QString& name, bool isOutput, int flags, int ptr ) +{ + QNEPort* port = new QNEPort( this ); + port->setName( name ); + port->setIsOutput( isOutput ); + port->setNEBlock( this ); + port->setPortFlags( flags ); + port->setPtr( ptr ); + + QFontMetrics fm( this->scene( )->font( ) ); + int w = fm.width( name ); + int h = fm.height( ); + if( w > this->m_Width - this->m_HorzMargin ) + this->m_Width = w + this->m_HorzMargin; + this->m_Height += h; + + QPainterPath p; + p.addRoundedRect( + -this->m_Width / 2, + -this->m_Height / 2, + this->m_Width, + this->m_Height, 5, 5 + ); + this->setPath( p ); + + int y = -this->m_Height / 2 + this->m_VertMargin + port->radius( ); + foreach( QGraphicsItem* port_, children( ) ) + { + if( port_->type( ) != QNEPort::Type ) + continue; + + QNEPort* port = ( QNEPort* ) port_; + if( port->isOutput( ) ) + port->setPos( this->m_Width/2 + port->radius( ), y ); + else + port->setPos( -this->m_Width/2 - port->radius( ), y ); + y += h; + + } // rof + return( port ); +} + +// ------------------------------------------------------------------------- +void PipelineEditor::QNEBlock:: +addInputPort( const QString& name ) +{ + this->addPort( name, false ); +} + +// ------------------------------------------------------------------------- +void PipelineEditor::QNEBlock:: +addOutputPort( const QString& name ) +{ + this->addPort( name, true ); +} + +// ------------------------------------------------------------------------- +void PipelineEditor::QNEBlock:: +addInputPorts( const QStringList& names ) +{ + foreach( QString n, names ) + this->addInputPort( n ); +} + +// ------------------------------------------------------------------------- +void PipelineEditor::QNEBlock:: +addOutputPorts( const QStringList& names ) +{ + foreach( QString n, names ) + this->addOutputPort( n ); +} + +// ------------------------------------------------------------------------- +void PipelineEditor::QNEBlock:: +save( QDataStream& ds ) +{ + ds << pos( ); + + int count( 0 ); + + foreach( QGraphicsItem* port_, children( ) ) + { + if( port_->type( ) != QNEPort::Type ) + continue; + count++; + + } // rof + + ds << count; + + foreach( QGraphicsItem* port_, children( ) ) + { + if( port_->type( ) != QNEPort::Type ) + continue; + + QNEPort* port = ( QNEPort* ) port_; + ds << ( quint64 ) port; + ds << port->portName( ); + ds << port->isOutput( ); + ds << port->portFlags( ); + + } // rof +} + +// ------------------------------------------------------------------------- +void PipelineEditor::QNEBlock:: +load( QDataStream& ds, QMap& portMap ) +{ + QPointF p; + ds >> p; + this->setPos( p ); + int count; + ds >> count; + for( int i = 0; i < count; i++ ) + { + QString name; + bool output; + int flags; + quint64 ptr; + + ds >> ptr; + ds >> name; + ds >> output; + ds >> flags; + portMap[ptr] = this->addPort( name, output, flags, ptr ); + + } // rof +} + +// ------------------------------------------------------------------------- +void PipelineEditor::QNEBlock:: +paint( + QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget + ) +{ + Q_UNUSED( option ); + Q_UNUSED( widget ); + + if( this->isSelected( ) ) + { + painter->setPen( QPen( Qt::darkYellow ) ); + painter->setBrush( Qt::yellow ); + } + else + { + painter->setPen( QPen( Qt::darkGreen ) ); + painter->setBrush( Qt::green ); + + } // fi + painter->drawPath( this->path( ) ); +} + +// ------------------------------------------------------------------------- +PipelineEditor::QNEBlock* PipelineEditor::QNEBlock:: +clone( ) +{ + QNEBlock* b = new QNEBlock( 0, this->scene( ) ); + + foreach( QGraphicsItem* port_, childItems( ) ) + { + if( port_->type( ) == QNEPort::Type ) + { + QNEPort* port = ( QNEPort* ) port_; + b->addPort( + port->portName( ), + port->isOutput( ), + port->portFlags( ), + port->ptr( ) + ); + + } // fi + + } // rof + return( b ); +} + +// ------------------------------------------------------------------------- +QVector< PipelineEditor::QNEPort* > PipelineEditor::QNEBlock:: +ports( ) +{ + QVector< PipelineEditor::QNEPort* > res; + foreach( QGraphicsItem* port_, childItems( ) ) + { + if( port_->type( ) == QNEPort::Type ) + res.append( ( QNEPort* ) port_ ); + + } // rof + return( res ); +} + +// ------------------------------------------------------------------------- +QVariant PipelineEditor::QNEBlock:: +itemChange( GraphicsItemChange change, const QVariant& value ) +{ + return( value ); +} + +// eof - $RCSfile$ diff --git a/appli/cpPipelineEditor/QNEBlock.h b/appli/cpPipelineEditor/QNEBlock.h new file mode 100644 index 0000000..516e871 --- /dev/null +++ b/appli/cpPipelineEditor/QNEBlock.h @@ -0,0 +1,82 @@ +/* Copyright (c) 2012, STANISLAW ADASZEWSKI + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of STANISLAW ADASZEWSKI nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL STANISLAW ADASZEWSKI BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +#ifndef __PIPELINEEDITOR__QNEBLOCK__H__ +#define __PIPELINEEDITOR__QNEBLOCK__H__ + +#include + +namespace PipelineEditor +{ + class QNEPort; + + class QNEBlock + : public QGraphicsPathItem + { + public: + typedef QNEBlock Self; + typedef QGraphicsPathItem Superclass; + + public: + enum { Type = QGraphicsItem::UserType + 3 }; + + QNEBlock( QGraphicsItem* parent = NULL, QGraphicsScene* scene = NULL ); + virtual ~QNEBlock( ); + + QNEPort* addPort( + const QString& name, bool isOutput, int flags = 0, int ptr = 0 + ); + void addInputPort( const QString& name ); + void addOutputPort( const QString& name ); + void addInputPorts( const QStringList& names ); + void addOutputPorts( const QStringList& names ); + void save( QDataStream& ds ); + void load( QDataStream& ds, QMap< quint64, QNEPort* >& portMap ); + void paint( + QPainter* painter, + const QStyleOptionGraphicsItem* option, + QWidget* widget + ); + QNEBlock* clone( ); + QVector< QNEPort* > ports( ); + + int type( ) const + { return( this->Type ); } + + protected: + QVariant itemChange( GraphicsItemChange change, const QVariant& value ); + + private: + int m_HorzMargin; + int m_VertMargin; + int m_Width; + int m_Height; + }; + +} // ecapseman + +#endif // __PIPELINEEDITOR__QNEBLOCK__H__ + +// eof - $RCSfile$ diff --git a/appli/cpPipelineEditor/QNEConnection.cxx b/appli/cpPipelineEditor/QNEConnection.cxx new file mode 100644 index 0000000..e038c5f --- /dev/null +++ b/appli/cpPipelineEditor/QNEConnection.cxx @@ -0,0 +1,155 @@ +/* Copyright (c) 2012, STANISLAW ADASZEWSKI + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of STANISLAW ADASZEWSKI nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL STANISLAW ADASZEWSKI BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "QNEConnection.h" + +#include "QNEPort.h" + +#include +#include +#include + +// ------------------------------------------------------------------------- +PipelineEditor::QNEConnection:: +QNEConnection( QGraphicsItem* parent, QGraphicsScene* scene ) + : Superclass( parent, scene ) +{ + this->setPen( QPen( Qt::black, 2 ) ); + this->setBrush( Qt::NoBrush ); + this->setZValue( -1 ); + this->m_Port1 = 0; + this->m_Port2 = 0; +} + +// ------------------------------------------------------------------------- +PipelineEditor::QNEConnection:: +~QNEConnection( ) +{ + if ( this->m_Port1 ) + this->m_Port1->connections( ).remove( + this->m_Port1->connections( ).indexOf( this ) + ); + if ( this->m_Port2 ) + this->m_Port2->connections( ).remove( + this->m_Port2->connections( ).indexOf( this ) + ); +} + +// ------------------------------------------------------------------------- +void PipelineEditor::QNEConnection:: +setPos1( const QPointF& p ) +{ + this->m_Pos1 = p; +} + +// ------------------------------------------------------------------------- +void PipelineEditor::QNEConnection:: +setPos2( const QPointF& p ) +{ + this->m_Pos2 = p; +} + +// ------------------------------------------------------------------------- +void PipelineEditor::QNEConnection:: +setPort1( QNEPort* p ) +{ + this->m_Port1 = p; + this->m_Port1->connections( ).append( this ); +} + +// ------------------------------------------------------------------------- +void PipelineEditor::QNEConnection:: +setPort2( QNEPort* p ) +{ + this->m_Port2 = p; + this->m_Port2->connections( ).append( this ); +} + +// ------------------------------------------------------------------------- +void PipelineEditor::QNEConnection:: +updatePosFromPorts( ) +{ + this->m_Pos1 = this->m_Port1->scenePos( ); + this->m_Pos2 = this->m_Port2->scenePos( ); +} + +// ------------------------------------------------------------------------- +void PipelineEditor::QNEConnection:: +updatePath( ) +{ + QPainterPath p; + + p.moveTo( this->m_Pos1 ); + + qreal dx = this->m_Pos2.x( ) - this->m_Pos1.x( ); + qreal dy = this->m_Pos2.y( ) - this->m_Pos1.y( ); + + QPointF ctr1( this->m_Pos1.x( ) + dx * 0.25, this->m_Pos1.y( ) + dy * 0.1 ); + QPointF ctr2( this->m_Pos1.x( ) + dx * 0.75, this->m_Pos1.y( ) + dy * 0.9 ); + + p.cubicTo( ctr1, ctr2, this->m_Pos2 ); + + this->setPath( p ); +} + +// ------------------------------------------------------------------------- +PipelineEditor::QNEPort* PipelineEditor::QNEConnection:: +port1( ) const +{ + return( this->m_Port1 ); +} + +// ------------------------------------------------------------------------- +PipelineEditor::QNEPort* PipelineEditor::QNEConnection:: +port2( ) const +{ + return( this->m_Port2 ); +} + +// ------------------------------------------------------------------------- +void PipelineEditor::QNEConnection:: +save( QDataStream& ds ) +{ + ds << ( quint64 ) this->m_Port1; + ds << ( quint64 ) this->m_Port2; +} + +// ------------------------------------------------------------------------- +void PipelineEditor::QNEConnection:: +load( QDataStream& ds, const QMap< quint64, QNEPort* >& portMap ) +{ + quint64 ptr1; + quint64 ptr2; + ds >> ptr1; + ds >> ptr2; + + this->setPort1( portMap[ ptr1 ] ); + this->setPort2( portMap[ ptr2 ] ); + this->updatePosFromPorts( ); + this->updatePath( ); +} + +// eof - $RCSfile$ diff --git a/appli/cpPipelineEditor/QNEConnection.h b/appli/cpPipelineEditor/QNEConnection.h new file mode 100644 index 0000000..869e283 --- /dev/null +++ b/appli/cpPipelineEditor/QNEConnection.h @@ -0,0 +1,76 @@ +/* Copyright (c) 2012, STANISLAW ADASZEWSKI + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of STANISLAW ADASZEWSKI nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL STANISLAW ADASZEWSKI BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef __PIPELINEEDITOR__QNECONNECTION__H__ +#define __PIPELINEEDITOR__QNECONNECTION__H__ + +#include + +namespace PipelineEditor +{ + class QNEPort; + + /** + */ + class QNEConnection + : public QGraphicsPathItem + { + public: + typedef QNEConnection Self; + typedef QGraphicsPathItem Superclass; + + public: + enum { Type = QGraphicsItem::UserType + 2 }; + + QNEConnection( QGraphicsItem* parent = 0, QGraphicsScene* scene = 0 ); + virtual ~QNEConnection( ); + + void setPos1( const QPointF& p ); + void setPos2( const QPointF& p ); + void setPort1( QNEPort* p ); + void setPort2( QNEPort* p ); + void updatePosFromPorts( ); + void updatePath( ); + QNEPort* port1( ) const; + QNEPort* port2( ) const; + + void save( QDataStream& ds ); + void load( QDataStream& ds, const QMap< quint64, QNEPort* >& portMap ); + + int type( ) const { return Type; } + + private: + QPointF m_Pos1; + QPointF m_Pos2; + QNEPort* m_Port1; + QNEPort* m_Port2; + }; + +} // ecapseman + +#endif // __PIPELINEEDITOR__QNECONNECTION__H__ + +// eof - $RCSfile$ diff --git a/appli/cpPipelineEditor/QNEMainWindow.cxx b/appli/cpPipelineEditor/QNEMainWindow.cxx new file mode 100644 index 0000000..5d7f7fe --- /dev/null +++ b/appli/cpPipelineEditor/QNEMainWindow.cxx @@ -0,0 +1,112 @@ +/* Copyright (c) 2012, STANISLAW ADASZEWSKI +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of STANISLAW ADASZEWSKI nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL STANISLAW ADASZEWSKI BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +#include "QNEMainWindow.h" +#include "ui_QNEMainWindow.h" + +#include "QNEBlock.h" +#include "QNodesEditor.h" + +#include +#include + +#include "QNEPort.h" + +QNEMainWindow::QNEMainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::QNEMainWindow) +{ + ui->setupUi(this); + + QGraphicsScene *s = new QGraphicsScene(); + ui->graphicsView->setScene(s); + ui->graphicsView->setRenderHint(QPainter::Antialiasing); + // ui->graphicsView->setDragMode(QGraphicsView::ScrollHandDrag); + + QNEBlock *b = new QNEBlock(0, s); + b->addPort("test", 0, QNEPort::NamePort); + b->addPort("TestBlock", 0, QNEPort::TypePort); + b->addInputPort("in1"); + b->addInputPort("in2"); + b->addInputPort("in3"); + b->addOutputPort("out1"); + b->addOutputPort("out2"); + b->addOutputPort("out3"); + + b = b->clone(); + b->setPos(150, 0); + + b = b->clone(); + b->setPos(150, 150); + + nodesEditor = new QNodesEditor(this); + nodesEditor->install(s); + + connect(ui->action_Save, SIGNAL(triggered()), this, SLOT(saveFile())); + connect(ui->action_Load, SIGNAL(triggered()), this, SLOT(loadFile())); + connect(ui->action_Quit, SIGNAL(triggered()), qApp, SLOT(quit())); + + ui->toolBar->addAction("Add block", this, SLOT(addBlock())); +} + +QNEMainWindow::~QNEMainWindow() +{ + delete ui; +} + +void QNEMainWindow::saveFile() +{ + QString fname = QFileDialog::getSaveFileName(); + if (fname.isEmpty()) + return; + + QFile f(fname); + f.open(QFile::WriteOnly); + QDataStream ds(&f); + nodesEditor->save(ds); +} + +void QNEMainWindow::loadFile() +{ + QString fname = QFileDialog::getOpenFileName(); + if (fname.isEmpty()) + return; + + QFile f(fname); + f.open(QFile::ReadOnly); + QDataStream ds(&f); + nodesEditor->load(ds); +} + +void QNEMainWindow::addBlock() +{ + QNEBlock *b = new QNEBlock(0, ui->graphicsView->scene()); + static const char* names[] = {"Vin", "Voutsadfasdf", "Imin", "Imax", "mul", "add", "sub", "div", "Conv", "FFT"}; + for (int i = 0; i < 4 + rand() % 3; i++) + { + b->addPort(names[rand() % 10], rand() % 2, 0, 0); + b->setPos(ui->graphicsView->sceneRect().center().toPoint()); + } +} diff --git a/appli/cpPipelineEditor/QNEMainWindow.h b/appli/cpPipelineEditor/QNEMainWindow.h new file mode 100644 index 0000000..4ee1100 --- /dev/null +++ b/appli/cpPipelineEditor/QNEMainWindow.h @@ -0,0 +1,55 @@ +/* Copyright (c) 2012, STANISLAW ADASZEWSKI +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of STANISLAW ADASZEWSKI nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL STANISLAW ADASZEWSKI BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +#ifndef QNEMAINWINDOW_H +#define QNEMAINWINDOW_H + +#include + +namespace Ui { + class QNEMainWindow; +} + +class QNodesEditor; + +class QNEMainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit QNEMainWindow(QWidget *parent = 0); + ~QNEMainWindow(); + +private slots: + void saveFile(); + void loadFile(); + void addBlock(); + +private: + Ui::QNEMainWindow *ui; + QNodesEditor *nodesEditor; +}; + +#endif // QNEMAINWINDOW_H diff --git a/appli/cpPipelineEditor/QNEMainWindow.ui b/appli/cpPipelineEditor/QNEMainWindow.ui new file mode 100644 index 0000000..29f3f8c --- /dev/null +++ b/appli/cpPipelineEditor/QNEMainWindow.ui @@ -0,0 +1,73 @@ + + + QNEMainWindow + + + + 0 + 0 + 540 + 389 + + + + QNodesEditor Demo (c) 2012 STANISLAW ADASZEWSKI, http://algoholic.eu + + + + + + + + + + + + 0 + 0 + 540 + 20 + + + + + &File + + + + + + + + + + + toolBar + + + TopToolBarArea + + + false + + + + + &Save + + + + + &Load + + + + + &Quit + + + + + + + diff --git a/appli/cpPipelineEditor/QNEPort.cxx b/appli/cpPipelineEditor/QNEPort.cxx new file mode 100644 index 0000000..7c140bb --- /dev/null +++ b/appli/cpPipelineEditor/QNEPort.cxx @@ -0,0 +1,191 @@ +/* Copyright (c) 2012, STANISLAW ADASZEWSKI + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of STANISLAW ADASZEWSKI nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL STANISLAW ADASZEWSKI BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "QNEPort.h" + +#include +#include +#include + +#include "QNEConnection.h" + +// ------------------------------------------------------------------------- +PipelineEditor::QNEPort:: +QNEPort( QGraphicsItem* parent, QGraphicsScene* scene ) + : Superclass( parent, scene ), + m_Radius( 5 ), + m_Margin( 2 ) +{ + this->m_Label = new QGraphicsTextItem( this ); + + QPainterPath p; + p.addEllipse( + -this->m_Radius, -this->m_Radius, + 2 * this->m_Radius, 2 * this->m_Radius + ); + + this->setPath( p ); + this->setPen( QPen( Qt::darkRed ) ); + this->setBrush( Qt::red ); + this->setFlag( QGraphicsItem::ItemSendsScenePositionChanges ); + this->m_PortFlags = 0; +} + +// ------------------------------------------------------------------------- +PipelineEditor::QNEPort:: +~QNEPort( ) +{ + foreach( QNEConnection* conn, this->m_Connections ) + delete conn; +} + +// ------------------------------------------------------------------------- +void PipelineEditor::QNEPort:: +setNEBlock( QNEBlock *b ) +{ + this->m_Block = b; +} + +// ------------------------------------------------------------------------- +void PipelineEditor::QNEPort:: +setName( const QString &n ) +{ + this->m_Name = n; + this->m_Label->setPlainText( n ); +} + +// ------------------------------------------------------------------------- +void PipelineEditor::QNEPort:: +setIsOutput( bool o ) +{ + this->m_IsOutput = o; + + QFontMetrics fm( this->scene( )->font( ) ); + QRect r = fm.boundingRect( this->m_Name ); + + int rm = this->m_Radius + this->m_Margin; + int h = -this->m_Label->boundingRect( ).height( ) / 2; + if( this->m_IsOutput ) + this->m_Label->setPos( + -rm - this->m_Label->boundingRect( ).width( ), h + ); + else + this->m_Label->setPos( rm, h ); +} + +// ------------------------------------------------------------------------- +int PipelineEditor::QNEPort:: +radius( ) +{ + return( this->m_Radius ); +} + +// ------------------------------------------------------------------------- +bool PipelineEditor::QNEPort:: +isOutput( ) +{ + return( this->m_IsOutput ); +} + +// ------------------------------------------------------------------------- +QVector< PipelineEditor::QNEConnection* >& PipelineEditor::QNEPort:: +connections( ) +{ + return( this->m_Connections ); +} + +// ------------------------------------------------------------------------- +void PipelineEditor::QNEPort:: +setPortFlags( int f ) +{ + this->m_PortFlags = f; + + if( this->m_PortFlags & Self::TypePort ) + { + QFont font( this->scene( )->font( ) ); + font.setItalic( true ); + this->m_Label->setFont( font ); + this->setPath( QPainterPath( ) ); + } + else if( this->m_PortFlags & Self::NamePort ) + { + QFont font( this->scene( )->font( ) ); + font.setBold( true ); + this->m_Label->setFont( font ); + this->setPath( QPainterPath( ) ); + + } // fi +} + +// ------------------------------------------------------------------------- +PipelineEditor::QNEBlock* PipelineEditor::QNEPort:: +block( ) const +{ + return( this->m_Block ); +} + +// ------------------------------------------------------------------------- +quint64 PipelineEditor::QNEPort:: +ptr( ) +{ + return( this->m_Ptr ); +} + +// ------------------------------------------------------------------------- +void PipelineEditor::QNEPort:: +setPtr( quint64 p ) +{ + this->m_Ptr = p; +} + +// ------------------------------------------------------------------------- +bool PipelineEditor::QNEPort:: +isConnected( QNEPort* other ) +{ + foreach( QNEConnection* conn, this->m_Connections ) + if( conn->port1( ) == other || conn->port2( ) == other ) + return( true ); + return( false ); +} + +// ------------------------------------------------------------------------- +QVariant PipelineEditor::QNEPort:: +itemChange( GraphicsItemChange change, const QVariant& value ) +{ + if( change == ItemScenePositionHasChanged ) + { + foreach( QNEConnection* conn, this->m_Connections ) + { + conn->updatePosFromPorts( ); + conn->updatePath( ); + + } // rof + + } // fi + return( value ); +} + +// eof - $RCSfile$ diff --git a/appli/cpPipelineEditor/QNEPort.h b/appli/cpPipelineEditor/QNEPort.h new file mode 100644 index 0000000..638e413 --- /dev/null +++ b/appli/cpPipelineEditor/QNEPort.h @@ -0,0 +1,92 @@ +/* Copyright (c) 2012, STANISLAW ADASZEWSKI + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of STANISLAW ADASZEWSKI nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL STANISLAW ADASZEWSKI BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef __PIPELINEEDITOR__QNEPORT__H__ +#define __PIPELINEEDITOR__QNEPORT__H__ + +#include + +namespace PipelineEditor +{ + class QNEBlock; + class QNEConnection; + + /** + */ + class QNEPort + : public QGraphicsPathItem + { + public: + typedef QNEPort Self; + typedef QGraphicsPathItem Superclass; + + public: + enum { Type = QGraphicsItem::UserType + 1 }; + enum { NamePort = 1, TypePort = 2 }; + + QNEPort( QGraphicsItem* parent = 0, QGraphicsScene* scene = NULL ); + virtual ~QNEPort( ); + + void setNEBlock( QNEBlock* b ); + void setName( const QString& n ); + void setIsOutput( bool o ); + int radius( ); + bool isOutput( ); + QVector< QNEConnection* >& connections( ); + void setPortFlags( int f ); + + inline const QString& portName( ) const + { return( this->m_Name ); } + inline int portFlags( ) const + { return( this->m_PortFlags ); } + int type( ) const + { return( this->Type ); } + + QNEBlock* block( ) const; + quint64 ptr( ); + void setPtr( quint64 p ); + bool isConnected( QNEPort* other ); + + protected: + QVariant itemChange( GraphicsItemChange change, const QVariant& value ); + + private: + QNEBlock* m_Block; + QString m_Name; + bool m_IsOutput; + QGraphicsTextItem* m_Label; + int m_Radius; + int m_Margin; + QVector< QNEConnection* > m_Connections; + int m_PortFlags; + quint64 m_Ptr; + }; + +} // ecapseman + +#endif // __PIPELINEEDITOR__QNEPORT__H__ + +// eof - $RCSfile$ diff --git a/appli/cpPipelineEditor/QNodesEditor.cxx b/appli/cpPipelineEditor/QNodesEditor.cxx new file mode 100644 index 0000000..9669eea --- /dev/null +++ b/appli/cpPipelineEditor/QNodesEditor.cxx @@ -0,0 +1,200 @@ +/* Copyright (c) 2012, STANISLAW ADASZEWSKI + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of STANISLAW ADASZEWSKI nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL STANISLAW ADASZEWSKI BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "QNodesEditor.h" + +#include +#include +#include + +#include "QNEPort.h" +#include "QNEConnection.h" +#include "QNEBlock.h" + +// ------------------------------------------------------------------------- +PipelineEditor::QNodesEditor:: +QNodesEditor( QObject* parent ) + : Superclass( parent ) +{ + this->m_Conn = NULL; +} + +// ------------------------------------------------------------------------- +PipelineEditor::QNodesEditor:: +~QNodesEditor( ) +{ +} + +// ------------------------------------------------------------------------- +void PipelineEditor::QNodesEditor:: +install( QGraphicsScene* s ) +{ + s->installEventFilter( this ); + this->m_Scene = s; +} + +// ------------------------------------------------------------------------- +QGraphicsItem* PipelineEditor::QNodesEditor:: +itemAt( const QPointF& pos ) +{ + QList< QGraphicsItem* > items = + this->m_Scene->items( QRectF( pos - QPointF( 1, 1 ), QSize( 3, 3 ) ) ); + + foreach( QGraphicsItem* item, items ) + if( item->type( ) > QGraphicsItem::UserType ) + return( item ); + return( NULL ); +} + +// ------------------------------------------------------------------------- +bool PipelineEditor::QNodesEditor:: +eventFilter( QObject* o, QEvent* e ) +{ + QGraphicsSceneMouseEvent* me = ( QGraphicsSceneMouseEvent* ) e; + + switch ( ( int ) e->type( ) ) + { + case QEvent::GraphicsThis->M_SceneMousePress: + { + switch ( ( int ) me->button( ) ) + { + case Qt::LeftButton: + { + QGraphicsItem* item = this->itemAt( me->this->m_ScenePos( ) ); + if( item && item->type( ) == QNEPort::Type ) + { + this->m_Conn = new QNEConnection( 0, this->m_Scene ); + this->m_Conn->setPort1( ( QNEPort* ) item ); + this->m_Conn->setPos1( item->this->m_ScenePos( ) ); + this->m_Conn->setPos2( me->this->m_ScenePos( ) ); + this->m_Conn->updatePath( ); + + return( true ); + } + else if( item && item->type( ) == QNEBlock::Type ) + { + /* if( selBlock ) + selBlock->setSelected( ); */ + // selBlock = ( QNEBlock* ) item; + + } // fi + break; + } + case Qt::RightButton: + { + QGraphicsItem* item = itemAt( me->this->m_ScenePos( ) ); + if( item && ( item->type( ) == QNEConnection::Type || item->type( ) == QNEBlock::Type ) ) + delete item; + // if( selBlock == ( QNEBlock* ) item ) + // selBlock = 0; + break; + } + } + } + case QEvent::GraphicsThis->M_SceneMouseMove: + { + if( this->m_Conn ) + { + this->m_Conn->setPos2( me->this->m_ScenePos( ) ); + this->m_Conn->updatePath( ); + return( true ); + } + break; + } + case QEvent::GraphicsThis->M_SceneMouseRelease: + { + if( this->m_Conn && me->button( ) == Qt::LeftButton ) + { + QGraphicsItem* item = itemAt( me->this->m_ScenePos( ) ); + if( item && item->type( ) == QNEPort::Type ) + { + QNEPort* port1 = this->m_Conn->port1( ); + QNEPort* port2 = ( QNEPort* ) item; + + if( port1->block( ) != port2->block( ) && port1->isOutput( ) != port2->isOutput( ) && !port1->isThis->M_Connected( port2 ) ) + { + this->m_Conn->setPos2( port2->this->m_ScenePos( ) ); + this->m_Conn->setPort2( port2 ); + this->m_Conn->updatePath( ); + this->m_Conn = NULL; + return( true ); + } + } + + delete this->m_Conn; + this->m_Conn = NULL; + return( true ); + } + break; + } + } + return( this->Superclass::eventFilter( o, e ) ); +} + +// ------------------------------------------------------------------------- +void PipelineEditor::QNodesEditor:: +save( QDataStream& ds ) +{ + foreach( QGraphicsItem* item, this->m_Scene->items( ) ) + if( item->type( ) == QNEBlock::Type ) + { + ds << item->type( ); + ( ( QNEBlock* ) item )->save( ds ); + } + + foreach( QGraphicsItem* item, this->m_Scene->items( ) ) + if( item->type( ) == QNEConnection::Type ) + { + ds << item->type( ); + ( ( QNEConnection* ) item )->save( ds ); + } +} + +// ------------------------------------------------------------------------- +void PipelineEditor::QNodesEditor:: +load( QDataStream& ds ) +{ + this->m_Scene->clear( ); + + QMap portMap; + + while ( !ds.atEnd( ) ) + { + int type; + ds >> type; + if( type == QNEBlock::Type ) + { + QNEBlock* block = new QNEBlock( 0, this->m_Scene ); + block->load( ds, portMap ); + } else if( type == QNEConnection::Type ) + { + QNEConnection* this->m_Conn = new QNEConnection( 0, this->m_Scene ); + this->m_Conn->load( ds, portMap ); + } + } +} + +// eof - $RCSfile$ diff --git a/appli/cpPipelineEditor/QNodesEditor.h b/appli/cpPipelineEditor/QNodesEditor.h new file mode 100644 index 0000000..3e90b50 --- /dev/null +++ b/appli/cpPipelineEditor/QNodesEditor.h @@ -0,0 +1,73 @@ +/* Copyright (c) 2012, STANISLAW ADASZEWSKI + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of STANISLAW ADASZEWSKI nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL STANISLAW ADASZEWSKI BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +#ifndef __PIPELINEEDITOR__QNODESEDITOR__H__ +#define __PIPELINEEDITOR__QNODESEDITOR__H__ + +#include + +namespace PipelineEditor +{ + class QGraphicsScene; + class QNEConnection; + class QGraphicsItem; + class QPointF; + class QNEBlock; + + /** + */ + class QNodesEditor + : public QObject + { + Q_OBJECT; + + public: + typedef QNodesEditor Self; + typedef QObject Superclass; + + public: + explicit QNodesEditor( QObject* parent = 0 ); + virtual ~QNodesEditor( ); + + void install( QGraphicsScene* s ); + + bool eventFilter( QObject* o, QEvent* e ); + + void save( QDataStream& ds ); + void load( QDataStream& ds ); + + private: + QGraphicsItem* itemAt( const QPointF& pos ); + + private: + QGraphicsScene* m_Scene; + QNEConnection* m_Conn; + }; + +} // ecapseman + +#endif // __PIPELINEEDITOR__QNODESEDITOR__H__ + +// eof - $RCSfile$ diff --git a/appli/cpPipelineEditor/main.cxx b/appli/cpPipelineEditor/main.cxx index 7154469..531d13e 100644 --- a/appli/cpPipelineEditor/main.cxx +++ b/appli/cpPipelineEditor/main.cxx @@ -1,4 +1,4 @@ -#include "cpPipelineEditor.h" +#include "QNEMainWindow.h" #include #include @@ -6,7 +6,7 @@ int main( int argc, char* argv[] ) { QApplication a( argc, argv ); - cpPipelineEditor w; + QNEMainWindow w; w.show( ); return( a.exec( ) ); diff --git a/lib/cpExtensions/DataStructures/Graph.h b/lib/cpExtensions/DataStructures/Graph.h index a23582f..5fb2707 100644 --- a/lib/cpExtensions/DataStructures/Graph.h +++ b/lib/cpExtensions/DataStructures/Graph.h @@ -48,6 +48,8 @@ namespace cpExtensions typename TMatrix::const_iterator BeginEdgesRows( ) const; typename TMatrix::const_iterator EndEdgesRows( ) const; + void Clear( ); + bool HasVertexIndex( const I& index ) const; void InsertVertex( const I& index, V& vertex ); V& GetVertex( const I& index ); diff --git a/lib/cpExtensions/DataStructures/Graph.hxx b/lib/cpExtensions/DataStructures/Graph.hxx index 9322977..c567f39 100644 --- a/lib/cpExtensions/DataStructures/Graph.hxx +++ b/lib/cpExtensions/DataStructures/Graph.hxx @@ -73,6 +73,15 @@ EndEdgesRows( ) const return( this->m_Matrix.end( ) ); } +// ------------------------------------------------------------------------- +template< class V, class C, class I > +void cpExtensions::DataStructures::Graph< V, C, I >:: +Clear( ) +{ + this->m_Vertices.clear( ); + this->m_Matrix.clear( ); +} + // ------------------------------------------------------------------------- template< class V, class C, class I > bool cpExtensions::DataStructures::Graph< V, C, I >:: diff --git a/lib/cpPlugins/Interface/Workspace.cxx b/lib/cpPlugins/Interface/Workspace.cxx index 4e5f51a..849e7cc 100644 --- a/lib/cpPlugins/Interface/Workspace.cxx +++ b/lib/cpPlugins/Interface/Workspace.cxx @@ -105,6 +105,14 @@ GetLoadedPluginFilters( const std::string& category ) const return( EMPTY ); } +// ------------------------------------------------------------------------- +void cpPlugins::Interface::Workspace:: +Clear( ) +{ + if( this->m_Graph.IsNotNull( ) ) + this->m_Graph->Clear( ); +} + // ------------------------------------------------------------------------- cpPlugins::Interface::Workspace:: TGraph* cpPlugins::Interface::Workspace:: @@ -201,6 +209,30 @@ GetParameters( const std::string& name ) const return( NULL ); } +// ------------------------------------------------------------------------- +cpPlugins::Interface::Workspace:: +TFilter* cpPlugins::Interface::Workspace:: +GetFilter( const std::string& name ) +{ + TFilter* f = + dynamic_cast< TFilter* >( + this->m_Graph->GetVertex( name ).GetPointer( ) + ); + return( f ); +} + +// ------------------------------------------------------------------------- +const cpPlugins::Interface::Workspace:: +TFilter* cpPlugins::Interface::Workspace:: +GetFilter( const std::string& name ) const +{ + const TFilter* f = + dynamic_cast< const TFilter* >( + this->m_Graph->GetVertex( name ).GetPointer( ) + ); + return( f ); +} + // ------------------------------------------------------------------------- bool cpPlugins::Interface::Workspace:: Reduce( const std::string& name ) @@ -219,7 +251,7 @@ Execute( ) std::string err = ""; for( auto sIt = sinks.begin( ); sIt != sinks.end( ); ++sIt ) { - std::string lerr = this->Execute( *sIt ); + std::string lerr = this->Execute( *sIt, NULL ); if( lerr != "" ) err += lerr + std::string( "\n" ); @@ -229,7 +261,7 @@ Execute( ) // ------------------------------------------------------------------------- std::string cpPlugins::Interface::Workspace:: -Execute( const std::string& name ) +Execute( const std::string& name, QWidget* p ) { // Get filter TFilter* f = @@ -243,7 +275,16 @@ Execute( const std::string& name ) ); // Execute and return - return( f->Update( ) ); + if( p != NULL ) + { + auto diag_res = f->ExecConfigurationDialog( p ); + if( diag_res == TFilter::DialogResult_NoModal ) + return( f->Update( ) ); + else + return( "" ); + } + else + return( f->Update( ) ); } // ------------------------------------------------------------------------- diff --git a/lib/cpPlugins/Interface/Workspace.h b/lib/cpPlugins/Interface/Workspace.h index 9bad734..6cf157d 100644 --- a/lib/cpPlugins/Interface/Workspace.h +++ b/lib/cpPlugins/Interface/Workspace.h @@ -9,6 +9,9 @@ #include #include +// Some forward declarations +class QWidget; + namespace cpPlugins { namespace Interface @@ -52,6 +55,7 @@ namespace cpPlugins std::string SaveWorkspace( const std::string& fname ) const; // Graph management + void Clear( ); TGraph* GetGraph( ); const TGraph* GetGraph( ) const; bool CreateFilter( const std::string& filter, const std::string& name ); @@ -62,13 +66,15 @@ namespace cpPlugins ); TParameters* GetParameters( const std::string& name ); const TParameters* GetParameters( const std::string& name ) const; + TFilter* GetFilter( const std::string& name ); + const TFilter* GetFilter( const std::string& name ) const; // Graph reduction bool Reduce( const std::string& name ); // Pipeline execution std::string Execute( ); - std::string Execute( const std::string& name ); + std::string Execute( const std::string& name, QWidget* p = NULL ); protected: void _UpdateLoadedPluginsInformation( ); diff --git a/lib/cpPlugins/Interface/WorkspaceIO.cxx b/lib/cpPlugins/Interface/WorkspaceIO.cxx index 0651011..e14a44e 100644 --- a/lib/cpPlugins/Interface/WorkspaceIO.cxx +++ b/lib/cpPlugins/Interface/WorkspaceIO.cxx @@ -8,6 +8,8 @@ LoadWorkspace( const std::string& fname ) TiXmlDocument* doc = new TiXmlDocument( fname.c_str( ) ); doc->LoadFile( ); TiXmlElement* root = doc->RootElement( ); + if( root == NULL ) + return( "cpPlugins::Interface::Workspace: No valid file" ); if( std::string( root->Value( ) ) != "cpPlugins_Workspace" ) return( "cpPlugins::Interface::Workspace: No valid workspace" ); std::stringstream err; @@ -233,7 +235,43 @@ LoadWorkspace( const std::string& fname ) std::string cpPlugins::Interface::Workspace:: SaveWorkspace( const std::string& fname ) const { - return( "" ); + std::stringstream err; + TiXmlDocument* doc = new TiXmlDocument( ); + TiXmlElement* root = new TiXmlElement( "cpPlugins_Workspace" ); + + // Save plugins + for( + auto plugIt = this->m_LoadedPlugins.begin( ); + plugIt != this->m_LoadedPlugins.end( ); + ++plugIt + ) + { + TiXmlElement* plugin = new TiXmlElement( "plugins" ); + plugin->SetAttribute( "filename", plugIt->c_str( ) ); + root->LinkEndChild( plugin ); + + } // rof + + // Save vertices + auto vIt = this->m_Graph->BeginVertices( ); + for( ; vIt != this->m_Graph->EndVertices( ); ++vIt ) + { + auto filter = dynamic_cast< TFilter* >( vIt->second.GetPointer( ) ); + auto data = dynamic_cast< TData* >( vIt->second.GetPointer( ) ); + if( filter != NULL ) + { + } + else if( data != NULL ) + { + } // fi + + } // rof + + // Physical write and return + doc->LinkEndChild( root ); + doc->SaveFile( fname.c_str( ) ); + delete doc; + return( err.str( ) ); } // eof - $RCSfile$ diff --git a/lib/cpPlugins/Plugins/IO/ImageReader.cxx b/lib/cpPlugins/Plugins/IO/ImageReader.cxx index a7c6687..8866f7d 100644 --- a/lib/cpPlugins/Plugins/IO/ImageReader.cxx +++ b/lib/cpPlugins/Plugins/IO/ImageReader.cxx @@ -106,7 +106,7 @@ _GenerateData( ) r = "ImageReader: Could not CreateImageIO for \"" + names[ 0 ] + "\""; } else - r = "No image files given"; + r = "ImageReader: No image files given"; return( r ); }