Visualization Library 2.0.0-b3

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

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
Qt4Widget.hpp
Go to the documentation of this file.
1 /**************************************************************************************/
2 /* */
3 /* Visualization Library */
4 /* http://visualizationlibrary.org */
5 /* */
6 /* Copyright (c) 2005-2017, 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 #ifndef Qt4Window_INCLUDE_ONCE
33 #define Qt4Window_INCLUDE_ONCE
34 
35 #include <vlQt4/link_config.hpp>
38 #include <QtGui/QApplication>
39 #include <QtGui/QMouseEvent>
40 #include <QtGui/QWidget>
41 #include <QtCore/QUrl>
42 #include <QtCore/QTimer>
43 #include <QtCore/QObject>
44 #include <QtOpenGL/QGLWidget>
45 #include <QtOpenGL/QGLFormat>
46 
47 namespace vlQt4
48 {
49 //-----------------------------------------------------------------------------
50 // Qt4Widget
51 //-----------------------------------------------------------------------------
53  class VLQT4_EXPORT Qt4Widget : public QGLWidget, public vl::OpenGLContext
54  {
55  Q_OBJECT
56 
57  public:
59  using QObject::setObjectName;
60 
61  Qt4Widget(QWidget* parent=NULL, const QGLWidget* shareWidget=NULL, Qt::WindowFlags f=0)
62  :QGLWidget(parent,shareWidget,f),
63  mRefresh(10) // 100 fps
64  {
65  setContinuousUpdate(true);
66  setMouseTracking(true);
67  setAutoBufferSwap(false);
68  setAcceptDrops(true);
69  // let Qt take care of object destruction.
71  }
72 
74  {
75  dispatchDestroyEvent();
76  }
77 
78  void dragEnterEvent(QDragEnterEvent *ev)
79  {
80  if (ev->mimeData()->hasUrls())
81  ev->acceptProposedAction();
82  }
83 
84  void dropEvent(QDropEvent* ev)
85  {
86  if ( ev->mimeData()->hasUrls() )
87  {
88  std::vector<vl::String> files;
89  QList<QUrl> list = ev->mimeData()->urls();
90  for(int i=0; i<list.size(); ++i)
91  {
92  if (list[i].path().isEmpty())
93  continue;
94  #ifdef WIN32
95  if (list[i].path()[0] == '/')
96  files.push_back( list[i].path().toStdString().c_str()+1 );
97  else
98  files.push_back( list[i].path().toStdString().c_str() );
99  #else
100  files.push_back( list[i].path().toStdString().c_str() );
101  #endif
102  }
103  dispatchFileDroppedEvent(files);
104  }
105  }
106 
107  bool initQt4Widget(const vl::String& title, const vl::OpenGLContextFormat& info, const QGLContext* shareContext=0, int x=0, int y=0, int width=640, int height=480)
108  {
109  // setFormat(fmt) is marked as deprecated so we use this other method
110  QGLContext* glctx = new QGLContext(context()->format(), this);
111  QGLFormat fmt = context()->format();
112 
113  #if QT_VERSION >= 0x040700
114  switch( info.openGLProfile() )
115  {
117  fmt.setProfile( QGLFormat::CompatibilityProfile );
118  fmt.setVersion( info.majVersion(), info.minVersion() );
119  break;
120  case vl::GLP_Core:
121  fmt.setProfile( QGLFormat::CoreProfile );
122  fmt.setVersion( info.majVersion(), info.minVersion() );
123  break;
124  case vl::GLP_Default:
125  // Don't care
126  break;
127  }
128  #endif
129 
130  // double buffer
131  fmt.setDoubleBuffer( info.doubleBuffer() );
132 
133  // color buffer
134  fmt.setRedBufferSize( info.rgbaBits().r() );
135  fmt.setGreenBufferSize( info.rgbaBits().g() );
136  fmt.setBlueBufferSize( info.rgbaBits().b() );
137  // setAlpha == true makes the create() function alway fail
138  // even if the returned format has the requested alpha channel
139  fmt.setAlphaBufferSize( info.rgbaBits().a() );
140  fmt.setAlpha( info.rgbaBits().a() != 0 );
141 
142  // accumulation buffer
143  int accum = vl::max( info.accumRGBABits().r(), info.accumRGBABits().g() );
144  accum = vl::max( accum, info.accumRGBABits().b() );
145  accum = vl::max( accum, info.accumRGBABits().a() );
146  fmt.setAccumBufferSize( accum );
147  fmt.setAccum( accum != 0 );
148 
149  // multisampling
150  if (info.multisample())
151  fmt.setSamples( info.multisampleSamples() );
152  fmt.setSampleBuffers( info.multisample() );
153 
154  // depth buffer
155  fmt.setDepthBufferSize( info.depthBufferBits() );
156  fmt.setDepth( info.depthBufferBits() != 0 );
157 
158  // stencil buffer
159  fmt.setStencilBufferSize( info.stencilBufferBits() );
160  fmt.setStencil( info.stencilBufferBits() != 0 );
161 
162  // stereo
163  fmt.setStereo( info.stereo() );
164 
165  // swap interval / v-sync
166  fmt.setSwapInterval( info.vSync() ? 1 : 0 );
167 
168  glctx->setFormat(fmt);
169  // this function returns false when we request an alpha buffer
170  // even if the created context seem to have the alpha buffer
171  /*bool ok = */glctx->create(shareContext);
172  setContext(glctx);
173 
174  framebuffer()->setWidth(width);
175  framebuffer()->setHeight(height);
176 
177  #ifndef NDEBUG
178  printf("--------------------------------------------\n");
179  printf("REQUESTED OpenGL Format:\n");
180  printf("--------------------------------------------\n");
181  printf("rgba = %d %d %d %d\n", fmt.redBufferSize(), fmt.greenBufferSize(), fmt.blueBufferSize(), fmt.alphaBufferSize() );
182  printf("double buffer = %d\n", (int)fmt.doubleBuffer() );
183  printf("depth buffer size = %d\n", fmt.depthBufferSize() );
184  printf("depth buffer = %d\n", fmt.depth() );
185  printf("stencil buffer size = %d\n", fmt.stencilBufferSize() );
186  printf("stencil buffer = %d\n", fmt.stencil() );
187  printf("accum buffer size %d\n", fmt.accumBufferSize() );
188  printf("accum buffer %d\n", fmt.accum() );
189  printf("stereo = %d\n", (int)fmt.stereo() );
190  printf("swap interval = %d\n", fmt.swapInterval() );
191  printf("multisample = %d\n", (int)fmt.sampleBuffers() );
192  printf("multisample samples = %d\n", (int)fmt.samples() );
193 
194  fmt = format();
195 
196  printf("--------------------------------------------\n");
197  printf("OBTAINED OpenGL Format:\n");
198  printf("--------------------------------------------\n");
199  printf("rgba = %d %d %d %d\n", fmt.redBufferSize(), fmt.greenBufferSize(), fmt.blueBufferSize(), fmt.alphaBufferSize() );
200  printf("double buffer = %d\n", (int)fmt.doubleBuffer() );
201  printf("depth buffer size = %d\n", fmt.depthBufferSize() );
202  printf("depth buffer = %d\n", fmt.depth() );
203  printf("stencil buffer size = %d\n", fmt.stencilBufferSize() );
204  printf("stencil buffer = %d\n", fmt.stencil() );
205  printf("accum buffer size %d\n", fmt.accumBufferSize() );
206  printf("accum buffer %d\n", fmt.accum() );
207  printf("stereo = %d\n", (int)fmt.stereo() );
208  printf("swap interval = %d\n", fmt.swapInterval() );
209  printf("multisample = %d\n", (int)fmt.sampleBuffers() );
210  printf("multisample samples = %d\n", (int)fmt.samples() );
211  printf("--------------------------------------------\n");
212  #endif
213 
214  setWindowTitle(title);
215  move(x,y);
216  resize(width,height);
217 
218  if (info.fullscreen())
219  setFullscreen(true);
220 
221  return true;
222  }
223 
224  virtual void setContinuousUpdate(bool continuous)
225  {
226  mContinuousUpdate = continuous;
227  if (continuous)
228  {
229  disconnect(&mUpdateTimer, SIGNAL(timeout()), this, SLOT(updateGL()));
230  connect(&mUpdateTimer, SIGNAL(timeout()), this, SLOT(updateGL()));
231  mUpdateTimer.setSingleShot(false);
232  mUpdateTimer.setInterval(mRefresh);
233  mUpdateTimer.start(0);
234  }
235  else
236  {
237  disconnect(&mUpdateTimer, SIGNAL(timeout()), this, SLOT(updateGL()));
238  mUpdateTimer.stop();
239  }
240  }
241 
242  void setRefreshRate( int msec )
243  {
244  mRefresh = msec;
245  mUpdateTimer.setInterval(mRefresh);
246  }
247 
249  {
250  return mRefresh;
251  }
252 
254  {
255  // OpenGL extensions initialization
256  initGLContext();
257 
258  dispatchInitEvent();
259  }
260 
261  void resizeGL(int width, int height)
262  {
263  dispatchResizeEvent(width, height);
264  }
265 
266  void paintGL()
267  {
268  dispatchUpdateEvent();
269  }
270 
271  void update()
272  {
273  QGLWidget::update();
274  // QGLWidget::updateGL();
275  }
276 
277  virtual void setWindowTitle(const vl::String& title)
278  {
279  QGLWidget::setWindowTitle( QString::fromStdString(title.toStdString()) );
280  }
281 
282  virtual bool setFullscreen(bool fullscreen)
283  {
284  mFullscreen = fullscreen;
285  if (fullscreen)
286  QGLWidget::setWindowState(QGLWidget::windowState() | Qt::WindowFullScreen);
287  else
288  QGLWidget::setWindowState(QGLWidget::windowState() & (~Qt::WindowFullScreen));
289  return true;
290  }
291 
292  virtual void quitApplication()
293  {
294  eraseAllEventListeners();
295  QApplication::quit();
296  }
297 
298  virtual void show()
299  {
300  QGLWidget::show();
301  }
302 
303  virtual void hide()
304  {
305  QGLWidget::hide();
306  }
307 
308  virtual void setPosition(int x, int y)
309  {
310  QGLWidget::move(x,y);
311  }
312 
313  virtual vl::ivec2 position() const
314  {
315  return vl::ivec2(QGLWidget::pos().x(), QGLWidget::pos().y());
316  }
317 
318  virtual void setSize(int w, int h)
319  {
320  // this already excludes the window's frame so it's ok for Visualization Library standards
321  QGLWidget::resize(w,h);
322  }
323 
324  virtual vl::ivec2 size() const
325  {
326  // this already excludes the window's frame so it's ok for Visualization Library standards
327  return vl::ivec2(QGLWidget::size().width(), QGLWidget::size().height());
328  }
329 
330  void swapBuffers()
331  {
332  QGLWidget::swapBuffers();
333  }
334 
335  void makeCurrent()
336  {
337  QGLWidget::makeCurrent();
338  }
339 
340  void setMousePosition(int x, int y)
341  {
342  QCursor::setPos( mapToGlobal(QPoint(x,y)) );
343  }
344 
345  void mouseMoveEvent(QMouseEvent* ev)
346  {
347  if (!mIgnoreNextMouseMoveEvent)
348  dispatchMouseMoveEvent(ev->x(), ev->y());
349  mIgnoreNextMouseMoveEvent = false;
350  }
351 
352  void mousePressEvent(QMouseEvent* ev)
353  {
355  switch(ev->button())
356  {
357  case Qt::LeftButton: bt = vl::LeftButton; break;
358  case Qt::RightButton: bt = vl::RightButton; break;
359  case Qt::MidButton: bt = vl::MiddleButton; break;
360  default:
361  bt = vl::UnknownButton; break;
362  }
363  dispatchMouseDownEvent(bt, ev->x(), ev->y());
364  }
365 
366  void mouseReleaseEvent(QMouseEvent* ev)
367  {
369  switch(ev->button())
370  {
371  case Qt::LeftButton: bt = vl::LeftButton; break;
372  case Qt::RightButton: bt = vl::RightButton; break;
373  case Qt::MidButton: bt = vl::MiddleButton; break;
374  default:
375  bt = vl::UnknownButton; break;
376  }
377  dispatchMouseUpEvent(bt, ev->x(), ev->y());
378  }
379 
380  void wheelEvent(QWheelEvent* ev)
381  {
382  dispatchMouseWheelEvent(ev->delta() / 120);
383  }
384 
385  void keyPressEvent(QKeyEvent* ev)
386  {
387  unsigned short unicode_ch = 0;
388  vl::EKey key = vl::Key_None;
389  translateKeyEvent(ev, unicode_ch, key);
390  dispatchKeyPressEvent(unicode_ch, key);
391  }
392 
393  void keyReleaseEvent(QKeyEvent* ev)
394  {
395  unsigned short unicode_ch = 0;
396  vl::EKey key = vl::Key_None;
397  translateKeyEvent(ev, unicode_ch, key);
398  dispatchKeyReleaseEvent(unicode_ch, key);
399  }
400 
401  virtual void setMouseVisible(bool visible)
402  {
403  mMouseVisible=visible;
404  if (visible)
405  QGLWidget::setCursor(Qt::ArrowCursor);
406  else
407  QGLWidget::setCursor(Qt::BlankCursor);
408  }
409 
410  virtual void getFocus()
411  {
412  QGLWidget::setFocus(Qt::OtherFocusReason);
413  }
414 
415  protected:
416  void translateKeyEvent(QKeyEvent* ev, unsigned short& unicode_out, vl::EKey& key_out);
417 
418  protected:
419  int mRefresh;
420  QTimer mUpdateTimer;
421  };
422  //-----------------------------------------------------------------------------
423 }
424 
425 #endif
void resizeGL(int width, int height)
Definition: Qt4Widget.hpp:261
virtual vl::ivec2 position() const
If the OpenGL context is a widget this function returns its position.
Definition: Qt4Widget.hpp:313
Vector2< int > ivec2
A 2 components vector with int precision.
Definition: Vector2.hpp:278
void dragEnterEvent(QDragEnterEvent *ev)
Definition: Qt4Widget.hpp:78
void setAutomaticDelete(bool autodel_on)
If set to true the Object is deleted when its reference count reaches 0.
Definition: Object.hpp:275
void swapBuffers()
Swaps the back and front buffers to present the last rendering.
Definition: Qt4Widget.hpp:330
void keyReleaseEvent(QKeyEvent *ev)
Definition: Qt4Widget.hpp:393
void setObjectName(const char *name)
The name of the object, by default set to the object&#39;s class name in debug builds.
Definition: Object.hpp:220
The Qt4Widget class implements an OpenGLContext using the Qt4 API.
Definition: Qt4Widget.hpp:53
The String class implements an advanced UTF16 (Unicode BMP) string manipulation engine.
Definition: String.hpp:62
int multisampleSamples() const
bool initQt4Widget(const vl::String &title, const vl::OpenGLContextFormat &info, const QGLContext *shareContext=0, int x=0, int y=0, int width=640, int height=480)
Definition: Qt4Widget.hpp:107
virtual void hide()
If the OpenGL context is a widget this function makes it invisible to the user.
Definition: Qt4Widget.hpp:303
const T_Scalar & r() const
Definition: Vector4.hpp:111
Represents an OpenGL context, possibly a widget or a pbuffer, which can also respond to keyboard...
virtual vl::ivec2 size() const
Definition: Qt4Widget.hpp:324
virtual void show()
If the OpenGL context is a widget this function makes it visible to the user.
Definition: Qt4Widget.hpp:298
virtual void getFocus()
If the OpenGL context is a widget this function requests the mouse focus on it.
Definition: Qt4Widget.hpp:410
void wheelEvent(QWheelEvent *ev)
Definition: Qt4Widget.hpp:380
void makeCurrent()
Sets the OpenGL context as current for the calling thread.
Definition: Qt4Widget.hpp:335
const T_Scalar & g() const
Definition: Vector4.hpp:112
The OpenGLContextFormat class encapsulates the settings of an OpenGL rendering context.
virtual void setSize(int w, int h)
If the OpenGL context is a widget this function sets its size.
Definition: Qt4Widget.hpp:318
virtual void setPosition(int x, int y)
If the OpenGL context is a widget this function sets its position.
Definition: Qt4Widget.hpp:308
const ivec4 & rgbaBits() const
virtual void setWindowTitle(const vl::String &title)
If the OpenGL context is a top window this function sets its title.
Definition: Qt4Widget.hpp:277
float max(float a, float b)
Definition: Vector2.hpp:311
const ivec4 & accumRGBABits() const
void keyPressEvent(QKeyEvent *ev)
Definition: Qt4Widget.hpp:385
void dropEvent(QDropEvent *ev)
Definition: Qt4Widget.hpp:84
The Qt4 bindings namespace.
EMouseButton
void setRefreshRate(int msec)
Definition: Qt4Widget.hpp:242
virtual bool setFullscreen(bool fullscreen)
If the OpenGL context is a widget this function requests a maximization to fullscreen.
Definition: Qt4Widget.hpp:282
void setMousePosition(int x, int y)
If the OpenGL context is a widget this function sets the mouse position.
Definition: Qt4Widget.hpp:340
const T_Scalar & b() const
Definition: Vector4.hpp:113
#define NULL
Definition: OpenGLDefs.hpp:81
void mouseMoveEvent(QMouseEvent *ev)
Definition: Qt4Widget.hpp:345
EOpenGLProfile openGLProfile() const
VLEGL_EXPORT void translateKeyEvent(WPARAM wParam, LPARAM lParam, unsigned short &unicode_out, vl::EKey &key_out)
Definition: EGLWindow.cpp:584
void update()
If the OpenGLContext is a widget this function requests a redraw and generates an updateEvent()...
Definition: Qt4Widget.hpp:271
void mouseReleaseEvent(QMouseEvent *ev)
Definition: Qt4Widget.hpp:366
void mousePressEvent(QMouseEvent *ev)
Definition: Qt4Widget.hpp:352
std::string toStdString() const
Returns a UTF8 encoded std::string.
Definition: String.cpp:1156
virtual void setMouseVisible(bool visible)
If the OpenGL context is a widget this function sets whether the mouse is visible over it or not...
Definition: Qt4Widget.hpp:401
virtual void quitApplication()
Asks to the windowing system that is managing the OpenGLContext to quit the application.
Definition: Qt4Widget.hpp:292
Qt4Widget(QWidget *parent=NULL, const QGLWidget *shareWidget=NULL, Qt::WindowFlags f=0)
Definition: Qt4Widget.hpp:61
const T_Scalar & a() const
Definition: Vector4.hpp:114
virtual void setContinuousUpdate(bool continuous)
If the OpenGL context is a widget this function sets whether its area is continuously updated at each...
Definition: Qt4Widget.hpp:224