/*************************************************************************** * Copyright by (C) 2004 by Garrett Potts * * Copyright by (C) 2009 by Jack R * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "ossimplanetviewer.h" #include #include #include #include OssimPlanetQgisGlWidget::OssimPlanetQgisGlWidget( QWidget * parent, const QGLWidget * shareWidget, Qt::WindowFlags f) :QGLWidget(parent, shareWidget, f), theMouseNavigationFlag(true), thePassAllUnhandledEventsFlag(true) { init(); } OssimPlanetQgisGlWidget::OssimPlanetQgisGlWidget( const QGLFormat & format, QWidget * parent, const QGLWidget * shareWidget, Qt::WindowFlags f ) :QGLWidget(format, parent, shareWidget, f), theMouseNavigationFlag(true), thePassAllUnhandledEventsFlag(true) { init(); } OssimPlanetQgisGlWidget::~OssimPlanetQgisGlWidget() { } void OssimPlanetQgisGlWidget::init() { theGraphicsWindow = new osgViewer::GraphicsWindowEmbedded(0, 0, width(), height()); setAcceptDrops(true); } void OssimPlanetQgisGlWidget::doIdleAnimationFrame() { frameIfNeeded(); } void OssimPlanetQgisGlWidget::setMouseNavigationFlag(bool flag) { theMouseNavigationFlag = flag; } bool OssimPlanetQgisGlWidget::getMouseNavigationFlag()const { return theMouseNavigationFlag; } void OssimPlanetQgisGlWidget::resizeGL( int width, int height ) { theGraphicsWindow->getEventQueue()->windowResize(0, 0, width, height ); theGraphicsWindow->resized(0,0,width,height); } void OssimPlanetQgisGlWidget::keyPressEvent( QKeyEvent* event ) { theGraphicsWindow->getEventQueue()->keyPress( qtKeyToOsg(event) ); addModifiers(theGraphicsWindow->getEventQueue(), event->modifiers()); if(thePassAllUnhandledEventsFlag) { event->ignore(); } updateGL(); } void OssimPlanetQgisGlWidget::keyReleaseEvent( QKeyEvent* event ) { theGraphicsWindow->getEventQueue()->keyRelease( qtKeyToOsg(event) ); addModifiers(theGraphicsWindow->getEventQueue(), event->modifiers()); if(thePassAllUnhandledEventsFlag) { event->ignore(); } updateGL(); } void OssimPlanetQgisGlWidget::mousePressEvent( QMouseEvent* event ) { int button = 0; switch(event->button()) { case(Qt::LeftButton): button = 1; break; case(Qt::MidButton): button = 2; break; case(Qt::RightButton): button = 3; break; case(Qt::NoButton): button = 0; break; default: button = 0; break; } theGraphicsWindow->getEventQueue()->mouseButtonPress(event->x(), event->y(), button); addModifiers(theGraphicsWindow->getEventQueue(), event->modifiers()); if(thePassAllUnhandledEventsFlag) { event->ignore(); } updateGL(); emit signalMousePressEvent(event); } void OssimPlanetQgisGlWidget::mouseReleaseEvent( QMouseEvent* event ) { int button = 0; switch(event->button()) { case(Qt::LeftButton): button = 1; break; case(Qt::MidButton): button = 2; break; case(Qt::RightButton): button = 3; break; case(Qt::NoButton): button = 0; break; default: button = 0; break; } theGraphicsWindow->getEventQueue()->mouseButtonRelease(event->x(), event->y(), button); addModifiers(theGraphicsWindow->getEventQueue(), event->modifiers()); if(thePassAllUnhandledEventsFlag) { event->ignore(); } updateGL(); emit signalMouseReleaseEvent(event); } void OssimPlanetQgisGlWidget::mouseMoveEvent( QMouseEvent* event ) { theGraphicsWindow->getEventQueue()->mouseMotion(event->x(), event->y()); addModifiers(theGraphicsWindow->getEventQueue(), event->modifiers()); updateGL(); emit signalMouseMoveEvent(event); } void OssimPlanetQgisGlWidget::dropEvent ( QDropEvent * event ) { emit signalDropEvent(event); } void OssimPlanetQgisGlWidget::dragEnterEvent(QDragEnterEvent *event) { emit signalDragEnterEvent(event); } osgGA::GUIEventAdapter::KeySymbol OssimPlanetQgisGlWidget::qtKeyToOsg(QKeyEvent * e)const { int qtKey = e->key(); switch(qtKey) { case Qt::Key_Up: { return(osgGA::GUIEventAdapter::KEY_Up); } case Qt::Key_Down: { return (osgGA::GUIEventAdapter::KEY_Down); } case Qt::Key_Left: { return (osgGA::GUIEventAdapter::KEY_Left); } case Qt::Key_Right: { return (osgGA::GUIEventAdapter::KEY_Right); } case Qt::Key_Return: { return (osgGA::GUIEventAdapter::KEY_Return); } default: { if((qtKey >= Qt::Key_A)&&(qtKey <= Qt::Key_Z)) { QString s = e->text(); std::string stdString = s.toStdString(); char c = *stdString.begin(); return (osgGA::GUIEventAdapter::KeySymbol)(c); } } } return (osgGA::GUIEventAdapter::KeySymbol)(qtKey); } void OssimPlanetQgisGlWidget::addModifiers(osg::ref_ptr eventQueue, Qt::KeyboardModifiers modifier) { if(!eventQueue.valid()) return; unsigned int modKeyMask = 0; osgGA::GUIEventAdapter* adapter = eventQueue->getCurrentEventState(); if(!adapter) return; if(modifier & Qt::ShiftModifier) { modKeyMask|=osgGA::GUIEventAdapter::MODKEY_SHIFT; } if(modifier & Qt::ControlModifier) { modKeyMask|=osgGA::GUIEventAdapter::MODKEY_CTRL; } if(modifier & Qt::AltModifier) { modKeyMask|=osgGA::GUIEventAdapter::MODKEY_ALT; } if(modifier & Qt::MetaModifier) { modKeyMask|=osgGA::GUIEventAdapter::MODKEY_META; } adapter->setModKeyMask(modKeyMask); } OssimPlanetQgisViewer::OssimPlanetQgisViewer(QWidget * parent, const QGLWidget * shareWidget, Qt::WindowFlags f) :OssimPlanetQgisGlWidget( parent, shareWidget, f ), theRequestRedrawFlag(false), theRequestContinuousUpdateFlag(false), theTimerInterval(0), theQTimer(0) { timer()->setInterval(theTimerInterval); timer()->setSingleShot(false); getCamera()->setViewport(new osg::Viewport(0, 0, width(), height())); getCamera()->setProjectionMatrixAsPerspective(45.0f, static_cast(width()) / static_cast(height()), 1.0f, 50.0); getCamera()->setGraphicsContext(getGraphicsWindow()); setThreadingModel(osgViewer::Viewer::SingleThreaded); timer()->start(); } OssimPlanetQgisViewer::OssimPlanetQgisViewer( const QGLFormat & format, QWidget * parent, const QGLWidget * shareWidget, Qt::WindowFlags f ) :OssimPlanetQgisGlWidget(format, parent, shareWidget, f), theRequestRedrawFlag(false), theRequestContinuousUpdateFlag(false), theTimerInterval(0), theQTimer(0) { timer()->setInterval(theTimerInterval); timer()->setSingleShot(false); getCamera()->setViewport(new osg::Viewport(0, 0, width(), height())); getCamera()->setProjectionMatrixAsPerspective(45.0f, static_cast(width()) / static_cast(height()), 1.0f, 50.0); getCamera()->setGraphicsContext(getGraphicsWindow()); setThreadingModel(osgViewer::Viewer::SingleThreaded); timer()->start(); } QTimer *OssimPlanetQgisViewer::timer() { if(!theQTimer) { theQTimer=new QTimer(this); connect(theQTimer,SIGNAL(timeout()),this,SLOT(doIdleAnimationFrame())); } return theQTimer; } void OssimPlanetQgisViewer::requestRedraw() { OpenThreads::ScopedLock lock(theDrawMutex); theRequestRedrawFlag = true; if(!timer()->isActive()) { timer()->setInterval(theTimerInterval); timer()->start(); } } void OssimPlanetQgisViewer::requestContinuousUpdate(bool needed) { OpenThreads::ScopedLock lock(theDrawMutex); theRequestContinuousUpdateFlag = needed; if(needed) { if(!timer()->isActive()) { timer()->setInterval(theTimerInterval); timer()->start(); } } } void OssimPlanetQgisViewer::updateTraversal() { ossimPlanetViewer::updateTraversal(); } void OssimPlanetQgisViewer::frameIfNeeded() { //OpenThreads::ScopedLock lock(theDrawMutex); bool doVBlankLimit = false; osg::Timer_t beginT = osg::Timer::instance()->tick(); osg::Timer_t endT; if(theRequestContinuousUpdateFlag||theRequestRedrawFlag) { theRequestRedrawFlag = false; updateGL(); doVBlankLimit = format().swapInterval() < 0; endT = osg::Timer::instance()->tick(); } else { advance(); theGraphicsWindow->getEventQueue()->frame(getViewerFrameStamp()->getReferenceTime()); eventTraversal(); updateTraversal(); doVBlankLimit = true; endT = osg::Timer::instance()->tick(); } if(doVBlankLimit) { double test = osg::Timer::instance()->delta_m(beginT, endT); const double sixtyHz = 1000/60; if(test < sixtyHz) { ulMilliSecondSleep((int)(sixtyHz-test)); } } } void OssimPlanetQgisViewer::paintGL() { frame(); } void OssimPlanetQgisViewer::mouseMoveEvent( QMouseEvent* event ) { OssimPlanetQgisGlWidget::mouseMoveEvent(event); }