2011-01-31 19:40:35 +08:00
|
|
|
/* -*-c++-*- OpenSceneGraph - Copyright (C) 2009 Wang Rui
|
|
|
|
*
|
2011-05-16 16:59:10 +08:00
|
|
|
* This library is open source and may be redistributed and/or modified under
|
|
|
|
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
2011-01-31 19:40:35 +08:00
|
|
|
* (at your option) any later version. The full license is in LICENSE file
|
|
|
|
* included with this distribution, and on the openscenegraph.org website.
|
2011-05-16 16:59:10 +08:00
|
|
|
*
|
2011-01-31 19:40:35 +08:00
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2011-05-16 16:59:10 +08:00
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2011-01-31 19:40:35 +08:00
|
|
|
* OpenSceneGraph Public License for more details.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef OSGVIEWER_GRAPHICSWINDOWQT
|
|
|
|
#define OSGVIEWER_GRAPHICSWINDOWQT
|
|
|
|
|
2014-04-23 17:08:26 +08:00
|
|
|
#include <QGLWidget>
|
|
|
|
|
2013-06-20 17:30:31 +08:00
|
|
|
#include <osgViewer/GraphicsWindow>
|
|
|
|
#include <osgQt/Export>
|
2015-06-16 03:59:01 +08:00
|
|
|
#include <osgQt/Version>
|
2013-06-20 17:30:31 +08:00
|
|
|
|
2013-06-10 22:34:25 +08:00
|
|
|
#include <QMutex>
|
|
|
|
#include <QEvent>
|
|
|
|
#include <QQueue>
|
|
|
|
#include <QSet>
|
From Kristofer Tingdahl, "I and my team have gone over the code again, and we feel that we are comfortable in our current proposal for change. It goes deeper than it did before, and I explain why:
There was code in the osgViewer/Viewer.cpp and osgViewer/CompositeViewer.cpp that transformed the Y-coordinates of an event. The code in the composite viewer did however miss the touch-data of the event. I thought that it should really be the GUIEventAdapter that should know about this, and hence I added the
GUIEventAdapter::setMouseYOrientationAndUpdateCoords which is re-computing the coordinates. First I simply added a boolean to the setMouseYOrientation function:
setMouseYOrientation( MouseYOrientation, bool updatecooreds=false );
but then the serializer complained.
This function is called from both the Viewer and the CompositeViewer. We have not tested from the viewer, but I cannot see it would not work from visual inspection.
The other change is in MultiTouchTrackballManipulator::handleMultiTouchDrag. I have removed the normalisation. The reason for that is that it normalised into screen coordinates from 0,0 to 1,1. The problem with that is that if you have a pinch event and you keep the distance say 300 pixels between your fingers, these 300 pixels represent 0.20 of the screen in the horizontal domain, but 0.3 of the screen in the vertical domain. A rotation of the pinch-fingers will hence result in a zoom in, as the normalised distance is changing between them.
A consequence of this is that I have changed the pan-code to use the same algorithm as the middle-mouse-pan.
The rest of it is very similar from previous revision, and there has been some fine-tuning here and there.
"
2014-04-25 01:14:54 +08:00
|
|
|
#include <QGLWidget>
|
2011-09-13 19:09:39 +08:00
|
|
|
|
2011-05-16 17:06:06 +08:00
|
|
|
class QInputEvent;
|
From Kristofer Tingdahl, "I and my team have gone over the code again, and we feel that we are comfortable in our current proposal for change. It goes deeper than it did before, and I explain why:
There was code in the osgViewer/Viewer.cpp and osgViewer/CompositeViewer.cpp that transformed the Y-coordinates of an event. The code in the composite viewer did however miss the touch-data of the event. I thought that it should really be the GUIEventAdapter that should know about this, and hence I added the
GUIEventAdapter::setMouseYOrientationAndUpdateCoords which is re-computing the coordinates. First I simply added a boolean to the setMouseYOrientation function:
setMouseYOrientation( MouseYOrientation, bool updatecooreds=false );
but then the serializer complained.
This function is called from both the Viewer and the CompositeViewer. We have not tested from the viewer, but I cannot see it would not work from visual inspection.
The other change is in MultiTouchTrackballManipulator::handleMultiTouchDrag. I have removed the normalisation. The reason for that is that it normalised into screen coordinates from 0,0 to 1,1. The problem with that is that if you have a pinch event and you keep the distance say 300 pixels between your fingers, these 300 pixels represent 0.20 of the screen in the horizontal domain, but 0.3 of the screen in the vertical domain. A rotation of the pinch-fingers will hence result in a zoom in, as the normalised distance is changing between them.
A consequence of this is that I have changed the pan-code to use the same algorithm as the middle-mouse-pan.
The rest of it is very similar from previous revision, and there has been some fine-tuning here and there.
"
2014-04-25 01:14:54 +08:00
|
|
|
class QGestureEvent;
|
2011-05-16 17:06:06 +08:00
|
|
|
|
|
|
|
namespace osgViewer {
|
|
|
|
class ViewerBase;
|
|
|
|
}
|
|
|
|
|
2011-01-31 19:40:35 +08:00
|
|
|
namespace osgQt
|
|
|
|
{
|
|
|
|
|
2011-05-16 17:06:06 +08:00
|
|
|
// forward declarations
|
|
|
|
class GraphicsWindowQt;
|
|
|
|
|
|
|
|
/// The function sets the WindowingSystem to Qt.
|
|
|
|
void OSGQT_EXPORT initQtWindowingSystem();
|
|
|
|
|
|
|
|
/** The function sets the viewer that will be used after entering
|
|
|
|
* the Qt main loop (QCoreApplication::exec()).
|
|
|
|
*
|
|
|
|
* The function also initializes internal structures required for proper
|
|
|
|
* scene rendering.
|
|
|
|
*
|
|
|
|
* The method must be called from main thread. */
|
|
|
|
void OSGQT_EXPORT setViewer( osgViewer::ViewerBase *viewer );
|
|
|
|
|
|
|
|
|
|
|
|
class OSGQT_EXPORT GLWidget : public QGLWidget
|
2011-01-31 19:40:35 +08:00
|
|
|
{
|
2011-05-16 17:06:06 +08:00
|
|
|
typedef QGLWidget inherited;
|
2011-09-13 19:09:39 +08:00
|
|
|
|
2011-01-31 19:40:35 +08:00
|
|
|
public:
|
2011-05-16 16:59:10 +08:00
|
|
|
|
2011-05-16 17:06:06 +08:00
|
|
|
GLWidget( QWidget* parent = NULL, const QGLWidget* shareWidget = NULL, Qt::WindowFlags f = 0, bool forwardKeyEvents = false );
|
|
|
|
GLWidget( QGLContext* context, QWidget* parent = NULL, const QGLWidget* shareWidget = NULL, Qt::WindowFlags f = 0, bool forwardKeyEvents = false );
|
|
|
|
GLWidget( const QGLFormat& format, QWidget* parent = NULL, const QGLWidget* shareWidget = NULL, Qt::WindowFlags f = 0, bool forwardKeyEvents = false );
|
|
|
|
virtual ~GLWidget();
|
|
|
|
|
|
|
|
inline void setGraphicsWindow( GraphicsWindowQt* gw ) { _gw = gw; }
|
|
|
|
inline GraphicsWindowQt* getGraphicsWindow() { return _gw; }
|
|
|
|
inline const GraphicsWindowQt* getGraphicsWindow() const { return _gw; }
|
|
|
|
|
|
|
|
inline bool getForwardKeyEvents() const { return _forwardKeyEvents; }
|
|
|
|
virtual void setForwardKeyEvents( bool f ) { _forwardKeyEvents = f; }
|
From Kristofer Tingdahl, "I and my team have gone over the code again, and we feel that we are comfortable in our current proposal for change. It goes deeper than it did before, and I explain why:
There was code in the osgViewer/Viewer.cpp and osgViewer/CompositeViewer.cpp that transformed the Y-coordinates of an event. The code in the composite viewer did however miss the touch-data of the event. I thought that it should really be the GUIEventAdapter that should know about this, and hence I added the
GUIEventAdapter::setMouseYOrientationAndUpdateCoords which is re-computing the coordinates. First I simply added a boolean to the setMouseYOrientation function:
setMouseYOrientation( MouseYOrientation, bool updatecooreds=false );
but then the serializer complained.
This function is called from both the Viewer and the CompositeViewer. We have not tested from the viewer, but I cannot see it would not work from visual inspection.
The other change is in MultiTouchTrackballManipulator::handleMultiTouchDrag. I have removed the normalisation. The reason for that is that it normalised into screen coordinates from 0,0 to 1,1. The problem with that is that if you have a pinch event and you keep the distance say 300 pixels between your fingers, these 300 pixels represent 0.20 of the screen in the horizontal domain, but 0.3 of the screen in the vertical domain. A rotation of the pinch-fingers will hence result in a zoom in, as the normalised distance is changing between them.
A consequence of this is that I have changed the pan-code to use the same algorithm as the middle-mouse-pan.
The rest of it is very similar from previous revision, and there has been some fine-tuning here and there.
"
2014-04-25 01:14:54 +08:00
|
|
|
|
|
|
|
inline bool getTouchEventsEnabled() const { return _touchEventsEnabled; }
|
|
|
|
void setTouchEventsEnabled( bool e );
|
2011-05-16 16:59:10 +08:00
|
|
|
|
2011-01-31 19:40:35 +08:00
|
|
|
void setKeyboardModifiers( QInputEvent* event );
|
2011-05-16 16:59:10 +08:00
|
|
|
|
2011-01-31 19:40:35 +08:00
|
|
|
virtual void keyPressEvent( QKeyEvent* event );
|
|
|
|
virtual void keyReleaseEvent( QKeyEvent* event );
|
|
|
|
virtual void mousePressEvent( QMouseEvent* event );
|
|
|
|
virtual void mouseReleaseEvent( QMouseEvent* event );
|
|
|
|
virtual void mouseDoubleClickEvent( QMouseEvent* event );
|
|
|
|
virtual void mouseMoveEvent( QMouseEvent* event );
|
|
|
|
virtual void wheelEvent( QWheelEvent* event );
|
From Kristofer Tingdahl, "I and my team have gone over the code again, and we feel that we are comfortable in our current proposal for change. It goes deeper than it did before, and I explain why:
There was code in the osgViewer/Viewer.cpp and osgViewer/CompositeViewer.cpp that transformed the Y-coordinates of an event. The code in the composite viewer did however miss the touch-data of the event. I thought that it should really be the GUIEventAdapter that should know about this, and hence I added the
GUIEventAdapter::setMouseYOrientationAndUpdateCoords which is re-computing the coordinates. First I simply added a boolean to the setMouseYOrientation function:
setMouseYOrientation( MouseYOrientation, bool updatecooreds=false );
but then the serializer complained.
This function is called from both the Viewer and the CompositeViewer. We have not tested from the viewer, but I cannot see it would not work from visual inspection.
The other change is in MultiTouchTrackballManipulator::handleMultiTouchDrag. I have removed the normalisation. The reason for that is that it normalised into screen coordinates from 0,0 to 1,1. The problem with that is that if you have a pinch event and you keep the distance say 300 pixels between your fingers, these 300 pixels represent 0.20 of the screen in the horizontal domain, but 0.3 of the screen in the vertical domain. A rotation of the pinch-fingers will hence result in a zoom in, as the normalised distance is changing between them.
A consequence of this is that I have changed the pan-code to use the same algorithm as the middle-mouse-pan.
The rest of it is very similar from previous revision, and there has been some fine-tuning here and there.
"
2014-04-25 01:14:54 +08:00
|
|
|
virtual bool gestureEvent( QGestureEvent* event );
|
2011-05-16 16:59:10 +08:00
|
|
|
|
2011-01-31 19:40:35 +08:00
|
|
|
protected:
|
2011-09-13 19:09:39 +08:00
|
|
|
|
|
|
|
int getNumDeferredEvents()
|
|
|
|
{
|
|
|
|
QMutexLocker lock(&_deferredEventQueueMutex);
|
|
|
|
return _deferredEventQueue.count();
|
|
|
|
}
|
|
|
|
void enqueueDeferredEvent(QEvent::Type eventType, QEvent::Type removeEventType = QEvent::None)
|
|
|
|
{
|
|
|
|
QMutexLocker lock(&_deferredEventQueueMutex);
|
|
|
|
|
|
|
|
if (removeEventType != QEvent::None)
|
|
|
|
{
|
|
|
|
if (_deferredEventQueue.removeOne(removeEventType))
|
|
|
|
_eventCompressor.remove(eventType);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_eventCompressor.find(eventType) == _eventCompressor.end())
|
|
|
|
{
|
|
|
|
_deferredEventQueue.enqueue(eventType);
|
|
|
|
_eventCompressor.insert(eventType);
|
2012-03-22 01:36:20 +08:00
|
|
|
}
|
2011-09-13 19:09:39 +08:00
|
|
|
}
|
|
|
|
void processDeferredEvents();
|
2012-03-22 01:36:20 +08:00
|
|
|
|
2011-05-16 17:06:06 +08:00
|
|
|
friend class GraphicsWindowQt;
|
|
|
|
GraphicsWindowQt* _gw;
|
|
|
|
|
2011-09-13 19:09:39 +08:00
|
|
|
QMutex _deferredEventQueueMutex;
|
|
|
|
QQueue<QEvent::Type> _deferredEventQueue;
|
|
|
|
QSet<QEvent::Type> _eventCompressor;
|
|
|
|
|
From Kristofer Tingdahl, "I and my team have gone over the code again, and we feel that we are comfortable in our current proposal for change. It goes deeper than it did before, and I explain why:
There was code in the osgViewer/Viewer.cpp and osgViewer/CompositeViewer.cpp that transformed the Y-coordinates of an event. The code in the composite viewer did however miss the touch-data of the event. I thought that it should really be the GUIEventAdapter that should know about this, and hence I added the
GUIEventAdapter::setMouseYOrientationAndUpdateCoords which is re-computing the coordinates. First I simply added a boolean to the setMouseYOrientation function:
setMouseYOrientation( MouseYOrientation, bool updatecooreds=false );
but then the serializer complained.
This function is called from both the Viewer and the CompositeViewer. We have not tested from the viewer, but I cannot see it would not work from visual inspection.
The other change is in MultiTouchTrackballManipulator::handleMultiTouchDrag. I have removed the normalisation. The reason for that is that it normalised into screen coordinates from 0,0 to 1,1. The problem with that is that if you have a pinch event and you keep the distance say 300 pixels between your fingers, these 300 pixels represent 0.20 of the screen in the horizontal domain, but 0.3 of the screen in the vertical domain. A rotation of the pinch-fingers will hence result in a zoom in, as the normalised distance is changing between them.
A consequence of this is that I have changed the pan-code to use the same algorithm as the middle-mouse-pan.
The rest of it is very similar from previous revision, and there has been some fine-tuning here and there.
"
2014-04-25 01:14:54 +08:00
|
|
|
bool _touchEventsEnabled;
|
|
|
|
|
2011-05-16 17:06:06 +08:00
|
|
|
bool _forwardKeyEvents;
|
2014-01-20 18:40:49 +08:00
|
|
|
qreal _devicePixelRatio;
|
2011-05-16 17:06:06 +08:00
|
|
|
|
|
|
|
virtual void resizeEvent( QResizeEvent* event );
|
|
|
|
virtual void moveEvent( QMoveEvent* event );
|
|
|
|
virtual void glDraw();
|
|
|
|
virtual bool event( QEvent* event );
|
2011-01-31 19:40:35 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
class OSGQT_EXPORT GraphicsWindowQt : public osgViewer::GraphicsWindow
|
|
|
|
{
|
|
|
|
public:
|
2011-05-16 17:06:06 +08:00
|
|
|
GraphicsWindowQt( osg::GraphicsContext::Traits* traits, QWidget* parent = NULL, const QGLWidget* shareWidget = NULL, Qt::WindowFlags f = 0 );
|
|
|
|
GraphicsWindowQt( GLWidget* widget );
|
2011-01-31 19:40:35 +08:00
|
|
|
virtual ~GraphicsWindowQt();
|
2011-05-16 16:59:10 +08:00
|
|
|
|
2011-05-16 17:06:06 +08:00
|
|
|
inline GLWidget* getGLWidget() { return _widget; }
|
|
|
|
inline const GLWidget* getGLWidget() const { return _widget; }
|
|
|
|
|
|
|
|
/// deprecated
|
|
|
|
inline GLWidget* getGraphWidget() { return _widget; }
|
|
|
|
/// deprecated
|
|
|
|
inline const GLWidget* getGraphWidget() const { return _widget; }
|
2012-03-22 01:36:20 +08:00
|
|
|
|
2011-09-13 19:09:39 +08:00
|
|
|
struct WindowData : public osg::Referenced
|
2011-01-31 19:40:35 +08:00
|
|
|
{
|
2012-02-07 19:41:20 +08:00
|
|
|
WindowData( GLWidget* widget = NULL, QWidget* parent = NULL ): _widget(widget), _parent(parent) {}
|
2011-05-16 17:06:06 +08:00
|
|
|
GLWidget* _widget;
|
2012-02-07 19:41:20 +08:00
|
|
|
QWidget* _parent;
|
2011-01-31 19:40:35 +08:00
|
|
|
};
|
2011-05-16 16:59:10 +08:00
|
|
|
|
2011-05-16 17:06:06 +08:00
|
|
|
bool init( QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f );
|
|
|
|
|
|
|
|
static QGLFormat traits2qglFormat( const osg::GraphicsContext::Traits* traits );
|
|
|
|
static void qglFormat2traits( const QGLFormat& format, osg::GraphicsContext::Traits* traits );
|
|
|
|
static osg::GraphicsContext::Traits* createTraits( const QGLWidget* widget );
|
2011-05-16 16:59:10 +08:00
|
|
|
|
2011-01-31 19:40:35 +08:00
|
|
|
virtual bool setWindowRectangleImplementation( int x, int y, int width, int height );
|
|
|
|
virtual void getWindowRectangle( int& x, int& y, int& width, int& height );
|
|
|
|
virtual bool setWindowDecorationImplementation( bool windowDecoration );
|
|
|
|
virtual bool getWindowDecoration() const;
|
|
|
|
virtual void grabFocus();
|
|
|
|
virtual void grabFocusIfPointerInWindow();
|
|
|
|
virtual void raiseWindow();
|
|
|
|
virtual void setWindowName( const std::string& name );
|
|
|
|
virtual std::string getWindowName();
|
|
|
|
virtual void useCursor( bool cursorOn );
|
|
|
|
virtual void setCursor( MouseCursor cursor );
|
From Kristofer Tingdahl, "I and my team have gone over the code again, and we feel that we are comfortable in our current proposal for change. It goes deeper than it did before, and I explain why:
There was code in the osgViewer/Viewer.cpp and osgViewer/CompositeViewer.cpp that transformed the Y-coordinates of an event. The code in the composite viewer did however miss the touch-data of the event. I thought that it should really be the GUIEventAdapter that should know about this, and hence I added the
GUIEventAdapter::setMouseYOrientationAndUpdateCoords which is re-computing the coordinates. First I simply added a boolean to the setMouseYOrientation function:
setMouseYOrientation( MouseYOrientation, bool updatecooreds=false );
but then the serializer complained.
This function is called from both the Viewer and the CompositeViewer. We have not tested from the viewer, but I cannot see it would not work from visual inspection.
The other change is in MultiTouchTrackballManipulator::handleMultiTouchDrag. I have removed the normalisation. The reason for that is that it normalised into screen coordinates from 0,0 to 1,1. The problem with that is that if you have a pinch event and you keep the distance say 300 pixels between your fingers, these 300 pixels represent 0.20 of the screen in the horizontal domain, but 0.3 of the screen in the vertical domain. A rotation of the pinch-fingers will hence result in a zoom in, as the normalised distance is changing between them.
A consequence of this is that I have changed the pan-code to use the same algorithm as the middle-mouse-pan.
The rest of it is very similar from previous revision, and there has been some fine-tuning here and there.
"
2014-04-25 01:14:54 +08:00
|
|
|
inline bool getTouchEventsEnabled() const { return _widget->getTouchEventsEnabled(); }
|
|
|
|
virtual void setTouchEventsEnabled( bool e ) { _widget->setTouchEventsEnabled(e); }
|
|
|
|
|
2011-05-16 16:59:10 +08:00
|
|
|
|
2011-01-31 19:40:35 +08:00
|
|
|
virtual bool valid() const;
|
|
|
|
virtual bool realizeImplementation();
|
|
|
|
virtual bool isRealizedImplementation() const;
|
|
|
|
virtual void closeImplementation();
|
|
|
|
virtual bool makeCurrentImplementation();
|
|
|
|
virtual bool releaseContextImplementation();
|
|
|
|
virtual void swapBuffersImplementation();
|
2011-09-13 19:09:39 +08:00
|
|
|
virtual void runOperations();
|
2012-03-22 01:36:20 +08:00
|
|
|
|
2011-01-31 19:40:35 +08:00
|
|
|
virtual void requestWarpPointer( float x, float y );
|
2011-05-16 16:59:10 +08:00
|
|
|
|
2011-01-31 19:40:35 +08:00
|
|
|
protected:
|
2011-05-16 17:06:06 +08:00
|
|
|
|
2011-09-13 19:09:39 +08:00
|
|
|
friend class GLWidget;
|
2011-05-16 17:06:06 +08:00
|
|
|
GLWidget* _widget;
|
|
|
|
bool _ownsWidget;
|
2011-01-31 19:40:35 +08:00
|
|
|
QCursor _currentCursor;
|
|
|
|
bool _realized;
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|