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