diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index deba442c94..3cd5c9a268 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -850,9 +850,18 @@ RayToEntityIntersectionResult EntityTreeRenderer::findRayIntersectionWorker(cons } void EntityTreeRenderer::connectSignalsToSlots(EntityScriptingInterface* entityScriptingInterface) { - connect(this, &EntityTreeRenderer::mousePressOnEntity, entityScriptingInterface, &EntityScriptingInterface::mousePressOnEntity); - connect(this, &EntityTreeRenderer::mouseMoveOnEntity, entityScriptingInterface, &EntityScriptingInterface::mouseMoveOnEntity); - connect(this, &EntityTreeRenderer::mouseReleaseOnEntity, entityScriptingInterface, &EntityScriptingInterface::mouseReleaseOnEntity); + connect(this, &EntityTreeRenderer::mousePressOnEntity, entityScriptingInterface, + [=](const RayToEntityIntersectionResult& intersection, const QMouseEvent* event, unsigned int deviceId){ + entityScriptingInterface->mousePressOnEntity(intersection.entityID, MouseEvent(*event, deviceId)); + }); + connect(this, &EntityTreeRenderer::mouseMoveOnEntity, entityScriptingInterface, + [=](const RayToEntityIntersectionResult& intersection, const QMouseEvent* event, unsigned int deviceId) { + entityScriptingInterface->mouseMoveOnEntity(intersection.entityID, MouseEvent(*event, deviceId)); + }); + connect(this, &EntityTreeRenderer::mouseReleaseOnEntity, entityScriptingInterface, + [=](const RayToEntityIntersectionResult& intersection, const QMouseEvent* event, unsigned int deviceId) { + entityScriptingInterface->mouseReleaseOnEntity(intersection.entityID, MouseEvent(*event, deviceId)); + }); connect(this, &EntityTreeRenderer::clickDownOnEntity, entityScriptingInterface, &EntityScriptingInterface::clickDownOnEntity); connect(this, &EntityTreeRenderer::holdingClickOnEntity, entityScriptingInterface, &EntityScriptingInterface::holdingClickOnEntity); @@ -900,7 +909,7 @@ void EntityTreeRenderer::mousePressEvent(QMouseEvent* event, unsigned int device RayToEntityIntersectionResult rayPickResult = findRayIntersectionWorker(ray, Octree::Lock, precisionPicking); if (rayPickResult.intersects) { //qCDebug(entitiesrenderer) << "mousePressEvent over entity:" << rayPickResult.entityID; - emit mousePressOnEntity(rayPickResult.entityID, MouseEvent(*event, deviceID)); + emit mousePressOnEntity(rayPickResult, event, deviceID); QScriptValueList entityScriptArgs = createMouseEventArgs(rayPickResult.entityID, event, deviceID); QScriptValue entityScript = loadEntityScript(rayPickResult.entity); @@ -930,7 +939,7 @@ void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event, unsigned int devi RayToEntityIntersectionResult rayPickResult = findRayIntersectionWorker(ray, Octree::Lock, precisionPicking); if (rayPickResult.intersects) { //qCDebug(entitiesrenderer) << "mouseReleaseEvent over entity:" << rayPickResult.entityID; - emit mouseReleaseOnEntity(rayPickResult.entityID, MouseEvent(*event, deviceID)); + emit mouseReleaseOnEntity(rayPickResult, event, deviceID); QScriptValueList entityScriptArgs = createMouseEventArgs(rayPickResult.entityID, event, deviceID); QScriptValue entityScript = loadEntityScript(rayPickResult.entity); @@ -979,7 +988,7 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event, unsigned int deviceI } //qCDebug(entitiesrenderer) << "mouseMoveEvent over entity:" << rayPickResult.entityID; - emit mouseMoveOnEntity(rayPickResult.entityID, MouseEvent(*event, deviceID)); + emit mouseMoveOnEntity(rayPickResult, event, deviceID); if (entityScript.property("mouseMoveOnEntity").isValid()) { entityScript.property("mouseMoveOnEntity").call(entityScript, entityScriptArgs); } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index eb8b44f5eb..9768d4a20a 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -93,9 +93,9 @@ public: virtual void errorInLoadingScript(const QUrl& url); signals: - void mousePressOnEntity(const EntityItemID& entityItemID, const MouseEvent& event); - void mouseMoveOnEntity(const EntityItemID& entityItemID, const MouseEvent& event); - void mouseReleaseOnEntity(const EntityItemID& entityItemID, const MouseEvent& event); + void mousePressOnEntity(const RayToEntityIntersectionResult& entityItemID, const QMouseEvent* event, unsigned int deviceId); + void mouseMoveOnEntity(const RayToEntityIntersectionResult& entityItemID, const QMouseEvent* event, unsigned int deviceId); + void mouseReleaseOnEntity(const RayToEntityIntersectionResult& entityItemID, const QMouseEvent* event, unsigned int deviceId); void clickDownOnEntity(const EntityItemID& entityItemID, const MouseEvent& event); void holdingClickOnEntity(const EntityItemID& entityItemID, const MouseEvent& event); diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index fe85a37762..3afd930ab0 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -23,6 +23,8 @@ #include #include +#include "EntityTreeRenderer.h" + const int FIXED_FONT_POINT_SIZE = 40; const float DPI = 30.47; const float METERS_TO_INCHES = 39.3701; @@ -63,6 +65,7 @@ RenderableWebEntityItem::~RenderableWebEntityItem() { void RenderableWebEntityItem::render(RenderArgs* args) { QOpenGLContext * currentContext = QOpenGLContext::currentContext(); QSurface * currentSurface = currentContext->surface(); + if (!_webSurface) { _webSurface = new OffscreenQmlSurface(); _webSurface->create(currentContext); @@ -89,6 +92,52 @@ void RenderableWebEntityItem::render(RenderArgs* args) { _webSurface->doneCurrent(); } }); + + auto forwardMouseEvent = [=](const RayToEntityIntersectionResult& intersection, const QMouseEvent* event, unsigned int deviceId) { + // Ignore mouse interaction if we're locked + if (this->getLocked()) { + return; + } + + if (intersection.entityID.id == getID()) { + if (event->button() == Qt::MouseButton::RightButton) { + if (event->type() == QEvent::MouseButtonRelease) { + AbstractViewStateInterface::instance()->postLambdaEvent([this] { + QMetaObject::invokeMethod(_webSurface->getRootItem(), "goBack"); + }); + } + return; + } + + if (event->button() == Qt::MouseButton::MiddleButton) { + if (event->type() == QEvent::MouseButtonRelease) { + AbstractViewStateInterface::instance()->postLambdaEvent([this] { + _webSurface->getRootItem()->setProperty("url", _sourceUrl); + }); + } + return; + } + + // Map the intersection point to an actual offscreen pixel + glm::vec3 point = intersection.intersection; + point -= getPosition(); + point = glm::inverse(getRotation()) * point; + point /= _dimensions; + point += 0.5f; + point.y = 1.0f - point.y; + point *= _dimensions * METERS_TO_INCHES * DPI; + // Forward the mouse event. + QMouseEvent mappedEvent(event->type(), + QPoint((int)point.x, (int)point.y), + event->screenPos(), event->button(), + event->buttons(), event->modifiers()); + QCoreApplication::sendEvent(_webSurface->getWindow(), &mappedEvent); + } + }; + EntityTreeRenderer* renderer = static_cast(args->_renderer); + QObject::connect(renderer, &EntityTreeRenderer::mousePressOnEntity, forwardMouseEvent); + QObject::connect(renderer, &EntityTreeRenderer::mouseReleaseOnEntity, forwardMouseEvent); + QObject::connect(renderer, &EntityTreeRenderer::mouseMoveOnEntity, forwardMouseEvent); } glm::vec2 dims = glm::vec2(_dimensions); @@ -106,8 +155,6 @@ void RenderableWebEntityItem::render(RenderArgs* args) { glm::vec3 halfDimensions = dimensions / 2.0f; glm::quat rotation = getRotation(); - //qCDebug(entitytree) << "RenderableWebEntityItem::render() id:" << getEntityItemID() << "text:" << getText(); - glPushMatrix(); { glTranslatef(position.x, position.y, position.z); diff --git a/libraries/render-utils/src/OffscreenQmlSurface.cpp b/libraries/render-utils/src/OffscreenQmlSurface.cpp index 5b39610640..9b497964e7 100644 --- a/libraries/render-utils/src/OffscreenQmlSurface.cpp +++ b/libraries/render-utils/src/OffscreenQmlSurface.cpp @@ -374,3 +374,6 @@ void OffscreenQmlSurface::setProxyWindow(QWindow* window) { _renderControl->_renderWindow = window; } +QQuickWindow* OffscreenQmlSurface::getWindow() { + return _quickWindow; +} \ No newline at end of file diff --git a/libraries/render-utils/src/OffscreenQmlSurface.h b/libraries/render-utils/src/OffscreenQmlSurface.h index dcb3e1e17e..a1b66b48ad 100644 --- a/libraries/render-utils/src/OffscreenQmlSurface.h +++ b/libraries/render-utils/src/OffscreenQmlSurface.h @@ -71,6 +71,7 @@ public: void setBaseUrl(const QUrl& baseUrl); QQuickItem* getRootItem(); + QQuickWindow* getWindow(); virtual bool eventFilter(QObject* originalDestination, QEvent* event);