]> Creatis software - cpPlugins.git/blob - appli/cpPipelineEditor/QNEBlock.cxx
More on graph editor
[cpPlugins.git] / appli / cpPipelineEditor / QNEBlock.cxx
1 /* Copyright (c) 2012, STANISLAW ADASZEWSKI\r
2    All rights reserved.\r
3 \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
14 \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
25 */\r
26 \r
27 #include "QNEBlock.h"\r
28 \r
29 #include <QPen>\r
30 #include <QGraphicsScene>\r
31 #include <QFontMetrics>\r
32 #include <QPainter>\r
33 #include <QStyleOptionGraphicsItem>\r
34 \r
35 #include "QNEPort.h"\r
36 #include "QNEConnection.h"\r
37 \r
38 // -------------------------------------------------------------------------\r
39 PipelineEditor::QNEBlock::\r
40 QNEBlock( TFilter* filter, QGraphicsItem* parent, QGraphicsScene* scene )\r
41   : Superclass( parent, scene ),\r
42     m_HorzMargin( 20 ),\r
43     m_VertMargin( 5 ),\r
44     m_NamePort( NULL ),\r
45     m_TypePort( NULL ),\r
46     m_Filter( filter )\r
47 {\r
48   QPainterPath p;\r
49   p.addRoundedRect( -50, -15, 100, 30, 5, 5 );\r
50 \r
51   this->setPath( p );\r
52   this->setPen( QPen( Qt::darkGreen ) );\r
53   this->setBrush( Qt::green );\r
54   this->setFlag( QGraphicsItem::ItemIsMovable );\r
55   this->setFlag( QGraphicsItem::ItemIsSelectable );\r
56 \r
57   this->m_Width = this->m_HorzMargin;\r
58   this->m_Height = this->m_VertMargin;\r
59 \r
60   // Configure names\r
61   this->setNamePort( this->m_Filter->GetName( ) );\r
62   this->_setTypePort( this->m_Filter->GetClassName( ) );\r
63 \r
64   // Add input ports\r
65   std::set< std::string > inputs;\r
66   this->m_Filter->GetInputsNames( inputs );\r
67   for( auto iIt = inputs.begin( ); iIt != inputs.end( ); ++iIt )\r
68     this->addInputPort( iIt->c_str( ) );\r
69 \r
70   // Add output ports\r
71   std::set< std::string > outputs;\r
72   this->m_Filter->GetOutputsNames( outputs );\r
73   for( auto oIt = outputs.begin( ); oIt != outputs.end( ); ++oIt )\r
74     this->addOutputPort( oIt->c_str( ) );\r
75 }\r
76 \r
77 // -------------------------------------------------------------------------\r
78 PipelineEditor::QNEBlock::\r
79 ~QNEBlock( )\r
80 {\r
81 }\r
82 \r
83 // -------------------------------------------------------------------------\r
84 void PipelineEditor::QNEBlock::\r
85 setNamePort( const QString& txt )\r
86 {\r
87   if( this->m_NamePort == NULL )\r
88     this->m_NamePort = new QNENamePort( this );\r
89   this->m_NamePort->setName( txt );\r
90   this->m_Filter->SetName( txt.toStdString( ) );\r
91   this->_configPort( this->m_NamePort );\r
92 }\r
93 \r
94 // -------------------------------------------------------------------------\r
95 PipelineEditor::QNEInputPort* PipelineEditor::QNEBlock::\r
96 addInputPort( const QString& txt )\r
97 {\r
98   QNEInputPort* ip = new QNEInputPort( this );\r
99   ip->setExtendedName(\r
100     (\r
101       txt.toStdString( ) +\r
102       std::string( "@" ) +\r
103       this->namePort( ).toStdString( )\r
104       ).c_str( )\r
105     );\r
106   ip->setName( txt );\r
107   this->m_InputPorts[ txt.toStdString( ) ] = ip;\r
108   this->_configPort( ip );\r
109   return( ip );\r
110 }\r
111 \r
112 // -------------------------------------------------------------------------\r
113 PipelineEditor::QNEOutputPort* PipelineEditor::QNEBlock::\r
114 addOutputPort( const QString& txt )\r
115 {\r
116   QNEOutputPort* op = new QNEOutputPort( this );\r
117   op->setExtendedName(\r
118     (\r
119       txt.toStdString( ) +\r
120       std::string( "@" ) +\r
121       this->namePort( ).toStdString( )\r
122       ).c_str( )\r
123     );\r
124   op->setName( txt );\r
125   this->m_OutputPorts[ txt.toStdString( ) ] = op;\r
126   this->_configPort( op );\r
127   return( op );\r
128 }\r
129 \r
130 // -------------------------------------------------------------------------\r
131 bool PipelineEditor::QNEBlock::\r
132 extendInputPort( const QString& txt, QNEConnection* conn )\r
133 {\r
134   auto p = this->m_InputPorts.find( txt.toStdString( ) );\r
135   auto i = this->m_ExtInputPorts.find( txt.toStdString( ) );\r
136   if( p != this->m_InputPorts.end( ) && i == this->m_ExtInputPorts.end( ) )\r
137   {\r
138     this->m_ExtInputPorts[ txt.toStdString( ) ] = conn;\r
139     return( true );\r
140   }\r
141   else\r
142     return( false );\r
143 }\r
144 \r
145 // -------------------------------------------------------------------------\r
146 bool PipelineEditor::QNEBlock::\r
147 extendOutputPort( const QString& txt, QNEConnection* conn )\r
148 {\r
149   auto p = this->m_OutputPorts.find( txt.toStdString( ) );\r
150   auto i = this->m_ExtOutputPorts.find( txt.toStdString( ) );\r
151   if( p != this->m_OutputPorts.end( ) && i == this->m_ExtOutputPorts.end( ) )\r
152   {\r
153     this->m_ExtOutputPorts[ txt.toStdString( ) ] = conn;\r
154     return( true );\r
155   }\r
156   else\r
157     return( false );\r
158 }\r
159 \r
160 // -------------------------------------------------------------------------\r
161 PipelineEditor::QNEInputPort* PipelineEditor::QNEBlock::\r
162 inputPort( const QString& txt )\r
163 {\r
164   auto i = this->m_InputPorts.find( txt.toStdString( ) );\r
165   if( i != this->m_InputPorts.end( ) )\r
166     return( i->second );\r
167   else\r
168     return( NULL );\r
169 }\r
170 \r
171 // -------------------------------------------------------------------------\r
172 PipelineEditor::QNEOutputPort* PipelineEditor::QNEBlock::\r
173 outputPort( const QString& txt )\r
174 {\r
175   auto o = this->m_OutputPorts.find( txt.toStdString( ) );\r
176   if( o != this->m_OutputPorts.end( ) )\r
177     return( o->second );\r
178   else\r
179     return( NULL );\r
180 }\r
181 \r
182 // -------------------------------------------------------------------------\r
183 QString PipelineEditor::QNEBlock::\r
184 namePort( ) const\r
185 {\r
186   return( this->m_NamePort->name( ) );\r
187 }\r
188 \r
189 // -------------------------------------------------------------------------\r
190 const PipelineEditor::QNEInputPort* PipelineEditor::QNEBlock::\r
191 inputPort( const QString& txt ) const\r
192 {\r
193   auto i = this->m_InputPorts.find( txt.toStdString( ) );\r
194   if( i != this->m_InputPorts.end( ) )\r
195     return( i->second );\r
196   else\r
197     return( NULL );\r
198 }\r
199 \r
200 // -------------------------------------------------------------------------\r
201 const PipelineEditor::QNEOutputPort* PipelineEditor::QNEBlock::\r
202 outputPort( const QString& txt ) const\r
203 {\r
204   auto o = this->m_OutputPorts.find( txt.toStdString( ) );\r
205   if( o != this->m_OutputPorts.end( ) )\r
206     return( o->second );\r
207   else\r
208     return( NULL );\r
209 }\r
210 \r
211 // -------------------------------------------------------------------------\r
212 const PipelineEditor::QNEConnection* PipelineEditor::QNEBlock::\r
213 extendedInputPort( const QString& txt ) const\r
214 {\r
215   auto i = this->m_ExtInputPorts.find( txt.toStdString( ) );\r
216   if( i != this->m_ExtInputPorts.end( ) )\r
217     return( i->second );\r
218   else\r
219     return( NULL );\r
220 }\r
221 \r
222 // -------------------------------------------------------------------------\r
223 const PipelineEditor::QNEConnection* PipelineEditor::QNEBlock::\r
224 extendedOutputPort( const QString& txt ) const\r
225 {\r
226   auto i = this->m_ExtOutputPorts.find( txt.toStdString( ) );\r
227   if( i != this->m_ExtOutputPorts.end( ) )\r
228     return( i->second );\r
229   else\r
230     return( NULL );\r
231 }\r
232 \r
233 // -------------------------------------------------------------------------\r
234 void PipelineEditor::QNEBlock::\r
235 paint(\r
236   QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget\r
237   )\r
238 {\r
239   Q_UNUSED( option );\r
240   Q_UNUSED( widget );\r
241 \r
242   if( this->isSelected( ) )\r
243   {\r
244     painter->setPen( QPen( Qt::darkYellow ) );\r
245     painter->setBrush( Qt::yellow );\r
246   }\r
247   else\r
248   {\r
249     painter->setPen( QPen( Qt::darkGreen ) );\r
250     painter->setBrush( Qt::green );\r
251 \r
252   } // fi\r
253   painter->drawPath( this->path( ) );\r
254 }\r
255 \r
256 // -------------------------------------------------------------------------\r
257 QVariant PipelineEditor::QNEBlock::\r
258 itemChange( GraphicsItemChange change, const QVariant& value )\r
259 {\r
260   return( value );\r
261 }\r
262 \r
263 // -------------------------------------------------------------------------\r
264 void PipelineEditor::QNEBlock::\r
265 _setTypePort( const QString& txt )\r
266 {\r
267   if( this->m_TypePort == NULL )\r
268     this->m_TypePort = new QNETypePort( this );\r
269   this->m_TypePort->setName( txt );\r
270   this->_configPort( this->m_TypePort );\r
271 }\r
272 \r
273 // -------------------------------------------------------------------------\r
274 void PipelineEditor::QNEBlock::\r
275 _configPort( QNEPort* port )\r
276 {\r
277   port->setBlock( this );\r
278 \r
279   QFontMetrics fm( this->scene( )->font( ) );\r
280   int w = fm.width( port->name( ) ) + ( 4 * port->radius( ) );\r
281   int h = fm.height( );\r
282   if( w > this->m_Width - this->m_HorzMargin )\r
283     this->m_Width = w + this->m_HorzMargin;\r
284   this->m_Height = this->m_InputPorts.size( ) + this->m_OutputPorts.size( );\r
285   this->m_Height += 4;\r
286   this->m_Height *= h;\r
287 \r
288   QPainterPath pth;\r
289   pth.addRoundedRect(\r
290     -this->m_Width / 2,\r
291     -this->m_Height / 2,\r
292     this->m_Width,\r
293     this->m_Height, 5, 5\r
294     );\r
295   this->setPath( pth );\r
296 \r
297   int y = -this->m_Height / 2 + this->m_VertMargin + port->radius( );\r
298   foreach( QGraphicsItem* i, this->children( ) )\r
299   {\r
300     QNEPort* p = dynamic_cast< QNEPort* >( i );\r
301     if( p == NULL )\r
302       continue;\r
303 \r
304     if( dynamic_cast< QNENamePort* >( i ) != NULL )\r
305       i->setPos( -this->m_Width / 2 + port->radius( ), y );\r
306     else if( dynamic_cast< QNETypePort* >( i ) != NULL )\r
307     {\r
308       i->setPos( -this->m_Width / 2 + port->radius( ), y );\r
309       y += h;\r
310     }\r
311     else if( dynamic_cast< QNEInputPort* >( i ) != NULL )\r
312       i->setPos( -this->m_Width / 2 - 2 * port->radius( ), y );\r
313     else if( dynamic_cast< QNEOutputPort* >( i ) != NULL )\r
314       i->setPos( this->m_Width / 2, y );\r
315 \r
316     /* TODO\r
317        QNEPort* p = dynamic_cast< QNEPort* >( i );\r
318        if( p == NULL )\r
319        continue;\r
320 \r
321        if( dynamic_cast< QNEOutputPort* >( p ) != NULL )\r
322        p->setPos( this->m_Width / 2 + port->radius( ), y );\r
323        else\r
324        p->setPos( -this->m_Width / 2 - port->radius( ), y );\r
325     */\r
326     y += h;\r
327 \r
328   } // rof\r
329 }\r
330 \r
331 // -------------------------------------------------------------------------\r
332 void PipelineEditor::QNEBlock::\r
333 mouseReleaseEvent( QGraphicsSceneMouseEvent* evt )\r
334 {\r
335   if( this->m_Filter.IsNotNull( ) )\r
336     this->m_Filter->SetViewCoords(\r
337       this->scenePos( ).x( ), this->scenePos( ).y( )\r
338       );\r
339   this->Superclass::mouseReleaseEvent( evt );\r
340 }\r
341 \r
342 // eof - $RCSfile$\r