00001
00002
00003
00004
00005
00006 #ifdef NT_MSVCPP
00007 #pragma warning(disable: 4786)
00008 #endif
00009
00010 #include "gui/DisplayControl.h"
00011 #include "gui/GUI.h"
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;
00041 m_user_menu =m_sub_menu = &menu.subMenu("Display");
00042
00043
00044 menu.add(new MenuClient<DisplayControl>(this));
00045
00046
00047
00048 m_scene = &m_control->scene();
00049 m_2d_scene = &m_control->scene_2d();
00050
00051 m_canvas = m_control->view().canvas();
00052
00053
00054 m_control->set_menu(m_sub_menu);
00055
00056
00057
00058 Projector p((Draw2D*)0); p.canvas();
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
00070
00071 #ifdef NT_MSVCPP //KAI can't handle this???
00072 namespace {
00073 #endif
00074 double sqr(double x){return x*x;}
00075
00076
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;
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
00106 class Axes: public DisplayRep
00107 {
00108 public:
00109 Axes(double scale=1.);
00110
00111
00112
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
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
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
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
00203
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 }
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
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()
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()
00292 {
00293 double scale = m_control->view().zoom();
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
00310
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
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
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
00399 {
00400 Vrml output(pout);
00401 ((Scene*)m_scene)->draw(&output);
00402 }
00403
00404 void DisplayControl::postScript()
00405
00406
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
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);
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
00436 if ( parent==0) {
00437 _menu = &_display->menu().subMenu(name) ;
00438 } else {
00439 _menu = &parent->_menu->subMenu(name);
00440
00441 parent->_submenus.push_back(this);
00442 }
00443
00444
00445 if( rep) _display->add(rep);
00446
00447
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 )
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();
00476 for(std::vector<DisplaySubMenu*>::iterator it = _submenus.begin(); it!=_submenus.end(); ++it)
00477 (*it)->show(false);
00478 }
00479 void DisplayControl::DisplaySubMenu::hide(bool )
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 }
00499
00500
00501