Visualization Library 2.0.0

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-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 #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  if ( info.majVersion() ) {
119  fmt.setVersion( info.majVersion(), info.minVersion() );
120  }
121  break;
122  case vl::GLP_Core:
123  fmt.setProfile( QGLFormat::CoreProfile );
124  if ( info.majVersion() ) {
125  fmt.setVersion( info.majVersion(), info.minVersion() );
126  }
127  break;
128  case vl::GLP_Default:
129  // Don't care
130  break;
131  }
132  #endif
133 
134  // double buffer
135  fmt.setDoubleBuffer( info.doubleBuffer() );
136 
137  // color buffer
138  fmt.setRedBufferSize( info.rgbaBits().r() );
139  fmt.setGreenBufferSize( info.rgbaBits().g() );
140  fmt.setBlueBufferSize( info.rgbaBits().b() );
141  // setAlpha == true makes the create() function alway fail
142  // even if the returned format has the requested alpha channel
143  fmt.setAlphaBufferSize( info.rgbaBits().a() );
144  fmt.setAlpha( info.rgbaBits().a() != 0 );
145 
146  // accumulation buffer
147  int accum = vl::max( info.accumRGBABits().r(), info.accumRGBABits().g() );
148  accum = vl::max( accum, info.accumRGBABits().b() );
149  accum = vl::max( accum, info.accumRGBABits().a() );
150  fmt.setAccumBufferSize( accum );
151  fmt.setAccum( accum != 0 );
152 
153  // multisampling
154  if (info.multisample())
155  fmt.setSamples( info.multisampleSamples() );
156  fmt.setSampleBuffers( info.multisample() );
157 
158  // depth buffer
159  fmt.setDepthBufferSize( info.depthBufferBits() );
160  fmt.setDepth( info.depthBufferBits() != 0 );
161 
162  // stencil buffer
163  fmt.setStencilBufferSize( info.stencilBufferBits() );
164  fmt.setStencil( info.stencilBufferBits() != 0 );
165 
166  // stereo
167  fmt.setStereo( info.stereo() );
168 
169  // swap interval / v-sync
170  fmt.setSwapInterval( info.vSync() ? 1 : 0 );
171 
172  glctx->setFormat(fmt);
173  // this function returns false when we request an alpha buffer
174  // even if the created context seem to have the alpha buffer
175  /*bool ok = */glctx->create(shareContext);
176  setContext(glctx);
177 
178  framebuffer()->setWidth(width);
179  framebuffer()->setHeight(height);
180 
181  #ifndef NDEBUG
182  printf("--------------------------------------------\n");
183  printf("REQUESTED OpenGL Format:\n");
184  printf("--------------------------------------------\n");
185  printf("rgba = %d %d %d %d\n", fmt.redBufferSize(), fmt.greenBufferSize(), fmt.blueBufferSize(), fmt.alphaBufferSize() );
186  printf("double buffer = %d\n", (int)fmt.doubleBuffer() );
187  printf("depth buffer size = %d\n", fmt.depthBufferSize() );
188  printf("depth buffer = %d\n", fmt.depth() );
189  printf("stencil buffer size = %d\n", fmt.stencilBufferSize() );
190  printf("stencil buffer = %d\n", fmt.stencil() );
191  printf("accum buffer size %d\n", fmt.accumBufferSize() );
192  printf("accum buffer %d\n", fmt.accum() );
193  printf("stereo = %d\n", (int)fmt.stereo() );
194  printf("swap interval = %d\n", fmt.swapInterval() );
195  printf("multisample = %d\n", (int)fmt.sampleBuffers() );
196  printf("multisample samples = %d\n", (int)fmt.samples() );
197 
198  fmt = format();
199 
200  printf("--------------------------------------------\n");
201  printf("OBTAINED OpenGL Format:\n");
202  printf("--------------------------------------------\n");
203  printf("rgba = %d %d %d %d\n", fmt.redBufferSize(), fmt.greenBufferSize(), fmt.blueBufferSize(), fmt.alphaBufferSize() );
204  printf("double buffer = %d\n", (int)fmt.doubleBuffer() );
205  printf("depth buffer size = %d\n", fmt.depthBufferSize() );
206  printf("depth buffer = %d\n", fmt.depth() );
207  printf("stencil buffer size = %d\n", fmt.stencilBufferSize() );
208  printf("stencil buffer = %d\n", fmt.stencil() );
209  printf("accum buffer size %d\n", fmt.accumBufferSize() );
210  printf("accum buffer %d\n", fmt.accum() );
211  printf("stereo = %d\n", (int)fmt.stereo() );
212  printf("swap interval = %d\n", fmt.swapInterval() );
213  printf("multisample = %d\n", (int)fmt.sampleBuffers() );
214  printf("multisample samples = %d\n", (int)fmt.samples() );
215  printf("--------------------------------------------\n");
216  #endif
217 
218  setWindowTitle(title);
219  move(x,y);
220  resize(width,height);
221 
222  if (info.fullscreen())
223  setFullscreen(true);
224 
225  return true;
226  }
227 
228  virtual void setContinuousUpdate(bool continuous)
229  {
230  mContinuousUpdate = continuous;
231  if (continuous)
232  {
233  disconnect(&mUpdateTimer, SIGNAL(timeout()), this, SLOT(updateGL()));
234  connect(&mUpdateTimer, SIGNAL(timeout()), this, SLOT(updateGL()));
235  mUpdateTimer.setSingleShot(false);
236  mUpdateTimer.setInterval(mRefresh);
237  mUpdateTimer.start(0);
238  }
239  else
240  {
241  disconnect(&mUpdateTimer, SIGNAL(timeout()), this, SLOT(updateGL()));
242  mUpdateTimer.stop();
243  }
244  }
245 
246  void setRefreshRate( int msec )
247  {
248  mRefresh = msec;
249  mUpdateTimer.setInterval(mRefresh);
250  }
251 
253  {
254  return mRefresh;
255  }
256 
258  {
259  // OpenGL extensions initialization
260  initGLContext();
261 
262  dispatchInitEvent();
263  }
264 
265  void resizeGL(int width, int height)
266  {
267  dispatchResizeEvent(width, height);
268  }
269 
270  void paintGL()
271  {
272  dispatchUpdateEvent();
273  }
274 
275  void update()
276  {
277  QGLWidget::update();
278  // QGLWidget::updateGL();
279  }
280 
281  virtual void setWindowTitle(const vl::String& title)
282  {
283  QGLWidget::setWindowTitle( QString::fromStdString(title.toStdString()) );
284  }
285 
286  virtual bool setFullscreen(bool fullscreen)
287  {
288  mFullscreen = fullscreen;
289  if (fullscreen)
290  QGLWidget::setWindowState(QGLWidget::windowState() | Qt::WindowFullScreen);
291  else
292  QGLWidget::setWindowState(QGLWidget::windowState() & (~Qt::WindowFullScreen));
293  return true;
294  }
295 
296  virtual void quitApplication()
297  {
298  eraseAllEventListeners();
299  QApplication::quit();
300  }
301 
302  virtual void show()
303  {
304  QGLWidget::show();
305  }
306 
307  virtual void hide()
308  {
309  QGLWidget::hide();
310  }
311 
312  virtual void setPosition(int x, int y)
313  {
314  QGLWidget::move(x,y);
315  }
316 
317  virtual vl::ivec2 position() const
318  {
319  return vl::ivec2(QGLWidget::pos().x(), QGLWidget::pos().y());
320  }
321 
322  virtual void setSize(int w, int h)
323  {
324  // this already excludes the window's frame so it's ok for Visualization Library standards
325  QGLWidget::resize(w,h);
326  }
327 
328  virtual vl::ivec2 size() const
329  {
330  // this already excludes the window's frame so it's ok for Visualization Library standards
331  return vl::ivec2(QGLWidget::size().width(), QGLWidget::size().height());
332  }
333 
334  void swapBuffers()
335  {
336  QGLWidget::swapBuffers();
337  }
338 
339  void makeCurrent()
340  {
341  QGLWidget::makeCurrent();
342  }
343 
344  void setMousePosition(int x, int y)
345  {
346  QCursor::setPos( mapToGlobal(QPoint(x,y)) );
347  }
348 
349  void mouseMoveEvent(QMouseEvent* ev)
350  {
351  if (!mIgnoreNextMouseMoveEvent)
352  dispatchMouseMoveEvent(ev->x(), ev->y());
353  mIgnoreNextMouseMoveEvent = false;
354  }
355 
356  void mousePressEvent(QMouseEvent* ev)
357  {
359  switch(ev->button())
360  {
361  case Qt::LeftButton: bt = vl::LeftButton; break;
362  case Qt::RightButton: bt = vl::RightButton; break;
363  case Qt::MidButton: bt = vl::MiddleButton; break;
364  default:
365  bt = vl::UnknownButton; break;
366  }
367  dispatchMouseDownEvent(bt, ev->x(), ev->y());
368  }
369 
370  void mouseReleaseEvent(QMouseEvent* ev)
371  {
373  switch(ev->button())
374  {
375  case Qt::LeftButton: bt = vl::LeftButton; break;
376  case Qt::RightButton: bt = vl::RightButton; break;
377  case Qt::MidButton: bt = vl::MiddleButton; break;
378  default:
379  bt = vl::UnknownButton; break;
380  }
381  dispatchMouseUpEvent(bt, ev->x(), ev->y());
382  }
383 
384  void wheelEvent(QWheelEvent* ev)
385  {
386  dispatchMouseWheelEvent(ev->delta() / 120);
387  }
388 
389  void keyPressEvent(QKeyEvent* ev)
390  {
391  unsigned short unicode_ch = 0;
392  vl::EKey key = vl::Key_None;
393  translateKeyEvent(ev, unicode_ch, key);
394  dispatchKeyPressEvent(unicode_ch, key);
395  }
396 
397  void keyReleaseEvent(QKeyEvent* ev)
398  {
399  unsigned short unicode_ch = 0;
400  vl::EKey key = vl::Key_None;
401  translateKeyEvent(ev, unicode_ch, key);
402  dispatchKeyReleaseEvent(unicode_ch, key);
403  }
404 
405  virtual void setMouseVisible(bool visible)
406  {
407  mMouseVisible=visible;
408  if (visible)
409  QGLWidget::setCursor(Qt::ArrowCursor);
410  else
411  QGLWidget::setCursor(Qt::BlankCursor);
412  }
413 
414  virtual void getFocus()
415  {
416  QGLWidget::setFocus(Qt::OtherFocusReason);
417  }
418 
419  protected:
420  void translateKeyEvent(QKeyEvent* ev, unsigned short& unicode_out, vl::EKey& key_out);
421 
422  protected:
423  int mRefresh;
424  QTimer mUpdateTimer;
425  };
426  //-----------------------------------------------------------------------------
427 }
428 
429 #endif
void resizeGL(int width, int height)
Definition: Qt4Widget.hpp:265
virtual vl::ivec2 position() const
If the OpenGL context is a widget this function returns its position.
Definition: Qt4Widget.hpp:317
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:334
void keyReleaseEvent(QKeyEvent *ev)
Definition: Qt4Widget.hpp:397
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:307
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:328
virtual void show()
If the OpenGL context is a widget this function makes it visible to the user.
Definition: Qt4Widget.hpp:302
virtual void getFocus()
If the OpenGL context is a widget this function requests the mouse focus on it.
Definition: Qt4Widget.hpp:414
void wheelEvent(QWheelEvent *ev)
Definition: Qt4Widget.hpp:384
void makeCurrent()
Sets the OpenGL context as current for the calling thread.
Definition: Qt4Widget.hpp:339
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:322
virtual void setPosition(int x, int y)
If the OpenGL context is a widget this function sets its position.
Definition: Qt4Widget.hpp:312
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:281
float max(float a, float b)
Definition: Vector2.hpp:311
const ivec4 & accumRGBABits() const
void keyPressEvent(QKeyEvent *ev)
Definition: Qt4Widget.hpp:389
void dropEvent(QDropEvent *ev)
Definition: Qt4Widget.hpp:84
The Qt4 bindings namespace.
EMouseButton
void setRefreshRate(int msec)
Definition: Qt4Widget.hpp:246
virtual bool setFullscreen(bool fullscreen)
If the OpenGL context is a widget this function requests a maximization to fullscreen.
Definition: Qt4Widget.hpp:286
void setMousePosition(int x, int y)
If the OpenGL context is a widget this function sets the mouse position.
Definition: Qt4Widget.hpp:344
const T_Scalar & b() const
Definition: Vector4.hpp:113
#define NULL
Definition: OpenGLDefs.hpp:81
void mouseMoveEvent(QMouseEvent *ev)
Definition: Qt4Widget.hpp:349
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:275
void mouseReleaseEvent(QMouseEvent *ev)
Definition: Qt4Widget.hpp:370
void mousePressEvent(QMouseEvent *ev)
Definition: Qt4Widget.hpp:356
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:405
virtual void quitApplication()
Asks to the windowing system that is managing the OpenGLContext to quit the application.
Definition: Qt4Widget.hpp:296
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:228