Salome HOME
SMH: 3.0.0 preparation - merged and adopted version (POLYWORK+HEAD)
[modules/visu.git] / src / VISUGUI / VisuGUI_TimeAnimation.cxx
1 //  VISU VISUGUI : GUI of VISU component
2 //
3 //  Copyright (C) 2003  CEA/DEN, EDF R&D
4 //
5 //
6 //
7 //  File   : VisuGUI_TimeAnimation.cxx
8 //  Author : Vitaly SMETANNIKOV
9 //  Module : VISU
10
11 #include "VisuGUI_TimeAnimation.h"
12
13 #include "VisuGUI.h"
14 #include "VisuGUI_Tools.h"
15 //#include "VisuGUI_MagnitudeDlg.h"
16 #include "VisuGUI_CutPlanesDlg.h"
17 #include "VisuGUI_VectorsDlg.h"
18 #include "VisuGUI_IsoSurfacesDlg.h"
19 #include "VisuGUI_StreamLinesDlg.h"
20
21 #include "VISU_TimeAnimation.h"
22
23 #include "VISU_ScalarMap_i.hh"
24 #include "VISU_IsoSurfaces_i.hh"
25 #include "VISU_DeformedShape_i.hh"
26 #include "VISU_CutPlanes_i.hh"
27 #include "VISU_CutLines_i.hh"
28 #include "VISU_Vectors_i.hh"
29 #include "VISU_StreamLines_i.hh"
30
31 #include "VISU_ScalarBarActor.hxx"
32
33 #include "SalomeApp_Application.h"
34
35 #include "SUIT_OverrideCursor.h"
36 #include "SUIT_MessageBox.h"
37 #include "SUIT_Desktop.h"
38 #include "SUIT_FileDlg.h"
39
40 #include "VTKViewer_ViewWindow.h"
41
42 #include <qlayout.h>
43 #include <qhbox.h>
44 #include <qhgroupbox.h>
45 #include <qwt_wheel.h>
46 #include <qlcdnumber.h>
47 #include <qlistbox.h>
48 #include <qvgroupbox.h>
49 #include <qthread.h>
50
51 //static double MAXVALUE = 1.0E+300;
52
53
54 SetupDlg::SetupDlg (QWidget* theParent, VISU_TimeAnimation* theAnimator)
55      : QDialog(theParent, "SetupDlg", true, WStyle_Customize |
56                WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu)
57 {
58   setCaption("Setup Animation");
59   setSizeGripEnabled( TRUE );
60   myAnimator = theAnimator;
61
62   QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 6);
63   aMainLayout->setSpacing(5);
64
65
66   QFrame* aRangeGrp = new QFrame(this);
67   QGridLayout* aRangeLayout = new QGridLayout( aRangeGrp );
68   aRangeLayout->setSpacing( 6 );
69   aRangeLayout->setMargin( 11 );
70   aRangeGrp->setFrameStyle(QFrame::Box | QFrame::Raised);
71
72   myUseRangeChk = new QCheckBox("Use range of time stamps", aRangeGrp);
73   aRangeLayout->addMultiCellWidget(myUseRangeChk, 0, 0, 0, 3);
74   myUseRangeChk->setChecked(myAnimator->isRangeDefined());
75
76   QLabel* aMinLbl = new QLabel("From", aRangeGrp);
77   aMinLbl->setEnabled(myUseRangeChk->isChecked());
78   aRangeLayout->addWidget(aMinLbl, 1, 0);
79   double aStep = (myAnimator->getMaxTime() - myAnimator->getMinTime())/(theAnimator->getFieldData(0).myNbTimes - 1);
80   myMinVal = new QtxDblSpinBox( myAnimator->getMinTime(), myAnimator->getMaxTime(), aStep, aRangeGrp );
81   myMinVal->setEnabled(myUseRangeChk->isChecked());
82   if (myUseRangeChk->isChecked())
83     myMinVal->setValue( myAnimator->getMinRange() );
84   else
85     myMinVal->setValue( myAnimator->getMinTime() );
86
87   connect(myMinVal, SIGNAL( valueChanged(double)),
88           this, SLOT( onMinValue(double) ));
89   aRangeLayout->addWidget(myMinVal, 1, 1);
90
91   QLabel* aMaxLbl = new QLabel("To", aRangeGrp);
92   aMaxLbl->setEnabled(myUseRangeChk->isChecked());
93   aRangeLayout->addWidget(aMaxLbl, 1, 2);
94   myMaxVal = new QtxDblSpinBox( myAnimator->getMinTime(), myAnimator->getMaxTime(), aStep, aRangeGrp );
95   myMaxVal->setEnabled(myUseRangeChk->isChecked());
96   if (myUseRangeChk->isChecked())
97     myMaxVal->setValue( myAnimator->getMaxRange() );
98   else
99     myMaxVal->setValue( myAnimator->getMaxTime() );
100
101   connect(myMaxVal, SIGNAL( valueChanged(double)),
102           this, SLOT( onMaxValue(double) ));
103   aRangeLayout->addWidget(myMaxVal, 1, 3);
104
105   connect(myUseRangeChk, SIGNAL( toggled(bool)),
106           aMinLbl, SLOT( setEnabled(bool) ));
107   connect(myUseRangeChk, SIGNAL( toggled(bool)),
108           aMaxLbl, SLOT( setEnabled(bool) ));
109   connect(myUseRangeChk, SIGNAL( toggled(bool)),
110           this, SLOT( onRangeCheck(bool) ));
111
112   aMainLayout->addWidget(aRangeGrp);
113
114
115   QHBox* aPropFrame = new QHBox(this);
116   aPropFrame->setSpacing(5);
117
118   QVGroupBox* aNamesBox = new QVGroupBox("Fields",aPropFrame);
119   myFieldLst = new QListBox(aNamesBox);
120   QStringList aFieldNames;
121   // Find names of fields
122   for (int i = 0; i < theAnimator->getNbFields(); i++) {
123     _PTR(SObject) aSO = theAnimator->getFieldData(i).myField;
124     aFieldNames.append(VISU::getValue(aSO, "myName"));
125   }
126   myFieldLst->insertStringList(aFieldNames);
127   myFieldLst->setSelected(0, true);
128   connect( myFieldLst, SIGNAL( highlighted(int) ),
129            this, SLOT( onFieldChange(int) ) );
130
131
132   QVGroupBox* aPropBox = new QVGroupBox("Properties", aPropFrame);
133   myTypeCombo = new QComboBox(aPropBox);
134   connect( myTypeCombo, SIGNAL( activated(int) ),
135            this, SLOT( onTypeChanged(int) ) );
136
137   //  QPushButton* aBarBtn = new QPushButton("Scalar Bar...", aPropBox);
138   //connect( aBarBtn, SIGNAL( clicked() ),
139   //       this, SLOT( onScalarBarDlg() ) );
140
141   myPropBtn = new QPushButton("Properties...", aPropBox);
142   //  myPropBtn->setEnabled(theAnimator->getFieldData(0).myPrsType != VISU::TSCALARMAP);
143   connect( myPropBtn, SIGNAL( clicked() ),
144            this, SLOT( onPreferencesDlg() ) );
145
146   onFieldChange(0);
147   aMainLayout->addWidget(aPropFrame);
148
149   QHBox* aBtnBox = new QHBox(this);
150   QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox->layout());
151   aBtnLayout->addStretch();
152
153   QPushButton* aCloseBtn = new QPushButton(tr("VISU_BUT_OK"), aBtnBox);
154   connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
155
156   aMainLayout->addWidget(aBtnBox);
157 }
158
159 //************************************************************************
160 void SetupDlg::onFieldChange (int theIndex)
161 {
162   FieldData& aData = myAnimator->getFieldData(theIndex);
163   myTypeCombo->clear();
164   myTypeCombo->insertItem("Scalar Map");
165   myTypeCombo->insertItem("Iso Surfaces");
166   myTypeCombo->insertItem("Cut Planes");
167
168   _PTR(SObject) aSObject = aData.myField;
169   long aNumComp = VISU::getValue(aSObject, "myNumComponent").toLong();
170   if (aNumComp > 1) {
171     myTypeCombo->insertItem("Deformed Shape");
172     myTypeCombo->insertItem("Vectors");
173     myTypeCombo->insertItem("Stream Lines");
174   }
175   switch (aData.myPrsType) {
176   case VISU::TSCALARMAP: //Scalar Map
177     myTypeCombo->setCurrentItem(0);
178     break;
179   case VISU::TISOSURFACE: //Iso Surfaces
180     myTypeCombo->setCurrentItem(1);
181     break;
182   case VISU::TCUTPLANES: //Cut Planes
183     myTypeCombo->setCurrentItem(2);
184     break;
185   case VISU::TDEFORMEDSHAPE: //Deformed Shape
186     myTypeCombo->setCurrentItem(3);
187     break;
188   case VISU::TVECTORS: //Vectors
189     myTypeCombo->setCurrentItem(4);
190     break;
191   case VISU::TSTREAMLINES: //Stream Lines
192     myTypeCombo->setCurrentItem(5);
193     aData.myPrsType = VISU::TSTREAMLINES;
194     break;
195   }
196   //myPropBtn->setEnabled(aData.myPrsType != VISU::TSCALARMAP);
197 }
198
199 //************************************************************************
200 void SetupDlg::onTypeChanged (int theIndex)
201 {
202   FieldData& aData = myAnimator->getFieldData(myFieldLst->currentItem());
203   switch (theIndex) {
204   case 0: //Scalar Map
205     aData.myPrsType = VISU::TSCALARMAP;
206     break;
207   case 1: //Iso Surfaces
208     aData.myPrsType = VISU::TISOSURFACE;
209     break;
210   case 2: //Cut Planes
211     aData.myPrsType = VISU::TCUTPLANES;
212     break;
213   case 3: //Deformed Shape
214     aData.myPrsType = VISU::TDEFORMEDSHAPE;
215     break;
216   case 4: //Vectors
217     aData.myPrsType = VISU::TVECTORS;
218     break;
219   case 5: //Stream Lines
220     aData.myPrsType = VISU::TSTREAMLINES;
221     break;
222   }
223   myAnimator->clearData(aData);
224   //myPropBtn->setEnabled(aData.myPrsType != VISU::TSCALARMAP);
225   //myAnimator->generatePresentations(myFieldLst->currentItem());
226 }
227
228 //************************************************************************
229 /*void SetupDlg::onScalarBarDlg() {
230   QApplication::setOverrideCursor( Qt::waitCursor );
231   FieldData& aData = myAnimator->getFieldData(myFieldLst->currentItem());
232   if (aData.myPrs == 0)
233     myAnimator->generatePresentations(myFieldLst->currentItem());
234   QApplication::restoreOverrideCursor();
235
236   VisuGUI_ScalarBarDlg* aScalarBarDlg = new VisuGUI_ScalarBarDlg();
237   aScalarBarDlg->initFromPrsObject(aData.myPrs[0]);
238   if (aScalarBarDlg->exec()) {
239     for (int i = 0; i < aData.myNbFrames; i++)
240       aScalarBarDlg->storeToPrsObject(aData.myPrs[i]);
241   }
242 }
243 */
244
245 //************************************************************************
246 void SetupDlg::onPreferencesDlg()
247 {
248   MESSAGE("SetupDlg::onPreferencesDlg() is not implemented");
249 /*  SUIT_OverrideCursor c;
250   FieldData& aData = myAnimator->getFieldData(myFieldLst->currentItem());
251   if (aData.myPrs.empty())
252     myAnimator->generatePresentations(myFieldLst->currentItem());
253
254 // BUG VISU5725 : Compatibility gcc 2.95
255 // #define EDITPRS(TYPE, DLG) \
256 //     { \
257 //       DLG* aDlg = new DLG(); \
258 //       aDlg->initFromPrsObject(dynamic_cast<TYPE*>(aData.myPrs.at(0))); \
259 //       if (aDlg->exec()) { \
260 //      for (int i = 0; i < aData.myNbFrames; i++) \
261 //        aDlg->storeToPrsObject(dynamic_cast<TYPE*>(aData.myPrs.at(i))); \
262 //       } \
263 //       delete aDlg; \
264 //     }
265
266
267 #define EDITPRS(TYPE, DLG) {DLG* aDlg = new DLG(); aDlg->initFromPrsObject(dynamic_cast<TYPE*>(aData.myPrs[0])); if (aDlg->exec()) { for (int i = 0; i < aData.myNbFrames; i++) aDlg->storeToPrsObject(dynamic_cast<TYPE*>(aData.myPrs[i])); } delete aDlg;}
268
269   switch (myTypeCombo->currentItem()) {
270   case 0: //Scalar Map
271     EDITPRS(VISU::ScalarMap_i, VisuGUI_ScalarBarDlg);
272     break;
273   case 1: //Iso Surfaces
274     EDITPRS(VISU::IsoSurfaces_i, VisuGUI_IsoSurfacesDlg);
275     break;
276   case 2: //Cut Planes
277     //    EDITPRS(VISU::CutPlanes_i, VisuGUI_CutPlanesDlg);
278     {
279       VisuGUI_CutPlanesDlg* aDlg = new VisuGUI_CutPlanesDlg(false, true);
280       //_CS_PhB :operator [] .at      aDlg->initFromPrsObject(dynamic_cast<VISU::CutPlanes_i*>(aData.myPrs.at(0)));
281       aDlg->initFromPrsObject(dynamic_cast<VISU::CutPlanes_i*>(aData.myPrs[0]));
282
283       if (aDlg->exec()) {
284         for (int i = 0; i < aData.myNbFrames; i++)
285       //_CS_PhB:operator [] .at   aDlg->storeToPrsObject(dynamic_cast<VISU::CutPlanes_i*>(aData.myPrs.at(i)));
286           aDlg->storeToPrsObject(dynamic_cast<VISU::CutPlanes_i*>(aData.myPrs[i]));
287       }
288       delete aDlg;
289     }
290     break;
291   case 3: //Deformed Shape
292     EDITPRS(VISU::DeformedShape_i, VisuGUI_MagnitudeDlg);
293     break;
294   case 4: //Vectors
295     EDITPRS(VISU::Vectors_i, VisuGUI_VectorsDlg);
296     break;
297   case 5: //Stream Lines
298     EDITPRS(VISU::StreamLines_i, VisuGUI_StreamLinesDlg);
299     break;
300   }
301 #undef EDITPRS
302 */
303 }
304
305 //************************************************************************
306 void SetupDlg::onRangeCheck (bool theCheck)
307 {
308   for (int i = 0; i < myAnimator->getNbFields(); i++)
309     myAnimator->clearData(myAnimator->getFieldData(i));
310
311   myMinVal->setEnabled(theCheck);
312   myMaxVal->setEnabled(theCheck);
313
314   if (!theCheck)
315     myAnimator->setAnimationRange(0, 0);
316   else {
317     //    if (myMinVal->value() < myMaxVal->value())
318     myAnimator->setAnimationRange(myMinVal->value(), myMaxVal->value());
319 //     else if (myMinVal->value() > myMaxVal->value())
320 //       myAnimator->setAnimationRange(myMaxVal->value(), myMinVal->value());
321 //     else // equal case
322 //       myAnimator->setAnimationRange(0, 0);
323   }
324 }
325
326 //************************************************************************
327 void SetupDlg::onMinValue (double theVal)
328 {
329   if (theVal > myAnimator->getMaxRange()) {
330     myMinVal->setValue( myAnimator->getMinTime() );
331     myMinVal->setFocus();
332     return;
333   }
334   for (int i = 0; i < myAnimator->getNbFields(); i++)
335     myAnimator->clearData(myAnimator->getFieldData(i));
336   myAnimator->setAnimationRange(theVal, myAnimator->getMaxRange());
337 }
338
339 //************************************************************************
340 void SetupDlg::onMaxValue (double theVal)
341 {
342   if (theVal < myAnimator->getMinRange()) {
343     myMaxVal->setValue( myAnimator->getMaxTime() );
344     myMaxVal->setFocus();
345     return;
346   }
347   for (int i = 0; i < myAnimator->getNbFields(); i++)
348     myAnimator->clearData(myAnimator->getFieldData(i));
349   myAnimator->setAnimationRange(myAnimator->getMinRange(), theVal);
350 }
351
352 static const char * firstIco[] = {
353 "18 10 2 1",
354 "       g None",
355 ".      g #000000",
356 "         .     .  ",
357 "  ..    ..    ..  ",
358 "  ..   ...   ...  ",
359 "  ..  ....  ....  ",
360 "  .. ..... .....  ",
361 "  .. ..... .....  ",
362 "  ..  ....  ....  ",
363 "  ..   ...   ...  ",
364 "  ..    ..    ..  ",
365 "         .     .  "};
366
367
368 static const char * lastIco[] = {
369 "18 10 2 1",
370 "       g None",
371 ".      g #000000",
372 "  .     .         ",
373 "  ..    ..    ..  ",
374 "  ...   ...   ..  ",
375 "  ....  ....  ..  ",
376 "  ..... ..... ..  ",
377 "  ..... ..... ..  ",
378 "  ....  ....  ..  ",
379 "  ...   ...   ..  ",
380 "  ..    ..    ..  ",
381 "  .     .         "};
382
383
384 static const char * leftIco[] = {
385 "11 10 2 1",
386 "       g None",
387 ".      g #000000",
388 "    .     .",
389 "   ..    ..",
390 "  ...   ...",
391 " ....  ....",
392 "..... .....",
393 "..... .....",
394 " ....  ....",
395 "  ...   ...",
396 "   ..    ..",
397 "    .     ."};
398
399 static const char * playIco[] = {
400 "14 14 2 1",
401 "       g None",
402 ".      g #000000",
403 "              ",
404 "              ",
405 "  ..          ",
406 "  ....        ",
407 "  ......      ",
408 "  ........    ",
409 "  ..........  ",
410 "  ..........  ",
411 "  ........    ",
412 "  ......      ",
413 "  ....        ",
414 "  ..          ",
415 "              ",
416 "              "};
417
418 static QPixmap MYplayPixmap(playIco);
419
420
421 static const char * rightIco[] = {
422 "11 10 2 1",
423 "       g None",
424 ".      g #000000",
425 ".     .    ",
426 "..    ..   ",
427 "...   ...  ",
428 "....  .... ",
429 "..... .....",
430 "..... .....",
431 "....  .... ",
432 "...   ...  ",
433 "..    ..   ",
434 ".     .    "};
435
436
437 static const char * pauseIco[] = {
438 "14 14 2 1",
439 "       g None",
440 ".      g #000000",
441 "              ",
442 "              ",
443 "   ..    ..   ",
444 "   ..    ..   ",
445 "   ..    ..   ",
446 "   ..    ..   ",
447 "   ..    ..   ",
448 "   ..    ..   ",
449 "   ..    ..   ",
450 "   ..    ..   ",
451 "   ..    ..   ",
452 "   ..    ..   ",
453 "              ",
454 "              "};
455
456 static QPixmap MYpausePixmap(pauseIco);
457
458
459 VisuGUI_TimeAnimationDlg::VisuGUI_TimeAnimationDlg (QWidget* parent, _PTR(Study) theStudy)
460      : QDialog(parent, "VisuGUI_TimeAnimationDlg", false, WStyle_Customize |
461                WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose)
462 {
463   setCaption("Animation");
464   setSizeGripEnabled( TRUE );
465   myStudy = theStudy;
466   isClosing = false;
467
468   //myAnimator = new VISU_TimeAnimation (VISU::GetDSStudy(theStudy));
469   myAnimator = new VISU_TimeAnimation (theStudy);
470   myAnimator->setSpeed(1);
471   myAnimator->setViewer(VISU::GetViewWindow());
472   connect(myAnimator, SIGNAL(frameChanged(long, double)), this, SLOT(onExecution(long, double)));
473   connect(myAnimator, SIGNAL(stopped()),                  this, SLOT(onStop()));
474
475   QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 6);
476   aMainLayout->setSpacing(5);
477
478   mySetupBtn = new QPushButton("Setup Animation...", this);
479   connect( mySetupBtn, SIGNAL( clicked() ),
480            this, SLOT( onSetupDlg() ) );
481   aMainLayout->addWidget(mySetupBtn);
482
483   myGenBtn = new QPushButton("Generate frames", this);
484   connect( myGenBtn, SIGNAL( clicked() ),
485            this, SLOT( createFrames() ) );
486   aMainLayout->addWidget(myGenBtn);
487
488   myPlayFrame = new QFrame(this);
489   myPlayFrame->setFrameStyle(QFrame::WinPanel | QFrame::Sunken);
490   myPlayFrame->setLineWidth( 1 );
491
492
493   // --- Play controls ---
494   QGridLayout* TopLayout = new QGridLayout( myPlayFrame );
495   TopLayout->setSpacing( 6 );
496   TopLayout->setMargin( 11 );
497
498   myTimeLbl = new QLabel("0", myPlayFrame);
499   TopLayout->addMultiCellWidget(myTimeLbl, 0, 0, 0, 2, Qt::AlignHCenter);
500
501   mySlider = new QSlider(Qt::Horizontal, myPlayFrame);
502   mySlider->setMinValue(0);
503   mySlider->setMaxValue(3);
504   mySlider->setTickInterval(1);
505   //mySlider->setTickmarks(QSlider::Below);
506   mySlider->setTracking(false);
507   connect( mySlider, SIGNAL( valueChanged(int) ),
508            this, SLOT( onWindowChanged(int) ) );
509   TopLayout->addMultiCellWidget(mySlider, 1, 1, 0, 2);
510
511   myPlayBtn = new QToolButton(myPlayFrame);
512   myPlayBtn->setIconSet(MYplayPixmap);
513   myPlayBtn->setToggleButton(true);
514   connect( myPlayBtn, SIGNAL( clicked() ),
515            this, SLOT( onPlayPressed() ) );
516   TopLayout->addMultiCellWidget(myPlayBtn, 2, 2, 0, 1);
517
518   QToolButton* aBackBtn = new QToolButton(myPlayFrame);
519   aBackBtn->setIconSet(QPixmap(leftIco));
520   connect( aBackBtn, SIGNAL( clicked() ),
521            this, SLOT( onBackPressed() ) );
522   TopLayout->addWidget(aBackBtn, 3, 0);
523
524   QToolButton* aForvardBtn = new QToolButton(myPlayFrame);
525   aForvardBtn->setIconSet(QPixmap(rightIco));
526   connect( aForvardBtn, SIGNAL( clicked() ),
527            this, SLOT( onForvardPressed() ) );
528   TopLayout->addWidget(aForvardBtn, 3, 1);
529
530   QToolButton* aFirstBtn = new QToolButton(myPlayFrame);
531   aFirstBtn->setIconSet(QPixmap(firstIco));
532   connect( aFirstBtn, SIGNAL( clicked() ),
533            this, SLOT( onFirstPressed() ) );
534   TopLayout->addWidget(aFirstBtn, 4, 0);
535
536   QToolButton* aLastBtn = new QToolButton(myPlayFrame);
537   aLastBtn->setIconSet(QPixmap(lastIco));
538   connect( aLastBtn, SIGNAL( clicked() ),
539            this, SLOT( onLastPressed() ) );
540   TopLayout->addWidget(aLastBtn, 4, 1);
541
542   QLabel* aSpeedLbl = new QLabel("Speed", myPlayFrame);
543   TopLayout->addWidget(aSpeedLbl, 4, 2, Qt::AlignRight);
544
545   QLCDNumber* aSpeedNum  = new QLCDNumber( 2, myPlayFrame );
546   aSpeedNum->setSegmentStyle(QLCDNumber::Flat);
547   aSpeedNum->display(1);
548   TopLayout->addWidget(aSpeedNum, 4, 3);
549
550   QwtWheel* aWheel = new QwtWheel(myPlayFrame);
551   aWheel->setOrientation(Qt::Vertical);
552   aWheel->setRange(1, 99, 1);
553   connect( aWheel, SIGNAL(valueChanged(double)),
554            aSpeedNum, SLOT(display(double)) );
555   connect( aWheel, SIGNAL(valueChanged(double)),
556            this, SLOT(onSpeedChange(double)) );
557   TopLayout->addMultiCellWidget(aWheel, 1, 3, 3, 3, Qt::AlignRight);
558
559   QCheckBox* aCycleCheck = new QCheckBox("Cycled animation",myPlayFrame);
560   aCycleCheck->setChecked(myAnimator->isCycling());
561   connect(aCycleCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setCyclingSlot(bool)));
562   TopLayout->addMultiCellWidget(aCycleCheck, 5, 5, 0, 3);
563
564   QCheckBox* aPropCheck = new QCheckBox("Use proportional timing",myPlayFrame);
565   aPropCheck->setChecked(myAnimator->isProportional());
566   connect(aPropCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setProportionalSlot(bool)));
567   TopLayout->addMultiCellWidget(aPropCheck, 6, 6, 0, 3);
568
569   QGroupBox* aSaveBox = new QGroupBox( "Saving", myPlayFrame );
570   aSaveBox->setColumnLayout(0, Qt::Horizontal );
571   QGridLayout* aSaveLay = new QGridLayout(aSaveBox->layout());
572   aSaveLay->setSpacing( 5 );
573   aSaveLay->setMargin( 5 );
574
575   mySaveCheck = new QCheckBox("Save pictures to directory", aSaveBox);
576   aSaveLay->addMultiCellWidget(mySaveCheck, 0, 0, 0, 2);
577   connect(mySaveCheck, SIGNAL( toggled(bool)),
578           aWheel, SLOT( setDisabled(bool) ));
579
580   QLabel* aPathLbl = new QLabel("Path:", aSaveBox);
581   aPathLbl->setEnabled(false);
582   connect(mySaveCheck, SIGNAL( toggled(bool)),
583           aPathLbl, SLOT( setEnabled(bool) ));
584   aSaveLay->addWidget(aPathLbl, 1, 0);
585
586   myPathEdit = new QLineEdit(aSaveBox);
587   myPathEdit->setEnabled(false);
588   connect(mySaveCheck, SIGNAL( toggled(bool)),
589           myPathEdit, SLOT( setEnabled(bool) ));
590   aSaveLay->addWidget(myPathEdit, 1, 1);
591
592   QPushButton* aBrowseBtn = new QPushButton("Browse...", aSaveBox);
593   aBrowseBtn->setEnabled(false);
594   connect(mySaveCheck, SIGNAL( toggled(bool)),
595           aBrowseBtn, SLOT( setEnabled(bool) ));
596   connect(aBrowseBtn, SIGNAL( clicked()),
597           this, SLOT( onBrowse() ));
598   mySaveCheck->setChecked(false);
599   aSaveLay->addWidget(aBrowseBtn, 1, 2);
600
601   TopLayout->addMultiCellWidget(aSaveBox, 7, 7, 0, 3);
602
603   aMainLayout->addWidget(myPlayFrame);
604
605   QHBox* aBtnBox = new QHBox(this);
606   QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox->layout());
607   aBtnLayout->addStretch();
608
609   QPushButton* aCloseBtn = new QPushButton(tr("BUT_CLOSE"), aBtnBox);
610   connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
611
612   aMainLayout->addWidget(aBtnBox);
613
614   myPlayFrame->setEnabled(false);
615 }
616
617 //************************************************************************
618 VisuGUI_TimeAnimationDlg::~VisuGUI_TimeAnimationDlg()
619 {
620   delete myAnimator;
621 }
622
623 //************************************************************************
624 void VisuGUI_TimeAnimationDlg::onTypeChange (int index)
625 {
626   stopAnimation();
627   myPropBtn->setEnabled(index != 0);
628
629   clearView();
630   myPlayFrame->setEnabled(false);
631 }
632
633 //************************************************************************
634 void VisuGUI_TimeAnimationDlg::addField (_PTR(SObject) theSObject)
635 {
636   myPlayFrame->setEnabled(false);
637   myAnimator->addField(VISU::GetSObject(theSObject));
638 }
639
640 //************************************************************************
641 void VisuGUI_TimeAnimationDlg::createFrames()
642 {
643   stopAnimation();
644   SUIT_OverrideCursor c;
645
646   for (int i = 0; i < myAnimator->getNbFields(); i++) {
647     if (myAnimator->getFieldData(i).myPrs.empty())
648       myAnimator->generatePresentations(i);
649   }
650   if (myAnimator->getNbFrames() == 0) {
651     myPlayFrame->setEnabled(false);
652     c.suspend();
653     SUIT_MessageBox::warn1(this,
654                            tr("ERROR"),
655                            tr("MSG_NO_ANIMATIONDATA"),
656                            tr("OK"));
657     return;
658   }
659   mySlider->setMaxValue(myAnimator->getNbFrames()-1);
660   myPlayFrame->setEnabled(true);
661   if (!myAnimator->generateFrames()) {
662     c.suspend();
663     //myPlayFrame->setEnabled(false);
664     SUIT_MessageBox::warn1(this,
665                            tr("ERROR"),
666                            myAnimator->getLastErrorMsg(),
667                            tr("OK"));
668     return;
669   }
670   //myPlayFrame->setEnabled(true);
671 }
672
673 //************************************************************************
674 void VisuGUI_TimeAnimationDlg::onPlayPressed()
675 {
676   if (myPlayBtn->isOn() && (!myAnimator->running())) {
677     myPlayBtn->setIconSet(MYpausePixmap);
678     if (mySaveCheck->isChecked())
679       myAnimator->dumpTo(myPathEdit->text());
680     else
681       myAnimator->dumpTo("");
682     mySetupBtn->setEnabled(false);
683     myGenBtn->setEnabled(false);
684     myAnimator->startAnimation();
685   } else {
686     myPlayBtn->setIconSet(MYplayPixmap);
687     myAnimator->stopAnimation();
688     mySetupBtn->setEnabled(true);
689     myGenBtn->setEnabled(true);
690   }
691 }
692
693 //************************************************************************
694 void VisuGUI_TimeAnimationDlg::onBackPressed()
695 {
696   //stopAnimation();
697   myAnimator->prevFrame();
698 }
699
700 //************************************************************************
701 void VisuGUI_TimeAnimationDlg::onForvardPressed()
702 {
703   myAnimator->nextFrame();
704 }
705
706 //************************************************************************
707 void VisuGUI_TimeAnimationDlg::onLastPressed()
708 {
709   myAnimator->lastFrame();
710 }
711
712 //************************************************************************
713 void VisuGUI_TimeAnimationDlg::onFirstPressed()
714 {
715   myAnimator->firstFrame();
716 }
717
718 //************************************************************************
719 void VisuGUI_TimeAnimationDlg::clearView()
720 {
721   myAnimator->clearView();
722 }
723
724 //************************************************************************
725 void VisuGUI_TimeAnimationDlg::closeEvent (QCloseEvent* theEvent)
726 {
727   myAnimator->stopAnimation();
728   if (myAnimator->running() && (! myAnimator->finished())) {
729     isClosing = true;
730     myEvent = theEvent;
731   } else {
732     QDialog::closeEvent(theEvent);
733   }
734 }
735
736 //************************************************************************
737 void VisuGUI_TimeAnimationDlg::onWindowChanged (int index)
738 {
739   if (myAnimator->isRunning()) return;
740   myAnimator->gotoFrame(index);
741 }
742
743 //************************************************************************
744 void VisuGUI_TimeAnimationDlg::onSpeedChange (double theSpeed)
745 {
746   myAnimator->setSpeed((int)theSpeed);
747 }
748
749 //************************************************************************
750 void VisuGUI_TimeAnimationDlg::stopAnimation()
751 {
752   myAnimator->stopAnimation();
753   myPlayBtn->setOn(false);
754   myPlayBtn->setIconSet(MYplayPixmap);
755   mySetupBtn->setEnabled(true);
756   myGenBtn->setEnabled(true);
757 }
758
759 //************************************************************************
760 void VisuGUI_TimeAnimationDlg::onExecution (long theNewFrame, double theTime)
761 {
762   myTimeLbl->setText(QString("%1").arg(theTime));
763   mySlider->setValue(theNewFrame);
764 }
765
766 //************************************************************************
767 void VisuGUI_TimeAnimationDlg::onSetupDlg()
768 {
769   if (myAnimator->getNbFrames() > 0) myAnimator->firstFrame();
770   SetupDlg* aDlg = new SetupDlg(this, myAnimator);
771   aDlg->exec();
772   myPlayFrame->setEnabled(false);
773   delete aDlg;
774 }
775
776 //************************************************************************
777 void VisuGUI_TimeAnimationDlg::onBrowse()
778 {
779   QString aPath = SUIT_FileDlg::getExistingDirectory(this, "/","Select path");
780   if (!aPath.isEmpty())
781     myPathEdit->setText(aPath);
782 }
783
784 //************************************************************************
785 void VisuGUI_TimeAnimationDlg::onStop()
786 {
787   if (isClosing) {
788     QDialog::closeEvent(myEvent);
789   } else {
790     myPlayBtn->setOn(false);
791     myPlayBtn->setIconSet(MYplayPixmap);
792     mySetupBtn->setEnabled(true);
793     myGenBtn->setEnabled(true);
794   }
795 }