diff options
author | Sean Harmer <sean.harmer@kdab.com> | 2015-10-25 10:13:19 +0000 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2015-10-25 11:07:14 +0000 |
commit | 9273ccc5dd0616d1443791dfba90ba9aa7b9c458 (patch) | |
tree | cdb8e4049b56d5116099a6a02aeb517e4229aa8c /src/render/picking | |
parent | c0cf00711a84b2ec5c2d0d24a83db57a31bfcdae (diff) |
Move picking into its own directory
Change-Id: I4982f08d18c855a57f621af28b13cc876f20eb16
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Diffstat (limited to 'src/render/picking')
-rw-r--r-- | src/render/picking/objectpicker.cpp | 163 | ||||
-rw-r--r-- | src/render/picking/objectpicker_p.h | 92 | ||||
-rw-r--r-- | src/render/picking/pickeventfilter.cpp | 93 | ||||
-rw-r--r-- | src/render/picking/pickeventfilter_p.h | 84 | ||||
-rw-r--r-- | src/render/picking/picking.pri | 13 | ||||
-rw-r--r-- | src/render/picking/qobjectpicker.cpp | 326 | ||||
-rw-r--r-- | src/render/picking/qobjectpicker.h | 99 | ||||
-rw-r--r-- | src/render/picking/qpickevent.cpp | 83 | ||||
-rw-r--r-- | src/render/picking/qpickevent.h | 71 |
9 files changed, 1024 insertions, 0 deletions
diff --git a/src/render/picking/objectpicker.cpp b/src/render/picking/objectpicker.cpp new file mode 100644 index 000000000..38775327c --- /dev/null +++ b/src/render/picking/objectpicker.cpp @@ -0,0 +1,163 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Paul Lemire paul.lemire350@gmail.com +** Contact: http://www.qt-project.org/legal +** +** 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 "objectpicker_p.h" +#include <Qt3DRender/qobjectpicker.h> +#include <Qt3DRender/qattribute.h> +#include <Qt3DCore/qscenepropertychange.h> +#include <Qt3DCore/qbackendscenepropertychange.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +namespace Render { + +ObjectPicker::ObjectPicker() + : QBackendNode(QBackendNode::ReadWrite) + , m_isDirty(false) + , m_hoverEnabled(false) +{ +} + +ObjectPicker::~ObjectPicker() +{ +} + +void ObjectPicker::cleanup() +{ + m_isDirty = false; + m_hoverEnabled = false; + m_pickAttributeId = Qt3DCore::QNodeId(); +} + +void ObjectPicker::updateFromPeer(Qt3DCore::QNode *peer) +{ + QObjectPicker *picker = static_cast<QObjectPicker *>(peer); + if (picker) { + if (picker->pickAttribute()) + m_pickAttributeId = picker->pickAttribute()->id(); + m_hoverEnabled = picker->hoverEnabled(); + m_isDirty = true; + } +} + +void ObjectPicker::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) +{ + const Qt3DCore::QScenePropertyChangePtr propertyChange = qSharedPointerCast<Qt3DCore::QScenePropertyChange>(e); + const QByteArray propertyName = propertyChange->propertyName(); + + if (propertyChange->type() == Qt3DCore::NodeUpdated) { + if (propertyName == QByteArrayLiteral("pickAttribute")) { + m_pickAttributeId = propertyChange->value().value<Qt3DCore::QNodeId>(); + m_isDirty = true; + } else if (propertyName == QByteArrayLiteral("hoverEnabled")) { + m_hoverEnabled = propertyChange->value().toBool(); + m_isDirty = true; + } + } +} + +Qt3DCore::QNodeId ObjectPicker::pickAttributeId() const +{ + return m_pickAttributeId; +} + +bool ObjectPicker::isDirty() const +{ + return m_isDirty; +} + +void ObjectPicker::unsetDirty() +{ + m_isDirty = false; +} + +void ObjectPicker::makeDirty() +{ + m_isDirty = true; +} + +bool ObjectPicker::hoverEnabled() const +{ + return m_hoverEnabled; +} + +void ObjectPicker::onClicked() +{ + Qt3DCore::QBackendScenePropertyChangePtr e(new Qt3DCore::QBackendScenePropertyChange(Qt3DCore::NodeUpdated, peerUuid())); + e->setPropertyName("clicked"); + e->setTargetNode(peerUuid()); + notifyObservers(e); +} + +void ObjectPicker::onPressed() +{ + Qt3DCore::QBackendScenePropertyChangePtr e(new Qt3DCore::QBackendScenePropertyChange(Qt3DCore::NodeUpdated, peerUuid())); + e->setPropertyName("pressed"); + e->setTargetNode(peerUuid()); + notifyObservers(e); +} + +void ObjectPicker::onReleased() +{ + Qt3DCore::QBackendScenePropertyChangePtr e(new Qt3DCore::QBackendScenePropertyChange(Qt3DCore::NodeUpdated, peerUuid())); + e->setPropertyName("released"); + e->setTargetNode(peerUuid()); + notifyObservers(e); +} + +void ObjectPicker::onEntered() +{ + Qt3DCore::QBackendScenePropertyChangePtr e(new Qt3DCore::QBackendScenePropertyChange(Qt3DCore::NodeUpdated, peerUuid())); + e->setPropertyName("entered"); + e->setTargetNode(peerUuid()); + notifyObservers(e); +} + +void ObjectPicker::onExited() +{ + Qt3DCore::QBackendScenePropertyChangePtr e(new Qt3DCore::QBackendScenePropertyChange(Qt3DCore::NodeUpdated, peerUuid())); + e->setPropertyName("exited"); + e->setTargetNode(peerUuid()); + notifyObservers(e); +} + +} // Render + +} // Qt3DRender + +QT_END_NAMESPACE diff --git a/src/render/picking/objectpicker_p.h b/src/render/picking/objectpicker_p.h new file mode 100644 index 000000000..a7dc0e3a2 --- /dev/null +++ b/src/render/picking/objectpicker_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Paul Lemire paul.lemire350@gmail.com +** Contact: http://www.qt-project.org/legal +** +** 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_RENDER_OBJECTPICKER_P_H +#define QT3DRENDER_RENDER_OBJECTPICKER_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 <Qt3DCore/qbackendnode.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +namespace Render { + +class Q_AUTOTEST_EXPORT ObjectPicker : public Qt3DCore::QBackendNode +{ +public: + ObjectPicker(); + ~ObjectPicker(); + + void cleanup(); + void updateFromPeer(Qt3DCore::QNode *peer) Q_DECL_FINAL; + void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_FINAL; + Qt3DCore::QNodeId pickAttributeId() const; + bool isDirty() const; + void unsetDirty(); + void makeDirty(); + bool hoverEnabled() const; + + void onClicked(); + void onPressed(); + void onReleased(); + void onEntered(); + void onExited(); + +private: + Qt3DCore::QNodeId m_pickAttributeId; + bool m_isDirty; + bool m_hoverEnabled; +}; + +} // Render + +} // Qt3DRender + +QT_END_NAMESPACE + +#endif // QT3DRENDER_RENDER_OBJECTPICKER_H diff --git a/src/render/picking/pickeventfilter.cpp b/src/render/picking/pickeventfilter.cpp new file mode 100644 index 000000000..35aed07a7 --- /dev/null +++ b/src/render/picking/pickeventfilter.cpp @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Paul Lemire paul.lemire350@gmail.com +** Contact: http://www.qt-project.org/legal +** +** 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 "pickeventfilter_p.h" + +#include <QtCore/QMutexLocker> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +namespace Render { + +PickEventFilter::PickEventFilter(QObject *parent) + : QObject(parent) +{ +} + +PickEventFilter::~PickEventFilter() +{ +} + +/*! + \internal + Called from a worker thread in the thread pool so be sure to + mutex protect the data. +*/ +QList<QMouseEvent> PickEventFilter::pendingEvents() +{ + QMutexLocker locker(&m_mutex); + QList<QMouseEvent> pendingEvents(m_pendingEvents); + m_pendingEvents.clear(); + return pendingEvents; +} + +/*! + \internal + Called from the main thread. +*/ +bool PickEventFilter::eventFilter(QObject *obj, QEvent *e) +{ + switch (e->type()) { + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseMove: + case Qt::TapGesture: { + QMutexLocker locker(&m_mutex); + m_pendingEvents.push_back(QMouseEvent(*static_cast<QMouseEvent *>(e))); + } + default: + break; + } + return false; +} + +} // Render + +} // Qt3DRender + +QT_END_NAMESPACE diff --git a/src/render/picking/pickeventfilter_p.h b/src/render/picking/pickeventfilter_p.h new file mode 100644 index 000000000..d34172e69 --- /dev/null +++ b/src/render/picking/pickeventfilter_p.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Paul Lemire paul.lemire350@gmail.com +** Contact: http://www.qt-project.org/legal +** +** 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_RENDER_PICKEVENTFILTER_H +#define QT3DRENDER_RENDER_PICKEVENTFILTER_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 <QObject> +#include <QMouseEvent> +#include <QtCore/qmutex.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +namespace Render { + +class PickEventFilter : public QObject +{ + Q_OBJECT +public: + explicit PickEventFilter(QObject *parent = Q_NULLPTR); + ~PickEventFilter(); + + QList<QMouseEvent> pendingEvents(); + +protected: + bool eventFilter(QObject *obj, QEvent *e) Q_DECL_FINAL; + +private: + QList<QMouseEvent> m_pendingEvents; + QMutex m_mutex; +}; + +} // Render + +} // Qt3DRender + +QT_END_NAMESPACE + +#endif // QT3DRENDER_RENDER_PICKEVENTFILTER_H diff --git a/src/render/picking/picking.pri b/src/render/picking/picking.pri new file mode 100644 index 000000000..72ec6498c --- /dev/null +++ b/src/render/picking/picking.pri @@ -0,0 +1,13 @@ +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/qobjectpicker.h \ + $$PWD/qpickevent.h \ + $$PWD/objectpicker_p.h \ + $$PWD/pickeventfilter_p.h + +SOURCES += \ + $$PWD/qobjectpicker.cpp \ + $$PWD/qpickevent.cpp \ + $$PWD/objectpicker.cpp \ + $$PWD/pickeventfilter.cpp diff --git a/src/render/picking/qobjectpicker.cpp b/src/render/picking/qobjectpicker.cpp new file mode 100644 index 000000000..7d1e4a946 --- /dev/null +++ b/src/render/picking/qobjectpicker.cpp @@ -0,0 +1,326 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** 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 "qobjectpicker.h" +#include <Qt3DCore/qentity.h> +#include <Qt3DCore/private/qcomponent_p.h> +#include <Qt3DCore/qbackendscenepropertychange.h> +#include <Qt3DRender/qattribute.h> +#include <Qt3DRender/qpickevent.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +/*! + \class Qt3DRender::QObjectPicker + + \brief The Qt3DRender::QObjectPicker class instantiates a component that can + be used to interact with a Qt3DCore::QEntity by a process known as picking. + + The signals pressed(), released(), clicked(), entered(), exited() are + emitted when the bounding volume defined by the pickAttribute property intersects + with a ray. + + \note Instances of this component shouldn't be shared, not respecting that + condition will most likely result in undefined behaviors. + + \since 5.6 +*/ + +/*! + \qmlsignal Qt3D.Render::ObjectPicker::pressed() +*/ + +/*! + \qmlsignal Qt3D.Render::ObjectPicker::released() +*/ + +/*! + \qmlsignal Qt3D.Render::ObjectPicker::clicked() +*/ + +/*! + \qmlsignal Qt3D.Render::ObjectPicker::entered() +*/ + +/*! + \qmlsignal Qt3D.Render::ObjectPicker::exited() +*/ + +/*! + \internal +*/ +class QObjectPickerPrivate : public Qt3DCore::QComponentPrivate +{ +public: + QObjectPickerPrivate() + : QComponentPrivate() + , m_pickAttribute(Q_NULLPTR) + , m_hoverEnabled(false) + , m_pressed(false) + , m_containsMouse(false) + , m_acceptedLastPressedEvent(true) + { + m_shareable = false; + } + + Q_DECLARE_PUBLIC(QObjectPicker) + Qt3DRender::QAttribute *m_pickAttribute; + bool m_hoverEnabled; + bool m_pressed; + bool m_containsMouse; + bool m_acceptedLastPressedEvent; + + enum EventType { + Pressed, + Released, + Clicked + }; + + void propagateEvent(QPickEvent *event, EventType type); + + void pressedEvent(QPickEvent *event); + void clickedEvent(QPickEvent *event); + void releasedEvent(QPickEvent *event); +}; + +QObjectPicker::QObjectPicker(Qt3DCore::QNode *parent) + : Qt3DCore::QComponent(*new QObjectPickerPrivate(), parent) +{ +} + +QObjectPicker::~QObjectPicker() +{ + QComponent::cleanup(); +} + +void QObjectPicker::setPickAttribute(QAttribute *pickAttribute) +{ + Q_D(QObjectPicker); + if (pickAttribute != d->m_pickAttribute) { + + if (pickAttribute && !pickAttribute->parent()) + pickAttribute->setParent(this); + + d->m_pickAttribute = pickAttribute; + emit pickAttributeChanged(); + } +} + +/*! + \qmlproperty Qt3D.Render.Attribute Qt3D.Render::ObjectPicker::pickAttribute +*/ +QAttribute *QObjectPicker::pickAttribute() const +{ + Q_D(const QObjectPicker); + return d->m_pickAttribute; +} + +void QObjectPicker::setHoverEnabled(bool hoverEnabled) +{ + Q_D(QObjectPicker); + if (hoverEnabled != d->m_hoverEnabled) { + d->m_hoverEnabled = hoverEnabled; + emit hoverEnabledChanged(); + } +} + +/*! + \qmlproperty bool Qt3D.Render::ObjectPicker::hoverEnabled +*/ +bool QObjectPicker::hoverEnabled() const +{ + Q_D(const QObjectPicker); + return d->m_hoverEnabled; +} + +/*! + \qmlproperty bool Qt3D.Render::ObjectPicker::containsMouse +*/ +bool QObjectPicker::containsMouse() const +{ + Q_D(const QObjectPicker); + return d->m_containsMouse; +} + +/*! + \qmlproperty bool Qt3D.Render::ObjectPicker::pressed +*/ +bool QObjectPicker::isPressed() const +{ + Q_D(const QObjectPicker); + return d->m_pressed; +} + +void QObjectPicker::copy(const QNode *ref) +{ + QComponent::copy(ref); + const QObjectPicker *picker = static_cast<const QObjectPicker *>(ref); + d_func()->m_hoverEnabled = picker->d_func()->m_hoverEnabled; + // Only clone the pickAttribute if we are it's parent, will be deleted by its parent otherwise + if (picker->d_func()->m_pickAttribute != Q_NULLPTR && picker->d_func()->m_pickAttribute->parent() == ref) + setPickAttribute(qobject_cast<QAttribute *>(QNode::clone(picker->d_func()->m_pickAttribute))); +} + +void QObjectPicker::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) +{ + Q_D(QObjectPicker); + Qt3DCore::QBackendScenePropertyChangePtr e = qSharedPointerCast<Qt3DCore::QBackendScenePropertyChange>(change); + if (e->type() == Qt3DCore::NodeUpdated) { + // TO DO: Complete this part + // to emit the correct signals + const QByteArray propertyName = e->propertyName(); + if (propertyName == QByteArrayLiteral("pressed")) { + QPickEvent e; + d->pressedEvent(&e); + } else if (propertyName == QByteArrayLiteral("released")) { + QPickEvent e; + d->releasedEvent(&e); + } else if (propertyName == QByteArrayLiteral("clicked")) { + QPickEvent e; + d->clickedEvent(&e); + } else if (propertyName == QByteArrayLiteral("entered")) { + emit entered(); + setContainsMouse(true); + } else if (propertyName == QByteArrayLiteral("exited")) { + setContainsMouse(false); + emit exited(); + } + } +} + +void QObjectPicker::setPressed(bool pressed) +{ + Q_D(QObjectPicker); + if (d->m_pressed != pressed) { + const bool blocked = blockNotifications(true); + d->m_pressed = pressed; + emit pressedChanged(); + blockNotifications(blocked); + } +} + +void QObjectPicker::setContainsMouse(bool containsMouse) +{ + Q_D(QObjectPicker); + if (d->m_containsMouse != containsMouse) { + const bool blocked = blockNotifications(true); + d->m_containsMouse = containsMouse; + emit containsMouseChanged(); + blockNotifications(blocked); + } +} + +/*! + \internal + */ +void QObjectPickerPrivate::propagateEvent(QPickEvent *event, EventType type) +{ + if (!m_entities.isEmpty()) { + Qt3DCore::QEntity *entity = m_entities.first(); + Qt3DCore::QEntity *parentEntity = Q_NULLPTR; + Qt3DRender::QObjectPicker *objectPicker = Q_NULLPTR; + while (entity != Q_NULLPTR && entity->parent() != Q_NULLPTR && !event->isAccepted()) { + parentEntity = entity->parentEntity(); + Q_FOREACH (Qt3DCore::QComponent *c, parentEntity->components()) { + if ((objectPicker = qobject_cast<Qt3DRender::QObjectPicker *>(c)) != Q_NULLPTR) { + QObjectPickerPrivate *objectPickerPrivate = static_cast<QObjectPickerPrivate *>(QObjectPickerPrivate::get(objectPicker)); + switch (type) { + case EventType::Pressed: + objectPickerPrivate->pressedEvent(event); + break; + case EventType::Released: + objectPickerPrivate->releasedEvent(event); + break; + case EventType::Clicked: + objectPickerPrivate->clickedEvent(event); + break; + } + break; + } + } + entity = parentEntity; + } + } +} + +/*! + \internal + */ +void QObjectPickerPrivate::pressedEvent(QPickEvent *event) +{ + Q_Q(QObjectPicker); + emit q->pressed(event); + + m_acceptedLastPressedEvent = event->isAccepted(); + if (!m_acceptedLastPressedEvent) { + // Travel parents to transmit the event + propagateEvent(event, EventType::Pressed); + } else { + q->setPressed(true); + } +} + +/*! + \internal + */ +void QObjectPickerPrivate::clickedEvent(QPickEvent *event) +{ + Q_Q(QObjectPicker); + emit q->clicked(event); + if (!event->isAccepted()) + propagateEvent(event, EventType::Clicked); +} + +/*! + \internal + */ +void QObjectPickerPrivate::releasedEvent(QPickEvent *event) +{ + Q_Q(QObjectPicker); + if (m_acceptedLastPressedEvent) { + emit q->released(event); + q->setPressed(false); + } else { + event->setAccepted(false); + propagateEvent(event, EventType::Released); + } +} + +} // Qt3DRender + +QT_END_NAMESPACE diff --git a/src/render/picking/qobjectpicker.h b/src/render/picking/qobjectpicker.h new file mode 100644 index 000000000..d7efe3c2b --- /dev/null +++ b/src/render/picking/qobjectpicker.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** 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_QOBJECTPICKER_H +#define QT3DRENDER_QOBJECTPICKER_H + +#include <Qt3DCore/qcomponent.h> +#include <Qt3DRender/qt3drender_global.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +class QAttribute; +class QObjectPickerPrivate; +class QPickEvent; + +class QT3DRENDERSHARED_EXPORT QObjectPicker : public Qt3DCore::QComponent +{ + Q_OBJECT + Q_PROPERTY(Qt3DRender::QAttribute *pickAttribute READ pickAttribute WRITE setPickAttribute NOTIFY pickAttributeChanged) + Q_PROPERTY(bool hoverEnabled READ hoverEnabled WRITE setHoverEnabled NOTIFY hoverEnabledChanged) + Q_PROPERTY(bool pressed READ isPressed NOTIFY pressedChanged) + Q_PROPERTY(bool containsMouse READ containsMouse NOTIFY containsMouseChanged) + +public: + explicit QObjectPicker(QNode *parent = Q_NULLPTR); + ~QObjectPicker(); + + void setPickAttribute(QAttribute *pickAttribute); + QAttribute *pickAttribute() const; + + void setHoverEnabled(bool hoverEnabled); + bool hoverEnabled() const; + + bool containsMouse() const; + bool isPressed() const; + +Q_SIGNALS: + void pressed(QPickEvent *event); + void released(QPickEvent *event); + void clicked(QPickEvent *event); + void entered(); + void exited(); + void pickAttributeChanged(); + void hoverEnabledChanged(); + void pressedChanged(); + void containsMouseChanged(); + +protected: + void copy(const Qt3DCore::QNode *ref) Q_DECL_OVERRIDE; + void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) Q_DECL_OVERRIDE; + +private: + void setPressed(bool pressed); + void setContainsMouse(bool containsMouse); + + QT3D_CLONEABLE(QObjectPicker) + Q_DECLARE_PRIVATE(QObjectPicker) +}; + +} // Qt3D + +QT_END_NAMESPACE + +#endif // QT3DRENDER_QOBJECTPICKER_H diff --git a/src/render/picking/qpickevent.cpp b/src/render/picking/qpickevent.cpp new file mode 100644 index 000000000..b2f7179b1 --- /dev/null +++ b/src/render/picking/qpickevent.cpp @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** 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 "qpickevent.h" +#include <private/qobject_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +class QPickEventPrivate : public QObjectPrivate +{ +public: + QPickEventPrivate() + : QObjectPrivate() + , m_accepted(true) + { + } + + bool m_accepted; +}; + +QPickEvent::QPickEvent() + : QObject(*new QPickEventPrivate()) +{ +} + +QPickEvent::~QPickEvent() +{ +} + +bool QPickEvent::isAccepted() const +{ + Q_D(const QPickEvent); + return d->m_accepted; +} + +void QPickEvent::setAccepted(bool accepted) +{ + Q_D(QPickEvent); + if (accepted != d->m_accepted) { + d->m_accepted = accepted; + emit acceptedChanged(); + } +} + +} // Qt3DRender + +QT_END_NAMESPACE + diff --git a/src/render/picking/qpickevent.h b/src/render/picking/qpickevent.h new file mode 100644 index 000000000..5a9408516 --- /dev/null +++ b/src/render/picking/qpickevent.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** 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_QPICKEVENT_H +#define QT3DRENDER_QPICKEVENT_H + +#include <QObject> +#include <Qt3DRender/qt3drender_global.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +class QPickEventPrivate; + +class QT3DRENDERSHARED_EXPORT QPickEvent : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted NOTIFY acceptedChanged) +public: + QPickEvent(); + ~QPickEvent(); + + bool isAccepted() const; + void setAccepted(bool accepted); + +Q_SIGNALS: + void acceptedChanged(); + +private: + Q_DECLARE_PRIVATE(QPickEvent) +}; + +} // Qt3DRender + +QT_END_NAMESPACE + +#endif // QT3DRENDER_QPICKEVENT_H |