Visualization Library 2.1.0

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
WXGLCanvas.cpp
Go to the documentation of this file.
1 /**************************************************************************************/
2 /* */
3 /* Visualization Library */
4 /* http://visualizationlibrary.org */
5 /* */
6 /* Copyright (c) 2005-2020, Michele Bosi */
7 /* All rights reserved. */
8 /* */
9 /* Redistribution and use in source and binary forms, with or without modification, */
10 /* are permitted provided that the following conditions are met: */
11 /* */
12 /* - Redistributions of source code must retain the above copyright notice, this */
13 /* list of conditions and the following disclaimer. */
14 /* */
15 /* - Redistributions in binary form must reproduce the above copyright notice, this */
16 /* list of conditions and the following disclaimer in the documentation and/or */
17 /* other materials provided with the distribution. */
18 /* */
19 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
20 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
21 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
22 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
23 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
24 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
25 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
26 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
27 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
28 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29 /* */
30 /**************************************************************************************/
31 
32 #include "vlWX/WXGLCanvas.hpp"
33 
34 using namespace vlWX;
35 using namespace vl;
36 
37 //-----------------------------------------------------------------------------
38 // WXGLCanvas
39 //-----------------------------------------------------------------------------
40 BEGIN_EVENT_TABLE(WXGLCanvas, wxGLCanvas)
41  EVT_IDLE(WXGLCanvas::OnIdle)
42  EVT_SIZE(WXGLCanvas::OnSize)
43  EVT_PAINT(WXGLCanvas::OnPaint)
44  EVT_ERASE_BACKGROUND(WXGLCanvas::OnEraseBackground)
45  EVT_KEY_DOWN( WXGLCanvas::OnKeyDown )
46  EVT_KEY_UP( WXGLCanvas::OnKeyUp )
47  /*EVT_CHAR( WXGLCanvas::OnChar )*/
48  EVT_ENTER_WINDOW( WXGLCanvas::OnMouseEnter )
49  EVT_ENTER_WINDOW (WXGLCanvas::OnMouseEnter)
50  EVT_LEFT_DOWN (WXGLCanvas::OnMouseDown)
51  EVT_MIDDLE_DOWN (WXGLCanvas::OnMouseDown)
52  EVT_RIGHT_DOWN (WXGLCanvas::OnMouseDown)
53  EVT_LEFT_UP (WXGLCanvas::OnMouseUp)
54  EVT_MIDDLE_UP (WXGLCanvas::OnMouseUp)
55  EVT_RIGHT_UP (WXGLCanvas::OnMouseUp)
56  EVT_MOUSEWHEEL (WXGLCanvas::OnMouseWheel)
57  EVT_MOTION (WXGLCanvas::OnMouseMotion)
58  EVT_DROP_FILES (WXGLCanvas::OnDropFiles)
59 END_EVENT_TABLE()
60 //-----------------------------------------------------------------------------
62  wxWindow *parent,
63  wxWindowID id,
64  //const wxGLContext *shared,
65  const int *attribList,
66  const wxPoint& pos,
67  const wxSize& size,
68  long style,
69  const wxString& name,
70  const wxPalette& palette):
71 wxGLCanvas(parent, id, attribList, pos, size, style, name, palette)
72 {
73  // let wxWidgets manage the deletion of this object
74  setAutomaticDelete(false);
75  mMouseCount = 0;
76  DragAcceptFiles(true);
77 
78  mWXGLContext = new wxGLContext(this);
79 }
80 //-----------------------------------------------------------------------------
82 {
83  dispatchDestroyEvent();
84  if ( mWXGLContext ) {
85  delete mWXGLContext;
86  mWXGLContext = NULL;
87  }
88 }
89 //-----------------------------------------------------------------------------
90 void WXGLCanvas::OnDropFiles(wxDropFilesEvent& ev)
91 {
92  std::vector<String> files;
93  for(int i=0; i<ev.GetNumberOfFiles(); ++i)
94  {
95  wxCharBuffer chars = ev.GetFiles()[i].ToUTF8();
96  String str = String::fromUTF8(chars.data());
97  files.push_back(str);
98  }
99  dispatchFileDroppedEvent(files);
100 }
101 //-----------------------------------------------------------------------------
102 void WXGLCanvas::OnIdle(wxIdleEvent& ev)
103 {
104  if (continuousUpdate())
105  Refresh(false);
106  /*else
107  Time::sleep(1);*/
108 }
109 //-----------------------------------------------------------------------------
110 void WXGLCanvas::OnMouseEnter( wxMouseEvent& WXUNUSED(ev) )
111 {
112  SetFocus();
113 }
114 //-----------------------------------------------------------------------------
115 void WXGLCanvas::OnMouseMotion( wxMouseEvent& ev )
116 {
117  dispatchMouseMoveEvent( ev.GetX(), ev.GetY() );
118 }
119 //-----------------------------------------------------------------------------
120 void WXGLCanvas::OnMouseWheel( wxMouseEvent& ev )
121 {
122  int d = ev.GetWheelRotation() / ev.GetWheelDelta();
123  dispatchMouseWheelEvent( d );
124 }
125 //-----------------------------------------------------------------------------
126 void WXGLCanvas::OnMouseUp( wxMouseEvent& ev )
127 {
128  if (ev.GetButton() == wxMOUSE_BTN_NONE)
129  return;
130  switch(ev.GetButton())
131  {
132  case wxMOUSE_BTN_LEFT: dispatchMouseUpEvent(LeftButton, ev.GetX(), ev.GetY()); break;
133  case wxMOUSE_BTN_MIDDLE: dispatchMouseUpEvent(MiddleButton, ev.GetX(), ev.GetY()); break;
134  case wxMOUSE_BTN_RIGHT: dispatchMouseUpEvent(RightButton, ev.GetX(), ev.GetY()); break;
135  default:
136  case wxMOUSE_BTN_ANY: dispatchMouseUpEvent(UnknownButton, ev.GetX(), ev.GetY()); break;
137  }
138  mMouseCount--;
139  // release only once
140  if (!mMouseCount)
141  ReleaseMouse();
142  VL_CHECK(mMouseCount>=0)
143 }
144 //-----------------------------------------------------------------------------
145 void WXGLCanvas::OnMouseDown( wxMouseEvent& ev )
146 {
147  if (ev.GetButton() == wxMOUSE_BTN_NONE)
148  return;
149  switch(ev.GetButton())
150  {
151  case wxMOUSE_BTN_LEFT: dispatchMouseDownEvent(LeftButton, ev.GetX(), ev.GetY()); break;
152  case wxMOUSE_BTN_MIDDLE: dispatchMouseDownEvent(MiddleButton, ev.GetX(), ev.GetY()); break;
153  case wxMOUSE_BTN_RIGHT: dispatchMouseDownEvent(RightButton, ev.GetX(), ev.GetY()); break;
154  default:
155  case wxMOUSE_BTN_ANY: dispatchMouseDownEvent(UnknownButton, ev.GetX(), ev.GetY()); break;
156  }
157  // capture only once
158  VL_CHECK(mMouseCount>=0)
159  if (!mMouseCount)
160  CaptureMouse();
161  mMouseCount++;
162 }
163 //-----------------------------------------------------------------------------
164 void WXGLCanvas::OnSize(wxSizeEvent& ev)
165 {
166  // this is also necessary to update the context on some platforms
167  wxWindow::SetSize(ev.GetSize());
168  wxSize s = GetClientSize();
169  dispatchResizeEvent(s.x, s.y);
170 }
171 //-----------------------------------------------------------------------------
172 void translateKey(int& unicode, EKey& key, const wxKeyEvent& ev)
173 {
174  // note
175  // ev.GetUnicodeKey() ritorna != anche per-non unicode characters
176  // ev.GetUnicodeKey() non ritorna vero carattere unicode
177  // see also OnChar(wxKeyEvent&)
178 
179  unicode = 0;
180  #if wxUSE_UNICODE == 1
181  unicode = ev.GetUnicodeKey();
182  #else
183  unicode = ev.GetKeyCode() < 128 ? ev.GetKeyCode() : 0;
184  #endif
185 
186  switch(ev.GetKeyCode())
187  {
188  case '0': key = Key_0; break;
189  case '1': key = Key_1; break;
190  case '2': key = Key_2; break;
191  case '3': key = Key_3; break;
192  case '4': key = Key_4; break;
193  case '5': key = Key_5; break;
194  case '6': key = Key_6; break;
195  case '7': key = Key_7; break;
196  case '8': key = Key_8; break;
197  case '9': key = Key_9; break;
198 
199  case 'Q': key = Key_Q; break;
200  case 'W': key = Key_W; break;
201  case 'E': key = Key_E; break;
202  case 'R': key = Key_R; break;
203  case 'T': key = Key_T; break;
204  case 'Y': key = Key_Y; break;
205  case 'U': key = Key_U; break;
206  case 'I': key = Key_I; break;
207  case 'O': key = Key_O; break;
208  case 'P': key = Key_P; break;
209  case 'A': key = Key_A; break;
210  case 'S': key = Key_S; break;
211  case 'D': key = Key_D; break;
212  case 'F': key = Key_F; break;
213  case 'G': key = Key_G; break;
214  case 'H': key = Key_H; break;
215  case 'J': key = Key_J; break;
216  case 'K': key = Key_K; break;
217  case 'L': key = Key_L; break;
218  case 'Z': key = Key_Z; break;
219  case 'X': key = Key_X; break;
220  case 'C': key = Key_C; break;
221  case 'V': key = Key_V; break;
222  case 'B': key = Key_B; break;
223  case 'N': key = Key_N; break;
224  case 'M': key = Key_M; break;
225 
226  case WXK_RETURN: key = Key_Return; break;
227  case WXK_BACK: key = Key_BackSpace; break;
228  case WXK_TAB: key = Key_Tab; break;
229  case WXK_SPACE: key = Key_Space; break;
230 
231  case WXK_CLEAR: key = Key_Clear; break;
232  case WXK_ESCAPE: key = Key_Escape; break;
233  case '!': key = Key_Exclam; break;
234  case '"': key = Key_QuoteDbl; break;
235  case '#': key = Key_Hash; break;
236  case '$': key = Key_Dollar; break;
237  case '&': key = Key_Ampersand; break;
238  case '\'': key = Key_Quote; break;
239  case '(': key = Key_LeftParen; break;
240  case ')': key = Key_RightParen; break;
241  case '*': key = Key_Asterisk; break;
242  case '+': key = Key_Plus; break;
243  case ',': key = Key_Comma; break;
244  case '-': key = Key_Minus; break;
245  case '.': key = Key_Period; break;
246  case '\\': key = Key_BackSlash; break;
247  case ':': key = Key_Colon; break;
248  case ';': key = Key_Semicolon; break;
249  case '<': key = Key_Less; break;
250  case '=': key = Key_Equal; break;
251  case '>': key = Key_Greater; break;
252  case '?': key = Key_Question; break;
253  case '@': key = Key_At; break;
254  case '[': key = Key_LeftBracket; break;
255  case '/': key = Key_Slash; break;
256  case ']': key = Key_RightBracket; break;
257  case '|': key = Key_Caret; break;
258  case '_': key = Key_Underscore; break;
259  case '`': key = Key_QuoteLeft; break;
260 
261  // non unicode keys
262 
263  case WXK_CONTROL: key = Key_Ctrl; unicode = 0; break;
264  //case WXK_: key = Key_LeftCtrl; unicode = 0; break;
265  //case WXK_: key = Key_RightCtrl; unicode = 0; break;
266  case WXK_ALT: key = Key_Alt; unicode = 0; break;
267  //case WXK_: key = Key_LeftAlt; unicode = 0; break;
268  //case WXK_: key = Key_RightAlt; unicode = 0; break;
269  case WXK_SHIFT: key = Key_Shift; unicode = 0; break;
270  //case WXK_: key = Key_LeftShift; unicode = 0; break;
271  //case WXK_: key = Key_RightShift; unicode = 0; break;
272  case WXK_INSERT: key = Key_Insert; unicode = 0; break;
273  case WXK_DELETE: key = Key_Delete; unicode = 0; break;
274  case WXK_HOME: key = Key_Home; unicode = 0; break;
275  case WXK_END: key = Key_End; unicode = 0; break;
276  case WXK_PRINT: key = Key_Print; unicode = 0; break;
277  case WXK_PAUSE: key = Key_Pause; unicode = 0; break;
278  case WXK_PAGEUP: key = Key_PageUp; unicode = 0; break;
279  case WXK_PAGEDOWN: key = Key_PageDown; unicode = 0; break;
280  case WXK_LEFT: key = Key_Left; unicode = 0; break;
281  case WXK_RIGHT: key = Key_Right; unicode = 0; break;
282  case WXK_UP: key = Key_Up; unicode = 0; break;
283  case WXK_DOWN: key = Key_Down; unicode = 0; break;
284  case WXK_F1: key = Key_F1; unicode = 0; break;
285  case WXK_F2: key = Key_F2; unicode = 0; break;
286  case WXK_F3: key = Key_F3; unicode = 0; break;
287  case WXK_F4: key = Key_F4; unicode = 0; break;
288  case WXK_F5: key = Key_F5; unicode = 0; break;
289  case WXK_F6: key = Key_F6; unicode = 0; break;
290  case WXK_F7: key = Key_F7; unicode = 0; break;
291  case WXK_F8: key = Key_F8; unicode = 0; break;
292  case WXK_F9: key = Key_F9; unicode = 0; break;
293  case WXK_F10: key = Key_F10; unicode = 0; break;
294  case WXK_F11: key = Key_F11; unicode = 0; break;
295  case WXK_F12: key = Key_F12; unicode = 0; break;
296  }
297 }
298 //-----------------------------------------------------------------------------
299 /*void WXGLCanvas::OnChar(wxKeyEvent& ev)
300 {
301  printf("key = %d, %d\n", (int)ev.GetKeyCode(), (int)ev.GetUnicodeKey() );
302 }*/
303 //-----------------------------------------------------------------------------
304 void WXGLCanvas::OnKeyDown( wxKeyEvent& ev )
305 {
306  /*printf("key = %d, %d\n", (int)ev.GetKeyCode(), (int)ev.GetUnicodeKey() );*/
307  int unicode = 0;
308  EKey key = Key_Unknown;
309  translateKey(unicode, key, ev);
310  dispatchKeyPressEvent(unicode,key);
311  ev.Skip();
312 }
313 //-----------------------------------------------------------------------------
314 void WXGLCanvas::OnKeyUp( wxKeyEvent& ev )
315 {
316  int unicode = 0;
317  EKey key = Key_Unknown;
318  translateKey(unicode, key, ev);
319  dispatchKeyReleaseEvent(unicode,key);
320  ev.Skip();
321 }
322 //-----------------------------------------------------------------------------
323 void WXGLCanvas::OnPaint( wxPaintEvent& )
324 {
325  // validate dirty client area
326  wxPaintDC dc(this);
327 
328  dispatchUpdateEvent();
329 
330  // for debugging purposes only
331  #if 0
332  makeCurrent();
333  float r = rand()%100 / 100.0f;
334  float g = rand()%100 / 100.0f;
335  float b = rand()%100 / 100.0f;
336  float a = rand()%100 / 100.0f;
337  glClearColor(r,g,b,a);
338  glClear(GL_COLOR_BUFFER_BIT);
339  swapBuffers();
340  #endif
341 }
342 //-----------------------------------------------------------------------------
343 void WXGLCanvas::OnEraseBackground(wxEraseEvent&)
344 {
345  // Do nothing, to avoid flashing.
346 }
347 //-----------------------------------------------------------------------------
348 bool WXGLCanvas::setFullscreen(bool fullscreen)
349 {
350  wxWindow* win = this;
351  while(win->GetParent())
352  {
353  win = win->GetParent();
354  wxTopLevelWindowBase* win_base = dynamic_cast<wxTopLevelWindowBase*>(win);
355  if (win_base)
356  {
357  win_base->ShowFullScreen(fullscreen, wxFULLSCREEN_ALL);
358  break;
359  }
360  }
361  mFullscreen = fullscreen;
362  return true;
363 }
364 //-----------------------------------------------------------------------------
366 {
367  wxApp* app = dynamic_cast<wxApp*>(wxApp::GetInstance());
368  if ( app )
369  {
370  app->ExitMainLoop();
371  }
372  eraseAllEventListeners();
373 }
374 //-----------------------------------------------------------------------------
376 {
377  if ( getWXGLContext() ) {
378  getWXGLContext()->SetCurrent( *this );
379  }
380 }
381 //-----------------------------------------------------------------------------
383 {
384  wxGLCanvas::SwapBuffers();
385 }
386 //-----------------------------------------------------------------------------
388 {
389  wxGLCanvas::SetFocus();
390 }
391 //-----------------------------------------------------------------------------
393 {
394  WarpPointer(x,y);
395 }
396 //-----------------------------------------------------------------------------
398 {
399  Refresh(false);
400 }
401 //-----------------------------------------------------------------------------
403 {
404  wxWindow* win = this;
405  while(win->GetParent())
406  win = win->GetParent();
407  #ifdef wxUSE_UNICODE
408  win->SetLabel(text.toStdWString().c_str());
409  #else
410  win->SetLabel(text.toStdString().c_str());
411  #endif
412 }
413 //-----------------------------------------------------------------------------
415 {
416  Show(true);
417 }
418 //-----------------------------------------------------------------------------
420 {
421  Show(false);
422 }
423 //-----------------------------------------------------------------------------
424 void WXGLCanvas::setPosition(int x, int y)
425 {
426  SetPosition(wxPoint(x,y));
427 }
428 
429 void WXGLCanvas::setSize(int w, int h)
430 {
431  SetClientSize(w,h);
432 }
433 //-----------------------------------------------------------------------------
435 {
436  wxPoint pt = GetPosition();
437  return ivec2(pt.x, pt.y);
438 }
439 //-----------------------------------------------------------------------------
441 {
442  wxSize s = GetClientSize();
443  return ivec2(s.GetWidth(), s.GetHeight());
444 }
445 //-----------------------------------------------------------------------------
446 void WXGLCanvas::setMouseVisible(bool visible)
447 {
448  if (mouseVisible() && !visible)
449  {
450  mCursor = GetCursor();
451  // of course this one does not work...
452  // SetCursor( wxCursor( wxCURSOR_BLANK ) );
453 
454  // not working either
455  // char bits[] = { 0xFF };
456  // char mask[] = { 0x00 };
457  // SetCursor( wxCursor(bits,1,1,-1,-1,mask) );
458 
459  // this seems to be the most portable
460  wxImage image(8,8);
461  image.SetRGB( wxRect(0,0,8,8), 255,255,255 );
462  image.SetMaskColour(255, 255, 255);
463  image.SetMask(true);
464  wxCursor cursor(image);
465  SetCursor(cursor);
466  }
467 
468  if (!mouseVisible() && visible)
469  {
470  SetCursor( mCursor );
471  }
472 
473  mMouseVisible = visible;
474 }
475 //-----------------------------------------------------------------------------
void swapBuffers()
Swaps the back and front buffers to present the last rendering.
Definition: WXGLCanvas.cpp:382
Vector2< int > ivec2
A 2 components vector with int precision.
Definition: Vector2.hpp:279
void OnIdle(wxIdleEvent &ev)
Definition: WXGLCanvas.cpp:102
void setMousePosition(int x, int y)
If the OpenGL context is a widget this function sets the mouse position.
Definition: WXGLCanvas.cpp:392
vl::ivec2 size() const
Definition: WXGLCanvas.cpp:440
std::wstring toStdWString() const
Returns the std::wstring representation of a String.
Definition: String.cpp:1144
void OnKeyDown(wxKeyEvent &ev)
Definition: WXGLCanvas.cpp:304
The String class implements an advanced UTF16 (Unicode BMP) string manipulation engine.
Definition: String.hpp:62
void OnEraseBackground(wxEraseEvent &ev)
Definition: WXGLCanvas.cpp:343
void quitApplication()
Asks to the windowing system that is managing the OpenGLContext to quit the application.
Definition: WXGLCanvas.cpp:365
Visualization Library main namespace.
void translateKey(int &unicode, EKey &key, const wxKeyEvent &ev)
Definition: WXGLCanvas.cpp:172
void setSize(int w, int h)
If the OpenGL context is a widget this function sets its size.
Definition: WXGLCanvas.cpp:429
void update()
If the OpenGLContext is a widget this function requests a redraw and generates an updateEvent()...
Definition: WXGLCanvas.cpp:397
void OnMouseUp(wxMouseEvent &ev)
Definition: WXGLCanvas.cpp:126
void setWindowTitle(const vl::String &text)
If the OpenGL context is a top window this function sets its title.
Definition: WXGLCanvas.cpp:402
#define NULL
Definition: OpenGLDefs.hpp:81
void OnKeyUp(wxKeyEvent &ev)
Definition: WXGLCanvas.cpp:314
void setMouseVisible(bool visible)
If the OpenGL context is a widget this function sets whether the mouse is visible over it or not...
Definition: WXGLCanvas.cpp:446
The wxWidgets bindings namespace.
void OnMouseWheel(wxMouseEvent &ev)
Definition: WXGLCanvas.cpp:120
void OnMouseEnter(wxMouseEvent &ev)
Definition: WXGLCanvas.cpp:110
void OnMouseMotion(wxMouseEvent &ev)
Definition: WXGLCanvas.cpp:115
vl::ivec2 position() const
If the OpenGL context is a widget this function returns its position.
Definition: WXGLCanvas.cpp:434
void show()
If the OpenGL context is a widget this function makes it visible to the user.
Definition: WXGLCanvas.cpp:414
The WXGLCanvas class implements a vl::OpenGLContext using the wxWidgets library.
Definition: WXGLCanvas.hpp:52
void OnMouseDown(wxMouseEvent &ev)
Definition: WXGLCanvas.cpp:145
void makeCurrent()
Sets the OpenGL context as current for the calling thread.
Definition: WXGLCanvas.cpp:375
std::string toStdString() const
Returns a UTF8 encoded std::string.
Definition: String.cpp:1156
void setPosition(int x, int y)
If the OpenGL context is a widget this function sets its position.
Definition: WXGLCanvas.cpp:424
void hide()
If the OpenGL context is a widget this function makes it invisible to the user.
Definition: WXGLCanvas.cpp:419
void OnPaint(wxPaintEvent &ev)
Definition: WXGLCanvas.cpp:323
#define VL_CHECK(expr)
Definition: checks.hpp:73
void getFocus()
If the OpenGL context is a widget this function requests the mouse focus on it.
Definition: WXGLCanvas.cpp:387
void OnDropFiles(wxDropFilesEvent &ev)
Definition: WXGLCanvas.cpp:90
bool setFullscreen(bool fullscreen)
If the OpenGL context is a widget this function requests a maximization to fullscreen.
Definition: WXGLCanvas.cpp:348
void OnSize(wxSizeEvent &ev)
Definition: WXGLCanvas.cpp:164