Documentation


MainController.cpp

Go to the documentation of this file.
00001 
00002 //                            MainController.cpp                              //
00004 
00005 #include <qspinbox.h>
00006 #include <qfiledialog.h>
00007 #include <qstatusbar.h>
00008 #include <qmessagebox.h>
00009 #include <qtoolbar.h>
00010 #include <qmenubar.h>
00011 #include <qtoolbutton.h>
00012 #include <qpixmap.h>
00013 #include <qimage.h>
00014 #include <qlayout.h>
00015 #include <qlcdnumber.h>
00016 #include <qdockarea.h>
00017 #include <qgroupbox.h>
00018 
00019 
00020 #include <animal/event/keyEvent.h>
00021 #include <animal/event/mouseEvent.h>
00022 #include <animal/X3DTK/Qt/x3dTransformGUI/x3dTransformQt.h>
00023 #include <animal/X3DTK/Qt/world/qglviewerWorld.h>
00024 #include <iostream>
00025 using std::cout;
00026 using std::cerr;
00027 using std::endl;
00028 
00029 #include "MainController.h"
00030 
00031 animal::World * animal::Engine::theWorld = NULL;
00032 
00033 static const char * recordButtonDown_xpm[] =
00034   {
00035     "16 16 4 1",
00036     "b c #f00000",
00037     "a c #f00606",
00038     "# c #f33434",
00039     ". c none",
00040     "................",
00041     "................",
00042     "......#aa#......",
00043     "....#bbbbbb#....",
00044     "...#bbbbbbbb#...",
00045     "...bbbbbbbbbb...",
00046     "..#bbbbbbbbbb#..",
00047     "..abbbbbbbbbba..",
00048     "..abbbbbbbbbba..",
00049     "..#bbbbbbbbbb#..",
00050     "...bbbbbbbbbb...",
00051     "...#bbbbbbbb#...",
00052     "....#bbbbbb#....",
00053     "......#aa#......",
00054     "................",
00055     "................"
00056   };
00057 
00058 static const char * recordButton_xpm[] =
00059   {
00060     "16 16 4 1",
00061     "b c #0000f0",
00062     "a c #0606f0",
00063     "# c #3434f3",
00064     ". c none",
00065     "................",
00066     "................",
00067     "......#aa#......",
00068     "....#bbbbbb#....",
00069     "...#bbbbbbbb#...",
00070     "...bbbbbbbbbb...",
00071     "..#bbbbbbbbbb#..",
00072     "..abbbbbbbbbba..",
00073     "..abbbbbbbbbba..",
00074     "..#bbbbbbbbbb#..",
00075     "...bbbbbbbbbb...",
00076     "...#bbbbbbbb#...",
00077     "....#bbbbbb#....",
00078     "......#aa#......",
00079     "................",
00080     "................"
00081   };
00082 
00084 MainController::MainController(X3DTK::MainScene * mainScene, bool use_docked_windows)
00085     : MainControllerDesigner(NULL, NULL, Qt::WDestructiveClose|Qt::WType_TopLevel)
00086     , mainScene(mainScene)
00087     ,x3dDirectory(std::string("."))
00088 {
00089   // init the viewer
00090   viewer->setMainController(this);
00091   viewer->show();
00092 
00093   // create the world associated to the viewer
00094   animal::Engine::setWorld(new X3DTK::Qt::QGLViewerWorld(viewer->camera()));
00095 
00096   // init the main scene
00097   mainScene->setMainController(this);
00098 
00099   // init the x3d qt tree
00100   x3dtreeqt->setMainController(this);
00101   x3dtreeqt->show();
00102   defineQWidgetCreationFunction(X3DTK::Qt::createTransformQWidget);
00103 
00104   //  Timer to call doStep()
00105   animTimer = new QTimer(this);
00106   connect(animTimer, SIGNAL(timeout()), this, SLOT(doStep()));
00107   // display animation rate
00108   connect( this, SIGNAL( animationFrequency( int ) ), update_rate_lCDNumber, SLOT( display(int) ) );
00109 
00110   // init the data for the animation
00111   go = false;
00112   realTime = false;
00113   animStep = 0.001*dt_SpinBox->value();
00114   displayStep = static_cast<int>(1000.0/delay_SpinBox->value());
00115 
00116   if( use_docked_windows )
00117   {
00118     // Create dock windows
00119     w1 = new QDockWindow( rightDock(), "dock1");
00120     w1->setResizeEnabled(true);
00121     x3dtreeqt->reparent(w1,0,QPoint(0,0));
00122     x3dtreeqt->setMaximumWidth(10000);
00123     w1->setWidget(x3dtreeqt);
00124 
00125     viewer->reparent(this,0,QPoint(0,0));
00126     setCentralWidget(viewer);
00127     viewer->setMaximumWidth(10000);
00128 
00129     w2 = new QDockWindow( topDock(), "dock2");
00130     w2->setResizeEnabled(true);
00131     groupBoxAnimation->reparent(w2,0,QPoint(0,0));
00132     w2->setWidget(groupBoxAnimation);
00133   }
00134 }
00135 
00137 // MainController::~MainController()
00138 // {
00139 //   //std::cerr<< "MainController::~MainController()"<<std::endl;
00140 // }
00141 
00142 //----------- Setters ------------
00143 void MainController::setViewer(X3DTK::Qt::Viewer * v)
00144 {
00145   if (viewer)
00146   {
00147     delete viewer;
00148     viewer = NULL;
00149   }
00150 
00151   if (v)
00152   {
00153     viewer = v;
00154     viewer->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)7, (QSizePolicy::SizeType)7, 0, 0, viewer->sizePolicy().hasHeightForWidth() ) );
00155     viewer->setMinimumSize( QSize( 320, 240 ) );
00156     viewer->setMainController(this);
00157     MainControllerDesignerLayout->addWidget( viewer, 1, 0 );
00158     viewer->show();
00159   }
00160 }
00161 void MainController::addEngine(animal::Engine * E)
00162 {
00163   mainScene->addEngine(E);
00164   viewer->viewAll();
00165 }
00166 
00167 //----------- Slots for the animation -------------
00168 
00169 void MainController::doStep()
00170 {
00171   static double cumulatedTime = 0;
00172   static int nbSteps = 0;
00173   const int period = 25;
00174 
00175   double dt = 0.001 * clock.restart();
00176   cumulatedTime += dt;
00177   nbSteps++;
00178   if( nbSteps==period )
00179   {
00180     emit animationFrequency( static_cast<int>(period/cumulatedTime) );
00181     //cerr<<"animationFrequency = "<<static_cast<int>(period/cumulatedTime)<<endl;
00182     nbSteps=0;
00183     cumulatedTime = 0;
00184   }
00185 
00186 
00187   if(!realTime)
00188     dt = animStep;
00189 
00190   mainScene->move(dt);
00191   viewer->drawAfterAnimation();
00192 }
00193 
00194 
00195 void MainController::startStop()
00196 {
00197   // go is true if the animation is playing
00198   go = !go;
00199 
00200   if (go)
00201   {
00202     // Clock for real time
00203     clock.restart();
00204     // animTimer is the timer which is connected to the slot doStep()
00205     animTimer->start(displayStep, FALSE);
00206   }
00207   else
00208     animTimer->stop();
00209 }
00210 
00211 void MainController::reset()
00212 {
00213   mainScene->reset();
00214   //viewer->updateFrustum();
00215   viewer->updateGL();
00216 }
00217 
00218 void MainController::setAnimStep( int ms)
00219 {
00220   // animStep simulates time step for animation if realTime is false
00221   animStep = 0.001*ms;
00222 }
00223 
00224 
00225 void MainController::setDisplayFreq( int hz)
00226 {
00227   // displayStep is the time interval for calling doStep()
00228   if( hz==0 )
00229   {
00230     displayStep = 0;
00231     animTimer->changeInterval( displayStep );
00232   }
00233   else
00234   {
00235     displayStep = static_cast<int>(1000.0/hz);
00236     animTimer->changeInterval( displayStep );
00237   }
00238   if( !go )
00239     animTimer->stop();
00240 }
00241 
00242 
00243 void MainController::setRealTime(bool b)
00244 {
00245   // realTime is true if the animation is computing in real time
00246   if( realTime != b )
00247   {
00248     realTime = b;
00249     if( realTime )
00250       clock.restart();
00251   }
00252 }
00253 
00254 //----------- End - Slots for the animation -------------
00255 void MainController::activatedManipMode()
00256 {
00257   std::cerr<<"MainController::activatedManipMode "<<std::endl;
00258 }
00259 
00260 //----------- Slots for Input/Output ------------
00261 
00262 //void MainController::createX3dLoader( X3DTK::X3D::EngineNodeCreator *  creator)
00263 //{
00264 //    mainScene->initX3dLoader(creator);//new X3DTK::X3D::QLoader(creator));
00265 //
00266 //}
00267 
00268 void MainController::fileOpen()
00269 {
00270   fileOpen("");
00271 }
00272 
00273 void MainController::fileOpen(const char * filename)
00274 {
00275   if (filename=="")
00276     openFile = QFileDialog::getOpenFileName(  x3dDirectory.data(),
00277                "X3D files (*.x3d)",
00278                this,
00279                "file open",
00280                "X3DAnimAL -- File Open" );
00281   else
00282     openFile = QString(filename);
00283 
00284 
00285   if (!QFile::exists(openFile))
00286   {
00287     statusBar()->message( "File not found: open abandoned" );
00288     return;
00289   }
00290 
00291   // Loads the file name.
00292   mainScene->load(openFile);
00293   // View all the scene
00294   viewer->viewAll();
00295   //Reset the qt x3d tree root node
00296   x3dtreeqt ->setSceneGraphRoot(mainScene->getX3DScene());
00297 }
00298 
00299 void MainController::fileInsert( X3DTK::X3D::X3DNode  * node)
00300 {
00301   QString filename = QFileDialog::getOpenFileName(
00302                        QString::null, "X3D Files (*.x3d)", this,
00303                        "file insert", "X3DAnimAL -- File Insert" );
00304   if ( filename.isEmpty() )
00305     statusBar()->message( "File Insert abandoned" );
00306   else
00307   {
00308     // Loads the file name.
00309     mainScene->load(filename, node);
00310     // View all the scene
00311     viewer->viewAll();
00312   }
00313 }
00314 
00315 void MainController::fileSave()
00316 {
00317   QString filename = QFileDialog::getSaveFileName(
00318                        QString::null, "X3D Files (*.x3d)", this,
00319                        "file save", "X3DAnimAL -- File Save" );
00320   if ( filename.isEmpty() )
00321     statusBar()->message( "File Save abandoned" );
00322   else
00323   {
00324     // Verify if the file exists
00325     QFile file(filename);
00326     if (file.exists())
00327     {
00328       switch( QMessageBox::warning( this, "File Name",
00329                                     "The file "+filename+" already exists.\n"
00330                                     "OK to overwrite it.\n\n",
00331                                     "Yes",
00332                                     "No",
00333                                     "Cancel",0, 1) )
00334       {
00335       case 0: // The user clicked the "Yes" button or pressed Enter
00336         mainScene->save(filename);
00337         break;
00338       case 1: // The user clicked the "No" or pressed Escape
00339         fileSave();
00340         break;
00341       case 2: // The user clicked the "Cancel"
00342         statusBar()->message( "File Save abandoned" );
00343         break;
00344       }
00345     }
00346     else
00347       mainScene->save(filename);
00348   }
00349 }
00350 
00351 
00352 void MainController::fileReload()
00353 {
00354   if ( openFile.isEmpty() )
00355     statusBar()->message( "File Open abandoned" );
00356   else
00357   {
00358     // Loads the file name.
00359     mainScene->load( openFile);
00360     // View all the scene
00361     viewer->viewAll();
00362     //Reset the qt x3d tree root node
00363     x3dtreeqt ->setSceneGraphRoot(mainScene->getX3DScene());
00364   }
00365 }
00366 
00367 //----------- End - Slots for Input/Output ------------
00368 
00369 //----------- Slots for GUI --------------------
00370 
00371 void MainController::toolBarSetShown(bool b)
00372 {
00373   toolBar->setShown(b);
00374 }
00375 
00376 void MainController::menuBarSetShown(bool b)
00377 {
00378   menubar->setShown(b);
00379   statusBar()->setShown(b);
00380 }
00381 
00382 void MainController::clickedRecordButton()
00383 {
00384   if (recordButton->isOn())
00385   {
00386     viewer->getViewerGUI()->move(this->x(),this->y());
00387     viewer->getViewerGUI()->hide();
00388     viewer->getViewerGUI()->show();
00389     recordButton->setOn(false);
00390   }
00391   else
00392   {
00393     toggleRecord(false);
00394   }
00395 }
00396 
00397 //----------- End -  Slots for GUI --------------------
00398 
00399 //----------- Slot for display ------------------------
00400 void MainController::display()
00401 {
00402   viewer->updateGL();
00403 }
00404 void MainController::computeBbox()
00405 {
00406   mainScene->computeBbox();
00407 }
00408 void MainController::viewAll()
00409 {
00410   viewer->viewAll();
00411 }
00412 //----------- End - Slots for display -----------------
00413 
00414 //----------- Recording state -------------------------
00415 void MainController::toggleRecord(bool b)
00416 {
00417   if (b)
00418   {
00419     if (viewer->setSnapshot(true))
00420     {
00421       recordButton->setPixmap(QPixmap(recordButtonDown_xpm));
00422       recordButton->setOn(true);
00423       viewer->getViewerGUI()->hide();
00424     }
00425     else
00426       switch( QMessageBox::warning( this, "Files names of captured frames",
00427                                     "The files names of captured frames are not valid !\nThe pattern of these names depends on the video file name.\nIf the video file name is video.mpg,\nthe pattern is video####.ppm.",
00428                                     "New video file name",
00429                                     "Quit", 0, 0, 1 ) )
00430       {
00431       case 0: // The user clicked the Retry again button or pressed Enter
00432         viewer->getViewerGUI()->chooseVideoName();
00433         break;
00434       case 1: // The user clicked the Quit or pressed Escape
00435         statusBar()->message( "Capture abandoned" );
00436         break;
00437       }
00438   }
00439   else
00440   {
00441     viewer->setSnapshot(false);
00442     recordButton->setPixmap(QPixmap(recordButton_xpm));
00443     recordButton->setOn(false);
00444     viewer->getViewerGUI()->move(this->x(),this->y());
00445     viewer->getViewerGUI()->hide();
00446     viewer->getViewerGUI()->show();
00447   }
00448 }
00449 //----------- End - Recording state --------------------
00450 
00451 //-----------X3DTK::X3D::X3DNode and their item-------------
00452 void MainController::addNode(X3DTK::X3D::X3DNode * node)
00453 {
00454   x3dtreeqt->addNode(node);
00455 }
00456 
00457 //----------- X3D node and their corresponding QWidget --
00458 
00460 void MainController::removeX3DQtMap(X3DTK::X3DAbstractNode* EN)
00461 {
00462   if (x3dQtMap[EN])
00463   {
00464     //std::cerr<<"MainController::removeX3DQtMap"<<std::endl;
00465     QWidget * q = x3dQtMap[EN];
00466 
00467     // Erase all the node which associated QWidget is x3dQtMap[EN]
00468     X3DTK::MFNode nodeToErase;
00469     for (X3DQtMap::iterator i=x3dQtMap.begin(); i!=x3dQtMap.end(); ++i )
00470       if ( (*i).second == q)
00471       {
00472         nodeToErase.push_back((*i).first);
00473       }
00474     for (X3DTK::MFNode::iterator i=nodeToErase.begin(); i!=nodeToErase.end(); ++i )
00475       x3dQtMap.erase(*i);
00476 
00477     // Delete the QWidget x3dQtMap[EN]
00478     if(q)
00479       delete q;
00480   }
00481 
00482   // Remove from X3DQtMap the QWidget of X3DTK::X3D::Transform parent of X3DTK::X3D::FrameNode EN
00483   // In fact, X3DTK::X3D::Transform changed attributes of its associated X3DTK::X3D::FrameNode
00484   if (dynamic_cast<X3DTK::X3D::FrameNode *>(EN))
00485   {
00486     X3DTK::MFNode list = EN->getParentList();
00487     X3DTK::X3DAbstractNode * parentNode =(*list.begin());
00488     removeX3DQtMap(parentNode);
00489   }
00490 }
00491 
00493 QWidget * MainController::createQWidgetController(X3DTK::X3D::X3DNode * node)
00494 {
00495   // Search the associated QWidget to the x3d engine node
00496   X3DTK::SFString string = node->getTypeName();
00497   for( X3DNodeQWidgetMap::iterator i=x3dNodeQWidgetMap.begin(); i!=x3dNodeQWidgetMap.end(); ++i )
00498     if((*i).first == string)
00499     {
00500 
00501       // The name of the node
00502       QString s1;
00503       X3DTK::SFString tmp = node->getName();
00504       if (tmp =="")
00505         s1 = QString(node->getType()->getName());
00506       else
00507         s1 = QString((node->getType()->getName()+" named "+tmp).data());
00508 
00509       // The dialog
00510       QDialog * dialog = new QDialog(this, s1);
00511       dialog->setCaption(s1);
00512 
00513       // Layout of the dialog
00514       QHBoxLayout * dialogLayout = new QHBoxLayout(dialog);
00515       dialogLayout->setAutoAdd(true);
00516 
00517       // The scroll bar
00518       QScrollView * sv = new QScrollView(dialog);
00519       sv->setResizePolicy(QScrollView::AutoOneFit);
00520 
00521       // Create the associated QWidget of the x3d node
00522       QWidget * Q = ((*i).second)(node, sv->viewport());
00523       if (Q)
00524       {
00525 
00526         QWidget::connect( Q, SIGNAL( changed() ), this, SLOT(computeBbox()));
00527         QWidget::connect( Q, SIGNAL( changed() ), this, SLOT(display()));
00528 
00529         sv->addChild(Q);
00530         //dialog->show();
00531         x3dQtMap[node] = dialog;
00532         return x3dQtMap[node];
00533       }
00534     }
00535 
00536   // How to link an x3d node to its QWidget
00537   std::cerr << std::endl;
00538   std::cerr << "Warning: a x3d node has no controller QWidget." << std::endl;
00539   std::cerr << "   To create an associated controller QWidget to one x3d node," << std::endl;
00540   std::cerr << "   see the documentation in $ANIMAL/doc/html/architecture.html#GUIController." << std::endl;
00541 
00542   return NULL;
00543 
00544 }
00545 //----------- End - X3D node and their corresponding QWidget --
00546 
00547 //----------- Mouse and key board events -------------
00548 void MainController::keyPressEvent(QKeyEvent *e)
00549 {
00550   if (e->key()==Qt::Key_R)
00551   {
00552     viewer->getViewerGUI()->show();
00553   }
00554 
00555   animal::KeyEvent * AKE
00556   = new animal::KeyEvent(e->type(), e->key(), e->state());
00557 
00558   mainScene->keyPressEvent(AKE);
00559 
00560   if (animTimer->isActive())
00561     doStep();
00562 }
00563 
00564 void MainController::mouseDoubleClickEvent(QMouseEvent * e)
00565 {
00566   float orig[3], dir[3];
00567   viewer->camera()->convertClickToLine(e->x(), e->y(), orig, dir);
00568 
00569   animal::MouseEvent * AME
00570   = new animal::MouseEvent( e->type(),
00571                             e->x(),
00572                             e->y(),
00573                             e->button(),
00574                             e->state(),
00575                             animal::Vec3(orig[0], orig[1], orig[2]),
00576                             animal::Vec3(dir[0], dir[1], dir[2]));
00577 
00578   mainScene->mouseDoubleClickEvent(AME);
00579 
00580   if (animTimer->isActive())
00581     doStep();
00582 }
00583 
00584 void MainController::mouseMoveEvent(QMouseEvent * e)
00585 {
00586   float orig[3], dir[3];
00587   viewer->camera()->convertClickToLine(e->x(), e->y(), orig, dir);
00588 
00589   animal::MouseEvent * AME
00590   = new animal::MouseEvent( e->type(),
00591                             e->x(),
00592                             e->y(),
00593                             e->button(),
00594                             e->state(),
00595                             animal::Vec3(orig[0], orig[1], orig[2]),
00596                             animal::Vec3(dir[0], dir[1], dir[2]));
00597   mainScene->mouseMoveEvent(AME);
00598 
00599   if (animTimer->isActive())
00600     doStep();
00601 }
00602 
00603 void MainController::mousePressEvent(QMouseEvent * e)
00604 {
00605   float orig[3], dir[3];
00606   viewer->camera()->convertClickToLine(e->x(), e->y(), orig, dir);
00607 
00608   animal::MouseEvent * AME
00609   = new animal::MouseEvent( e->type(),
00610                             e->x(),
00611                             e->y(),
00612                             e->button(),
00613                             e->state(),
00614                             animal::Vec3(orig[0], orig[1], orig[2]),
00615                             animal::Vec3(dir[0], dir[1], dir[2]));
00616   mainScene->mousePressEvent(AME);
00617 
00618   if (animTimer->isActive())
00619     doStep();
00620 }
00621 
00622 void MainController::mouseReleaseEvent(QMouseEvent * e)
00623 {
00624   float orig[3], dir[3];
00625   viewer->camera()->convertClickToLine(e->x(), e->y(), orig, dir);
00626 
00627   animal::MouseEvent * AME
00628   = new animal::MouseEvent( e->type(),
00629                             e->x(),
00630                             e->y(),
00631                             e->button(),
00632                             e->state(),
00633                             animal::Vec3(orig[0], orig[1], orig[2]),
00634                             animal::Vec3(dir[0], dir[1], dir[2]));
00635   mainScene->mouseReleaseEvent(AME);
00636 
00637   if (animTimer->isActive())
00638     doStep();
00639 }
00640 //----------- End - Mouse and key board events -------------
00641 
00642 // ----------  FF: picking -----------------------------
00643 animal::ConstrainedItem* MainController::pickPoint( float origin[3], float direction[3],
00644     float threshold )
00645 {
00646   return mainScene->pickPoint(origin, direction, threshold );
00647 }
00648 // ----------  end FF: picking -----------------------------
00649 
00650 
00655 void MainController::setX3dDirectory(const std::string& d)
00656 {
00657   x3dDirectory = d;
00658 }
00659 
00660 
00664 std::string MainController::getX3dDirectory() const
00665 {
00666   return x3dDirectory;
00667 }

Generated on Thu Dec 23 13:52:25 2004 by doxygen 1.3.6