Visualization Library v1.0.3A lightweight C++ OpenGL middleware for 2D/3D graphics |
[Download] [Tutorials] [All Classes] [Grouped Classes] |
00001 /**************************************************************************************/ 00002 /* */ 00003 /* Visualization Library */ 00004 /* http://visualizationlibrary.org */ 00005 /* */ 00006 /* Copyright (c) 2005-2010, Michele Bosi */ 00007 /* All rights reserved. */ 00008 /* */ 00009 /* Redistribution and use in source and binary forms, with or without modification, */ 00010 /* are permitted provided that the following conditions are met: */ 00011 /* */ 00012 /* - Redistributions of source code must retain the above copyright notice, this */ 00013 /* list of conditions and the following disclaimer. */ 00014 /* */ 00015 /* - Redistributions in binary form must reproduce the above copyright notice, this */ 00016 /* list of conditions and the following disclaimer in the documentation and/or */ 00017 /* other materials provided with the distribution. */ 00018 /* */ 00019 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */ 00020 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */ 00021 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ 00022 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */ 00023 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */ 00024 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ 00025 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */ 00026 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 00027 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ 00028 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 00029 /* */ 00030 /**************************************************************************************/ 00031 00032 #include "vlWX/WXGLCanvas.hpp" 00033 00034 using namespace vlWX; 00035 using namespace vl; 00036 00037 //----------------------------------------------------------------------------- 00038 // WXGLCanvas 00039 //----------------------------------------------------------------------------- 00040 BEGIN_EVENT_TABLE(WXGLCanvas, wxGLCanvas) 00041 EVT_IDLE(WXGLCanvas::OnIdle) 00042 EVT_SIZE(WXGLCanvas::OnSize) 00043 EVT_PAINT(WXGLCanvas::OnPaint) 00044 EVT_ERASE_BACKGROUND(WXGLCanvas::OnEraseBackground) 00045 EVT_KEY_DOWN( WXGLCanvas::OnKeyDown ) 00046 EVT_KEY_UP( WXGLCanvas::OnKeyUp ) 00047 /*EVT_CHAR( WXGLCanvas::OnChar )*/ 00048 EVT_ENTER_WINDOW( WXGLCanvas::OnMouseEnter ) 00049 EVT_ENTER_WINDOW (WXGLCanvas::OnMouseEnter) 00050 EVT_LEFT_DOWN (WXGLCanvas::OnMouseDown) 00051 EVT_MIDDLE_DOWN (WXGLCanvas::OnMouseDown) 00052 EVT_RIGHT_DOWN (WXGLCanvas::OnMouseDown) 00053 EVT_LEFT_UP (WXGLCanvas::OnMouseUp) 00054 EVT_MIDDLE_UP (WXGLCanvas::OnMouseUp) 00055 EVT_RIGHT_UP (WXGLCanvas::OnMouseUp) 00056 EVT_MOUSEWHEEL (WXGLCanvas::OnMouseWheel) 00057 EVT_MOTION (WXGLCanvas::OnMouseMotion) 00058 EVT_DROP_FILES (WXGLCanvas::OnDropFiles) 00059 END_EVENT_TABLE() 00060 //----------------------------------------------------------------------------- 00061 WXGLCanvas::~WXGLCanvas() 00062 { 00063 dispatchDestroyEvent(); 00064 } 00065 //----------------------------------------------------------------------------- 00066 WXGLCanvas::WXGLCanvas( 00067 wxWindow *parent, 00068 const wxGLContext *shared, 00069 wxWindowID id, 00070 const wxPoint& pos, 00071 const wxSize& size, 00072 long style, 00073 int *attribList, 00074 const wxString& name, 00075 const wxPalette& palette): 00076 wxGLCanvas(parent, shared, id, pos, size, style, name, attribList) 00077 { 00078 // let wxWidgets manage the deletion of this object 00079 setAutomaticDelete(false); 00080 mMouseCount = 0; 00081 DragAcceptFiles(true); 00082 } 00083 //----------------------------------------------------------------------------- 00084 void WXGLCanvas::OnDropFiles(wxDropFilesEvent& ev) 00085 { 00086 std::vector<String> files; 00087 for(int i=0; i<ev.GetNumberOfFiles(); ++i) 00088 { 00089 wxCharBuffer chars = ev.GetFiles()[i].ToUTF8(); 00090 String str = String::fromUTF8(chars.data()); 00091 files.push_back(str); 00092 } 00093 dispatchFileDroppedEvent(files); 00094 } 00095 //----------------------------------------------------------------------------- 00096 void WXGLCanvas::OnIdle(wxIdleEvent& ev) 00097 { 00098 if (continuousUpdate()) 00099 Refresh(false); 00100 /*else 00101 Time::sleep(1);*/ 00102 } 00103 //----------------------------------------------------------------------------- 00104 void WXGLCanvas::OnMouseEnter( wxMouseEvent& WXUNUSED(ev) ) 00105 { 00106 SetFocus(); 00107 } 00108 //----------------------------------------------------------------------------- 00109 void WXGLCanvas::OnMouseMotion( wxMouseEvent& ev ) 00110 { 00111 dispatchMouseMoveEvent( ev.GetX(), ev.GetY() ); 00112 } 00113 //----------------------------------------------------------------------------- 00114 void WXGLCanvas::OnMouseWheel( wxMouseEvent& ev ) 00115 { 00116 int d = ev.GetWheelRotation() / ev.GetWheelDelta(); 00117 dispatchMouseWheelEvent( d ); 00118 } 00119 //----------------------------------------------------------------------------- 00120 void WXGLCanvas::OnMouseUp( wxMouseEvent& ev ) 00121 { 00122 if (ev.GetButton() == wxMOUSE_BTN_NONE) 00123 return; 00124 switch(ev.GetButton()) 00125 { 00126 case wxMOUSE_BTN_LEFT: dispatchMouseUpEvent(LeftButton, ev.GetX(), ev.GetY()); break; 00127 case wxMOUSE_BTN_MIDDLE: dispatchMouseUpEvent(MiddleButton, ev.GetX(), ev.GetY()); break; 00128 case wxMOUSE_BTN_RIGHT: dispatchMouseUpEvent(RightButton, ev.GetX(), ev.GetY()); break; 00129 default: 00130 case wxMOUSE_BTN_ANY: dispatchMouseUpEvent(UnknownButton, ev.GetX(), ev.GetY()); break; 00131 } 00132 mMouseCount--; 00133 // release only once 00134 if (!mMouseCount) 00135 ReleaseMouse(); 00136 VL_CHECK(mMouseCount>=0) 00137 } 00138 //----------------------------------------------------------------------------- 00139 void WXGLCanvas::OnMouseDown( wxMouseEvent& ev ) 00140 { 00141 if (ev.GetButton() == wxMOUSE_BTN_NONE) 00142 return; 00143 switch(ev.GetButton()) 00144 { 00145 case wxMOUSE_BTN_LEFT: dispatchMouseDownEvent(LeftButton, ev.GetX(), ev.GetY()); break; 00146 case wxMOUSE_BTN_MIDDLE: dispatchMouseDownEvent(MiddleButton, ev.GetX(), ev.GetY()); break; 00147 case wxMOUSE_BTN_RIGHT: dispatchMouseDownEvent(RightButton, ev.GetX(), ev.GetY()); break; 00148 default: 00149 case wxMOUSE_BTN_ANY: dispatchMouseDownEvent(UnknownButton, ev.GetX(), ev.GetY()); break; 00150 } 00151 // capture only once 00152 VL_CHECK(mMouseCount>=0) 00153 if (!mMouseCount) 00154 CaptureMouse(); 00155 mMouseCount++; 00156 } 00157 //----------------------------------------------------------------------------- 00158 void WXGLCanvas::OnSize(wxSizeEvent& ev) 00159 { 00160 // this is also necessary to update the context on some platforms 00161 wxGLCanvas::OnSize(ev); 00162 wxSize s = GetClientSize(); 00163 dispatchResizeEvent(s.x, s.y); 00164 } 00165 //----------------------------------------------------------------------------- 00166 void translateKey(int& unicode, EKey& key, const wxKeyEvent& ev) 00167 { 00168 // note 00169 // ev.GetUnicodeKey() ritorna != anche per-non unicode characters 00170 // ev.GetUnicodeKey() non ritorna vero carattere unicode 00171 // see also OnChar(wxKeyEvent&) 00172 00173 unicode = 0; 00174 #if wxUSE_UNICODE == 1 00175 unicode = ev.GetUnicodeKey(); 00176 #else 00177 unicode = ev.GetKeyCode() < 128 ? ev.GetKeyCode() : 0; 00178 #endif 00179 00180 switch(ev.GetKeyCode()) 00181 { 00182 case '0': key = Key_0; break; 00183 case '1': key = Key_1; break; 00184 case '2': key = Key_2; break; 00185 case '3': key = Key_3; break; 00186 case '4': key = Key_4; break; 00187 case '5': key = Key_5; break; 00188 case '6': key = Key_6; break; 00189 case '7': key = Key_7; break; 00190 case '8': key = Key_8; break; 00191 case '9': key = Key_9; break; 00192 00193 case 'Q': key = Key_Q; break; 00194 case 'W': key = Key_W; break; 00195 case 'E': key = Key_E; break; 00196 case 'R': key = Key_R; break; 00197 case 'T': key = Key_T; break; 00198 case 'Y': key = Key_Y; break; 00199 case 'U': key = Key_U; break; 00200 case 'I': key = Key_I; break; 00201 case 'O': key = Key_O; break; 00202 case 'P': key = Key_P; break; 00203 case 'A': key = Key_A; break; 00204 case 'S': key = Key_S; break; 00205 case 'D': key = Key_D; break; 00206 case 'F': key = Key_F; break; 00207 case 'G': key = Key_G; break; 00208 case 'H': key = Key_H; break; 00209 case 'J': key = Key_J; break; 00210 case 'K': key = Key_K; break; 00211 case 'L': key = Key_L; break; 00212 case 'Z': key = Key_Z; break; 00213 case 'X': key = Key_X; break; 00214 case 'C': key = Key_C; break; 00215 case 'V': key = Key_V; break; 00216 case 'B': key = Key_B; break; 00217 case 'N': key = Key_N; break; 00218 case 'M': key = Key_M; break; 00219 00220 case WXK_RETURN: key = Key_Return; break; 00221 case WXK_BACK: key = Key_BackSpace; break; 00222 case WXK_TAB: key = Key_Tab; break; 00223 case WXK_SPACE: key = Key_Space; break; 00224 00225 case WXK_CLEAR: key = Key_Clear; break; 00226 case WXK_ESCAPE: key = Key_Escape; break; 00227 case '!': key = Key_Exclam; break; 00228 case '"': key = Key_QuoteDbl; break; 00229 case '#': key = Key_Hash; break; 00230 case '$': key = Key_Dollar; break; 00231 case '&': key = Key_Ampersand; break; 00232 case '\'': key = Key_Quote; break; 00233 case '(': key = Key_LeftParen; break; 00234 case ')': key = Key_RightParen; break; 00235 case '*': key = Key_Asterisk; break; 00236 case '+': key = Key_Plus; break; 00237 case ',': key = Key_Comma; break; 00238 case '-': key = Key_Minus; break; 00239 case '.': key = Key_Period; break; 00240 case '\\': key = Key_Slash; break; 00241 case ':': key = Key_Colon; break; 00242 case ';': key = Key_Semicolon; break; 00243 case '<': key = Key_Less; break; 00244 case '=': key = Key_Equal; break; 00245 case '>': key = Key_Greater; break; 00246 case '?': key = Key_Question; break; 00247 case '@': key = Key_At; break; 00248 case '[': key = Key_LeftBracket; break; 00249 case '/': key = Key_BackSlash; break; 00250 case ']': key = Key_RightBracket; break; 00251 case '|': key = Key_Caret; break; 00252 case '_': key = Key_Underscore; break; 00253 case '`': key = Key_QuoteLeft; break; 00254 00255 // non unicode keys 00256 00257 case WXK_CONTROL: key = Key_Ctrl; unicode = 0; break; 00258 //case WXK_: key = Key_LeftCtrl; unicode = 0; break; 00259 //case WXK_: key = Key_RightCtrl; unicode = 0; break; 00260 case WXK_ALT: key = Key_Alt; unicode = 0; break; 00261 //case WXK_: key = Key_LeftAlt; unicode = 0; break; 00262 //case WXK_: key = Key_RightAlt; unicode = 0; break; 00263 case WXK_SHIFT: key = Key_Shift; unicode = 0; break; 00264 //case WXK_: key = Key_LeftShift; unicode = 0; break; 00265 //case WXK_: key = Key_RightShift; unicode = 0; break; 00266 case WXK_INSERT: key = Key_Insert; unicode = 0; break; 00267 case WXK_DELETE: key = Key_Delete; unicode = 0; break; 00268 case WXK_HOME: key = Key_Home; unicode = 0; break; 00269 case WXK_END: key = Key_End; unicode = 0; break; 00270 case WXK_PRINT: key = Key_Print; unicode = 0; break; 00271 case WXK_PAUSE: key = Key_Pause; unicode = 0; break; 00272 case WXK_PAGEUP: key = Key_PageUp; unicode = 0; break; 00273 case WXK_PAGEDOWN: key = Key_PageDown; unicode = 0; break; 00274 case WXK_LEFT: key = Key_Left; unicode = 0; break; 00275 case WXK_RIGHT: key = Key_Right; unicode = 0; break; 00276 case WXK_UP: key = Key_Up; unicode = 0; break; 00277 case WXK_DOWN: key = Key_Down; unicode = 0; break; 00278 case WXK_F1: key = Key_F1; unicode = 0; break; 00279 case WXK_F2: key = Key_F2; unicode = 0; break; 00280 case WXK_F3: key = Key_F3; unicode = 0; break; 00281 case WXK_F4: key = Key_F4; unicode = 0; break; 00282 case WXK_F5: key = Key_F5; unicode = 0; break; 00283 case WXK_F6: key = Key_F6; unicode = 0; break; 00284 case WXK_F7: key = Key_F7; unicode = 0; break; 00285 case WXK_F8: key = Key_F8; unicode = 0; break; 00286 case WXK_F9: key = Key_F9; unicode = 0; break; 00287 case WXK_F10: key = Key_F10; unicode = 0; break; 00288 case WXK_F11: key = Key_F11; unicode = 0; break; 00289 case WXK_F12: key = Key_F12; unicode = 0; break; 00290 } 00291 } 00292 //----------------------------------------------------------------------------- 00293 /*void WXGLCanvas::OnChar(wxKeyEvent& ev) 00294 { 00295 printf("key = %d, %d\n", (int)ev.GetKeyCode(), (int)ev.GetUnicodeKey() ); 00296 }*/ 00297 //----------------------------------------------------------------------------- 00298 void WXGLCanvas::OnKeyDown( wxKeyEvent& ev ) 00299 { 00300 /*printf("key = %d, %d\n", (int)ev.GetKeyCode(), (int)ev.GetUnicodeKey() );*/ 00301 int unicode = 0; 00302 EKey key = Key_Unknown; 00303 translateKey(unicode, key, ev); 00304 dispatchKeyPressEvent(unicode,key); 00305 ev.Skip(); 00306 } 00307 //----------------------------------------------------------------------------- 00308 void WXGLCanvas::OnKeyUp( wxKeyEvent& ev ) 00309 { 00310 int unicode = 0; 00311 EKey key = Key_Unknown; 00312 translateKey(unicode, key, ev); 00313 dispatchKeyReleaseEvent(unicode,key); 00314 ev.Skip(); 00315 } 00316 //----------------------------------------------------------------------------- 00317 void WXGLCanvas::OnPaint( wxPaintEvent& ) 00318 { 00319 // validate dirty client area 00320 wxPaintDC dc(this); 00321 00322 dispatchRunEvent(); 00323 00324 // for debugging purposes only 00325 #if 0 00326 makeCurrent(); 00327 float r = rand()%100 / 100.0f; 00328 float g = rand()%100 / 100.0f; 00329 float b = rand()%100 / 100.0f; 00330 float a = rand()%100 / 100.0f; 00331 glClearColor(r,g,b,a); 00332 glClear(GL_COLOR_BUFFER_BIT); 00333 swapBuffers(); 00334 #endif 00335 } 00336 //----------------------------------------------------------------------------- 00337 void WXGLCanvas::OnEraseBackground(wxEraseEvent&) 00338 { 00339 // Do nothing, to avoid flashing. 00340 } 00341 //----------------------------------------------------------------------------- 00342 bool WXGLCanvas::setFullscreen(bool fullscreen) 00343 { 00344 wxWindow* win = this; 00345 while(win->GetParent()) 00346 { 00347 win = win->GetParent(); 00348 wxTopLevelWindowBase* win_base = dynamic_cast<wxTopLevelWindowBase*>(win); 00349 if (win_base) 00350 { 00351 win_base->ShowFullScreen(fullscreen, wxFULLSCREEN_ALL); 00352 break; 00353 } 00354 } 00355 mFullscreen = fullscreen; 00356 return true; 00357 } 00358 //----------------------------------------------------------------------------- 00359 void WXGLCanvas::quitApplication() 00360 { 00361 wxApp* app = dynamic_cast<wxApp*>(wxApp::GetInstance()); 00362 if (app) 00363 app->ExitMainLoop(); 00364 eraseAllEventListeners(); 00365 } 00366 //----------------------------------------------------------------------------- 00367 void WXGLCanvas::makeCurrent() 00368 { 00369 #ifndef __WXMOTIF__ 00370 if (!GetContext()) return; 00371 #endif 00372 00373 SetCurrent(); 00374 } 00375 //----------------------------------------------------------------------------- 00376 void WXGLCanvas::swapBuffers() 00377 { 00378 #ifndef __WXMOTIF__ 00379 if (!GetContext()) return; 00380 #endif 00381 00382 SwapBuffers(); 00383 } 00384 //----------------------------------------------------------------------------- 00385 void WXGLCanvas::getFocus() 00386 { 00387 SetFocus(); 00388 } 00389 //----------------------------------------------------------------------------- 00390 void WXGLCanvas::setMousePosition(int x, int y) 00391 { 00392 WarpPointer(x,y); 00393 } 00394 //----------------------------------------------------------------------------- 00395 void WXGLCanvas::update() 00396 { 00397 Refresh(false); 00398 } 00399 //----------------------------------------------------------------------------- 00400 void WXGLCanvas::setWindowTitle(const String& text) 00401 { 00402 wxWindow* win = this; 00403 while(win->GetParent()) 00404 win = win->GetParent(); 00405 #ifdef wxUSE_UNICODE 00406 win->SetLabel(text.toStdWString().c_str()); 00407 #else 00408 win->SetLabel(text.toStdString().c_str()); 00409 #endif 00410 } 00411 //----------------------------------------------------------------------------- 00412 void WXGLCanvas::show() 00413 { 00414 Show(true); 00415 } 00416 //----------------------------------------------------------------------------- 00417 void WXGLCanvas::hide() 00418 { 00419 Show(false); 00420 } 00421 //----------------------------------------------------------------------------- 00422 void WXGLCanvas::setPosition(int x, int y) 00423 { 00424 SetPosition(wxPoint(x,y)); 00425 } 00426 00427 void WXGLCanvas::setSize(int w, int h) 00428 { 00429 SetClientSize(w,h); 00430 } 00431 //----------------------------------------------------------------------------- 00432 ivec2 WXGLCanvas::position() const 00433 { 00434 wxPoint pt = GetPosition(); 00435 return ivec2(pt.x, pt.y); 00436 } 00437 //----------------------------------------------------------------------------- 00438 void WXGLCanvas::setMouseVisible(bool visible) 00439 { 00440 if (mouseVisible() && !visible) 00441 { 00442 mCursor = GetCursor(); 00443 // of course this one does not work... 00444 // SetCursor( wxCursor( wxCURSOR_BLANK ) ); 00445 00446 // not working either 00447 // char bits[] = { 0xFF }; 00448 // char mask[] = { 0x00 }; 00449 // SetCursor( wxCursor(bits,1,1,-1,-1,mask) ); 00450 00451 // this seems to be the most portable 00452 wxImage image(8,8); 00453 image.SetRGB( wxRect(0,0,8,8), 255,255,255 ); 00454 image.SetMaskColour(255, 255, 255); 00455 image.SetMask(true); 00456 wxCursor cursor(image); 00457 SetCursor(cursor); 00458 } 00459 00460 if (!mouseVisible() && visible) 00461 { 00462 SetCursor( mCursor ); 00463 } 00464 00465 mMouseVisible = visible; 00466 } 00467 //-----------------------------------------------------------------------------