]> Creatis software - cpPlugins.git/blob - lib/cpPlugins/ActorPropertiesQtDialog.cxx
Visual properties dialog finished.
[cpPlugins.git] / lib / cpPlugins / ActorPropertiesQtDialog.cxx
1 #include <cpPlugins/ActorPropertiesQtDialog.h>
2
3 #ifdef cpPlugins_QT4
4
5 #include <vtkActor.h>
6 #include <vtkAxesActor.h>
7 #include <vtkImageActor.h>
8 #include <vtkImageData.h>
9 #include <vtkImageProperty.h>
10 #include <vtkMapper.h>
11 #include <vtkProperty.h>
12
13 #include <QCheckBox>
14 #include <QColorDialog>
15 #include <QDoubleSpinBox>
16 #include <QPushButton>
17 #include <QSlider>
18
19 // -------------------------------------------------------------------------
20 cpPlugins::ActorPropertiesQtDialog::
21 ActorPropertiesQtDialog( QWidget* parent, Qt::WindowFlags f )
22   : QDialog( parent, f ),
23     m_WidgetsUpdated( false )
24 {
25   this->m_Title = new QLabel( this );
26   this->m_Title->setText( "Visualization properties" );
27   this->m_MainLayout = new QGridLayout( this );
28   this->m_ToolsLayout = new QVBoxLayout( );
29   this->m_ToolsLayout->addWidget( this->m_Title );
30   this->m_MainLayout->addLayout( this->m_ToolsLayout, 0, 0, 1, 1 );
31 }
32
33 // -------------------------------------------------------------------------
34 cpPlugins::ActorPropertiesQtDialog::
35 ~ActorPropertiesQtDialog( )
36 {
37   this->m_Actors.clear( );
38   this->m_Windows.clear( );
39   delete this->m_Title;
40   delete this->m_ToolsLayout;
41   delete this->m_MainLayout;
42 }
43
44 // -------------------------------------------------------------------------
45 bool cpPlugins::ActorPropertiesQtDialog::
46 addActor( vtkProp* obj )
47 {
48   if( obj == NULL )
49     return( false );
50
51   if( this->m_Actors.size( ) > 0 )
52   {
53     bool     s = this->_addActor< vtkAxesActor >( obj );
54     if( !s ) s = this->_addActor< vtkImageActor >( obj );
55     if( !s ) s = this->_addActor< vtkActor >( obj );
56     return( s );
57   }
58   else
59   {
60     this->m_Actors.insert( obj );
61     this->m_WidgetsUpdated = false;
62     return( true );
63
64   } // fi
65 }
66
67 // -------------------------------------------------------------------------
68 bool cpPlugins::ActorPropertiesQtDialog::
69 addRenderWindow( vtkRenderWindow* win )
70 {
71   if( win == NULL )
72     return( false );
73   this->m_Windows.insert( win );
74   this->m_WidgetsUpdated = false;
75   return( true );
76 }
77
78 // -------------------------------------------------------------------------
79 int cpPlugins::ActorPropertiesQtDialog::
80 exec( )
81 {
82   this->_updateWidgets( );
83   int ret = this->QDialog::exec( );
84   /* TODO
85      if( ret == 1 )
86      this->updateParameters( );
87      else
88      this->updateView( );
89   */
90   return( ret );
91 }
92
93 // -------------------------------------------------------------------------
94 void cpPlugins::ActorPropertiesQtDialog::
95 _addButtons( )
96 {
97   // Add buttons
98   this->m_Buttons = new QDialogButtonBox( QDialogButtonBox::Ok );
99   this->connect(
100     this->m_Buttons, SIGNAL( accepted( ) ), this, SLOT( accept( ) )
101     );
102   this->connect(
103     this->m_Buttons, SIGNAL( rejected( ) ), this, SLOT( reject( ) )
104     );
105   this->m_ToolsLayout->addWidget( this->m_Buttons );
106   this->m_WidgetsUpdated = true;
107 }
108
109 // -------------------------------------------------------------------------
110 void cpPlugins::ActorPropertiesQtDialog::
111 _updateWidgets( )
112 {
113   if( this->m_WidgetsUpdated || this->m_Actors.size( ) == 0 )
114     return;
115   bool     s = this->_configureForAxes( );
116   if( !s ) s = this->_configureForImage( );
117   if( !s ) s = this->_configureForMesh( );
118   this->_addButtons( );
119 }
120
121 // -------------------------------------------------------------------------
122 bool cpPlugins::ActorPropertiesQtDialog::
123 _configureForAxes( )
124 {
125   if( this->m_Actors.size( ) == 0 )
126     return( false );
127   auto actor =
128     dynamic_cast< vtkAxesActor* >( this->m_Actors.begin( )->GetPointer( ) );
129   if( actor == NULL )
130     return( false );
131
132   // Set dialog title
133   std::stringstream title;
134   title << "Parameters for an object of class \"Axes\"";
135   this->m_Title->setText( title.str( ).c_str( ) );
136
137   return( true );
138 }
139
140 // -------------------------------------------------------------------------
141 bool cpPlugins::ActorPropertiesQtDialog::
142 _configureForImage( )
143 {
144   if( this->m_Actors.size( ) == 0 )
145     return( false );
146   auto actor =
147     dynamic_cast< vtkImageActor* >( this->m_Actors.begin( )->GetPointer( ) );
148   if( actor == NULL )
149     return( false );
150   auto image = actor->GetInput( );
151   if( image == NULL )
152     return( false );
153
154   // Get properties
155   auto prop = actor->GetProperty( );
156   double r[ 2 ];
157   image->GetScalarRange( r );
158   double w = actor->GetProperty( )->GetColorWindow( );
159   double l = actor->GetProperty( )->GetColorLevel( );
160   double sw = double( 1000 ) * w / ( r[ 1 ] - r[ 0 ] );
161   double sl = double( 1000 ) * ( l - r[ 0 ] ) / ( r[ 1 ] - r[ 0 ] );
162   double op = double( 10 ) * prop->GetOpacity( );
163
164   // Set dialog title
165   std::stringstream title;
166   title << "Parameters for an object of class \"Image\"";
167   this->m_Title->setText( title.str( ).c_str( ) );
168
169   // Create widgets
170   QDoubleSpinBox* win_box = new QDoubleSpinBox( this );
171   win_box->setObjectName( "win_box" );
172   win_box->setDecimals( 3 );
173   win_box->setMinimum( 0 );
174   win_box->setMaximum( r[ 1 ] - r[ 0 ] );
175   win_box->setValue( w );
176   win_box->connect(
177     win_box, SIGNAL( valueChanged( double ) ),
178     this, SLOT( _boxWindow( double ) )
179     );
180
181   QSlider* win_sld = new QSlider( Qt::Horizontal, this );
182   win_sld->setObjectName( "win_sld" );
183   win_sld->setRange( 0, 1000 );
184   win_sld->setValue( ( unsigned int )( sw ) );
185   win_sld->connect(
186     win_sld, SIGNAL( valueChanged( int ) ),
187     this, SLOT( _sldWindow( int ) )
188     );
189
190   QHBoxLayout* win_layout = new QHBoxLayout( );
191   QLabel* win_label = new QLabel( this );
192   win_label->setText( QString( "Window: " ) );
193   win_layout->addWidget( win_label );
194   win_layout->addWidget( win_box );
195   win_layout->addWidget( win_sld );
196   this->m_ToolsLayout->addLayout( win_layout );
197
198   QDoubleSpinBox* lev_box = new QDoubleSpinBox( this );
199   lev_box->setObjectName( "lev_box" );
200   lev_box->setDecimals( 3 );
201   lev_box->setMinimum( r[ 0 ] );
202   lev_box->setMaximum( r[ 1 ] );
203   lev_box->setValue( l );
204   lev_box->connect(
205     lev_box, SIGNAL( valueChanged( double ) ),
206     this, SLOT( _boxLevel( double ) )
207     );
208
209   QSlider* lev_sld = new QSlider( Qt::Horizontal, this );
210   lev_sld->setObjectName( "lev_sld" );
211   lev_sld->setRange( 0, 1000 );
212   lev_sld->setValue( ( unsigned int )( sl ) );
213   lev_sld->connect(
214     lev_sld, SIGNAL( valueChanged( int ) ),
215     this, SLOT( _sldLevel( int ) )
216     );
217
218   QHBoxLayout* lev_layout = new QHBoxLayout( );
219   QLabel* lev_label = new QLabel( this );
220   lev_label->setText( QString( "Level: " ) );
221   lev_layout->addWidget( lev_label );
222   lev_layout->addWidget( lev_box );
223   lev_layout->addWidget( lev_sld );
224   this->m_ToolsLayout->addLayout( lev_layout );
225
226   // Configure generic objects
227   QSlider* op_sld = new QSlider( Qt::Horizontal, this );
228   op_sld->setObjectName( "op_sld" );
229   op_sld->setRange( 0, 10 );
230   op_sld->setValue( ( unsigned int )( op ) );
231   op_sld->connect(
232     op_sld, SIGNAL( valueChanged( int ) ),
233     this, SLOT( _sldOpacity( int ) )
234     );
235
236   QHBoxLayout* op_layout = new QHBoxLayout( );
237   QLabel* op_label = new QLabel( this );
238   op_label->setText( QString( "Opacity: " ) );
239   op_layout->addWidget( op_label );
240   op_layout->addWidget( op_sld );
241   this->m_ToolsLayout->addLayout( op_layout );
242
243   return( true );
244 }
245
246 // -------------------------------------------------------------------------
247 bool cpPlugins::ActorPropertiesQtDialog::
248 _configureForMesh( )
249 {
250   if( this->m_Actors.size( ) == 0 )
251     return( false );
252   auto actor =
253     dynamic_cast< vtkActor* >( this->m_Actors.begin( )->GetPointer( ) );
254   if( actor == NULL )
255     return( false );
256   auto prop = actor->GetProperty( );
257
258   // Set dialog title
259   std::stringstream title;
260   title << "Parameters for an object of class \"Mesh\"";
261   this->m_Title->setText( title.str( ).c_str( ) );
262
263   // Input boxes
264   QSpinBox* ps_box = new QSpinBox( this );
265   ps_box->setObjectName( "ps_box" );
266   ps_box->setMinimum( 1 );
267   ps_box->setMaximum( 100 );
268   ps_box->setValue( prop->GetPointSize( ) );
269   ps_box->connect(
270     ps_box, SIGNAL( valueChanged( int ) ),
271     this, SLOT( _boxPointSize( int ) )
272     );
273
274   QHBoxLayout* ps_layout = new QHBoxLayout( );
275   QLabel* ps_label = new QLabel( this );
276   ps_label->setText( QString( "Point size: " ) );
277   ps_layout->addWidget( ps_label );
278   ps_layout->addWidget( ps_box );
279   this->m_ToolsLayout->addLayout( ps_layout );
280
281   QSpinBox* lw_box = new QSpinBox( this );
282   lw_box->setObjectName( "lw_box" );
283   lw_box->setMinimum( 1 );
284   lw_box->setMaximum( 100 );
285   lw_box->setValue( prop->GetLineWidth( ) );
286   lw_box->connect(
287     lw_box, SIGNAL( valueChanged( int ) ),
288     this, SLOT( _boxLineWidth( int ) )
289     );
290
291   QHBoxLayout* lw_layout = new QHBoxLayout( );
292   QLabel* lw_label = new QLabel( this );
293   lw_label->setText( QString( "Line width: " ) );
294   lw_layout->addWidget( lw_label );
295   lw_layout->addWidget( lw_box );
296   this->m_ToolsLayout->addLayout( lw_layout );
297
298   QCheckBox* sv_box = new QCheckBox( this );
299   sv_box->setObjectName( "sv_box" );
300   sv_box->setText( "Scalar visibility: " );
301   sv_box->setChecked( ( actor->GetMapper( )->GetScalarVisibility( ) == 1 ) );
302   sv_box->connect(
303     sv_box, SIGNAL( stateChanged( int ) ),
304     this, SLOT( _scalarVisibility( int ) )
305     );
306
307   QHBoxLayout* sv_layout = new QHBoxLayout( );
308   sv_layout->addWidget( sv_box );
309   this->m_ToolsLayout->addLayout( sv_layout );
310
311   double cr, cg, cb;
312   prop->GetColor( cr, cg, cb );
313   cr *= double( 255 );
314   cg *= double( 255 );
315   cb *= double( 255 );
316
317   QPushButton* color_button = new QPushButton( "Color", this );
318   color_button->setObjectName( "color_button" );
319   QPalette color_palette = color_button->palette( );
320   color_palette.setColor( QPalette::Button, QColor( cr, cg, cb ) );
321   color_button->setAutoFillBackground( true );
322   color_button->setPalette( color_palette );
323   color_button->update( );
324   color_button->connect(
325     color_button, SIGNAL( clicked( ) ),
326     this, SLOT( _color( ) )
327     );
328
329   QHBoxLayout* color_layout = new QHBoxLayout( );
330   color_layout->addWidget( color_button );
331   this->m_ToolsLayout->addLayout( color_layout );
332
333   // Configure generic objects
334   QSlider* op_sld = new QSlider( Qt::Horizontal, this );
335   op_sld->setObjectName( "op_sld" );
336   op_sld->setRange( 0, 10 );
337   op_sld->setValue(
338     ( unsigned int )( prop->GetOpacity( ) * double( 10 ) )
339     );
340   op_sld->connect(
341     op_sld, SIGNAL( valueChanged( int ) ),
342     this, SLOT( _sldOpacity( int ) )
343     );
344
345   QHBoxLayout* op_layout = new QHBoxLayout( );
346   QLabel* op_label = new QLabel( this );
347   op_label->setText( QString( "Opacity: " ) );
348   op_layout->addWidget( op_label );
349   op_layout->addWidget( op_sld );
350   this->m_ToolsLayout->addLayout( op_layout );
351
352   return( true );
353 }
354
355 // -------------------------------------------------------------------------
356 void cpPlugins::ActorPropertiesQtDialog::
357 _setWindow( double w )
358 {
359   if( this->m_Actors.size( ) == 0 )
360     return;
361   auto aIt = this->m_Actors.begin( );
362   for( ; aIt != this->m_Actors.end( ); ++aIt )
363   {
364     auto actor = dynamic_cast< vtkImageActor* >( aIt->GetPointer( ) );
365     if( actor != NULL )
366     {
367       actor->GetProperty( )->SetColorWindow( w );
368       actor->Modified( );
369
370     } // fi
371
372   } // rof
373   this->_render( );
374 }
375
376 // -------------------------------------------------------------------------
377 void cpPlugins::ActorPropertiesQtDialog::
378 _setLevel( double l )
379 {
380   if( this->m_Actors.size( ) == 0 )
381     return;
382   auto aIt = this->m_Actors.begin( );
383   for( ; aIt != this->m_Actors.end( ); ++aIt )
384   {
385     auto actor = dynamic_cast< vtkImageActor* >( aIt->GetPointer( ) );
386     if( actor != NULL )
387     {
388       actor->GetProperty( )->SetColorLevel( l );
389       actor->Modified( );
390
391     } // fi
392
393   } // rof
394   this->_render( );
395 }
396
397 // -------------------------------------------------------------------------
398 void cpPlugins::ActorPropertiesQtDialog::
399 _render( )
400 {
401   for( auto i = this->m_Windows.begin( ); i != this->m_Windows.end( ); ++i )
402     ( *i )->Render( );
403 }
404
405 // -------------------------------------------------------------------------
406 template< class _TActor >
407 bool cpPlugins::ActorPropertiesQtDialog::
408 _addActor( vtkProp* obj )
409 {
410   auto new_obj = dynamic_cast< _TActor* >( obj );
411   auto pre_obj =
412     dynamic_cast< _TActor* >( this->m_Actors.begin( )->GetPointer( ) );
413   if( new_obj != NULL && pre_obj != NULL )
414   {
415     this->m_Actors.insert( obj );
416     this->m_WidgetsUpdated = false;
417     return( true );
418   }
419   else
420     return( false );
421 }
422
423 // -------------------------------------------------------------------------
424 void cpPlugins::ActorPropertiesQtDialog::
425 _boxWindow( double v )
426 {
427   auto* box = this->findChild< QDoubleSpinBox* >( "win_box" );
428   auto* sld = this->findChild< QSlider* >( "win_sld" );
429   if( box == NULL || sld == NULL )
430     return;
431
432   double min = double( sld->minimum( ) );
433   double max = double( sld->maximum( ) );
434   double vmin = box->minimum( );
435   double vmax = box->maximum( );
436   double s = ( v - vmin ) / ( vmax - vmin );
437   s = ( ( max - min ) * s ) + min;
438
439   bool o = sld->blockSignals( true );
440   sld->setValue( ( unsigned int )( s ) );
441   sld->blockSignals( o );
442   this->_setWindow( v );
443 }
444
445 // -------------------------------------------------------------------------
446 void cpPlugins::ActorPropertiesQtDialog::
447 _sldWindow( int v )
448 {
449   auto* box = this->findChild< QDoubleSpinBox* >( "win_box" );
450   auto* sld = this->findChild< QSlider* >( "win_sld" );
451   if( box == NULL || sld == NULL )
452     return;
453
454   double min = double( sld->minimum( ) );
455   double max = double( sld->maximum( ) );
456   double vmin = box->minimum( );
457   double vmax = box->maximum( );
458   double s = ( double( v ) - min ) / ( max - min );
459   s = ( ( vmax - vmin ) * s ) + vmin;
460
461   bool o = box->blockSignals( true );
462   box->setValue( s );
463   box->blockSignals( o );
464   this->_setWindow( s );
465 }
466
467 // -------------------------------------------------------------------------
468 void cpPlugins::ActorPropertiesQtDialog::
469 _boxLevel( double v )
470 {
471   auto* box = this->findChild< QDoubleSpinBox* >( "lev_box" );
472   auto* sld = this->findChild< QSlider* >( "lev_sld" );
473   if( box == NULL || sld == NULL )
474     return;
475
476   double min = double( sld->minimum( ) );
477   double max = double( sld->maximum( ) );
478   double vmin = box->minimum( );
479   double vmax = box->maximum( );
480   double s = ( v - vmin ) / ( vmax - vmin );
481   s = ( ( max - min ) * s ) + min;
482
483   bool o = sld->blockSignals( true );
484   sld->setValue( ( unsigned int )( s ) );
485   sld->blockSignals( o );
486   this->_setLevel( v );
487 }
488
489 // -------------------------------------------------------------------------
490 void cpPlugins::ActorPropertiesQtDialog::
491 _sldLevel( int v )
492 {
493   auto* box = this->findChild< QDoubleSpinBox* >( "lev_box" );
494   auto* sld = this->findChild< QSlider* >( "lev_sld" );
495   if( box == NULL || sld == NULL )
496     return;
497
498   double min = double( sld->minimum( ) );
499   double max = double( sld->maximum( ) );
500   double vmin = box->minimum( );
501   double vmax = box->maximum( );
502   double s = ( double( v ) - min ) / ( max - min );
503   s = ( ( vmax - vmin ) * s ) + vmin;
504
505   bool o = box->blockSignals( true );
506   box->setValue( s );
507   box->blockSignals( o );
508   this->_setLevel( s );
509 }
510
511 // -------------------------------------------------------------------------
512 void cpPlugins::ActorPropertiesQtDialog::
513 _sldOpacity( int v )
514 {
515   if( this->m_Actors.size( ) == 0 )
516     return;
517   auto* sld = this->findChild< QSlider* >( "op_sld" );
518   if( sld == NULL )
519     return;
520
521   double min = double( sld->minimum( ) );
522   double max = double( sld->maximum( ) );
523   double s = ( double( v ) - min ) / ( max - min );
524
525   auto aIt = this->m_Actors.begin( );
526   for( ; aIt != this->m_Actors.end( ); ++aIt )
527   {
528     auto ia = dynamic_cast< vtkImageActor* >( aIt->GetPointer( ) );
529     auto ma = dynamic_cast< vtkActor* >( aIt->GetPointer( ) );
530     if( ia != NULL )
531     {
532       ia->GetProperty( )->SetOpacity( s );
533       ia->Modified( );
534     }
535     else if( ma != NULL )
536     {
537       ma->GetProperty( )->SetOpacity( s );
538       ma->Modified( );
539
540     } // fi
541
542   } // rof
543   this->_render( );
544 }
545
546 // -------------------------------------------------------------------------
547 void cpPlugins::ActorPropertiesQtDialog::
548 _boxPointSize( int v )
549 {
550 }
551
552 // -------------------------------------------------------------------------
553 void cpPlugins::ActorPropertiesQtDialog::
554 _boxLineWidth( int v )
555 {
556 }
557
558 // -------------------------------------------------------------------------
559 void cpPlugins::ActorPropertiesQtDialog::
560 _scalarVisibility( int v )
561 {
562   if( this->m_Actors.size( ) == 0 )
563     return;
564   auto* btn = this->findChild< QPushButton* >( "color_button" );
565   auto* chk = this->findChild< QCheckBox* >( "sv_box" );
566   if( btn == NULL || chk == NULL )
567     return;
568   QPalette pal = btn->palette( );
569   QColor color = pal.color( QPalette::Button );
570   double rgb[ 3 ];
571   rgb[ 0 ] = double( color.red( ) ) / double( 255 );
572   rgb[ 1 ] = double( color.green( ) ) / double( 255 );
573   rgb[ 2 ] = double( color.blue( ) ) / double( 255 );
574
575   auto aIt = this->m_Actors.begin( );
576   for( ; aIt != this->m_Actors.end( ); ++aIt )
577   {
578     auto ma = dynamic_cast< vtkActor* >( aIt->GetPointer( ) );
579     if( ma != NULL )
580     {
581       if( !( chk->isChecked( ) ) )
582       {
583         ma->GetMapper( )->ScalarVisibilityOff( );
584         ma->GetProperty( )->SetColor( rgb );
585       }
586       else
587         ma->GetMapper( )->ScalarVisibilityOn( );
588       ma->Modified( );
589
590     } // fi
591
592   } // rof
593   this->_render( );
594 }
595
596 // -------------------------------------------------------------------------
597 void cpPlugins::ActorPropertiesQtDialog::
598 _color( )
599 {
600   if( this->m_Actors.size( ) == 0 )
601     return;
602   auto* btn = this->findChild< QPushButton* >( "color_button" );
603   auto* chk = this->findChild< QCheckBox* >( "sv_box" );
604   if( btn == NULL || chk == NULL )
605     return;
606
607   QPalette pal = btn->palette( );
608   QColor color =
609     QColorDialog::getColor(
610       pal.color( QPalette::Button ),
611       this,
612       "Select Color",
613       QColorDialog::DontUseNativeDialog
614       );
615   if( color.isValid( ) )
616   {
617     pal.setColor( QPalette::Button, color );
618     btn->setAutoFillBackground( true );
619     btn->setPalette( pal );
620     btn->update( );
621     this->_scalarVisibility( 0 );
622
623   } // fi
624 }
625
626 #endif // cpPlugins_QT4
627
628 // eof - $RCSfile$