00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef Qt5Window_INCLUDE_ONCE
00033 #define Qt5Window_INCLUDE_ONCE
00034
00035 #include <vlQt5/link_config.hpp>
00036 #include <vlCore/VisualizationLibrary.hpp>
00037 #include <vlGraphics/OpenGLContext.hpp>
00038 #include <QtWidgets/QApplication>
00039 #include <QtGui/QMouseEvent>
00040 #include <QtWidgets/QWidget>
00041 #include <QtCore/QUrl>
00042 #include <QtCore/QTimer>
00043 #include <QtCore/QObject>
00044 #include <QtCore/QMimeData>
00045 #include <QtOpenGL/QGLWidget>
00046 #include <QtOpenGL/QGLFormat>
00047
00048 namespace vlQt5
00049 {
00050
00051
00052
00054 class VLQT5_EXPORT Qt5Widget : public QGLWidget, public vl::OpenGLContext
00055 {
00056 Q_OBJECT
00057
00058 public:
00059 using vl::Object::setObjectName;
00060 using QObject::setObjectName;
00061
00062 Qt5Widget(QWidget* parent=NULL, const QGLWidget* shareWidget=NULL, Qt::WindowFlags f=0)
00063 :QGLWidget(parent,shareWidget,f),
00064 mRefresh(10)
00065 {
00066 setContinuousUpdate(true);
00067 setMouseTracking(true);
00068 setAutoBufferSwap(false);
00069 setAcceptDrops(true);
00070
00071 vl::OpenGLContext::setAutomaticDelete(false);
00072 }
00073
00074 ~Qt5Widget()
00075 {
00076 dispatchDestroyEvent();
00077 }
00078
00079 void dragEnterEvent(QDragEnterEvent *ev)
00080 {
00081 if (ev->mimeData()->hasUrls())
00082 ev->acceptProposedAction();
00083 }
00084
00085 void dropEvent(QDropEvent* ev)
00086 {
00087 if ( ev->mimeData()->hasUrls() )
00088 {
00089 std::vector<vl::String> files;
00090 QList<QUrl> list = ev->mimeData()->urls();
00091 for(int i=0; i<list.size(); ++i)
00092 {
00093 if (list[i].path().isEmpty())
00094 continue;
00095 #ifdef WIN32
00096 if (list[i].path()[0] == '/')
00097 files.push_back( list[i].path().toStdString().c_str()+1 );
00098 else
00099 files.push_back( list[i].path().toStdString().c_str() );
00100 #else
00101 files.push_back( list[i].path().toStdString().c_str() );
00102 #endif
00103 }
00104 dispatchFileDroppedEvent(files);
00105 }
00106 }
00107
00108 bool initQt5Widget(const vl::String& title, const vl::OpenGLContextFormat& info, const QGLContext* shareContext=0, int x=0, int y=0, int width=640, int height=480)
00109 {
00110
00111 QGLContext* glctx = new QGLContext(context()->format(), this);
00112 QGLFormat fmt = context()->format();
00113
00114
00115 fmt.setDoubleBuffer( info.doubleBuffer() );
00116
00117
00118 fmt.setRedBufferSize( info.rgbaBits().r() );
00119 fmt.setGreenBufferSize( info.rgbaBits().g() );
00120 fmt.setBlueBufferSize( info.rgbaBits().b() );
00121
00122
00123 fmt.setAlphaBufferSize( info.rgbaBits().a() );
00124 fmt.setAlpha( info.rgbaBits().a() != 0 );
00125
00126
00127 int accum = vl::max( info.accumRGBABits().r(), info.accumRGBABits().g() );
00128 accum = vl::max( accum, info.accumRGBABits().b() );
00129 accum = vl::max( accum, info.accumRGBABits().a() );
00130 fmt.setAccumBufferSize( accum );
00131 fmt.setAccum( accum != 0 );
00132
00133
00134 if (info.multisample())
00135 fmt.setSamples( info.multisampleSamples() );
00136 fmt.setSampleBuffers( info.multisample() );
00137
00138
00139 fmt.setDepthBufferSize( info.depthBufferBits() );
00140 fmt.setDepth( info.depthBufferBits() != 0 );
00141
00142
00143 fmt.setStencilBufferSize( info.stencilBufferBits() );
00144 fmt.setStencil( info.stencilBufferBits() != 0 );
00145
00146
00147 fmt.setStereo( info.stereo() );
00148
00149
00150 fmt.setSwapInterval( info.vSync() ? 1 : 0 );
00151
00152 glctx->setFormat(fmt);
00153
00154
00155 glctx->create(shareContext);
00156 setContext(glctx);
00157
00158 initGLContext();
00159
00160 framebuffer()->setWidth(width);
00161 framebuffer()->setHeight(height);
00162
00163 #ifndef NDEBUG
00164 printf("--------------------------------------------\n");
00165 printf("REQUESTED OpenGL Format:\n");
00166 printf("--------------------------------------------\n");
00167 printf("rgba = %d %d %d %d\n", fmt.redBufferSize(), fmt.greenBufferSize(), fmt.blueBufferSize(), fmt.alphaBufferSize() );
00168 printf("double buffer = %d\n", (int)fmt.doubleBuffer() );
00169 printf("depth buffer size = %d\n", fmt.depthBufferSize() );
00170 printf("depth buffer = %d\n", fmt.depth() );
00171 printf("stencil buffer size = %d\n", fmt.stencilBufferSize() );
00172 printf("stencil buffer = %d\n", fmt.stencil() );
00173 printf("accum buffer size %d\n", fmt.accumBufferSize() );
00174 printf("accum buffer %d\n", fmt.accum() );
00175 printf("stereo = %d\n", (int)fmt.stereo() );
00176 printf("swap interval = %d\n", fmt.swapInterval() );
00177 printf("multisample = %d\n", (int)fmt.sampleBuffers() );
00178 printf("multisample samples = %d\n", (int)fmt.samples() );
00179
00180 fmt = format();
00181
00182 printf("--------------------------------------------\n");
00183 printf("OBTAINED OpenGL Format:\n");
00184 printf("--------------------------------------------\n");
00185 printf("rgba = %d %d %d %d\n", fmt.redBufferSize(), fmt.greenBufferSize(), fmt.blueBufferSize(), fmt.alphaBufferSize() );
00186 printf("double buffer = %d\n", (int)fmt.doubleBuffer() );
00187 printf("depth buffer size = %d\n", fmt.depthBufferSize() );
00188 printf("depth buffer = %d\n", fmt.depth() );
00189 printf("stencil buffer size = %d\n", fmt.stencilBufferSize() );
00190 printf("stencil buffer = %d\n", fmt.stencil() );
00191 printf("accum buffer size %d\n", fmt.accumBufferSize() );
00192 printf("accum buffer %d\n", fmt.accum() );
00193 printf("stereo = %d\n", (int)fmt.stereo() );
00194 printf("swap interval = %d\n", fmt.swapInterval() );
00195 printf("multisample = %d\n", (int)fmt.sampleBuffers() );
00196 printf("multisample samples = %d\n", (int)fmt.samples() );
00197 printf("--------------------------------------------\n");
00198 #endif
00199
00200 setWindowTitle(title);
00201 move(x,y);
00202 resize(width,height);
00203
00204 if (info.fullscreen())
00205 setFullscreen(true);
00206
00207 return true;
00208 }
00209
00210 virtual void setContinuousUpdate(bool continuous)
00211 {
00212 mContinuousUpdate = continuous;
00213 if (continuous)
00214 {
00215 disconnect(&mUpdateTimer, SIGNAL(timeout()), this, SLOT(updateGL()));
00216 connect(&mUpdateTimer, SIGNAL(timeout()), this, SLOT(updateGL()));
00217 mUpdateTimer.setSingleShot(false);
00218 mUpdateTimer.setInterval(mRefresh);
00219 mUpdateTimer.start(0);
00220 }
00221 else
00222 {
00223 disconnect(&mUpdateTimer, SIGNAL(timeout()), this, SLOT(updateGL()));
00224 mUpdateTimer.stop();
00225 }
00226 }
00227
00228 void setRefreshRate( int msec )
00229 {
00230 mRefresh = msec;
00231 mUpdateTimer.setInterval(mRefresh);
00232 }
00233
00234 int refreshRate()
00235 {
00236 return mRefresh;
00237 }
00238
00239 void initializeGL()
00240 {
00241
00242 dispatchInitEvent();
00243 }
00244
00245 void resizeGL(int width, int height)
00246 {
00247 dispatchResizeEvent(width, height);
00248 }
00249
00250 void paintGL()
00251 {
00252 dispatchRunEvent();
00253 }
00254
00255 void update()
00256 {
00257 QGLWidget::update();
00258
00259 }
00260
00261 virtual void setWindowTitle(const vl::String& title)
00262 {
00263 QGLWidget::setWindowTitle( QString::fromStdString(title.toStdString()) );
00264 }
00265
00266 virtual bool setFullscreen(bool fullscreen)
00267 {
00268 mFullscreen = fullscreen;
00269 if (fullscreen)
00270 QGLWidget::setWindowState(QGLWidget::windowState() | Qt::WindowFullScreen);
00271 else
00272 QGLWidget::setWindowState(QGLWidget::windowState() & (~Qt::WindowFullScreen));
00273 return true;
00274 }
00275
00276 virtual void quitApplication()
00277 {
00278 eraseAllEventListeners();
00279 QApplication::quit();
00280 }
00281
00282 virtual void show()
00283 {
00284 QGLWidget::show();
00285 }
00286
00287 virtual void hide()
00288 {
00289 QGLWidget::hide();
00290 }
00291
00292 virtual void setPosition(int x, int y)
00293 {
00294 QGLWidget::move(x,y);
00295 }
00296
00297 virtual vl::ivec2 position() const
00298 {
00299 return vl::ivec2(QGLWidget::pos().x(), QGLWidget::pos().y());
00300 }
00301
00302 virtual void setSize(int w, int h)
00303 {
00304
00305 QGLWidget::resize(w,h);
00306 }
00307
00308 virtual vl::ivec2 size() const
00309 {
00310
00311 return vl::ivec2(QGLWidget::size().width(), QGLWidget::size().height());
00312 }
00313
00314 void swapBuffers()
00315 {
00316 QGLWidget::swapBuffers();
00317 }
00318
00319 void makeCurrent()
00320 {
00321 QGLWidget::makeCurrent();
00322 }
00323
00324 void setMousePosition(int x, int y)
00325 {
00326 QCursor::setPos( mapToGlobal(QPoint(x,y)) );
00327 }
00328
00329 void mouseMoveEvent(QMouseEvent* ev)
00330 {
00331 if (!mIgnoreNextMouseMoveEvent)
00332 dispatchMouseMoveEvent(ev->x(), ev->y());
00333 mIgnoreNextMouseMoveEvent = false;
00334 }
00335
00336 void mousePressEvent(QMouseEvent* ev)
00337 {
00338 vl::EMouseButton bt = vl::NoButton;
00339 switch(ev->button())
00340 {
00341 case Qt::LeftButton: bt = vl::LeftButton; break;
00342 case Qt::RightButton: bt = vl::RightButton; break;
00343 case Qt::MidButton: bt = vl::MiddleButton; break;
00344 default:
00345 bt = vl::UnknownButton; break;
00346 }
00347 dispatchMouseDownEvent(bt, ev->x(), ev->y());
00348 }
00349
00350 void mouseReleaseEvent(QMouseEvent* ev)
00351 {
00352 vl::EMouseButton bt = vl::NoButton;
00353 switch(ev->button())
00354 {
00355 case Qt::LeftButton: bt = vl::LeftButton; break;
00356 case Qt::RightButton: bt = vl::RightButton; break;
00357 case Qt::MidButton: bt = vl::MiddleButton; break;
00358 default:
00359 bt = vl::UnknownButton; break;
00360 }
00361 dispatchMouseUpEvent(bt, ev->x(), ev->y());
00362 }
00363
00364 void wheelEvent(QWheelEvent* ev)
00365 {
00366 dispatchMouseWheelEvent(ev->delta() / 120);
00367 }
00368
00369 void keyPressEvent(QKeyEvent* ev)
00370 {
00371 unsigned short unicode_ch = 0;
00372 vl::EKey key = vl::Key_None;
00373 translateKeyEvent(ev, unicode_ch, key);
00374 dispatchKeyPressEvent(unicode_ch, key);
00375 }
00376
00377 void keyReleaseEvent(QKeyEvent* ev)
00378 {
00379 unsigned short unicode_ch = 0;
00380 vl::EKey key = vl::Key_None;
00381 translateKeyEvent(ev, unicode_ch, key);
00382 dispatchKeyReleaseEvent(unicode_ch, key);
00383 }
00384
00385 virtual void setMouseVisible(bool visible)
00386 {
00387 mMouseVisible=visible;
00388 if (visible)
00389 QGLWidget::setCursor(Qt::ArrowCursor);
00390 else
00391 QGLWidget::setCursor(Qt::BlankCursor);
00392 }
00393
00394 virtual void getFocus()
00395 {
00396 QGLWidget::setFocus(Qt::OtherFocusReason);
00397 }
00398
00399 protected:
00400 void translateKeyEvent(QKeyEvent* ev, unsigned short& unicode_out, vl::EKey& key_out);
00401
00402 protected:
00403 int mRefresh;
00404 QTimer mUpdateTimer;
00405 };
00406
00407 }
00408
00409 #endif