diff options
author | Antti Määttä <antti.maatta@qt.io> | 2016-11-22 13:45:45 +0200 |
---|---|---|
committer | Antti Määttä <antti.maatta@qt.io> | 2017-01-27 12:06:52 +0000 |
commit | 1e04bb374fafe4a00d0fd4b8d5a0c5588781f888 (patch) | |
tree | 9422c8d25b1d55b0e5bdd9d92f3917f7e4fd4efd | |
parent | 7d1ba2e0676241634f38d907b10ae6e2bd2c6f0a (diff) |
Move event forwarding to frontend
Move the event forwarding to frontend so that the target object
destruction can be handled properly.
Change-Id: I6bdee731760cee69334aad7ca39f0dd16c44a471
Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r-- | src/render/picking/eventforward.cpp | 41 | ||||
-rw-r--r-- | src/render/picking/eventforward_p.h | 4 | ||||
-rw-r--r-- | src/render/picking/picking.pri | 6 | ||||
-rw-r--r-- | src/render/picking/posteventstofrontend.cpp | 74 | ||||
-rw-r--r-- | src/render/picking/posteventstofrontend_p.h | 81 | ||||
-rw-r--r-- | src/render/picking/qeventforward.cpp | 31 | ||||
-rw-r--r-- | src/render/picking/qeventforward.h | 4 | ||||
-rw-r--r-- | src/render/picking/qeventforward_p.h | 1 |
8 files changed, 217 insertions, 25 deletions
diff --git a/src/render/picking/eventforward.cpp b/src/render/picking/eventforward.cpp index 132e022ce..0216542bd 100644 --- a/src/render/picking/eventforward.cpp +++ b/src/render/picking/eventforward.cpp @@ -40,6 +40,7 @@ #include <private/qeventforward_p.h> #include <private/eventforward_p.h> +#include <private/posteventstofrontend_p.h> #include <QtGui/qevent.h> #include <QtCore/qcoreapplication.h> @@ -51,7 +52,7 @@ namespace Qt3DRender { namespace Render { EventForward::EventForward() - : m_target(nullptr) + : BackendNode(QBackendNode::ReadWrite) , m_forwardMouseEvents(false) , m_forwardKeyboardEvents(false) , m_focus(false) @@ -67,7 +68,6 @@ EventForward::~EventForward() void EventForward::cleanup() { setEnabled(false); - m_target = nullptr; m_coordinateAttribute = ""; m_coordinateTransform.setToIdentity(); m_forwardMouseEvents = false; @@ -75,11 +75,6 @@ void EventForward::cleanup() m_focus = false; } -QObject *EventForward::target() const -{ - return m_target; -} - QString EventForward::coordinateAttribute() const { return m_coordinateAttribute; @@ -105,11 +100,6 @@ bool EventForward::focus() const return m_focus; } -void EventForward::setTarget(QObject *target) -{ - m_target = target; -} - void EventForward::setCoordinateTransform(const QMatrix4x4 &transform) { m_coordinateTransform = transform; @@ -139,7 +129,6 @@ void EventForward::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr { const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QEventForwardData>>(change); const auto &data = typedChange->data; - setTarget(data.target); setCoordinateAttribute(data.coordinateAttribute); setCoordinateTransform(data.coordinateTransform); setForwardMouseEvents(data.forwardMouseEvents); @@ -153,9 +142,7 @@ void EventForward::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) const Qt3DCore::QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(e); - if (propertyChange->propertyName() == QByteArrayLiteral("target")) - setTarget(propertyChange->value().value<QObject*>()); - else if (propertyChange->propertyName() == QByteArrayLiteral("coordinateTransform")) + if (propertyChange->propertyName() == QByteArrayLiteral("coordinateTransform")) setCoordinateTransform(propertyChange->value().value<QMatrix4x4>()); else if (propertyChange->propertyName() == QByteArrayLiteral("coordinateAttribute")) setCoordinateAttribute(propertyChange->value().toString()); @@ -177,16 +164,30 @@ void EventForward::forward(const QMouseEvent &event, const QVector4D &coordinate QMouseEvent *mouseEvent = new QMouseEvent(event.type(), local, local, local, event.button(), event.buttons(), event.modifiers(), Qt::MouseEventSynthesizedByApplication); - QCoreApplication::postEvent(m_target, mouseEvent); + + PostEventsToFrontendPtr events = PostEventsToFrontendPtr::create(mouseEvent); + + auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId()); + e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll); + e->setPropertyName("events"); + e->setValue(QVariant::fromValue(events)); + notifyObservers(e); } -void EventForward::forward(const QList<QKeyEvent> &events) +void EventForward::forward(const QList<QKeyEvent> &keyEvents) { - for (const QKeyEvent &e : events) { + QVector<QEvent *> eventsToSend; + for (const QKeyEvent &e : keyEvents) { QKeyEvent *keyEvent = new QKeyEvent(e.type(), e.key(), e.modifiers(), e.nativeScanCode(), e.nativeVirtualKey(), e.nativeModifiers()); - QCoreApplication::postEvent(m_target, keyEvent); + eventsToSend.append(keyEvent); } + PostEventsToFrontendPtr events = PostEventsToFrontendPtr::create(eventsToSend); + auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId()); + e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll); + e->setPropertyName("events"); + e->setValue(QVariant::fromValue(events)); + notifyObservers(e); } } // Render diff --git a/src/render/picking/eventforward_p.h b/src/render/picking/eventforward_p.h index e090ba5e4..663298e40 100644 --- a/src/render/picking/eventforward_p.h +++ b/src/render/picking/eventforward_p.h @@ -69,7 +69,6 @@ public: void cleanup(); - QObject *target() const; QString coordinateAttribute() const; QMatrix4x4 coordinateTransform() const; bool forwardMouseEvents() const; @@ -86,12 +85,11 @@ public: void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_FINAL; void forward(const QMouseEvent &event, const QVector4D &coordinate); - void forward(const QList<QKeyEvent> &events); + void forward(const QList<QKeyEvent> &keyEvents); private: void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) Q_DECL_FINAL; - QObject *m_target; QString m_coordinateAttribute; QMatrix4x4 m_coordinateTransform; bool m_forwardMouseEvents; diff --git a/src/render/picking/picking.pri b/src/render/picking/picking.pri index e581a8f8a..c2eb8f50b 100644 --- a/src/render/picking/picking.pri +++ b/src/render/picking/picking.pri @@ -10,7 +10,8 @@ HEADERS += \ $$PWD/qobjectpicker_p.h \ $$PWD/qeventforward.h \ $$PWD/qeventforward_p.h \ - $$PWD/eventforward_p.h + $$PWD/eventforward_p.h \ + $$PWD/posteventstofrontend_p.h SOURCES += \ $$PWD/qobjectpicker.cpp \ @@ -19,4 +20,5 @@ SOURCES += \ $$PWD/objectpicker.cpp \ $$PWD/pickeventfilter.cpp \ $$PWD/qeventforward.cpp \ - $$PWD/eventforward.cpp + $$PWD/eventforward.cpp \ + $$PWD/posteventstofrontend.cpp diff --git a/src/render/picking/posteventstofrontend.cpp b/src/render/picking/posteventstofrontend.cpp new file mode 100644 index 000000000..51f986902 --- /dev/null +++ b/src/render/picking/posteventstofrontend.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "posteventstofrontend_p.h" + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +PostEventsToFrontend::PostEventsToFrontend() + : QObject() +{ + +} + +PostEventsToFrontend::PostEventsToFrontend(QEvent *event) + : QObject() +{ + m_events.append(event); +} + +PostEventsToFrontend::PostEventsToFrontend(const QVector<QEvent *> &events) + : QObject() +{ + m_events = events; +} + +PostEventsToFrontend::~PostEventsToFrontend() +{ + for (QEvent *e : m_events) + delete e; +} + +QVector<QEvent *> &PostEventsToFrontend::events() +{ + return m_events; +} + +} + +QT_END_NAMESPACE diff --git a/src/render/picking/posteventstofrontend_p.h b/src/render/picking/posteventstofrontend_p.h new file mode 100644 index 000000000..5dd29b047 --- /dev/null +++ b/src/render/picking/posteventstofrontend_p.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DRENDER_POSTEVENTSTOFRONTEND_P_H +#define QT3DRENDER_POSTEVENTSTOFRONTEND_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qevent.h> +#include <QtCore/qvector.h> +#include <QtCore/qsharedpointer.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +class Q_AUTOTEST_EXPORT PostEventsToFrontend : public QObject +{ + Q_OBJECT +public: + PostEventsToFrontend(); + PostEventsToFrontend(QEvent *event); + PostEventsToFrontend(const QVector<QEvent *> &events); + ~PostEventsToFrontend(); + + QVector<QEvent *> &events(); +private: + QVector<QEvent *> m_events; +}; + +typedef QSharedPointer<PostEventsToFrontend> PostEventsToFrontendPtr; + +} // Qt3DRender + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(Qt3DRender::PostEventsToFrontend*) + +#endif // QT3DRENDER_POSTEVENTSTOFRONTEND_P_H diff --git a/src/render/picking/qeventforward.cpp b/src/render/picking/qeventforward.cpp index 8aa22e276..08546fabd 100644 --- a/src/render/picking/qeventforward.cpp +++ b/src/render/picking/qeventforward.cpp @@ -36,8 +36,12 @@ #include "qeventforward.h" #include "qeventforward_p.h" +#include "posteventstofrontend_p.h" #include <Qt3DCore/qpropertyupdatedchange.h> +#include <QtCore/qcoreapplication.h> + +#include <QtGui/qevent.h> QT_BEGIN_NAMESPACE @@ -148,11 +152,24 @@ QObject *QEventForward::target() const return d->m_target; } +void QEventForward::targetDestroyed(QObject *target) +{ + Q_D(QEventForward); + Q_ASSERT(target == d->m_target); + setTarget(nullptr); +} + void QEventForward::setTarget(QObject *target) { Q_D(QEventForward); if (target != d->m_target) { + if (d->m_target != nullptr) + QObject::disconnect(d->m_destructionConnection); d->m_target = target; + if (d->m_target) { + d->m_destructionConnection = QObject::connect(target, &QObject::destroyed, + this, &QEventForward::targetDestroyed); + } emit targetChanged(target); } } @@ -249,6 +266,20 @@ Qt3DCore::QNodeCreatedChangeBasePtr QEventForward::createNodeCreationChange() co return creationChange; } +void QEventForward::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) +{ + Q_D(QEventForward); + Qt3DCore::QPropertyUpdatedChangePtr e + = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(change); + if (e->type() == Qt3DCore::PropertyUpdated && d->m_target != nullptr) { + if (e->propertyName() == QByteArrayLiteral("events")) { + PostEventsToFrontendPtr postedEvents = e->value().value<PostEventsToFrontendPtr>(); + for (QEvent *event : postedEvents->events()) + QCoreApplication::sendEvent(d->m_target, event); + } + } +} + } // Qt3DRender QT_END_NAMESPACE diff --git a/src/render/picking/qeventforward.h b/src/render/picking/qeventforward.h index 28659606b..ee8100318 100644 --- a/src/render/picking/qeventforward.h +++ b/src/render/picking/qeventforward.h @@ -87,9 +87,13 @@ Q_SIGNALS: void forwardKeyboardEventsChanged(bool forward); void focusChanged(bool focus); +protected: + void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) Q_DECL_OVERRIDE; + private: Q_DECLARE_PRIVATE(QEventForward) Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const Q_DECL_OVERRIDE; + void targetDestroyed(QObject *target); }; } // Qt3DRender diff --git a/src/render/picking/qeventforward_p.h b/src/render/picking/qeventforward_p.h index 4aa6834df..c087bc8f5 100644 --- a/src/render/picking/qeventforward_p.h +++ b/src/render/picking/qeventforward_p.h @@ -81,6 +81,7 @@ public: bool m_forwardMouseEvents; bool m_forwardKeyboardEvents; bool m_focus; + QMetaObject::Connection m_destructionConnection; }; struct QEventForwardData |