]> SALOME platform Git repositories - modules/visu.git/blob - src/VISUGUI/VisuGUI_Sweep.cxx
Salome HOME
Merge from V5_1_main 14/05/2010
[modules/visu.git] / src / VISUGUI / VisuGUI_Sweep.cxx
1 //  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  This library is free software; you can redistribute it and/or
4 //  modify it under the terms of the GNU Lesser General Public
5 //  License as published by the Free Software Foundation; either
6 //  version 2.1 of the License.
7 //
8 //  This library is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 //  Lesser General Public License for more details.
12 //
13 //  You should have received a copy of the GNU Lesser General Public
14 //  License along with this library; if not, write to the Free Software
15 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 //  VISU VISUGUI : GUI of VISU component
21 //  File   : VisuGUI_Slider.cxx
22 //  Author : Oleg UVAROV
23 //  Module : VISU
24 //
25 #include "VisuGUI_Sweep.h"
26 #include "VisuGUI_Tools.h"
27
28 #include "SUIT_ResourceMgr.h"
29
30 #include "LightApp_SelectionMgr.h"
31
32 #include <SalomeApp_IntSpinBox.h>
33 #include <SalomeApp_DoubleSpinBox.h>
34
35 #include "VISU_Actor.h"
36
37 #include "VisuGUI.h"
38 #include "VisuGUI_Tools.h"
39 #include "VisuGUI_ViewTools.h"
40 #include "VISU_ColoredPrs3d_i.hh"
41 #include "VISU_Actor.h"
42
43 #include "QtxDockWidget.h"
44
45 #include <QMainWindow>
46 #include <QComboBox>
47 #include <QFont>
48 #include <QLabel>
49 #include <QLayout>
50 #include <QLineEdit>
51 #include <QToolButton>
52 #include <QToolTip>
53 #include <QSlider>
54 #include <QGroupBox>
55 #include <QCheckBox>
56 #include <QRadioButton>
57 #include <QTimer>
58 #include <QAction>
59
60 #include <vtkMath.h>
61
62 /*!
63   Constructor
64 */
65 VisuGUI_Sweep::VisuGUI_Sweep( VisuGUI* theModule, 
66                               QMainWindow* theParent,
67                               LightApp_SelectionMgr* theSelectionMgr )
68   : QWidget( theParent )
69   , myModule( theModule )
70   , myViewWindow( NULL )
71 {
72   setWindowTitle( tr("TITLE") );
73   setObjectName( tr("TITLE") );
74
75   SUIT_ResourceMgr* aResourceMgr = VISU::GetResourceMgr();
76
77   //----------------------------------------------------------------------------
78   QVBoxLayout* aVBoxLayout = new QVBoxLayout( this );
79
80   QTabWidget* aTabWidget = new QTabWidget( this );
81   aTabWidget->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed );
82   aVBoxLayout->addWidget( aTabWidget );
83
84   {
85     QWidget* aNavigationTab = new QWidget();
86     {
87       QVBoxLayout* aVBoxLayout = new QVBoxLayout( aNavigationTab );
88       {
89         QHBoxLayout* aHBoxLayout = new QHBoxLayout();
90         
91         QLabel* aStartSweepPosition = new QLabel( aNavigationTab );
92         aStartSweepPosition->setText( tr( "START_SWEEP_POSITION" ) );
93         aHBoxLayout->addWidget( aStartSweepPosition );
94       
95         mySweepSlider = new QSlider( aNavigationTab );
96         mySweepSlider->setOrientation( Qt::Horizontal );
97         mySweepSlider->setMinimum( 0 );
98         aHBoxLayout->addWidget( mySweepSlider );
99         
100         QLabel* anEndSweepPosition = new QLabel( aNavigationTab );
101         anEndSweepPosition->setText( tr( "END_SWEEP_POSITION" ) );
102         aHBoxLayout->addWidget( anEndSweepPosition );
103         
104         aVBoxLayout->addLayout( aHBoxLayout );
105       }
106       {
107         QHBoxLayout* aHBoxLayout = new QHBoxLayout();
108       
109         myFirstButton = new QToolButton( aNavigationTab );
110         myFirstButton->setIcon( aResourceMgr->loadPixmap( "VISU", tr( "ICON_SLIDER_FIRST" ) ) );
111         myFirstButton->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
112         connect( myFirstButton, SIGNAL( clicked() ), SLOT( onFirst() ) );
113         aHBoxLayout->addWidget( myFirstButton );
114         
115         myPreviousButton = new QToolButton( aNavigationTab );
116         myPreviousButton->setIcon( aResourceMgr->loadPixmap( "VISU", tr( "ICON_SLIDER_PREVIOUS" ) ) );
117         myPreviousButton->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
118         connect( myPreviousButton, SIGNAL( clicked() ), SLOT( onPrevious() ) );
119         aHBoxLayout->addWidget( myPreviousButton );
120         
121         myPlayButton = new QToolButton( aNavigationTab );
122         myPlayButton->setIcon( aResourceMgr->loadPixmap( "VISU", tr( "ICON_SLIDER_PLAY" ) ) );
123         myPlayButton->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
124         myPlayButton->setCheckable( true );
125         aHBoxLayout->addWidget( myPlayButton );
126         
127         myNextButton = new QToolButton( aNavigationTab );
128         myNextButton->setIcon( aResourceMgr->loadPixmap( "VISU", tr( "ICON_SLIDER_NEXT" ) ) );
129         myNextButton->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
130         connect( myNextButton, SIGNAL( clicked() ), SLOT( onNext() ) );
131         aHBoxLayout->addWidget( myNextButton );
132         
133         myLastButton = new QToolButton( aNavigationTab );
134         myLastButton->setIcon( aResourceMgr->loadPixmap( "VISU", tr( "ICON_SLIDER_LAST" ) ) );
135         myLastButton->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
136         connect( myLastButton, SIGNAL( clicked() ), SLOT( onLast() ) );
137         aHBoxLayout->addWidget( myLastButton );
138         
139         aVBoxLayout->addLayout( aHBoxLayout );
140       }
141       {
142         QHBoxLayout* aHBoxLayout = new QHBoxLayout();
143       
144         QToolButton* aStopButton = new QToolButton( aNavigationTab );
145         aStopButton->setIcon( aResourceMgr->loadPixmap( "VISU", tr( "ICON_SWEEP_STOP" ) ) );
146         aStopButton->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
147         aStopButton->setCheckable( false );
148         connect( aStopButton, SIGNAL( clicked( ) ), SLOT( onStop( ) ) );
149         aHBoxLayout->addWidget( aStopButton );
150         
151         myIsCycled = new QCheckBox( aNavigationTab );
152         myIsCycled->setText( tr( "IS_CYCLED" ) );
153         myIsCycled->setChecked( false );
154         aHBoxLayout->addWidget( myIsCycled );
155         
156         aVBoxLayout->addLayout( aHBoxLayout );
157       }
158
159       aTabWidget->addTab( aNavigationTab, tr( "NAVIGATION_TAB" ) );
160     }
161   }
162   {
163     QWidget* aPropertiesTab = new QWidget();
164     {
165       QGridLayout* aGridLayout = new QGridLayout( aPropertiesTab );     
166       {
167         QHBoxLayout* aHBoxLayout = new QHBoxLayout();
168         
169         QLabel* aModeAnnotation = new QLabel( aPropertiesTab );
170         aModeAnnotation->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Preferred );
171         aModeAnnotation->setText( tr( "MODE" ) );
172         aHBoxLayout->addWidget( aModeAnnotation );
173         
174         mySweepMode = new QComboBox( aPropertiesTab );
175         mySweepMode->insertItems( 0, QStringList() 
176                                   << tr( "LINEAR" ) 
177                                   << tr( "COSINUSOIDAL" ) 
178                                   << tr( "SINUSOIDAL" ) );
179         mySweepMode->setCurrentIndex( aResourceMgr->integerValue( "VISU", "sweeping_modes", 0 ) );
180         aHBoxLayout->addWidget( mySweepMode );
181         
182         myIntervals = new QComboBox( aPropertiesTab );
183         myIntervals->insertItems( 0, QStringList() 
184                                   << tr( "[ 0, +PI ]" ) 
185                                   << tr( "[ -PI, +PI ]" ) );
186         myIntervals->setCurrentIndex( aResourceMgr->integerValue( "VISU", "sweeping_is2PI", 0 ) );
187         aHBoxLayout->addWidget( myIntervals );
188         
189         aGridLayout->addLayout( aHBoxLayout, 0, 0, 1, 2 );
190       }
191       
192       QLabel* aNumberOfStepsAnnotation = new QLabel( aPropertiesTab );
193       aNumberOfStepsAnnotation->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Preferred );
194       aNumberOfStepsAnnotation->setText( tr( "NUMBER_OF_STEPS" ) );
195       aGridLayout->addWidget( aNumberOfStepsAnnotation, 1, 0, 1, 1 );
196       
197       myNumberOfSteps = new SalomeApp_IntSpinBox( aPropertiesTab );
198       myNumberOfSteps->setAcceptNames( false );
199       connect( myNumberOfSteps, SIGNAL( valueChanged( int ) ), SLOT( onNumberOfStepsChanged( int ) ) );
200       myNumberOfSteps->setValue( aResourceMgr->integerValue( "VISU", "sweeping_number_steps", 40 ) );
201       aGridLayout->addWidget( myNumberOfSteps, 1, 1, 1, 1 );
202       
203       QLabel* aStepDelayAnnotation = new QLabel( aPropertiesTab );
204       aStepDelayAnnotation->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Preferred );
205       aStepDelayAnnotation->setText( tr( "DELAY_BETWEEN_STEPS" ) );
206       aGridLayout->addWidget( aStepDelayAnnotation, 2, 0, 1, 1 );
207       
208       myStepDelay = new SalomeApp_DoubleSpinBox( aPropertiesTab );
209       VISU::initSpinBox( myStepDelay, 0., 99.99, .1, "parametric_precision" );
210       myStepDelay->setValue( aResourceMgr->doubleValue("VISU", "sweeping_time_step", 0.1) );
211       aGridLayout->addWidget( myStepDelay, 2, 1, 1, 1 );
212     }
213
214     aTabWidget->addTab( aPropertiesTab, tr( "PROPERTIES_TAB" ) );
215   }
216
217   {
218     QSpacerItem* aSpacerItem = new QSpacerItem( 16, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
219     aVBoxLayout->addItem( aSpacerItem );
220   }
221
222
223   //----------------------------------------------------------------------------
224   QtxDockWidget* aQtxDockWidget = new QtxDockWidget( true, theParent );
225   theParent->addDockWidget( Qt::BottomDockWidgetArea , aQtxDockWidget );
226   aQtxDockWidget->setObjectName( objectName() );
227   aQtxDockWidget->setWidget( this );
228
229   myToggleViewAction = aQtxDockWidget->toggleViewAction();
230   myToggleViewAction->setIcon( QIcon( aResourceMgr->loadPixmap( "VISU", tr( "ICON_SWEEP_PANEL" ) ) ) );
231   myToggleViewAction->setToolTip( tr( "MEN_SWEEP_PANE" ) );
232   myToggleViewAction->setText( tr( "MEN_SWEEP_PANE" ) );
233   myToggleViewAction->setCheckable( true );
234   aQtxDockWidget->setVisible( false );
235
236   connect( myToggleViewAction, SIGNAL( toggled( bool ) ), this, SLOT( onToggleView( bool ) ) );
237
238   //----------------------------------------------------------------------------
239   myTimer = new QTimer( this );
240
241   myPlayPixmap = aResourceMgr->loadPixmap( "VISU", tr( "ICON_SLIDER_PLAY" ) );
242   myPausePixmap = aResourceMgr->loadPixmap( "VISU", tr( "ICON_SLIDER_PAUSE" ) );
243
244   connect( myTimer, SIGNAL( timeout() ), SLOT( onTimeout() ) );
245
246   connect( myPlayButton, SIGNAL( toggled( bool ) ), SLOT( onPlay( bool ) ) );
247
248   connect( mySweepSlider, SIGNAL( valueChanged( int ) ), SLOT( onValueChanged( int ) ) );
249
250   connect( myStepDelay, SIGNAL( valueChanged( double ) ), SLOT( onDelayChanged( double ) ) );
251
252   connect( mySweepMode, SIGNAL( currentIndexChanged( int ) ), SLOT( onModeChanged( int ) ) );
253
254   connect( theModule, SIGNAL( moduleDeactivated() ), SLOT( onModuleDeactivated() ) );
255
256   connect( theModule, SIGNAL( moduleActivated() ), SLOT( onModuleActivated() ) );
257
258   connect( theSelectionMgr, SIGNAL( currentSelectionChanged() ), SLOT( onSelectionChanged() ) );
259
260   onSelectionChanged();
261   
262   onModeChanged( mySweepMode->currentIndex() );
263 }
264
265
266 //----------------------------------------------------------------------------
267 VisuGUI_Sweep::~VisuGUI_Sweep()
268 {}
269
270
271 //----------------------------------------------------------------------------
272 QAction* VisuGUI_Sweep::toggleViewAction()
273 {
274   return myToggleViewAction;
275 }
276
277
278 //----------------------------------------------------------------------------
279 void VisuGUI_Sweep::onModuleDeactivated()
280 {
281   setHidden( true );
282
283   onEnable( true );
284 }
285
286
287 //----------------------------------------------------------------------------
288 void VisuGUI_Sweep::onModuleActivated()
289 {
290   setHidden( false );
291 }
292
293
294 //----------------------------------------------------------------------------
295 namespace
296 {
297   struct TEnabler
298   {
299     VisuGUI_Sweep* myWidget;
300     bool& myIsValidSelection;
301
302     TEnabler( VisuGUI_Sweep* theWidget, bool& theIsValidSelection )
303       : myWidget( theWidget )
304       , myIsValidSelection( theIsValidSelection )
305     {}
306     
307     ~TEnabler()
308     {
309       myWidget->onEnable( !myIsValidSelection );
310     }
311   };
312 }
313
314
315 //----------------------------------------------------------------------------
316 void VisuGUI_Sweep::onSelectionChanged()
317 {
318   VISU_Actor* anActor = NULL;
319   VISU::Prs3d_i* aPrs3d = NULL;
320   SVTK_ViewWindow* aViewWindow = NULL;
321
322   bool anIsValidSelection = VISU::GetPrs3dSelectionInfo( myModule, aPrs3d, aViewWindow, anActor );
323
324   // To instantiate special helper class which will analyze validity of selection 
325   // and make appropritate actions
326   TEnabler anEnabler( this, anIsValidSelection );
327
328   anIsValidSelection &= bool( aViewWindow );
329
330   // To keep the pointer on the view window properly it is necessary to get known when
331   // it will be destroyed
332   if ( myViewWindow != aViewWindow ) {
333     if ( myViewWindow )
334       disconnect( myViewWindow, SIGNAL( destroyed( QObject * ) ), this, SLOT( onSelectionChanged() ) );
335
336     myViewWindow = aViewWindow;
337
338     if ( myViewWindow )
339       connect( myViewWindow, SIGNAL( destroyed( QObject * ) ), this, SLOT( onSelectionChanged() ) );
340   }
341
342   if(!VISU::GetActiveViewWindow<SVTK_ViewWindow>(myModule)) {
343     myActor = NULL;
344     return;
345   }
346
347   VISU::ColoredPrs3d_i* aColoredPrs3d = dynamic_cast< VISU::ColoredPrs3d_i* >( aPrs3d );
348   anIsValidSelection &= ( aColoredPrs3d && aColoredPrs3d->IsTimeStampFixed() );
349
350   myColoredPrs3d = aColoredPrs3d;
351
352   if ( myColoredPrs3d ) {
353     myColoredPrs3d->SetMapScale( 1.0 );
354     myColoredPrs3d->UpdateActors();
355   }
356
357   anIsValidSelection &= ( anActor && anActor->GetVisibility() );
358
359   myActor = anActor;
360 }
361
362
363 //----------------------------------------------------------------------------
364 void VisuGUI_Sweep::onValueChanged( int value )
365 {
366   bool anIsValidSelection = ( myColoredPrs3d != NULL )
367                           && (myActor != NULL );
368
369   if ( !anIsValidSelection )
370     return;
371
372   QApplication::setOverrideCursor(Qt::WaitCursor);
373
374   int aSweepMode = mySweepMode->currentIndex();
375   int aNbSteps = myNumberOfSteps->value();
376   
377   double anArgument = double( value ) / aNbSteps;
378
379   int anIntervalMode = myIntervals->currentIndex();
380   // To correct the input value according to the given interval mode
381   if ( aSweepMode != 0 ) {
382     switch ( anIntervalMode ) {
383     case 0 :
384       anArgument = vtkMath::Pi() * anArgument;
385       break;
386     case 1 :
387       anArgument = -vtkMath::Pi() + 2.0 * vtkMath::Pi() * anArgument;
388       break;
389     default :
390       break;
391     }
392   }
393   
394   // To correct the input value according to the given sweep mode
395   double aValue = anArgument;
396   switch ( aSweepMode ) {
397   case 1 :
398     aValue = ( 1.0 - cos( anArgument ) ) / 2.0;
399     break;
400   case 2 :
401     aValue = sin( anArgument - vtkMath::Pi() / 2.0 );
402     break;
403   default :
404     break;
405   }
406
407   try {
408     myColoredPrs3d->SetMapScale( aValue );
409     myColoredPrs3d->UpdateActor( myActor );
410     if(myViewWindow)
411       myViewWindow->Repaint();
412   } catch (std::exception& exc) {
413     INFOS( "Follow exception was occured :\n" << exc.what() );
414   } catch (...) {
415     INFOS( "Unknown exception was occured!" );
416   }
417
418   QApplication::restoreOverrideCursor();
419 }
420
421
422 //----------------------------------------------------------------------------
423 void VisuGUI_Sweep::onDelayChanged( double value )
424 {
425   myTimer->start( int( value * 1000 ) );
426 }
427
428
429 //----------------------------------------------------------------------------
430 void VisuGUI_Sweep::onNumberOfStepsChanged( int value )
431 {
432   int anOldNumberOfSteps = mySweepSlider->maximum();
433   mySweepSlider->setMaximum( value );
434
435   double aValue = double( value );
436
437   double aNewSweepValue = aValue / anOldNumberOfSteps * mySweepSlider->value();
438   mySweepSlider->setValue( int( aNewSweepValue + 1 ) );
439
440   double aNewPageStep = aValue / 10;
441   mySweepSlider->setPageStep( int( aNewPageStep + 1 ) );
442 }
443
444
445 //----------------------------------------------------------------------------
446 void VisuGUI_Sweep::onModeChanged( int )
447 {
448   myIntervals->setEnabled( mySweepMode->currentIndex() != 0 );
449 }
450
451
452 //----------------------------------------------------------------------------
453 void VisuGUI_Sweep::onFirst()
454 {
455   mySweepSlider->setValue( mySweepSlider->minimum() );
456 }
457
458
459 //----------------------------------------------------------------------------
460 void VisuGUI_Sweep::onPrevious()
461 {
462   mySweepSlider->setValue( mySweepSlider->value() - 1 );
463 }
464
465 void VisuGUI_Sweep::onNext()
466 {
467   mySweepSlider->setValue( mySweepSlider->value() + 1 );
468 }
469
470 void VisuGUI_Sweep::onLast()
471 {
472   mySweepSlider->setValue( mySweepSlider->maximum() );
473 }
474
475 //----------------------------------------------------------------------------
476 void VisuGUI_Sweep::onPlay( bool on )
477 {
478   if ( on ) {
479     myPlayButton->setIcon( myPausePixmap );
480     myTimer->start( int( myStepDelay->value() * 1000 ) );
481     myPlayButton->setChecked( true );
482   } else {
483     myTimer->stop();
484     myPlayButton->setChecked( false );
485     myPlayButton->setIcon( myPlayPixmap );
486   }
487 }
488
489
490 //----------------------------------------------------------------------------
491 void VisuGUI_Sweep::onToggleView( bool on )
492 {
493   if ( !on ) {
494     onPlay( on );
495   }
496 }
497
498
499 //----------------------------------------------------------------------------
500 void VisuGUI_Sweep::onStop()
501 {
502   onPlay( false );
503   mySweepSlider->setValue( mySweepSlider->maximum() );
504
505   if ( myViewWindow )
506     myViewWindow->Repaint();
507 }
508
509
510 //----------------------------------------------------------------------------
511 void VisuGUI_Sweep::onEnable( bool on )
512 {
513   onStop();
514
515   mySweepSlider->setEnabled( !on );
516   
517   myFirstButton->setEnabled( !on );
518   myPreviousButton->setEnabled( !on );
519   
520   myPlayButton->setEnabled( !on );
521   
522   myNextButton->setEnabled( !on );
523   myLastButton->setEnabled( !on );
524 }
525
526
527 //----------------------------------------------------------------------------
528 void VisuGUI_Sweep::onTimeout()
529 {
530   int value = mySweepSlider->value();
531   if ( value < mySweepSlider->maximum() ) {
532     mySweepSlider->setValue( value + 1 );
533   } else {
534     if ( myIsCycled->isChecked() )
535       mySweepSlider->setValue( 0 );
536     else
537       myPlayButton->setChecked( false );
538     //myStopButton->setEnabled( false );
539   }
540 }
541
542
543 //----------------------------------------------------------------------------