root/OpenSceneGraph/trunk/src/osgQt/QGraphicsViewAdapter.cpp @ 12292

Revision 12292, 22.4 kB (checked in by robert, 4 years ago)

Ran svn propset -R svn:eol-style native . on the OpenSceneGraph

  • Property svn:eol-style set to native
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2009 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#include <osgQt/QGraphicsViewAdapter>
15#include <osgQt/QWidgetImage>
16
17#include <QtOpenGL/QGLWidget>
18
19#include <osg/Version>
20#include <osgGA/GUIEventAdapter>
21
22#include <osg/NodeVisitor>
23#include <osg/io_utils>
24#include <QtGui/QGraphicsItem>
25#include <QtGui/QGraphicsProxyWidget>
26
27#define MYQKEYEVENT 2000
28#define MYQPOINTEREVENT 2001
29
30namespace osgQt
31{
32
33QCoreApplication* getOrCreateQApplication()
34{
35    if (QApplication::instance()==0)
36    {
37        static char** argv = 0;
38        static int argc = 0;
39        static QApplication app(argc,argv);
40    }
41    return QApplication::instance();
42}
43
44class MyQKeyEvent : public QEvent
45{
46public:
47    MyQKeyEvent( int key, bool down ):
48        QEvent( QEvent::Type(MYQKEYEVENT) ),
49        _key(key), _down(down) {}
50
51    int         _key;
52    bool        _down;
53};
54
55struct MyQPointerEvent : public QEvent
56{
57    MyQPointerEvent(int x, int y, unsigned int buttonMask):
58        QEvent( QEvent::Type(MYQPOINTEREVENT) ),
59        _x(x), _y(y),_buttonMask(buttonMask) {}
60
61    int _x, _y;
62    unsigned int _buttonMask;
63};
64
65
66const QImage::Format s_imageFormat = QImage::Format_ARGB32_Premultiplied;
67
68QGraphicsViewAdapter::QGraphicsViewAdapter(osg::Image* image, QWidget* widget):
69    _image(image),
70    _previousQtMouseX(-1),
71    _previousQtMouseY(-1),
72    _previousSentEvent(false),
73    _qtKeyModifiers(Qt::NoModifier),
74    _backgroundColor(255, 255, 255),
75    _widget(widget)
76{
77    // make sure we have a valid QApplication before we start creating widgets.
78    getOrCreateQApplication();
79
80
81    setUpKeyMap();
82
83    _graphicsScene = new QGraphicsScene;
84    _graphicsScene->addWidget(widget);
85
86    _graphicsView = new QGraphicsView;
87    _graphicsView->setScene(_graphicsScene);
88    _graphicsView->viewport()->setParent(0);
89
90#if (QT_VERSION_CHECK(4, 5, 0) <= QT_VERSION)
91    _graphicsScene->setStickyFocus(true);
92#endif
93
94    _width = _graphicsScene->width();
95    _height = _graphicsScene->height();
96
97    _qimages[0] = QImage(QSize(_width, _height), s_imageFormat);
98    _qimages[1] = QImage(QSize(_width, _height), s_imageFormat);
99    _qimages[2] = QImage(QSize(_width, _height), s_imageFormat);
100
101    _currentRead = 0;
102    _currentWrite = 1;
103    _previousWrite = 2;
104    _previousFrameNumber = osg::UNINITIALIZED_FRAME_NUMBER;
105    _newImageAvailable = false;
106
107    connect(_graphicsScene, SIGNAL(changed(const QList<QRectF> &)),
108            this, SLOT(repaintRequestedSlot(const QList<QRectF> &)));
109    connect(_graphicsScene, SIGNAL(sceneRectChanged(const QRectF &)),
110            this, SLOT(repaintRequestedSlot(const QRectF &)));
111
112    assignImage(0);
113}
114
115void QGraphicsViewAdapter::repaintRequestedSlot(const QList<QRectF>&)
116{
117    // OSG_NOTICE<<"QGraphicsViewAdapter::repaintRequestedSlot"<<std::endl;
118    render();
119}
120
121void QGraphicsViewAdapter::repaintRequestedSlot(const QRectF&)
122{
123    // OSG_NOTICE<<"QGraphicsViewAdapter::repaintRequestedSlot"<<std::endl;
124    render();
125}
126
127void QGraphicsViewAdapter::customEvent ( QEvent * event )
128{
129    if (event->type()==MYQKEYEVENT)
130    {
131        MyQKeyEvent* keyEvent = (MyQKeyEvent*)event;
132        handleKeyEvent(keyEvent->_key, keyEvent->_down);
133    }
134    else if (event->type()==MYQPOINTEREVENT)
135    {
136        MyQPointerEvent* pointerEvent = (MyQPointerEvent*)event;
137        handlePointerEvent(pointerEvent->_x, pointerEvent->_y, pointerEvent->_buttonMask);
138    }
139}
140
141
142void QGraphicsViewAdapter::setUpKeyMap()
143{
144    _keyMap[osgGA::GUIEventAdapter::KEY_BackSpace] = Qt::Key_Backspace;
145    _keyMap[osgGA::GUIEventAdapter::KEY_Tab] = Qt::Key_Tab;
146    _keyMap[osgGA::GUIEventAdapter::KEY_Linefeed] = Qt::Key_Return; // No LineFeed in Qt!
147    _keyMap[osgGA::GUIEventAdapter::KEY_Clear] = Qt::Key_Clear;
148    _keyMap[osgGA::GUIEventAdapter::KEY_Return] = Qt::Key_Return;
149    _keyMap[osgGA::GUIEventAdapter::KEY_Pause] = Qt::Key_Pause;
150    _keyMap[osgGA::GUIEventAdapter::KEY_Scroll_Lock] = Qt::Key_ScrollLock;
151    _keyMap[osgGA::GUIEventAdapter::KEY_Sys_Req] = Qt::Key_SysReq;
152    _keyMap[osgGA::GUIEventAdapter::KEY_Escape] = Qt::Key_Escape;
153    _keyMap[osgGA::GUIEventAdapter::KEY_Delete] = Qt::Key_Delete;
154
155    _keyMap[osgGA::GUIEventAdapter::KEY_Home] = Qt::Key_Home;
156    _keyMap[osgGA::GUIEventAdapter::KEY_Left] = Qt::Key_Left;
157    _keyMap[osgGA::GUIEventAdapter::KEY_Up] = Qt::Key_Up;
158    _keyMap[osgGA::GUIEventAdapter::KEY_Right] = Qt::Key_Right;
159    _keyMap[osgGA::GUIEventAdapter::KEY_Down] = Qt::Key_Down;
160    _keyMap[osgGA::GUIEventAdapter::KEY_Prior] = Qt::Key_Left; // no Prior in Qt
161    _keyMap[osgGA::GUIEventAdapter::KEY_Page_Up] = Qt::Key_PageUp;
162    _keyMap[osgGA::GUIEventAdapter::KEY_Next] = Qt::Key_Right; // No Next in Qt
163    _keyMap[osgGA::GUIEventAdapter::KEY_Page_Down] = Qt::Key_PageDown;
164    _keyMap[osgGA::GUIEventAdapter::KEY_End] = Qt::Key_End;
165    _keyMap[osgGA::GUIEventAdapter::KEY_Begin] = Qt::Key_Home; // No Begin in Qt
166
167    _keyMap[osgGA::GUIEventAdapter::KEY_Select] = Qt::Key_Select;
168    _keyMap[osgGA::GUIEventAdapter::KEY_Print] = Qt::Key_Print;
169    _keyMap[osgGA::GUIEventAdapter::KEY_Execute] = Qt::Key_Execute;
170    _keyMap[osgGA::GUIEventAdapter::KEY_Insert] = Qt::Key_Insert;
171    //_keyMap[osgGA::GUIEventAdapter::KEY_Undo] = Qt::Key_; // no Undo
172    //_keyMap[osgGA::GUIEventAdapter::KEY_Redo] = Qt::Key_; // no Redo
173    _keyMap[osgGA::GUIEventAdapter::KEY_Menu] = Qt::Key_Menu;
174    _keyMap[osgGA::GUIEventAdapter::KEY_Find] = Qt::Key_Search; // no Qt Find
175    _keyMap[osgGA::GUIEventAdapter::KEY_Cancel] = Qt::Key_Cancel;
176    _keyMap[osgGA::GUIEventAdapter::KEY_Help] = Qt::Key_Help;
177    _keyMap[osgGA::GUIEventAdapter::KEY_Break] = Qt::Key_Escape; // no break
178    _keyMap[osgGA::GUIEventAdapter::KEY_Mode_switch] = Qt::Key_Mode_switch;
179    _keyMap[osgGA::GUIEventAdapter::KEY_Script_switch] = Qt::Key_Mode_switch; // no Script switch
180    _keyMap[osgGA::GUIEventAdapter::KEY_Num_Lock] = Qt::Key_NumLock;
181
182    _keyMap[osgGA::GUIEventAdapter::KEY_Shift_L] = Qt::Key_Shift;
183    _keyMap[osgGA::GUIEventAdapter::KEY_Shift_R] = Qt::Key_Shift;
184    _keyMap[osgGA::GUIEventAdapter::KEY_Control_L] = Qt::Key_Control;
185    _keyMap[osgGA::GUIEventAdapter::KEY_Control_R] = Qt::Key_Control;
186    _keyMap[osgGA::GUIEventAdapter::KEY_Caps_Lock] = Qt::Key_CapsLock;
187    _keyMap[osgGA::GUIEventAdapter::KEY_Shift_Lock] = Qt::Key_CapsLock;
188
189    _keyMap[osgGA::GUIEventAdapter::KEY_Meta_L] = Qt::Key_Meta; // Qt doesn't have a Meta L
190    _keyMap[osgGA::GUIEventAdapter::KEY_Meta_R] = Qt::Key_Meta; // Qt doesn't have a Meta R
191    _keyMap[osgGA::GUIEventAdapter::KEY_Alt_L] = Qt::Key_Alt; // Qt doesn't have a Alt L
192    _keyMap[osgGA::GUIEventAdapter::KEY_Alt_R] = Qt::Key_Alt; // Qt doesn't have a Alt R
193    _keyMap[osgGA::GUIEventAdapter::KEY_Super_L] = Qt::Key_Super_L;
194    _keyMap[osgGA::GUIEventAdapter::KEY_Super_R] = Qt::Key_Super_R;
195    _keyMap[osgGA::GUIEventAdapter::KEY_Hyper_L] = Qt::Key_Hyper_L;
196    _keyMap[osgGA::GUIEventAdapter::KEY_Hyper_R] = Qt::Key_Hyper_R;
197
198    _keyMap[osgGA::GUIEventAdapter::KEY_KP_Space] = Qt::Key_Space;
199    _keyMap[osgGA::GUIEventAdapter::KEY_KP_Tab] = Qt::Key_Tab;
200    _keyMap[osgGA::GUIEventAdapter::KEY_KP_Enter] = Qt::Key_Enter;
201    _keyMap[osgGA::GUIEventAdapter::KEY_KP_F1] = Qt::Key_F1;
202    _keyMap[osgGA::GUIEventAdapter::KEY_KP_F2] = Qt::Key_F2;
203    _keyMap[osgGA::GUIEventAdapter::KEY_KP_F3] = Qt::Key_F3;
204    _keyMap[osgGA::GUIEventAdapter::KEY_KP_F4] = Qt::Key_F4;
205    _keyMap[osgGA::GUIEventAdapter::KEY_KP_Home] = Qt::Key_Home;
206    _keyMap[osgGA::GUIEventAdapter::KEY_KP_Left] = Qt::Key_Left;
207    _keyMap[osgGA::GUIEventAdapter::KEY_KP_Up] = Qt::Key_Up;
208    _keyMap[osgGA::GUIEventAdapter::KEY_KP_Right] = Qt::Key_Right;
209    _keyMap[osgGA::GUIEventAdapter::KEY_KP_Down] = Qt::Key_Down;
210    _keyMap[osgGA::GUIEventAdapter::KEY_KP_Prior] = Qt::Key_Left;
211    _keyMap[osgGA::GUIEventAdapter::KEY_KP_Page_Up] = Qt::Key_PageUp;
212    _keyMap[osgGA::GUIEventAdapter::KEY_KP_Next] = Qt::Key_Right;
213    _keyMap[osgGA::GUIEventAdapter::KEY_KP_Page_Down] = Qt::Key_PageDown;
214    _keyMap[osgGA::GUIEventAdapter::KEY_KP_End] = Qt::Key_End;
215
216    // _keyMap[osgGA::GUIEventAdapter::KEY_KP_Begin] = Qt::Key_Begin;
217    _keyMap[osgGA::GUIEventAdapter::KEY_KP_Insert] = Qt::Key_Insert;
218    _keyMap[osgGA::GUIEventAdapter::KEY_KP_Delete] = Qt::Key_Delete;
219    _keyMap[osgGA::GUIEventAdapter::KEY_KP_Equal] = Qt::Key_Equal;
220    _keyMap[osgGA::GUIEventAdapter::KEY_KP_Multiply] = Qt::Key_Asterisk;
221    _keyMap[osgGA::GUIEventAdapter::KEY_KP_Add] = Qt::Key_Plus;
222    //_keyMap[osgGA::GUIEventAdapter::KEY_KP_Separator] = Qt::Key_;
223    _keyMap[osgGA::GUIEventAdapter::KEY_KP_Subtract] = Qt::Key_Minus;
224    _keyMap[osgGA::GUIEventAdapter::KEY_KP_Decimal] = Qt::Key_Period;
225    _keyMap[osgGA::GUIEventAdapter::KEY_KP_Divide] = Qt::Key_division;
226    _keyMap[osgGA::GUIEventAdapter::KEY_KP_0] = Qt::Key_0;
227    _keyMap[osgGA::GUIEventAdapter::KEY_KP_1] = Qt::Key_1;
228    _keyMap[osgGA::GUIEventAdapter::KEY_KP_2] = Qt::Key_2;
229    _keyMap[osgGA::GUIEventAdapter::KEY_KP_3] = Qt::Key_3;
230    _keyMap[osgGA::GUIEventAdapter::KEY_KP_4] = Qt::Key_4;
231    _keyMap[osgGA::GUIEventAdapter::KEY_KP_5] = Qt::Key_5;
232    _keyMap[osgGA::GUIEventAdapter::KEY_KP_6] = Qt::Key_6;
233    _keyMap[osgGA::GUIEventAdapter::KEY_KP_7] = Qt::Key_7;
234    _keyMap[osgGA::GUIEventAdapter::KEY_KP_8] = Qt::Key_8;
235    _keyMap[osgGA::GUIEventAdapter::KEY_KP_9] = Qt::Key_9;
236
237    _keyMap[osgGA::GUIEventAdapter::KEY_F1] = Qt::Key_F1;
238    _keyMap[osgGA::GUIEventAdapter::KEY_F2] = Qt::Key_F2;
239    _keyMap[osgGA::GUIEventAdapter::KEY_F3] = Qt::Key_F3;
240    _keyMap[osgGA::GUIEventAdapter::KEY_F4] = Qt::Key_F4;
241    _keyMap[osgGA::GUIEventAdapter::KEY_F5] = Qt::Key_F5;
242    _keyMap[osgGA::GUIEventAdapter::KEY_F6] = Qt::Key_F6;
243    _keyMap[osgGA::GUIEventAdapter::KEY_F7] = Qt::Key_F7;
244    _keyMap[osgGA::GUIEventAdapter::KEY_F8] = Qt::Key_F8;
245    _keyMap[osgGA::GUIEventAdapter::KEY_F9] = Qt::Key_F9;
246    _keyMap[osgGA::GUIEventAdapter::KEY_F10] = Qt::Key_F10;
247    _keyMap[osgGA::GUIEventAdapter::KEY_F11] = Qt::Key_F11;
248    _keyMap[osgGA::GUIEventAdapter::KEY_F12] = Qt::Key_F12;
249    _keyMap[osgGA::GUIEventAdapter::KEY_F13] = Qt::Key_F13;
250    _keyMap[osgGA::GUIEventAdapter::KEY_F14] = Qt::Key_F14;
251    _keyMap[osgGA::GUIEventAdapter::KEY_F15] = Qt::Key_F15;
252    _keyMap[osgGA::GUIEventAdapter::KEY_F16] = Qt::Key_F16;
253    _keyMap[osgGA::GUIEventAdapter::KEY_F17] = Qt::Key_F17;
254    _keyMap[osgGA::GUIEventAdapter::KEY_F18] = Qt::Key_F18;
255    _keyMap[osgGA::GUIEventAdapter::KEY_F19] = Qt::Key_F19;
256    _keyMap[osgGA::GUIEventAdapter::KEY_F20] = Qt::Key_F20;
257    _keyMap[osgGA::GUIEventAdapter::KEY_F21] = Qt::Key_F21;
258    _keyMap[osgGA::GUIEventAdapter::KEY_F22] = Qt::Key_F22;
259    _keyMap[osgGA::GUIEventAdapter::KEY_F23] = Qt::Key_F23;
260    _keyMap[osgGA::GUIEventAdapter::KEY_F24] = Qt::Key_F24;
261    _keyMap[osgGA::GUIEventAdapter::KEY_F25] = Qt::Key_F25;
262    _keyMap[osgGA::GUIEventAdapter::KEY_F26] = Qt::Key_F26;
263    _keyMap[osgGA::GUIEventAdapter::KEY_F27] = Qt::Key_F27;
264    _keyMap[osgGA::GUIEventAdapter::KEY_F28] = Qt::Key_F28;
265    _keyMap[osgGA::GUIEventAdapter::KEY_F29] = Qt::Key_F29;
266    _keyMap[osgGA::GUIEventAdapter::KEY_F30] = Qt::Key_F30;
267    _keyMap[osgGA::GUIEventAdapter::KEY_F31] = Qt::Key_F31;
268    _keyMap[osgGA::GUIEventAdapter::KEY_F32] = Qt::Key_F32;
269    _keyMap[osgGA::GUIEventAdapter::KEY_F33] = Qt::Key_F33;
270    _keyMap[osgGA::GUIEventAdapter::KEY_F34] = Qt::Key_F34;
271    _keyMap[osgGA::GUIEventAdapter::KEY_F35] = Qt::Key_F35;
272
273}
274
275QWidget* QGraphicsViewAdapter::getWidgetAt(const QPoint& pos)
276{
277   QWidget* childAt = _graphicsView->childAt(pos);
278   if(childAt)
279   {
280       return childAt;
281   }
282 
283   QGraphicsItem* item = _graphicsView->itemAt(pos);
284   if(item && item->contains(item->mapFromScene(pos)))
285   {
286      QGraphicsProxyWidget* p = dynamic_cast<QGraphicsProxyWidget*>(item);
287      if(p)
288      { 
289         childAt = p->widget();
290         QWidget* c;
291         while( (c = childAt->childAt(childAt->mapFromGlobal(pos)))!=0 )
292         {
293            childAt = c;
294         }
295         return childAt;
296      }
297   }
298   return NULL;
299}
300
301bool QGraphicsViewAdapter::sendPointerEvent(int x, int y, int buttonMask)
302{
303    _previousQtMouseX = x;
304    _previousQtMouseY = _graphicsView->size().height() - y;
305   
306    QPoint pos(_previousQtMouseX, _previousQtMouseY);
307   
308    if (getWidgetAt(pos) != NULL || (_previousSentEvent && buttonMask != 0))
309    {
310        QCoreApplication::postEvent(this, new MyQPointerEvent(x,y,buttonMask));
311        OSG_INFO<<"sendPointerEvent("<<x<<", "<<y<<") sent"<<std::endl;
312        _previousSentEvent = true;
313        return true;
314    }
315   
316    OSG_INFO<<"sendPointerEvent("<<x<<", "<<y<<") not sent"<<std::endl;
317    _previousSentEvent = false;
318    return false;
319}
320
321bool QGraphicsViewAdapter::handlePointerEvent(int x, int y, int buttonMask)
322{
323    OSG_INFO<<"dispatchPointerEvent("<<x<<", "<<y<<", "<<buttonMask<<")"<<std::endl;
324
325    y = _graphicsView->size().height()-y;
326
327    bool leftButtonPressed = (buttonMask & osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)!=0;
328    bool middleButtonPressed = (buttonMask & osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON)!=0;
329    bool rightButtonPressed = (buttonMask & osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON)!=0;
330
331    bool prev_leftButtonPressed = (_previousButtonMask & osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)!=0;
332    bool prev_middleButtonPressed = (_previousButtonMask & osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON)!=0;
333    bool prev_rightButtonPressed = (_previousButtonMask & osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON)!=0;
334
335    OSG_INFO<<"leftButtonPressed "<<leftButtonPressed<<std::endl;
336    OSG_INFO<<"middleButtonPressed "<<middleButtonPressed<<std::endl;
337    OSG_INFO<<"rightButtonPressed "<<rightButtonPressed<<std::endl;
338
339    Qt::MouseButtons qtMouseButtons =
340        (leftButtonPressed ? Qt::LeftButton : Qt::NoButton) |
341        (middleButtonPressed ? Qt::MidButton : Qt::NoButton) |
342        (rightButtonPressed ? Qt::RightButton : Qt::NoButton);
343
344    const QRect viewportGeometry = _graphicsView->viewport()->geometry();
345    const QPoint globalPos(x, y);
346     
347
348     
349    if (buttonMask != _previousButtonMask)
350    {
351        Qt::MouseButton qtButton = Qt::NoButton;
352        QEvent::Type eventType = QEvent::None;
353        if (leftButtonPressed != prev_leftButtonPressed)
354        {
355            qtButton = Qt::LeftButton;
356            eventType = leftButtonPressed ? QEvent::MouseButtonPress : QEvent::MouseButtonRelease ;
357        }
358        else if (middleButtonPressed != prev_middleButtonPressed)
359        {
360            qtButton = Qt::MidButton;
361            eventType = middleButtonPressed ? QEvent::MouseButtonPress : QEvent::MouseButtonRelease ;
362        }
363        else if (rightButtonPressed != prev_rightButtonPressed)
364        {
365            qtButton = Qt::RightButton;
366            eventType = rightButtonPressed ? QEvent::MouseButtonPress : QEvent::MouseButtonRelease ;
367            if(!rightButtonPressed)
368            {
369               QWidget* targetWidget = getWidgetAt(globalPos);
370               if(targetWidget)
371               {
372                  QPoint localPos = targetWidget->mapFromGlobal(globalPos);
373                  QContextMenuEvent* cme = new QContextMenuEvent(QContextMenuEvent::Mouse, localPos, globalPos);
374                  QCoreApplication::postEvent(targetWidget, cme);
375               }               
376            }
377        }
378     
379        if (eventType==QEvent::MouseButtonPress)
380        {
381            _image->sendFocusHint(true);
382        }
383
384        QMouseEvent event(eventType, globalPos, qtButton, qtMouseButtons, 0);
385        QCoreApplication::sendEvent(_graphicsView->viewport(), &event );
386
387        _previousButtonMask = buttonMask;
388    }
389    else if (x != _previousMouseX || y != _previousMouseY)
390    {
391        QMouseEvent event(QEvent::MouseMove, globalPos, Qt::NoButton, qtMouseButtons, 0);
392        QCoreApplication::sendEvent(_graphicsView->viewport(), &event);
393
394        _previousMouseX = x;
395        _previousMouseY = y;
396    }
397
398    return true;
399}
400
401bool QGraphicsViewAdapter::sendKeyEvent(int key, bool keyDown)
402{
403    QPoint pos(_previousQtMouseX, _previousQtMouseY);
404    if (getWidgetAt(pos) != NULL)
405    {
406        QCoreApplication::postEvent(this, new MyQKeyEvent(key,keyDown));
407        return true;
408    }
409
410    return false;
411}
412
413bool QGraphicsViewAdapter::handleKeyEvent(int key, bool keyDown)
414{
415    QEvent::Type eventType = keyDown ? QEvent::KeyPress : QEvent::KeyRelease;
416
417    OSG_INFO<<"sendKeyEvent("<<key<<", "<<keyDown<<")"<<std::endl;
418
419    if (key==osgGA::GUIEventAdapter::KEY_Shift_L || key==osgGA::GUIEventAdapter::KEY_Shift_R)
420    {
421        _qtKeyModifiers = (_qtKeyModifiers & ~Qt::ShiftModifier) | (keyDown ? Qt::ShiftModifier : Qt::NoModifier);
422    }
423
424    if (key==osgGA::GUIEventAdapter::KEY_Control_L || key==osgGA::GUIEventAdapter::KEY_Control_R)
425    {
426        _qtKeyModifiers = (_qtKeyModifiers & ~Qt::ControlModifier) | (keyDown ? Qt::ControlModifier : Qt::NoModifier);
427    }
428
429    if (key==osgGA::GUIEventAdapter::KEY_Alt_L || key==osgGA::GUIEventAdapter::KEY_Alt_R)
430    {
431        _qtKeyModifiers = (_qtKeyModifiers & ~Qt::ControlModifier) | (keyDown ? Qt::ControlModifier : Qt::NoModifier);
432    }
433
434    if (key==osgGA::GUIEventAdapter::KEY_Meta_L || key==osgGA::GUIEventAdapter::KEY_Meta_R)
435    {
436        _qtKeyModifiers = (_qtKeyModifiers & ~Qt::MetaModifier) | (keyDown ? Qt::MetaModifier : Qt::NoModifier);
437    }
438
439    Qt::Key qtkey;
440    QChar input;
441
442    KeyMap::iterator itr = _keyMap.find(key);
443    if (itr != _keyMap.end())
444    {
445        qtkey = itr->second;
446    }
447    else
448    {
449        qtkey = (Qt::Key)key;
450        input = QChar(key);
451    }
452
453    QKeyEvent event(eventType, qtkey, _qtKeyModifiers, input);
454    QCoreApplication::sendEvent(_graphicsScene.data(), &event);
455    return true;
456}
457
458void QGraphicsViewAdapter::setFrameLastRendered(const osg::FrameStamp* frameStamp)
459{
460    OSG_INFO<<"setFrameLastRendered("<<frameStamp->getFrameNumber()<<")"<<std::endl;
461
462    if (_newImageAvailable && _previousFrameNumber!=frameStamp->getFrameNumber())
463    {
464        {
465            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_qimagesMutex);
466
467            // make sure that _previousFrameNumber hasn't been updated by another thread since we entered this branch.
468            if (_previousFrameNumber==frameStamp->getFrameNumber()) return;
469            _previousFrameNumber = frameStamp->getFrameNumber();
470
471            std::swap(_currentRead, _previousWrite);
472            _newImageAvailable = false;
473        }
474
475        assignImage(_currentRead);
476    }
477}
478
479void QGraphicsViewAdapter::clearWriteBuffer()
480{
481    QImage& image = _qimages[_currentWrite];
482    image.fill(_backgroundColor.rgba ());
483    image = QGLWidget::convertToGLFormat(image);
484
485    // swap the write buffers in a thread safe way
486    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_qimagesMutex);
487    std::swap(_currentWrite, _previousWrite);
488    _newImageAvailable = true;
489}
490
491void QGraphicsViewAdapter::render()
492{
493    OSG_INFO<<"Current write = "<<_currentWrite<<std::endl;
494    QImage& image = _qimages[_currentWrite];
495
496    // If we got a resize, act on it, first by resizing the view, then the current image
497
498    {
499        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_qresizeMutex);
500        if (_graphicsView->size().width() != _width || _graphicsView->size().height() != _height)
501        {
502            _graphicsView->setGeometry(0, 0, _width, _height);
503            _graphicsView->viewport()->setGeometry(0, 0, _width, _height);
504
505            _widget->setGeometry(0, 0, _width, _height);
506        }
507
508        if (image.width() != _width || image.height() != _height)
509        {
510            _qimages[_currentWrite] = QImage(_width, _height, s_imageFormat);
511            image = _qimages[_currentWrite];
512        }
513        OSG_INFO << "render image " << _currentWrite << " with size (" << _width << "," << _height << ")" <<std::endl;
514    }
515   
516#if 1
517    // paint the image with the graphics view
518    QPainter painter(&image);
519
520    // Clear the image otherwise there are artifacts for some widgets that overpaint.
521    painter.setCompositionMode(QPainter::CompositionMode_Source);
522    painter.fillRect(0, 0, image.width(), image.height(), _backgroundColor);
523    painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
524
525    QRectF destinationRect(0, 0, image.width(), image.height());
526    QRect sourceRect(0, 0, image.width(), image.height());
527    _graphicsView->render(&painter, destinationRect, sourceRect, Qt::IgnoreAspectRatio);
528    painter.end();
529#elif 0
530    QPixmap pixmap(QPixmap::grabWidget(_graphicsView.data(), QRect(0, 0, image.width(), image.height())));
531    image = pixmap.toImage();
532#else
533    // paint the image with the graphics view
534    QPixmap pixmap(image.width(), image.height());
535    // Clear the image otherwise there are artifacts for some widgets that overpaint.
536    pixmap.fill(Qt::transparent);
537    QPainter painter(&pixmap);
538
539    QRectF destinationRect(0, 0, image.width(), image.height());
540    QRect sourceRect(0, 0, image.width(), image.height());
541    _graphicsView->render(&painter, destinationRect, _graphicsView->viewport()->rect());
542    painter.end();
543
544    image = pixmap.toImage();
545#endif
546
547    // convert into OpenGL format - flipping around the Y axis and swizzling the pixels
548    image = QGLWidget::convertToGLFormat(image);
549
550    // swap the write buffers in a thread safe way
551    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_qimagesMutex);
552    std::swap(_currentWrite, _previousWrite);
553    _newImageAvailable = true;
554}
555
556void QGraphicsViewAdapter::assignImage(unsigned int i)
557{
558    QImage& image = _qimages[i];
559    unsigned char* data = image.bits();
560
561    OSG_INFO<<"assignImage("<<i<<") image = "<<&image<<" size = ("<<image.width()<<","<<image.height()<<") data = "<<(void*)data<<std::endl;
562
563    _image->setImage(image.width(), image.height(), 1,
564                     4, GL_RGBA, GL_UNSIGNED_BYTE,
565                     data, osg::Image::NO_DELETE, 1);
566}
567
568void QGraphicsViewAdapter::resize(int width, int height)
569{
570    OSG_INFO << "resize to (" << width << "," << height << ")" <<std::endl;
571
572    // Save the new width and height which will take effect on the next render() (in the Qt thread).
573   
574    {
575        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_qresizeMutex);
576        _width = width;
577        _height = height;
578    }
579
580    // Force an update so render() will be called.
581    _graphicsScene->update(_graphicsScene->sceneRect());
582}
583
584}
Note: See TracBrowser for help on using the browser.