Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

ThyrixMainFrame.cpp

Go to the documentation of this file.
00001 #include "wxIncludes.h"
00002 #include <wx/xrc/xmlres.h>
00003 #include <wx/image.h>
00004 #include <wx/menu.h>
00005 #include <wx/toolbar.h>
00006 #include <wx/metafile.h>
00007 #include <wx/gdicmn.h>
00008 #include "ThyrixApplication.h"
00009 #include "ThyrixMainFrame.h"
00010 #include "World.h"
00011 
00012 
00013 //Used in a C++ implementation file to complete the declaration of a class that 
00014 //has run-time type information.
00015 //(?)
00016 IMPLEMENT_CLASS(ThyrixMainFrame, wxFrame)
00017 
00018 // the event tables connect the wxWindows events with the functions (event
00019 // handlers) which process them. It can be also done at run-time, but for the
00020 // simple menu events like this the static method is much simpler.
00021 BEGIN_EVENT_TABLE(ThyrixMainFrame, wxFrame)
00022     //EVT_MENU(XRCID("file_menu_exit"), ThyrixMainFrame::OnQuit)
00023     //EVT_MENU(XRCID("help_menu_about"), ThyrixMainFrame::OnAbout)
00024     //EVT_PAINT(ThyrixMainFrame::onPaint)
00025     EVT_MOTION(ThyrixMainFrame::onMotion)
00026       EVT_LEFT_DOWN(ThyrixMainFrame::onLeftDown)
00027       EVT_LEFT_UP(ThyrixMainFrame::onLeftUp)
00028       EVT_RIGHT_DOWN(ThyrixMainFrame::onRightDown)
00029       EVT_RIGHT_UP(ThyrixMainFrame::onRightUp)
00030     EVT_CLOSE(ThyrixMainFrame::OnClose)
00031     //EVT_IDLE(ThyrixMainFrame::OnIdle)
00032     EVT_MENU_RANGE(ThyrixMainFrame::kMenuTimePause, 
00033                    ThyrixMainFrame::kMenuTimeMax,
00034                    ThyrixMainFrame::onSetSpeed)
00035     EVT_MENU_RANGE(ThyrixMainFrame::kMenuFps30,
00036                    ThyrixMainFrame::kMenuFps90,
00037                    ThyrixMainFrame::onSetFps)
00038     EVT_MENU(kMenuStep, ThyrixMainFrame::onStep)
00039       EVT_MENU(kMenuCapture, ThyrixMainFrame::onCapture)
00040 
00041 END_EVENT_TABLE()
00042 
00043 //frame constructor
00044 ThyrixMainFrame::ThyrixMainFrame(const wxString& title, World* world,
00045       int bufferWidth, int bufferHeight, int zoom)
00046     : wxFrame((wxFrame *)NULL, -1, title, wxDefaultPosition, wxDefaultSize),
00047       thread(this),
00048       gui(0),
00049          world(world),
00050          bufferWidth(bufferWidth),
00051          bufferHeight(bufferHeight),
00052          zoom(zoom){
00053    thread.world=world;
00054    
00055    // set the frame icon
00056    SetIcon(wxICON(Thyrix));
00057    
00058    //set the background color of the frame
00059    SetBackgroundColour(*wxWHITE);
00060 
00061    /* load the menubar & toolbar
00062        please, find a way to load these from the executable, not from
00063        separate data (.xml) files.
00064        SetMenuBar(wxXmlResource::Get()->LoadMenuBar("main_menubar"));
00065        SetToolBar(wxXmlResource::Get()->LoadToolBar(this, "main_toolbar"));
00066     */
00067    
00068    // Set the buffer bitmap and the corresponding memory DC
00069    bitmap.Create(bufferWidth,bufferHeight);
00070    buffer.SelectObject(bitmap);
00071    buffer.SetBackground(*wxWHITE_BRUSH);
00072    buffer.Clear();
00073    
00074    CreateStatusBar(3);
00075 
00076    //create a toolbar with one button
00077    wxToolBar* toolbar = CreateToolBar(wxTB_TEXT | wxTB_NOICONS);
00078    wxBitmap dummy;
00079    toolbar->AddTool(kMenuStep, "Step", dummy);
00080    toolbar->AddTool(kMenuCapture, "Capture", dummy);
00081    toolbar->Realize();
00082 
00083    buildMenu();
00084    
00085    SetClientSize(bufferWidth,bufferHeight+5);
00086    thread.Create();
00087 }
00088 
00089 // frame destructor
00090 ThyrixMainFrame::~ThyrixMainFrame() {
00091    thread.Delete();
00092    delete gui;
00093    gui=NULL;
00094 }
00095 
00096 void ThyrixMainFrame::buildMenu() {
00097    wxMenu *timeMenu = new wxMenu;
00098    timeMenu->AppendRadioItem(kMenuTimePause,   "Step by step");
00099    timeMenu->AppendRadioItem(kMenuTimeDiv10,"/10 \tslow time");
00100    timeMenu->AppendRadioItem(kMenuTimeX1,   "x1 \treal time");
00101    timeMenu->AppendRadioItem(kMenuTimeX3,   "x3 \ttime factor");
00102    timeMenu->AppendRadioItem(kMenuTimeX10,  "x10 \ttime factor");
00103    timeMenu->AppendRadioItem(kMenuTimeX30,  "x30 \ttime factor");
00104    timeMenu->AppendRadioItem(kMenuTimeX100, "x100 \ttime factor");
00105    timeMenu->AppendRadioItem(kMenuTimeMax,  "Maximum speed");
00106    //timeMenu->Check(kMenuTimeX1, true);
00107    timeMenu->Check(kMenuTimeMax, true);
00108 
00109    wxMenu *displayMenu = new wxMenu;
00110    displayMenu->AppendRadioItem(kMenuFps30,   "30 Frames Per Second");
00111    displayMenu->AppendRadioItem(kMenuFps60,   "60 FPS");
00112    displayMenu->AppendRadioItem(kMenuFps90,   "90 FPS");
00113    displayMenu->Check(kMenuFps30, true);
00114 
00115    wxMenuBar *menubar = new wxMenuBar;
00116    menubar->Append(timeMenu, "Speed");
00117    menubar->Append(displayMenu, "Display");
00118    SetMenuBar(menubar);
00119 }
00120 
00121 void ThyrixMainFrame::start() {
00122    gui = new GUIWx(0,bufferHeight,zoom,GetStatusBar());
00123    thread.Run();
00124 }
00125 
00126 void ThyrixMainFrame::onStep(wxCommandEvent& event) {
00127    thread.step();
00128 }
00129 
00130 void ThyrixMainFrame::onCapture(wxCommandEvent& event) {
00131    wxMetafileDC* dc=new wxMetafileDC("capture.wmf",bufferWidth,bufferHeight);
00132    paintDC(dc);
00133    wxMetafile* metafile=dc->Close();
00134    metafile->SetClipboard((int)(dc->MaxX() + 10), (int)(dc->MaxY() + 10) );
00135    delete metafile;
00136    delete dc;
00137 
00138 }
00139 
00140 void ThyrixMainFrame::onSetFps(wxCommandEvent& event) {
00141    switch(event.GetId()) {
00142    case kMenuFps30:
00143       thread.setFramesPerSecond(30);
00144       break;
00145    case kMenuFps60:
00146       thread.setFramesPerSecond(60);
00147       break;
00148    case kMenuFps90:
00149       thread.setFramesPerSecond(90);
00150       break;
00151    }
00152 }
00153 
00154 void ThyrixMainFrame::onSetSpeed(wxCommandEvent& event) {
00155     switch(event.GetId()) {
00156     case kMenuTimePause:
00157         thread.setPause();
00158         break;
00159     case kMenuTimeDiv10:
00160         thread.setTimeFactor(0.1f);
00161         break;
00162     case kMenuTimeX1:
00163         thread.setTimeFactor(1);
00164         break;
00165     case kMenuTimeX3:
00166         thread.setTimeFactor(3);
00167         break;
00168     case kMenuTimeX10:
00169         thread.setTimeFactor(10);
00170         break;
00171     case kMenuTimeX30:
00172         thread.setTimeFactor(30);
00173         break;
00174     case kMenuTimeX100:
00175         thread.setTimeFactor(100);
00176         break;
00177     case kMenuTimeMax:
00178         thread.setTimeFactor(1000);
00179         break;
00180     }
00181 }
00182 
00183 /*
00184 void ThyrixMainFrame::OnIdle(wxIdleEvent& event) {
00185     event.RequestMore();
00186     
00187     for (int i = 0; i < 100; ++i) {
00188         simulator->advanceTime();
00189     }
00190     paint();
00191 }
00192 */
00193 
00194 
00195 
00196 void ThyrixMainFrame::OnClose(wxCloseEvent& event){
00197    //thread.Delete();
00198    Destroy();
00199 }
00200 
00201 /*
00202 void ThyrixMainFrame::OnQuit(wxCommandEvent& event){
00203    // TRUE is to force the frame to close
00204    Close(TRUE);
00205 }
00206 */
00207 
00208 /*
00209 void ThyrixMainFrame::OnAbout(wxCommandEvent& event){
00210    // called when help - about is picked from the menu or toolbar
00211    wxString msg;
00212    msg.Printf(_("Thyrix: a simulator for virtual environments\n(c) Arxia / Coneural 2003\n"));
00213    wxMessageBox(msg, _("About Thyrix"), wxOK | wxICON_INFORMATION, this);
00214 }
00215 */
00216 
00217 /*
00218 void ThyrixMainFrame::onPaint(wxPaintEvent& event){
00219    //If no DC is created, the program does not stop. From the WX documentation (wxPaintEvent):
00220    //In a paint event handler, the application must always create a wxPaintDC object, 
00221    //even if you do not use it. Otherwise, under MS Windows, refreshing for this and 
00222    //other windows will go wrong.
00223 
00224    wxPaintDC dc(this); 
00225    //dc.Blit(0,50,600,400,&buffer,0,0);
00226 }
00227 */
00228 
00229 void ThyrixMainFrame::paint(){
00230    wxClientDC dc(this);
00231    //here you can chose, to paint either directly to screen,
00232    //or paint to a memoryDC & copy to screen (to avoid flicker).
00233    //paintDC(&dc);
00234    paintDC(&buffer);
00235    dc.Blit(0,30,bufferWidth,bufferHeight,&buffer,0,0);
00236 }
00237 
00238 /*
00239 void ThyrixMainFrame::onEraseBackground(wxEraseEvent& event){
00240 }
00241 */
00242 
00243 void ThyrixMainFrame::onMotion(wxMouseEvent& event){
00244    if(event.LeftIsDown()){
00245       world->setMouseCoordinates(gui->inverseMapX(event.GetX()), gui->inverseMapY(event.GetY()));
00246    }
00247 }
00248 
00249 void ThyrixMainFrame::onLeftDown(wxMouseEvent& event){
00250    float x=gui->inverseMapX(event.GetX());
00251    float y=gui->inverseMapY(event.GetY());
00252    world->onMouseLeftDown(x,y);
00253    //simulator->applyMouseForce(x,y);
00254    //simulator->setMouseCoordinates(x,y);
00255 }
00256 
00257 void ThyrixMainFrame::onLeftUp(wxMouseEvent& event){
00258    float x=gui->inverseMapX(event.GetX());
00259    float y=gui->inverseMapY(event.GetY());
00260    world->onMouseLeftUp(x,y);
00261    //simulator->unsetMouseForce();
00262 }
00263 
00264 void ThyrixMainFrame::onRightDown(wxMouseEvent& event){
00265    float x=gui->inverseMapX(event.GetX());
00266    float y=gui->inverseMapY(event.GetY());
00267    world->onMouseRightDown(x,y);
00268 }
00269 
00270 void ThyrixMainFrame::onRightUp(wxMouseEvent& event){
00271    float x=gui->inverseMapX(event.GetX());
00272    float y=gui->inverseMapY(event.GetY());
00273    world->onMouseRightUp(x,y);
00274 }
00275 
00276 
00277 void ThyrixMainFrame::paintDC(wxDC* dc){
00278    //dc->SetOptimization(true);
00279    dc->BeginDrawing();
00280    dc->Clear();
00281    gui->setDC(dc);
00282    world->draw(gui);
00283    dc->EndDrawing();
00284 }

Thyrix homepageUsers' guide

(C) Arxia 2004-2005