81 {GUIEventAdapter::KEY_Space, Qt::Key_Space,
" "},
82 {GUIEventAdapter::KEY_Escape, Qt::Key_Escape,
"\x1B"},
83 {GUIEventAdapter::KEY_Return, Qt::Key_Return,
"\r"},
84 {GUIEventAdapter::KEY_Tab, Qt::Key_Tab,
"\t"},
85 {GUIEventAdapter::KEY_BackSpace, Qt::Key_Backspace,
"\x08"},
86 {GUIEventAdapter::KEY_Delete, Qt::Key_Delete,
"\x7f"},
88 {GUIEventAdapter::KEY_Period, Qt::Key_Period,
"."},
89 {GUIEventAdapter::KEY_Comma, Qt::Key_Comma,
","},
90 {GUIEventAdapter::KEY_Colon, Qt::Key_Colon,
":"},
91 {GUIEventAdapter::KEY_Quote, Qt::Key_QuoteLeft,
"'"},
92 {GUIEventAdapter::KEY_Quotedbl, Qt::Key_QuoteDbl,
"\""},
93 {GUIEventAdapter::KEY_Underscore, Qt::Key_Underscore,
"_"},
94 {GUIEventAdapter::KEY_Plus, Qt::Key_Plus,
"+"},
95 {GUIEventAdapter::KEY_Minus, Qt::Key_Minus,
"-"},
96 {GUIEventAdapter::KEY_Asterisk, Qt::Key_Asterisk,
"*"},
97 {GUIEventAdapter::KEY_Equals, Qt::Key_Equal,
"="},
98 {GUIEventAdapter::KEY_Slash, Qt::Key_Slash,
"/"},
100 {GUIEventAdapter::KEY_Left, Qt::Key_Left},
101 {GUIEventAdapter::KEY_Right, Qt::Key_Right},
102 {GUIEventAdapter::KEY_Up, Qt::Key_Up},
103 {GUIEventAdapter::KEY_Down, Qt::Key_Down},
105 {GUIEventAdapter::KEY_Shift_L, Qt::Key_Shift},
106 {GUIEventAdapter::KEY_Shift_R, Qt::Key_Shift},
107 {GUIEventAdapter::KEY_Control_L, Qt::Key_Control},
108 {GUIEventAdapter::KEY_Control_R, Qt::Key_Control},
109 {GUIEventAdapter::KEY_Meta_L, Qt::Key_Meta},
110 {GUIEventAdapter::KEY_Meta_R, Qt::Key_Meta},
302 bool handle(
const GUIEventAdapter& ea, GUIActionAdapter& aa, osg::Object*, osg::NodeVisitor*)
override
306 if (ea.getHandled())
return false;
309 if (ea.getEventType() == GUIEventAdapter::FRAME) {
310 _drawable->frameEvent();
315 const float fixedY = (ea.getMouseYOrientation() == GUIEventAdapter::Y_INCREASING_UPWARDS) ? ea.getWindowHeight() - ea.getY() : ea.getY();
316 const double pixelRatio = _drawable->foreignOSGWindow->devicePixelRatio();
318 QPointF pointInWindow{ea.getX() / pixelRatio, fixedY / pixelRatio};
319 QPointF screenPt = pointInWindow +
320 QPointF{ea.getWindowX() / pixelRatio, ea.getWindowY() / pixelRatio};
325 switch (ea.getEventType()) {
326 case (GUIEventAdapter::DRAG):
327 case (GUIEventAdapter::MOVE): {
328 QMouseEvent m(QEvent::MouseMove, pointInWindow, pointInWindow, screenPt,
330 osgButtonMaskToQt(ea), osgModifiersToQt(ea));
331 QCoreApplication::sendEvent(_drawable->quickWindow, &m);
332 return m.isAccepted();
335 case (GUIEventAdapter::PUSH):
336 case (GUIEventAdapter::RELEASE): {
337 const bool isUp = (ea.getEventType() == GUIEventAdapter::RELEASE);
338 QMouseEvent m(isUp ? QEvent::MouseButtonRelease : QEvent::MouseButtonPress,
339 pointInWindow, pointInWindow, screenPt,
341 osgButtonMaskToQt(ea), osgModifiersToQt(ea));
342 QCoreApplication::sendEvent(_drawable->quickWindow, &m);
345 if (m.isAccepted()) {
347 auto active = puActiveWidget();
349 active->invokeDownCallback();
361 return m.isAccepted();
364 case (GUIEventAdapter::KEYDOWN):
365 case (GUIEventAdapter::KEYUP): {
366 if (!_drawable->quickWindow->activeFocusItem()) {
370 const bool isKeyRelease = (ea.getEventType() == GUIEventAdapter::KEYUP);
371 const auto& key = osgKeyToQt(ea.getKey());
374 QKeyEvent k(isKeyRelease ? QEvent::KeyRelease : QEvent::KeyPress,
375 key.qt, osgModifiersToQt(ea), s);
376 QCoreApplication::sendEvent(_drawable->quickWindow, &k);
377 return k.isAccepted();
387 Qt::MouseButtons osgButtonMaskToQt(
const osgGA::GUIEventAdapter& ea)
const
389 const int mask = ea.getButtonMask();
390 Qt::MouseButtons result = Qt::NoButton;
391 if (mask & osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
392 result |= Qt::LeftButton;
394 if (mask & osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON)
395 result |= Qt::MiddleButton;
397 if (mask & osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON)
398 result |= Qt::RightButton;
403 Qt::MouseButton osgButtonToQt(
const osgGA::GUIEventAdapter& ea)
const
405 switch (ea.getButton()) {
406 case osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON:
return Qt::LeftButton;
407 case osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON:
return Qt::MiddleButton;
408 case osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON:
return Qt::RightButton;
417 Qt::KeyboardModifiers osgModifiersToQt(
const osgGA::GUIEventAdapter& ea)
const
419 Qt::KeyboardModifiers result = Qt::NoModifier;
420 const int mask = ea.getModKeyMask();
421 if (mask & osgGA::GUIEventAdapter::MODKEY_ALT) result |= Qt::AltModifier;
422 if (mask & osgGA::GUIEventAdapter::MODKEY_CTRL) result |= Qt::ControlModifier;
423 if (mask & osgGA::GUIEventAdapter::MODKEY_META) result |= Qt::MetaModifier;
424 if (mask & osgGA::GUIEventAdapter::MODKEY_SHIFT) result |= Qt::ShiftModifier;
428 QtKey osgKeyToQt(
int code)
const
432 [](
const QtKey& a,
const QtKey& b) {
return a.
osg < b.osg; });
434 qWarning() <<
"no mapping defined for OSG key:" << code;
441 void populateKeymap()
447 for (
int i = 0;
i < 10; ++
i) {
448 global_keymap.emplace_back(GUIEventAdapter::KEY_0 +
i, Qt::Key_0 +
i, QString::number(
i));
451 for (
int i = 0;
i < 26; ++
i) {
452 global_keymap.emplace_back(GUIEventAdapter::KEY_A +
i, Qt::Key_A +
i, QChar::fromLatin1(
'a' +
i));
455 for (
int i = 0;
i < 26; ++
i) {
456 global_keymap.emplace_back(
'A' +
i, Qt::Key_A +
i, QChar::fromLatin1(
'A' +
i));
464 [](
const QtKey& a,
const QtKey& b) { return a.osg < b.osg; });
472 setUseDisplayList(
false);
473 setDataVariance(Object::DYNAMIC);
475 osg::StateSet* stateSet = getOrCreateStateSet();
476 stateSet->setRenderBinDetails(1001,
"RenderBin");
478 QSurfaceFormat format;
479 format.setRenderableType(QSurfaceFormat::OpenGL);
480 QSurfaceFormat::setDefaultFormat(format);
482 static bool doneQmlRegistration =
false;
483 if (!doneQmlRegistration) {
484 doneQmlRegistration =
true;
491 qmlRegisterType<FGQmlPropertyNode>(
"FlightGear", 1, 0,
"Property");
492 qmlRegisterType<DialogStateController>(
"FlightGear", 1, 0,
"DialogStateController");
506 osg::GraphicsContext* gc = gw;
513 d->foreignOSGWindow->setSurfaceType(QSurface::OpenGLSurface);
522 d->quickWindow =
new QQuickWindow(d->renderControl);
523 d->quickWindow->setClearBeforeRendering(
false);
525 d->qmlEngine =
new QQmlEngine;
527 SGPath rootQMLPath = SGPath::fromUtf8(
fgGetString(
"/sim/gui/qml-root-path"));
528 SG_LOG(SG_GENERAL, SG_INFO,
"Root QML dir:" << rootQMLPath.dir());
529 d->qmlEngine->addImportPath(QString::fromStdString(rootQMLPath.dir()));
532 if (!d->qmlEngine->incubationController())
533 d->qmlEngine->setIncubationController(d->quickWindow->incubationController());
538 QObject::connect(d->renderControl, &QQuickRenderControl::sceneChanged,
540 QObject::connect(d->renderControl, &QQuickRenderControl::renderRequested,
549 if (!d->renderControlInited) {
550 d->initRenderControl();
553 if (QOpenGLContext::currentContext() != d->qtContext) {
554 QOpenGLContextPrivate::setCurrentContext(d->qtContext);
557 QOpenGLFunctions* glFuncs = d->qtContext->functions();
559 d->quickWindow->resetOpenGLState();
562 glFuncs->glPixelStorei(GL_PACK_ALIGNMENT, 4);
563 glFuncs->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
564 glFuncs->glPixelStorei(GL_PACK_ROW_LENGTH, 0);
565 glFuncs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
567 d->renderControl->render();
570 d->quickWindow->resetOpenGLState();