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