Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

DisplayControl.cxx

Go to the documentation of this file.
00001 //     $Id: DisplayControl.cxx,v 1.4 2001/10/06 04:22:14 burnett Exp $
00002 //  Author: Toby Burnett
00003 //
00004 // implementation of  Display control
00005 
00006 #ifdef NT_MSVCPP
00007 #pragma warning(disable: 4786)
00008 #endif
00009 
00010 #include "gui/DisplayControl.h"
00011 #include "gui/GUI.h"   // for the gui window
00012 #include "gui/SubMenu.h"
00013 
00014 #include "gui/DisplayRep.h"
00015 #include "gui/SceneControl.h"
00016 #include "gui/Scene.h"
00017 #include "Vrml.h"
00018 #include "gui/Draw2D.h"
00019 #include "PSdraw.h"
00020 #include "gui/Projector.h"
00021 
00022 
00023 #include "gui/PrintControl.h"
00024 #include "gui/SimpleCommand.h"
00025 
00026 #include <string>  
00027 #include <fstream>
00028 #include <strstream>
00029 #include <iomanip>
00030 #include <cmath>
00031 
00032 namespace gui {
00033 
00034 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00035 DisplayControl::DisplayControl(Menu& menu, SceneControl* control)
00036     : m_control(control),
00037      m_axis_size(100),
00038      m_running(false)
00039 {
00040   m_menu_bar = &menu;  // pointer to use below
00041     m_user_menu =m_sub_menu = &menu.subMenu("Display");
00042 
00043     // schedule to have our finishSetup called
00044     menu.add(new MenuClient<DisplayControl>(this));
00045 
00046 
00047     // get a pointer to the scene
00048     m_scene = &m_control->scene();
00049     m_2d_scene = &m_control->scene_2d();
00050 
00051     m_canvas = m_control->view().canvas();
00052 
00053     // give the scene control a pointer to the menu, so it can pop it up
00054     m_control->set_menu(m_sub_menu);
00055 
00056 
00057     // this is to force link to include the Projector
00058     Projector p((Draw2D*)0); p.canvas(); //fool warning?
00059 
00060 }
00061 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00062 DisplayControl::~DisplayControl()
00063 {
00064     delete m_control;
00065     for( std::vector<DisplaySubMenu*>::iterator it=_submenus.begin(); it !=_submenus.end(); ++it)
00066         delete *it;
00067 }
00068 //=====================================================================
00069 //         anonymous namespace for helper classes
00070 //=====================================================================
00071 #ifdef NT_MSVCPP  //KAI can't handle this???
00072 namespace {
00073 #endif
00074 double sqr(double x){return x*x;}
00075 
00076 //     VRML_command class
00077 class VRML_command : public Command {
00078 public:
00079     VRML_command(DisplayControl* dcon):m_dcon(dcon){}
00080     void execute(); 
00081 private:
00082     DisplayControl* m_dcon;
00083 };
00084 
00085 void VRML_command::execute() {
00086     static std::string filename("glast.wrl");
00087     char* answer = GUI::instance()->askForFileName(filename.c_str(),"save"
00088                                 ,"vrml files (*.wrl)|*.wrl|all files|*.*|") ;
00089     if( !answer) return;        // check for cancel
00090     filename = answer;
00091     std::ofstream vrml_file(filename.c_str());
00092     if( vrml_file.rdbuf()->is_open() ) m_dcon->vrml(vrml_file);
00093     else GUI::instance()->inform("Could not open the file");
00094 }
00095 
00096 class PrintInstructions : public Command {
00097     friend class DisplayControl;
00098     PrintInstructions(SceneControl* disp, std::ostream* out):m_disp(disp), m_out(out){}
00099     void execute(){m_disp->print_commands(*m_out);}
00100     SceneControl* m_disp;
00101     std::ostream* m_out;
00102 
00103 };
00104 
00105 //   Private class used by DisplayControl to define axes
00106 class Axes: public DisplayRep
00107 {
00108 public:
00109     Axes(double scale=1.);
00110     // the constructor creates the representation
00111 
00112     // dummy  clear, update
00113     void clear(){};
00114     void update(){};
00115     
00116 private:
00117 };
00118 
00119 
00120 Axes::Axes(double scale)
00121 {
00122     static GraphicsVector unitvector[3] =
00123     {GraphicsVector(1.,0.,0.),
00124     GraphicsVector(0.,1.,0.),
00125     GraphicsVector(0.,0.,1.)
00126     };
00127     
00128     static const char* axislabel[3]={"x","y","z"};
00129     set_color("black");
00130     for( int i=0; i<3; i++){
00131         move_to(GraphicsVector(0,0,0));
00132         line_to((scale)*unitvector[i]);
00133         drawText(axislabel[i]);
00134     }
00135     flush();
00136 }
00137 
00138 //=====================================================================
00139 //   Private class used by DisplayControl to display reference point
00140 static double  amin(double x){return  fabs(x)<1e-5? 0:x;}
00141 class ReferencePoint : public DisplayRep2D
00142 {
00143 public:
00144     ReferencePoint(DisplayControl& dc):m_dc(dc){};
00145     void draw2D(Draw2D* canvas) {
00146         std::strstream text;
00147         GraphicsVector p(m_dc.reference_point());
00148         static int precision=3, w=10;
00149         text << "ref pt: "  << std::setprecision(precision) << std::setiosflags(std::ios::fixed)
00150              << "("
00151              << std::setw(w) << amin(p.x())  << ','
00152              << std::setw(w) << amin(p.y())  << ','
00153              << std::setw(w) << amin(p.z())  << ')' << '\0';
00154         const float s=0.025f;
00155         canvas->set_rgb(1,0,0);
00156         canvas->move_to(0,s);
00157         canvas->line_to(0,-s);
00158         canvas->move_to(s,0);
00159         canvas->line_to(-s,0);
00160         canvas->set_rgb(0,0,0);
00161 
00162         // display in ULH corner for now?
00163         canvas->draw_string(-0.95f, 0.9f, text.str());
00164 #ifdef _MSC_VER // avoids memory leak in Visual
00165         text.freeze(false);
00166 #endif
00167     }
00168 private:
00169     const DisplayControl& m_dc;
00170 };
00171 //=====================================================================
00172 //   Private class used by DisplayControl to display reference point
00173 class Scale : public DisplayRep2D
00174 {
00175 public:
00176     Scale(SceneControl* dc):m_dc(dc){};
00177     void draw2D(Draw2D* canvas){
00178         const float xa=-0.9f, xb=-0.7f, y=0.8f;
00179         double scale =   
00180             sqrt(( m_dc->view().transformToWorld(xa,y)
00181                  - m_dc->view().transformToWorld(xb,y)
00182                  ).mag2());
00183         std::strstream text;
00184         text <<  std::setprecision(3) << scale  << '\0';
00185         canvas->move_to(xa, y+0.025);
00186         canvas->line_to(xa, y-0.025);
00187         canvas->move_to(xa, y);
00188         canvas->line_to(xb, y);
00189         canvas->move_to(xb, y+0.025);
00190         canvas->line_to(xb, y-0.025);
00191         canvas->draw_string(xb+0.01, y-0.01, text.str());
00192 
00193 #ifdef _MSC_VER // avoids memory leak in Visual
00194         text.freeze(false);
00195 #endif
00196     }
00197 private:
00198     SceneControl* m_dc;
00199 };
00201 //   add a view to display, with a buttons or a toggle in the Display menu
00203 // File-scope stuff to define hide and show commands
00204     class ShowIt : public Command    {
00205     friend class DisplayControl;
00206         ShowIt( DisplayControl* s,DisplayRep * rep, bool f)
00207             :m_scene(s),m_rep(rep),m_flag(f){}
00208         void execute()
00209         {
00210             m_rep->update();
00211             m_rep->show(m_flag);
00212             m_scene->redisplay();
00213         }
00214         DisplayControl* m_scene;
00215         DisplayRep* m_rep;
00216         bool m_flag;
00217     };
00218     class HideIt : public Command    {
00219     friend class DisplayControl;
00220         HideIt( DisplayControl* s,DisplayRep * rep, bool f)
00221             :m_scene(s),m_rep(rep),m_flag(f){}
00222         void execute()
00223         {
00224             m_rep->hide(m_flag);
00225             m_scene->redisplay();
00226         }
00227         DisplayControl* m_scene;
00228         DisplayRep* m_rep;
00229         bool m_flag;
00230     };
00231 
00232 #ifdef NT_MSVCPP
00233 } // anonymous namespace
00234 #endif
00235 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00236 void
00237 DisplayControl::finishSetup()
00238 //---------------------------
00239 {
00240     m_sub_menu->addSeparator();
00241 
00242     if( m_axis_size != 0)  add( new Axes(m_axis_size),"axes" );
00243     add( new ReferencePoint(*this),"Reference point", false);
00244     add( new Scale(m_control), "Scale", false);
00245 
00246     m_sub_menu->addButton("Set ref. pt...", 
00247         new SimpleCommand<DisplayControl>(this, &DisplayControl::setRefPt));
00248 
00249     m_sub_menu->addButton("Set magnification...", 
00250 
00251         new SimpleCommand<DisplayControl>(this, &DisplayControl::setScale));
00252 
00253     // the rest of these on a sub menu
00254 
00255     gui::SubMenu* system= &m_sub_menu->subMenu("System");
00256 
00257     system->addToggle("3D Enabled", m_scene->enabled(),
00258         new SimpleCommand<Scene>(m_scene,&Scene::enable),
00259         new SimpleCommand<Scene>(m_scene,&Scene::disable)
00260                 );
00261     system->addToggle("2D Enabled", m_2d_scene->enabled(),
00262         new SimpleCommand<Scene>(m_2d_scene,&Scene::enable),
00263         new SimpleCommand<Scene>(m_2d_scene,&Scene::disable)
00264                 );
00265     system->addButton("clear", 
00266         new SimpleCommand<DisplayControl>(this,&DisplayControl::clear));
00267 
00268     system->addButton("update", 
00269         new SimpleCommand<DisplayControl>(this,&DisplayControl::update));
00270 
00271     system->addButton("Dump to postscript",
00272         new SimpleCommand<DisplayControl>(this,&DisplayControl::postScript));
00273     system->addButton("Dump to vrml",new VRML_command(this));
00274     system->addButton("Print instructions",
00275                            new PrintInstructions(m_control,PrintControl::instance()->out()));
00276 
00277     m_running = true;
00278     m_scene->update();
00279     m_2d_scene->update();
00280 }
00281 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00282 void DisplayControl::setRefPt()  // called by button
00283 {
00284    GraphicsVector&  p = m_control->reference_point();  
00285    double d[]={p.x(),p.y(),p.z()};
00286    m_menu_bar->query("Reference point?",d,3);
00287    p = GraphicsVector(d[0],d[1],d[2]);
00288  
00289 }
00290 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00291 void DisplayControl::setScale()  // called by dialog 
00292 {
00293     double scale = m_control->view().zoom(); //current zoom factor
00294     double zoom_factor = scale;
00295     m_menu_bar->query("Magnification?",&scale);
00296     if(zoom_factor==scale&&zoom_factor!=0) return;
00297     m_control->view().zoom(scale/zoom_factor); 
00298     m_control->redisplay();
00299 }
00300 
00301 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00302 void DisplayControl::setAxisSize(float size)
00303 {
00304     m_axis_size = size;
00305 }
00306 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00307 void DisplayControl::redisplay()
00308 //---------------------------
00309 // This is necesary to prevent the setup calls for ShowIt and HideIt calling
00310 // Motif before the display has been realized
00311 {
00312     if( m_running )
00313         m_control->redisplay();
00314 }
00315 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00316 void DisplayControl::clear()
00317 //-------------------------
00318 {
00319     m_scene->clear();
00320     m_2d_scene->clear();
00321     redisplay();
00322 }
00323 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00324 void DisplayControl::update()
00325 //-------------------------
00326 {
00327     m_scene->update();
00328     m_2d_scene->update();
00329     redisplay();
00330 }
00331 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00332 
00333 
00334 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00335 GUI::Toggle* 
00336 DisplayControl::add(DisplayRep* pRep, const std::string& name, int state)
00337 {
00338     m_scene->add(pRep);
00339         
00340     // now control it, if requested
00341     if( !name.length() ) return 0;
00342 
00343     return addButton(pRep,name,state);
00344 }
00345 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00346 void
00347 DisplayControl::add(DisplayRep2D* pRep, const std::string& name, int state)
00348 {
00349     m_control->scene_2d().add(pRep);
00350 
00351     if( name.empty() ) return;
00352     addButton(pRep, name, state);
00353 
00354 }
00355 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00356 GUI::Toggle*
00357 DisplayControl::addButton(DisplayRep* pRep, const std::string& name, int state)
00358 {
00359 
00360     Command* showit = new ShowIt(this, pRep, state>=0);
00361     Command* hideit = new HideIt(this, pRep, state>=0);
00362     if( state <0 ) {
00363         // special flag to make separate show and hide buttons
00364         m_user_menu->addButton(std::string("show ")+name, showit);
00365         m_user_menu->addButton(std::string("hide ")+name, hideit);
00366         return 0;
00367     } 
00368 
00369     if( state>0 ) showit->execute(); else hideit->execute();
00370     return m_user_menu->addToggle(name, state>0, showit, hideit );
00371 
00372 }
00373 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00374 void DisplayControl::useMenu(gui::SubMenu* m)
00375 {
00376     m_user_menu = m? m : m_sub_menu;
00377 }
00378 
00379 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00380 void
00381 DisplayControl::setTitle(const std::string& t){GUI::instance()->setTitle(t.c_str());}
00382 
00383 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00384 GraphicsVector&  DisplayControl::reference_point()
00385 //--------------------------------------------------
00386 {
00387   return m_control->reference_point();
00388 }
00389 
00390 const GraphicsVector&  DisplayControl::reference_point()const
00391 //--------------------------------------------------
00392 {
00393   return const_cast<const GraphicsVector&>(m_control->reference_point());
00394 }
00395 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00396 void DisplayControl::vrml(std::ostream& pout)
00397 //--------------------------------------
00398 // ask the scene to dump itself to a VRML file
00399 {
00400   Vrml output(pout);
00401     ((Scene*)m_scene)->draw(&output);
00402 }
00403 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00404 void DisplayControl::postScript()
00405 //--------------------------------
00406 // ask the scene to draw itself to a file in postscript
00407 {
00408     static const char* filename = "temp.ps";
00409     PSdraw ps(filename);
00410     if( !ps() ) {
00411         GUI::instance()->inform("Cannot open file for postscript output");
00412         return;
00413     }
00414 
00415     m_control->redisplay(&ps);
00416     std::ostrstream msg; msg << "Postscript version written to file " << filename << '\0';
00417     GUI::instance()->inform(msg.str());
00418 }
00419 
00420 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00421 //      SubMenu implementation
00422 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00423 DisplayControl::DisplaySubMenu& DisplayControl::subMenu(const std::string& name, DisplayRep *rep)
00424 {
00425     DisplaySubMenu* s = new DisplaySubMenu(this, 0, rep, name);
00426     _submenus.push_back(s);  // save in this list to delete 
00427     return *s; 
00428 }
00429 
00430 DisplayControl::DisplaySubMenu::DisplaySubMenu(DisplayControl* display,DisplaySubMenu* parent, DisplayRep * rep, const std::string& name)
00431 : _rep(rep)
00432 , _display(display)
00433 {
00434 
00435     // create a new submenu with the name;
00436     if ( parent==0) {
00437         _menu = &_display->menu().subMenu(name) ;
00438     } else {
00439         _menu = &parent->_menu->subMenu(name); 
00440         // and add to list of DisplayReps in parent menu
00441         parent->_submenus.push_back(this);
00442     }
00443 
00444     // add the rep, if there is one, to the DisplayControl object for display
00445     if( rep) _display->add(rep);
00446 
00447     // top buttons to show or hide all on the menu or under it
00448     _menu->addButton("Show all", new gui::SimpleCommand<DisplaySubMenu>(this, &DisplaySubMenu::show));
00449     _menu->addButton("Hide all", new gui::SimpleCommand<DisplaySubMenu>(this, &DisplaySubMenu::hide));
00450     _menu->addSeparator();
00451 
00452 
00453 }
00454 DisplayControl::DisplaySubMenu& DisplayControl::DisplaySubMenu::subMenu(const std::string& name,DisplayRep * rep)
00455 {
00456     return *new DisplayControl::DisplaySubMenu(_display,this,rep,name);
00457 }
00458     
00459 void DisplayControl::DisplaySubMenu::add(DisplayRep * rep, const std::string& name)
00460 {
00461     _display->useMenu(_menu);
00462     GUI::Toggle* display_toggle = _display->add(rep,name);
00463     if( display_toggle !=0) _rep_list.push_back(display_toggle);
00464     _display->useMenu();
00465 }
00466 void DisplayControl::DisplaySubMenu::show(){
00467    _display->set_running(false); show(true); _display->set_running(true); _display->redisplay();}
00468 void DisplayControl::DisplaySubMenu::hide(){
00469    _display->set_running(false); hide(true); _display->set_running(true); _display->redisplay();}
00470 
00471 void DisplayControl::DisplaySubMenu::show(bool /* update*/)
00472 {
00473     if(_rep) _rep->show();
00474     for(std::vector<GUI::Toggle*>::iterator itt=_rep_list.begin(); itt!=_rep_list.end(); ++itt)
00475         (*itt)->set(); //set the toggle to the correct state
00476     for(std::vector<DisplaySubMenu*>::iterator it = _submenus.begin(); it!=_submenus.end(); ++it)
00477         (*it)->show(false);
00478 }
00479 void DisplayControl::DisplaySubMenu::hide(bool /*update */)
00480 {
00481     if(_rep) _rep->hide();
00482     
00483     for(std::vector<GUI::Toggle*>::iterator itt=_rep_list.begin(); itt!=_rep_list.end(); ++itt)
00484         (*itt)->unset();
00485     for(std::vector<DisplaySubMenu*>::iterator it = _submenus.begin(); it!=_submenus.end(); ++it)
00486         (*it)->hide(false); 
00487 }
00488 
00489 DisplayControl::DisplaySubMenu::~DisplaySubMenu()
00490 {
00491     for(std::vector<DisplaySubMenu*>::iterator it = _submenus.begin(); it!=_submenus.end(); ++it) delete (*it);
00492 
00493 }
00494 
00495 
00496 
00497 
00498 }// namespace gui
00499 
00500 
00501 

Generated at Wed Nov 21 12:20:54 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000