From 53fde839229fd23989da0311f34f69c86dc0f393 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 12 Oct 2017 11:21:50 -0700 Subject: [PATCH 01/11] cleaning up pointerevents, wip --- interface/src/Application.cpp | 80 ----------------- interface/src/Application.h | 13 --- interface/src/ui/overlays/Overlays.cpp | 67 +++++++++------ interface/src/ui/overlays/Overlays.h | 18 ++-- .../src/EntityTreeRenderer.cpp | 86 ++++++------------- .../src/EntityTreeRenderer.h | 13 --- .../src/RenderableWebEntityItem.cpp | 23 +++-- .../entities/src/EntityScriptingInterface.cpp | 41 +++++---- .../entities/src/EntityScriptingInterface.h | 19 ++-- 9 files changed, 118 insertions(+), 242 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 60ae1843d6..648339e739 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1470,46 +1470,17 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo // Keyboard focus handling for Web overlays. auto overlays = &(qApp->getOverlays()); - - connect(overlays, &Overlays::mousePressOnOverlay, [=](const OverlayID& overlayID, const PointerEvent& event) { - auto thisOverlay = std::dynamic_pointer_cast(overlays->getOverlay(overlayID)); - // Only Web overlays can have keyboard focus. - if (thisOverlay) { - setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); - setKeyboardFocusOverlay(overlayID); - } - }); - connect(overlays, &Overlays::overlayDeleted, [=](const OverlayID& overlayID) { if (overlayID == _keyboardFocusedOverlay.get()) { setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); } }); - connect(overlays, &Overlays::mousePressOffOverlay, [=]() { - setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); - }); - connect(this, &Application::aboutToQuit, [=]() { setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); }); - connect(overlays, - SIGNAL(mousePressOnOverlay(const OverlayID&, const PointerEvent&)), - DependencyManager::get().data(), - SLOT(contextOverlays_mousePressOnOverlay(const OverlayID&, const PointerEvent&))); - - connect(overlays, - SIGNAL(hoverEnterOverlay(const OverlayID&, const PointerEvent&)), - DependencyManager::get().data(), - SLOT(contextOverlays_hoverEnterOverlay(const OverlayID&, const PointerEvent&))); - - connect(overlays, - SIGNAL(hoverLeaveOverlay(const OverlayID&, const PointerEvent&)), - DependencyManager::get().data(), - SLOT(contextOverlays_hoverLeaveOverlay(const OverlayID&, const PointerEvent&))); - // Add periodic checks to send user activity data static int CHECK_NEARBY_AVATARS_INTERVAL_MS = 10000; static int NEARBY_AVATAR_RADIUS_METERS = 10; @@ -3336,7 +3307,6 @@ void Application::mouseDoublePressEvent(QMouseEvent* event) { event->buttons(), event->modifiers()); if (!_aboutToQuit) { - getOverlays().mouseDoublePressEvent(&mappedEvent); if (!_controllerScriptingInterface->areEntityClicksCaptured()) { getEntities()->mouseDoublePressEvent(&mappedEvent); } @@ -4489,11 +4459,6 @@ QUuid Application::getKeyboardFocusEntity() const { return _keyboardFocusedEntity.get(); } -void Application::setKeyboardFocusEntity(QUuid id) { - EntityItemID entityItemID(id); - setKeyboardFocusEntity(entityItemID); -} - static const float FOCUS_HIGHLIGHT_EXPANSION_FACTOR = 1.05f; void Application::setKeyboardFocusEntity(EntityItemID entityItemID) { @@ -7357,51 +7322,6 @@ bool Application::isForeground() const { return _isForeground && !_window->isMinimized(); } -void Application::sendMousePressOnEntity(QUuid id, PointerEvent event) { - EntityItemID entityItemID(id); - emit getEntities()->mousePressOnEntity(entityItemID, event); -} - -void Application::sendMouseMoveOnEntity(QUuid id, PointerEvent event) { - EntityItemID entityItemID(id); - emit getEntities()->mouseMoveOnEntity(entityItemID, event); -} - -void Application::sendMouseReleaseOnEntity(QUuid id, PointerEvent event) { - EntityItemID entityItemID(id); - emit getEntities()->mouseReleaseOnEntity(entityItemID, event); -} - -void Application::sendClickDownOnEntity(QUuid id, PointerEvent event) { - EntityItemID entityItemID(id); - emit getEntities()->clickDownOnEntity(entityItemID, event); -} - -void Application::sendHoldingClickOnEntity(QUuid id, PointerEvent event) { - EntityItemID entityItemID(id); - emit getEntities()->holdingClickOnEntity(entityItemID, event); -} - -void Application::sendClickReleaseOnEntity(QUuid id, PointerEvent event) { - EntityItemID entityItemID(id); - emit getEntities()->clickReleaseOnEntity(entityItemID, event); -} - -void Application::sendHoverEnterEntity(QUuid id, PointerEvent event) { - EntityItemID entityItemID(id); - emit getEntities()->hoverEnterEntity(entityItemID, event); -} - -void Application::sendHoverOverEntity(QUuid id, PointerEvent event) { - EntityItemID entityItemID(id); - emit getEntities()->hoverOverEntity(entityItemID, event); -} - -void Application::sendHoverLeaveEntity(QUuid id, PointerEvent event) { - EntityItemID entityItemID(id); - emit getEntities()->hoverLeaveEntity(entityItemID, event); -} - // FIXME? perhaps two, one for the main thread and one for the offscreen UI rendering thread? static const int UI_RESERVED_THREADS = 1; // Windows won't let you have all the cores diff --git a/interface/src/Application.h b/interface/src/Application.h index 772646f379..10b1637ad9 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -277,18 +277,6 @@ public: gpu::TexturePointer getDefaultSkyboxTexture() const { return _defaultSkyboxTexture; } gpu::TexturePointer getDefaultSkyboxAmbientTexture() const { return _defaultSkyboxAmbientTexture; } - Q_INVOKABLE void sendMousePressOnEntity(QUuid id, PointerEvent event); - Q_INVOKABLE void sendMouseMoveOnEntity(QUuid id, PointerEvent event); - Q_INVOKABLE void sendMouseReleaseOnEntity(QUuid id, PointerEvent event); - - Q_INVOKABLE void sendClickDownOnEntity(QUuid id, PointerEvent event); - Q_INVOKABLE void sendHoldingClickOnEntity(QUuid id, PointerEvent event); - Q_INVOKABLE void sendClickReleaseOnEntity(QUuid id, PointerEvent event); - - Q_INVOKABLE void sendHoverEnterEntity(QUuid id, PointerEvent event); - Q_INVOKABLE void sendHoverOverEntity(QUuid id, PointerEvent event); - Q_INVOKABLE void sendHoverLeaveEntity(QUuid id, PointerEvent event); - OverlayID getTabletScreenID() const; OverlayID getTabletHomeButtonID() const; QUuid getTabletFrameID() const; // may be an entity or an overlay @@ -388,7 +376,6 @@ public slots: void setKeyboardFocusHighlight(const glm::vec3& position, const glm::quat& rotation, const glm::vec3& dimensions); QUuid getKeyboardFocusEntity() const; // thread-safe - void setKeyboardFocusEntity(QUuid id); void setKeyboardFocusEntity(EntityItemID entityItemID); OverlayID getKeyboardFocusOverlay(); diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 0280cf2038..dd4e8ed74b 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -37,6 +37,8 @@ #include "Web3DOverlay.h" #include +#include "ui/overlays/ContextOverlayInterface.h" + Q_LOGGING_CATEGORY(trace_render_overlays, "trace.render.overlays") extern void initOverlay3DPipelines(render::ShapePlumber& plumber, bool depthTest = false); @@ -717,27 +719,27 @@ bool Overlays::isAddedOverlay(OverlayID id) { } void Overlays::sendMousePressOnOverlay(const OverlayID& overlayID, const PointerEvent& event) { - QMetaObject::invokeMethod(this, "mousePressOnOverlay", Q_ARG(OverlayID, overlayID), Q_ARG(PointerEvent, event)); + mousePressEvent(overlayID, event); } void Overlays::sendMouseReleaseOnOverlay(const OverlayID& overlayID, const PointerEvent& event) { - QMetaObject::invokeMethod(this, "mouseReleaseOnOverlay", Q_ARG(OverlayID, overlayID), Q_ARG(PointerEvent, event)); + emit mouseReleaseOnOverlay(overlayID, event); } void Overlays::sendMouseMoveOnOverlay(const OverlayID& overlayID, const PointerEvent& event) { - QMetaObject::invokeMethod(this, "mouseMoveOnOverlay", Q_ARG(OverlayID, overlayID), Q_ARG(PointerEvent, event)); + emit mouseMoveOnOverlay(overlayID, event); } -void Overlays::sendHoverEnterOverlay(const OverlayID& id, const PointerEvent& event) { - QMetaObject::invokeMethod(this, "hoverEnterOverlay", Q_ARG(OverlayID, id), Q_ARG(PointerEvent, event)); +void Overlays::sendHoverEnterOverlay(const OverlayID& overlayID, const PointerEvent& event) { + hoverEnterEvent(overlayID, event); } -void Overlays::sendHoverOverOverlay(const OverlayID& id, const PointerEvent& event) { - QMetaObject::invokeMethod(this, "hoverOverOverlay", Q_ARG(OverlayID, id), Q_ARG(PointerEvent, event)); +void Overlays::sendHoverOverOverlay(const OverlayID& overlayID, const PointerEvent& event) { + emit hoverOverOverlay(overlayID, event); } -void Overlays::sendHoverLeaveOverlay(const OverlayID& id, const PointerEvent& event) { - QMetaObject::invokeMethod(this, "hoverLeaveOverlay", Q_ARG(OverlayID, id), Q_ARG(PointerEvent, event)); +void Overlays::sendHoverLeaveOverlay(const OverlayID& overlayID, const PointerEvent& event) { + hoverLeaveEvent(overlayID, event); } OverlayID Overlays::getKeyboardFocusOverlay() { @@ -891,27 +893,40 @@ bool Overlays::mousePressEvent(QMouseEvent* event) { _currentClickingOnOverlayID = rayPickResult.overlayID; PointerEvent pointerEvent = calculateOverlayPointerEvent(_currentClickingOnOverlayID, ray, rayPickResult, event, PointerEvent::Press); - emit mousePressOnOverlay(_currentClickingOnOverlayID, pointerEvent); + mousePressEvent(_currentClickingOnOverlayID, pointerEvent); return true; } - emit mousePressOffOverlay(); + qApp->setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); return false; } -bool Overlays::mouseDoublePressEvent(QMouseEvent* event) { - PerformanceTimer perfTimer("Overlays::mouseDoublePressEvent"); +void Overlays::mousePressEvent(const OverlayID& overlayID, const PointerEvent& event) { + // Send press to context overlay + // contextOverlays_mousePressOnOverlay is not threadsafe and mousePressEvent can be called from scripts, so use an auto connection + QMetaObject::invokeMethod(DependencyManager::get().data(), "contextOverlays_mousePressOnOverlay", Q_ARG(OverlayID, overlayID), Q_ARG(PointerEvent, event)); - PickRay ray = qApp->computePickRay(event->x(), event->y()); - RayToOverlayIntersectionResult rayPickResult = findRayIntersectionForMouseEvent(ray); - if (rayPickResult.intersects) { - _currentClickingOnOverlayID = rayPickResult.overlayID; - - auto pointerEvent = calculateOverlayPointerEvent(_currentClickingOnOverlayID, ray, rayPickResult, event, PointerEvent::Press); - emit mouseDoublePressOnOverlay(_currentClickingOnOverlayID, pointerEvent); - return true; + // Focus keyboard on web overlays + // TODO: generalize this to allow any entity to recieve keyboard focus + auto thisOverlay = std::dynamic_pointer_cast(getOverlay(overlayID)); + if (thisOverlay) { + qApp->setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); + qApp->setKeyboardFocusOverlay(overlayID); } - emit mouseDoublePressOffOverlay(); - return false; + + // Send press to web overlays + emit mousePressOnOverlay(overlayID, event); +} + +void Overlays::hoverEnterEvent(const OverlayID& overlayID, const PointerEvent& event) { + // Send hoverEnter to context overlay + // contextOverlays_hoverEnterOverlay is not threadsafe and hoverEnterEvent can be called from scripts, so use an auto connection + QMetaObject::invokeMethod(DependencyManager::get().data(), "contextOverlays_hoverEnterOverlay", Q_ARG(OverlayID, overlayID), Q_ARG(PointerEvent, event)); +} + +void Overlays::hoverLeaveEvent(const OverlayID& overlayID, const PointerEvent& event) { + // Send hoverLeave to context overlay + // contextOverlays_hoverLeaveOverlay is not threadsafe and hoverLeaveEvent can be called from scripts, so use an auto connection + QMetaObject::invokeMethod(DependencyManager::get().data(), "contextOverlays_hoverLeaveOverlay", Q_ARG(OverlayID, overlayID), Q_ARG(PointerEvent, event)); } bool Overlays::mouseReleaseEvent(QMouseEvent* event) { @@ -940,12 +955,12 @@ bool Overlays::mouseMoveEvent(QMouseEvent* event) { // If previously hovering over a different overlay then leave hover on that overlay. if (_currentHoverOverOverlayID != UNKNOWN_OVERLAY_ID && rayPickResult.overlayID != _currentHoverOverOverlayID) { auto pointerEvent = calculateOverlayPointerEvent(_currentHoverOverOverlayID, ray, rayPickResult, event, PointerEvent::Move); - emit hoverLeaveOverlay(_currentHoverOverOverlayID, pointerEvent); + hoverLeaveEvent(_currentHoverOverOverlayID, pointerEvent); } // If hovering over a new overlay then enter hover on that overlay. if (rayPickResult.overlayID != _currentHoverOverOverlayID) { - emit hoverEnterOverlay(rayPickResult.overlayID, pointerEvent); + hoverEnterEvent(rayPickResult.overlayID, pointerEvent); } // Hover over current overlay. @@ -956,7 +971,7 @@ bool Overlays::mouseMoveEvent(QMouseEvent* event) { // If previously hovering an overlay then leave hover. if (_currentHoverOverOverlayID != UNKNOWN_OVERLAY_ID) { auto pointerEvent = calculateOverlayPointerEvent(_currentHoverOverOverlayID, ray, rayPickResult, event, PointerEvent::Move); - emit hoverLeaveOverlay(_currentHoverOverOverlayID, pointerEvent); + hoverLeaveEvent(_currentHoverOverOverlayID, pointerEvent); _currentHoverOverOverlayID = UNKNOWN_OVERLAY_ID; } diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 732a437eae..d5517bbb9d 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -103,10 +103,13 @@ public: OverlayID addOverlay(const Overlay::Pointer& overlay); bool mousePressEvent(QMouseEvent* event); - bool mouseDoublePressEvent(QMouseEvent* event); bool mouseReleaseEvent(QMouseEvent* event); bool mouseMoveEvent(QMouseEvent* event); + void mousePressEvent(const OverlayID& overlayID, const PointerEvent& event); + void hoverEnterEvent(const OverlayID& overlayID, const PointerEvent& event); + void hoverLeaveEvent(const OverlayID& overlayID, const PointerEvent& event); + void cleanupAllOverlays(); public slots: @@ -298,9 +301,9 @@ public slots: void sendMouseReleaseOnOverlay(const OverlayID& overlayID, const PointerEvent& event); void sendMouseMoveOnOverlay(const OverlayID& overlayID, const PointerEvent& event); - void sendHoverEnterOverlay(const OverlayID& id, const PointerEvent& event); - void sendHoverOverOverlay(const OverlayID& id, const PointerEvent& event); - void sendHoverLeaveOverlay(const OverlayID& id, const PointerEvent& event); + void sendHoverEnterOverlay(const OverlayID& overlayID, const PointerEvent& event); + void sendHoverOverOverlay(const OverlayID& overlayID, const PointerEvent& event); + void sendHoverLeaveOverlay(const OverlayID& overlayID, const PointerEvent& event); OverlayID getKeyboardFocusOverlay(); void setKeyboardFocusOverlay(OverlayID id); @@ -316,15 +319,12 @@ signals: void panelDeleted(OverlayID id); void mousePressOnOverlay(OverlayID overlayID, const PointerEvent& event); - void mouseDoublePressOnOverlay(OverlayID overlayID, const PointerEvent& event); void mouseReleaseOnOverlay(OverlayID overlayID, const PointerEvent& event); void mouseMoveOnOverlay(OverlayID overlayID, const PointerEvent& event); - void mousePressOffOverlay(); - void mouseDoublePressOffOverlay(); - void hoverEnterOverlay(OverlayID overlayID, const PointerEvent& event); - void hoverOverOverlay(OverlayID overlayID, const PointerEvent& event); void hoverLeaveOverlay(OverlayID overlayID, const PointerEvent& event); + // FIXME: nothing connects to this signal anymore + void hoverOverOverlay(OverlayID overlayID, const PointerEvent& event); private: void cleanupOverlaysToDelete(); diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 9e700b0efe..9bbc6caaf2 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -245,7 +245,7 @@ void EntityTreeRenderer::update(bool simulate) { // not yet released the hold then this is still considered a holdingClickOnEntity event // and we want to simulate this message here as well as in mouse move if (_lastPointerEventValid && !_currentClickingOnEntityID.isInvalidID()) { - emit holdingClickOnEntity(_currentClickingOnEntityID, _lastPointerEvent); + emit DependencyManager::get()->holdingClickOnEntity(_currentClickingOnEntityID, _lastPointerEvent); _entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "holdingClickOnEntity", _lastPointerEvent); } } @@ -434,19 +434,6 @@ void EntityTreeRenderer::processEraseMessage(ReceivedMessage& message, const Sha } 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::clickDownOnEntity, entityScriptingInterface, &EntityScriptingInterface::clickDownOnEntity); - connect(this, &EntityTreeRenderer::holdingClickOnEntity, entityScriptingInterface, &EntityScriptingInterface::holdingClickOnEntity); - connect(this, &EntityTreeRenderer::clickReleaseOnEntity, entityScriptingInterface, &EntityScriptingInterface::clickReleaseOnEntity); - - connect(this, &EntityTreeRenderer::hoverEnterEntity, entityScriptingInterface, &EntityScriptingInterface::hoverEnterEntity); - connect(this, &EntityTreeRenderer::hoverOverEntity, entityScriptingInterface, &EntityScriptingInterface::hoverOverEntity); - connect(this, &EntityTreeRenderer::hoverLeaveEntity, entityScriptingInterface, &EntityScriptingInterface::hoverLeaveEntity); - connect(this, &EntityTreeRenderer::enterEntity, entityScriptingInterface, &EntityScriptingInterface::enterEntity); connect(this, &EntityTreeRenderer::leaveEntity, entityScriptingInterface, &EntityScriptingInterface::leaveEntity); connect(this, &EntityTreeRenderer::collisionWithEntity, entityScriptingInterface, &EntityScriptingInterface::collisionWithEntity); @@ -518,10 +505,7 @@ void EntityTreeRenderer::mousePressEvent(QMouseEvent* event) { PickRay ray = _viewState->computePickRay(event->x(), event->y()); RayToEntityIntersectionResult rayPickResult = _getPrevRayPickResultOperator(_mouseRayPickID); if (rayPickResult.intersects) { - //qCDebug(entitiesrenderer) << "mousePressEvent over entity:" << rayPickResult.entityID; - - auto entity = getTree()->findEntityByEntityItemID(rayPickResult.entityID); - auto properties = entity->getProperties(); + auto properties = rayPickResult.entity->getProperties(); QString urlString = properties.getHref(); QUrl url = QUrl(urlString, QUrl::StrictMode); if (url.isValid() && !url.isEmpty()){ @@ -535,14 +519,15 @@ void EntityTreeRenderer::mousePressEvent(QMouseEvent* event) { toPointerButton(*event), toPointerButtons(*event), Qt::NoModifier); // TODO -- check for modifier keys? - emit mousePressOnEntity(rayPickResult.entityID, pointerEvent); + auto entityScriptingInterface = DependencyManager::get(); + emit entityScriptingInterface->mousePressOnEntity(rayPickResult.entityID, pointerEvent); if (_entitiesScriptEngine) { _entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mousePressOnEntity", pointerEvent); } _currentClickingOnEntityID = rayPickResult.entityID; - emit clickDownOnEntity(_currentClickingOnEntityID, pointerEvent); + emit entityScriptingInterface->clickDownOnEntity(_currentClickingOnEntityID, pointerEvent); if (_entitiesScriptEngine) { _entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "clickDownOnEntity", pointerEvent); } @@ -574,23 +559,21 @@ void EntityTreeRenderer::mouseDoublePressEvent(QMouseEvent* event) { rayPickResult.surfaceNormal, ray.direction, toPointerButton(*event), toPointerButtons(*event), Qt::NoModifier); - emit mouseDoublePressOnEntity(rayPickResult.entityID, pointerEvent); - + auto entityScriptingInterface = DependencyManager::get(); + emit entityScriptingInterface->mouseDoublePressOnEntity(rayPickResult.entityID, pointerEvent); if (_entitiesScriptEngine) { _entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseDoublePressOnEntity", pointerEvent); } _currentClickingOnEntityID = rayPickResult.entityID; - emit clickDownOnEntity(_currentClickingOnEntityID, pointerEvent); + emit entityScriptingInterface->clickDownOnEntity(_currentClickingOnEntityID, pointerEvent); if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "doubleclickOnEntity", pointerEvent); + _entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "doubleClickOnEntity", pointerEvent); } _lastPointerEvent = pointerEvent; _lastPointerEventValid = true; - } else { - emit mouseDoublePressOffEntity(); } } @@ -602,6 +585,7 @@ void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event) { } PerformanceTimer perfTimer("EntityTreeRenderer::mouseReleaseEvent"); + auto entityScriptingInterface = DependencyManager::get(); PickRay ray = _viewState->computePickRay(event->x(), event->y()); RayToEntityIntersectionResult rayPickResult = _getPrevRayPickResultOperator(_mouseRayPickID); if (rayPickResult.intersects) { @@ -614,7 +598,7 @@ void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event) { toPointerButton(*event), toPointerButtons(*event), Qt::NoModifier); // TODO -- check for modifier keys? - emit mouseReleaseOnEntity(rayPickResult.entityID, pointerEvent); + emit entityScriptingInterface->mouseReleaseOnEntity(rayPickResult.entityID, pointerEvent); if (_entitiesScriptEngine) { _entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseReleaseOnEntity", pointerEvent); } @@ -624,20 +608,18 @@ void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event) { } // Even if we're no longer intersecting with an entity, if we started clicking on it, and now - // we're releasing the button, then this is considered a clickOn event + // we're releasing the button, then this is considered a clickReleaseOn event if (!_currentClickingOnEntityID.isInvalidID()) { - - auto entity = getTree()->findEntityByID(_currentClickingOnEntityID); - glm::vec2 pos2D = projectOntoEntityXYPlane(entity, ray, rayPickResult); + glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult); PointerEvent pointerEvent(PointerEvent::Release, MOUSE_POINTER_ID, pos2D, rayPickResult.intersection, rayPickResult.surfaceNormal, ray.direction, toPointerButton(*event), toPointerButtons(*event), Qt::NoModifier); // TODO -- check for modifier keys? - emit clickReleaseOnEntity(_currentClickingOnEntityID, pointerEvent); + emit entityScriptingInterface->clickReleaseOnEntity(_currentClickingOnEntityID, pointerEvent); if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "clickReleaseOnEntity", pointerEvent); + _entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "clickReleaseOnEntity", pointerEvent); } } @@ -653,6 +635,7 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) { } PerformanceTimer perfTimer("EntityTreeRenderer::mouseMoveEvent"); + auto entityScriptingInterface = DependencyManager::get(); PickRay ray = _viewState->computePickRay(event->x(), event->y()); RayToEntityIntersectionResult rayPickResult = _getPrevRayPickResultOperator(_mouseRayPickID); if (rayPickResult.intersects) { @@ -663,7 +646,7 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) { toPointerButton(*event), toPointerButtons(*event), Qt::NoModifier); // TODO -- check for modifier keys? - emit mouseMoveOnEntity(rayPickResult.entityID, pointerEvent); + emit entityScriptingInterface->mouseMoveOnEntity(rayPickResult.entityID, pointerEvent); if (_entitiesScriptEngine) { _entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseMoveEvent", pointerEvent); @@ -675,16 +658,14 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) { // if we were previously hovering over an entity, and this new entity is not the same as our previous entity // then we need to send the hover leave. if (!_currentHoverOverEntityID.isInvalidID() && rayPickResult.entityID != _currentHoverOverEntityID) { - - auto entity = getTree()->findEntityByID(_currentHoverOverEntityID); - glm::vec2 pos2D = projectOntoEntityXYPlane(entity, ray, rayPickResult); + glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult); PointerEvent pointerEvent(PointerEvent::Move, MOUSE_POINTER_ID, pos2D, rayPickResult.intersection, rayPickResult.surfaceNormal, ray.direction, toPointerButton(*event), toPointerButtons(*event), Qt::NoModifier); // TODO -- check for modifier keys? - emit hoverLeaveEntity(_currentHoverOverEntityID, pointerEvent); + emit entityScriptingInterface->hoverLeaveEntity(_currentHoverOverEntityID, pointerEvent); if (_entitiesScriptEngine) { _entitiesScriptEngine->callEntityScriptMethod(_currentHoverOverEntityID, "hoverLeaveEntity", pointerEvent); } @@ -693,7 +674,7 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) { // If the new hover entity does not match the previous hover entity then we are entering the new one // this is true if the _currentHoverOverEntityID is known or unknown if (rayPickResult.entityID != _currentHoverOverEntityID) { - emit hoverEnterEntity(rayPickResult.entityID, pointerEvent); + emit entityScriptingInterface->hoverEnterEntity(rayPickResult.entityID, pointerEvent); if (_entitiesScriptEngine) { _entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "hoverEnterEntity", pointerEvent); } @@ -701,7 +682,7 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) { // and finally, no matter what, if we're intersecting an entity then we're definitely hovering over it, and // we should send our hover over event - emit hoverOverEntity(rayPickResult.entityID, pointerEvent); + emit entityScriptingInterface->hoverOverEntity(rayPickResult.entityID, pointerEvent); if (_entitiesScriptEngine) { _entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "hoverOverEntity", pointerEvent); } @@ -717,38 +698,21 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) { // if we were previously hovering over an entity, and we're no longer hovering over any entity then we need to // send the hover leave for our previous entity if (!_currentHoverOverEntityID.isInvalidID()) { - - auto entity = getTree()->findEntityByID(_currentHoverOverEntityID); - glm::vec2 pos2D = projectOntoEntityXYPlane(entity, ray, rayPickResult); + glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult); PointerEvent pointerEvent(PointerEvent::Move, MOUSE_POINTER_ID, pos2D, rayPickResult.intersection, rayPickResult.surfaceNormal, ray.direction, toPointerButton(*event), toPointerButtons(*event), Qt::NoModifier); // TODO -- check for modifier keys? - emit hoverLeaveEntity(_currentHoverOverEntityID, pointerEvent); + emit entityScriptingInterface->hoverLeaveEntity(_currentHoverOverEntityID, pointerEvent); if (_entitiesScriptEngine) { _entitiesScriptEngine->callEntityScriptMethod(_currentHoverOverEntityID, "hoverLeaveEntity", pointerEvent); } _currentHoverOverEntityID = UNKNOWN_ENTITY_ID; // makes it the unknown ID - } - } - // Even if we're no longer intersecting with an entity, if we started clicking on an entity and we have - // not yet released the hold then this is still considered a holdingClickOnEntity event - if (!_currentClickingOnEntityID.isInvalidID()) { - - auto entity = getTree()->findEntityByID(_currentClickingOnEntityID); - glm::vec2 pos2D = projectOntoEntityXYPlane(entity, ray, rayPickResult); - PointerEvent pointerEvent(PointerEvent::Move, MOUSE_POINTER_ID, - pos2D, rayPickResult.intersection, - rayPickResult.surfaceNormal, ray.direction, - toPointerButton(*event), toPointerButtons(*event), - Qt::NoModifier); // TODO -- check for modifier keys? - - emit holdingClickOnEntity(_currentClickingOnEntityID, pointerEvent); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "holdingClickOnEntity", pointerEvent); + _lastPointerEvent = pointerEvent; + _lastPointerEventValid = true; } } } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 1b1d46d50c..b7c0a29104 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -117,20 +117,7 @@ public: void onEntityChanged(const EntityItemID& id); signals: - void mousePressOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); - void mouseDoublePressOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); - void mouseMoveOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); - void mouseReleaseOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); void mousePressOffEntity(); - void mouseDoublePressOffEntity(); - - void clickDownOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); - void holdingClickOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); - void clickReleaseOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); - - void hoverEnterEntity(const EntityItemID& entityItemID, const PointerEvent& event); - void hoverOverEntity(const EntityItemID& entityItemID, const PointerEvent& event); - void hoverLeaveEntity(const EntityItemID& entityItemID, const PointerEvent& event); void enterEntity(const EntityItemID& entityItemID); void leaveEntity(const EntityItemID& entityItemID); diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index 4688ef5d2b..1e83783828 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -24,7 +24,6 @@ #include #include -#include "EntityTreeRenderer.h" #include "EntitiesRendererLogging.h" @@ -240,11 +239,11 @@ bool WebEntityRenderer::buildWebSurface(const TypedEntityPointer& entity) { } }; - auto renderer = DependencyManager::get(); - QObject::connect(renderer.data(), &EntityTreeRenderer::mousePressOnEntity, this, forwardPointerEvent); - QObject::connect(renderer.data(), &EntityTreeRenderer::mouseReleaseOnEntity, this, forwardPointerEvent); - QObject::connect(renderer.data(), &EntityTreeRenderer::mouseMoveOnEntity, this, forwardPointerEvent); - QObject::connect(renderer.data(), &EntityTreeRenderer::hoverLeaveEntity, this, + auto entityScriptingInterface = DependencyManager::get(); + QObject::connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, this, forwardPointerEvent); + QObject::connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity, this, forwardPointerEvent); + QObject::connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity, this, forwardPointerEvent); + QObject::connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, this, [=](const EntityItemID& entityItemID, const PointerEvent& event) { if (this->_pressed && entity->getID() == entityItemID) { // If the user mouses off the entity while the button is down, simulate a touch end. @@ -295,12 +294,12 @@ void WebEntityRenderer::destroyWebSurface() { } webSurface->pause(); - auto renderer = DependencyManager::get(); - if (renderer) { - QObject::disconnect(renderer.data(), &EntityTreeRenderer::mousePressOnEntity, this, nullptr); - QObject::disconnect(renderer.data(), &EntityTreeRenderer::mouseReleaseOnEntity, this, nullptr); - QObject::disconnect(renderer.data(), &EntityTreeRenderer::mouseMoveOnEntity, this, nullptr); - QObject::disconnect(renderer.data(), &EntityTreeRenderer::hoverLeaveEntity, this, nullptr); + auto entityScriptingInterface = DependencyManager::get(); + if (entityScriptingInterface) { + QObject::disconnect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, this, nullptr); + QObject::disconnect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity, this, nullptr); + QObject::disconnect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity, this, nullptr); + QObject::disconnect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, this, nullptr); } webSurface.reset(); } diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index f5117dddc0..cb802ce768 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -1624,43 +1624,46 @@ QUuid EntityScriptingInterface::getKeyboardFocusEntity() const { } void EntityScriptingInterface::setKeyboardFocusEntity(QUuid id) { - QMetaObject::invokeMethod(qApp, "setKeyboardFocusEntity", Qt::QueuedConnection, Q_ARG(QUuid, id)); + QMetaObject::invokeMethod(qApp, "setKeyboardFocusEntity", Qt::DirectConnection, Q_ARG(EntityItemID, id)); } -void EntityScriptingInterface::sendMousePressOnEntity(QUuid id, PointerEvent event) { - QMetaObject::invokeMethod(qApp, "sendMousePressOnEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event)); +// FIXME: the following methods need to be calling EntityTreeRenderer::mouseXXX methods +// Otherwise, like right now, they will not trigger entity script callbacks +// They should still work on web entities and with Interface script event handlers +void EntityScriptingInterface::sendMousePressOnEntity(EntityItemID id, PointerEvent event) { + emit DependencyManager::get()->mousePressOnEntity(id, event); } -void EntityScriptingInterface::sendMouseMoveOnEntity(QUuid id, PointerEvent event) { - QMetaObject::invokeMethod(qApp, "sendMouseMoveOnEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event)); +void EntityScriptingInterface::sendMouseMoveOnEntity(EntityItemID id, PointerEvent event) { + emit DependencyManager::get()->mouseMoveOnEntity(id, event); } -void EntityScriptingInterface::sendMouseReleaseOnEntity(QUuid id, PointerEvent event) { - QMetaObject::invokeMethod(qApp, "sendMouseReleaseOnEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event)); +void EntityScriptingInterface::sendMouseReleaseOnEntity(EntityItemID id, PointerEvent event) { + emit DependencyManager::get()->mouseReleaseOnEntity(id, event); } -void EntityScriptingInterface::sendClickDownOnEntity(QUuid id, PointerEvent event) { - QMetaObject::invokeMethod(qApp, "sendClickDownOnEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event)); +void EntityScriptingInterface::sendClickDownOnEntity(EntityItemID id, PointerEvent event) { + emit DependencyManager::get()->clickDownOnEntity(id, event); } -void EntityScriptingInterface::sendHoldingClickOnEntity(QUuid id, PointerEvent event) { - QMetaObject::invokeMethod(qApp, "sendHoldingClickOnEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event)); +void EntityScriptingInterface::sendHoldingClickOnEntity(EntityItemID id, PointerEvent event) { + emit DependencyManager::get()->holdingClickOnEntity(id, event); } -void EntityScriptingInterface::sendClickReleaseOnEntity(QUuid id, PointerEvent event) { - QMetaObject::invokeMethod(qApp, "sendClickReleaseOnEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event)); +void EntityScriptingInterface::sendClickReleaseOnEntity(EntityItemID id, PointerEvent event) { + emit DependencyManager::get()->clickReleaseOnEntity(id, event); } -void EntityScriptingInterface::sendHoverEnterEntity(QUuid id, PointerEvent event) { - QMetaObject::invokeMethod(qApp, "sendHoverEnterEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event)); +void EntityScriptingInterface::sendHoverEnterEntity(EntityItemID id, PointerEvent event) { + emit DependencyManager::get()->hoverEnterEntity(id, event); } -void EntityScriptingInterface::sendHoverOverEntity(QUuid id, PointerEvent event) { - QMetaObject::invokeMethod(qApp, "sendHoverOverEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event)); +void EntityScriptingInterface::sendHoverOverEntity(EntityItemID id, PointerEvent event) { + emit DependencyManager::get()->hoverOverEntity(id, event); } -void EntityScriptingInterface::sendHoverLeaveEntity(QUuid id, PointerEvent event) { - QMetaObject::invokeMethod(qApp, "sendHoverLeaveEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event)); +void EntityScriptingInterface::sendHoverLeaveEntity(EntityItemID id, PointerEvent event) { + emit DependencyManager::get()->hoverLeaveEntity(id, event); } bool EntityScriptingInterface::wantsHandControllerPointerEvents(QUuid id) { diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index 989d3dd89d..b755a2eb30 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -345,17 +345,17 @@ public slots: Q_INVOKABLE QUuid getKeyboardFocusEntity() const; Q_INVOKABLE void setKeyboardFocusEntity(QUuid id); - Q_INVOKABLE void sendMousePressOnEntity(QUuid id, PointerEvent event); - Q_INVOKABLE void sendMouseMoveOnEntity(QUuid id, PointerEvent event); - Q_INVOKABLE void sendMouseReleaseOnEntity(QUuid id, PointerEvent event); + Q_INVOKABLE void sendMousePressOnEntity(EntityItemID id, PointerEvent event); + Q_INVOKABLE void sendMouseMoveOnEntity(EntityItemID id, PointerEvent event); + Q_INVOKABLE void sendMouseReleaseOnEntity(EntityItemID id, PointerEvent event); - Q_INVOKABLE void sendClickDownOnEntity(QUuid id, PointerEvent event); - Q_INVOKABLE void sendHoldingClickOnEntity(QUuid id, PointerEvent event); - Q_INVOKABLE void sendClickReleaseOnEntity(QUuid id, PointerEvent event); + Q_INVOKABLE void sendClickDownOnEntity(EntityItemID id, PointerEvent event); + Q_INVOKABLE void sendHoldingClickOnEntity(EntityItemID id, PointerEvent event); + Q_INVOKABLE void sendClickReleaseOnEntity(EntityItemID id, PointerEvent event); - Q_INVOKABLE void sendHoverEnterEntity(QUuid id, PointerEvent event); - Q_INVOKABLE void sendHoverOverEntity(QUuid id, PointerEvent event); - Q_INVOKABLE void sendHoverLeaveEntity(QUuid id, PointerEvent event); + Q_INVOKABLE void sendHoverEnterEntity(EntityItemID id, PointerEvent event); + Q_INVOKABLE void sendHoverOverEntity(EntityItemID id, PointerEvent event); + Q_INVOKABLE void sendHoverLeaveEntity(EntityItemID id, PointerEvent event); Q_INVOKABLE bool wantsHandControllerPointerEvents(QUuid id); @@ -402,6 +402,7 @@ signals: void canWriteAssetsChanged(bool canWriteAssets); void mousePressOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); + void mouseDoublePressOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); void mouseMoveOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); void mouseReleaseOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); From 1a047613bfe70ecf5b84e7db152341ac215a8a9d Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 12 Oct 2017 12:31:36 -0700 Subject: [PATCH 02/11] fix pointerevents on entities from scripts --- .../src/EntityTreeRenderer.cpp | 73 ++++++++++--------- .../entities/src/EntityScriptingInterface.cpp | 21 +++--- 2 files changed, 46 insertions(+), 48 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 9bbc6caaf2..8cb39abf5e 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -84,7 +84,42 @@ void EntityTreeRenderer::resetEntitiesScriptEngine() { _scriptingServices->registerScriptEngineWithApplicationServices(_entitiesScriptEngine); _entitiesScriptEngine->runInThread(); auto entitiesScriptEngineProvider = qSharedPointerCast(_entitiesScriptEngine); - DependencyManager::get()->setEntitiesScriptEngine(entitiesScriptEngineProvider); + auto entityScriptingInterface = DependencyManager::get(); + entityScriptingInterface->setEntitiesScriptEngine(entitiesScriptEngineProvider); + + // Connect mouse events to entity script callbacks + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "mousePressOnEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseDoublePressOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseDoublePressOnEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseMoveOnEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseReleaseOnEntity", event); + }); + + connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickDownOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "clickDownOnEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::holdingClickOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "holdingClickOnEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickReleaseOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "clickReleaseOnEntity", event); + }); + + connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverEnterEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverEnterEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverOverEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverOverEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverLeaveEntity", event); + }); } void EntityTreeRenderer::clear() { @@ -246,7 +281,6 @@ void EntityTreeRenderer::update(bool simulate) { // and we want to simulate this message here as well as in mouse move if (_lastPointerEventValid && !_currentClickingOnEntityID.isInvalidID()) { emit DependencyManager::get()->holdingClickOnEntity(_currentClickingOnEntityID, _lastPointerEvent); - _entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "holdingClickOnEntity", _lastPointerEvent); } } @@ -522,15 +556,8 @@ void EntityTreeRenderer::mousePressEvent(QMouseEvent* event) { auto entityScriptingInterface = DependencyManager::get(); emit entityScriptingInterface->mousePressOnEntity(rayPickResult.entityID, pointerEvent); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mousePressOnEntity", pointerEvent); - } - _currentClickingOnEntityID = rayPickResult.entityID; emit entityScriptingInterface->clickDownOnEntity(_currentClickingOnEntityID, pointerEvent); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "clickDownOnEntity", pointerEvent); - } _lastPointerEvent = pointerEvent; _lastPointerEventValid = true; @@ -551,8 +578,6 @@ void EntityTreeRenderer::mouseDoublePressEvent(QMouseEvent* event) { PickRay ray = _viewState->computePickRay(event->x(), event->y()); RayToEntityIntersectionResult rayPickResult = _getPrevRayPickResultOperator(_mouseRayPickID); if (rayPickResult.intersects) { - //qCDebug(entitiesrenderer) << "mouseDoublePressEvent over entity:" << rayPickResult.entityID; - glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult); PointerEvent pointerEvent(PointerEvent::Press, MOUSE_POINTER_ID, pos2D, rayPickResult.intersection, @@ -561,15 +586,9 @@ void EntityTreeRenderer::mouseDoublePressEvent(QMouseEvent* event) { auto entityScriptingInterface = DependencyManager::get(); emit entityScriptingInterface->mouseDoublePressOnEntity(rayPickResult.entityID, pointerEvent); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseDoublePressOnEntity", pointerEvent); - } _currentClickingOnEntityID = rayPickResult.entityID; emit entityScriptingInterface->clickDownOnEntity(_currentClickingOnEntityID, pointerEvent); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "doubleClickOnEntity", pointerEvent); - } _lastPointerEvent = pointerEvent; _lastPointerEventValid = true; @@ -599,9 +618,6 @@ void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event) { Qt::NoModifier); // TODO -- check for modifier keys? emit entityScriptingInterface->mouseReleaseOnEntity(rayPickResult.entityID, pointerEvent); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseReleaseOnEntity", pointerEvent); - } _lastPointerEvent = pointerEvent; _lastPointerEventValid = true; @@ -618,9 +634,6 @@ void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event) { Qt::NoModifier); // TODO -- check for modifier keys? emit entityScriptingInterface->clickReleaseOnEntity(_currentClickingOnEntityID, pointerEvent); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "clickReleaseOnEntity", pointerEvent); - } } // makes it the unknown ID, we just released so we can't be clicking on anything @@ -648,9 +661,9 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) { emit entityScriptingInterface->mouseMoveOnEntity(rayPickResult.entityID, pointerEvent); + // FIXME: this is a duplicate of mouseMoveOnEntity, but it seems like some scripts might use this naming if (_entitiesScriptEngine) { _entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseMoveEvent", pointerEvent); - _entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseMoveOnEntity", pointerEvent); } // handle the hover logic... @@ -666,26 +679,17 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) { Qt::NoModifier); // TODO -- check for modifier keys? emit entityScriptingInterface->hoverLeaveEntity(_currentHoverOverEntityID, pointerEvent); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(_currentHoverOverEntityID, "hoverLeaveEntity", pointerEvent); - } } // If the new hover entity does not match the previous hover entity then we are entering the new one // this is true if the _currentHoverOverEntityID is known or unknown if (rayPickResult.entityID != _currentHoverOverEntityID) { emit entityScriptingInterface->hoverEnterEntity(rayPickResult.entityID, pointerEvent); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "hoverEnterEntity", pointerEvent); - } } // and finally, no matter what, if we're intersecting an entity then we're definitely hovering over it, and // we should send our hover over event emit entityScriptingInterface->hoverOverEntity(rayPickResult.entityID, pointerEvent); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "hoverOverEntity", pointerEvent); - } // remember what we're hovering over _currentHoverOverEntityID = rayPickResult.entityID; @@ -706,9 +710,6 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) { Qt::NoModifier); // TODO -- check for modifier keys? emit entityScriptingInterface->hoverLeaveEntity(_currentHoverOverEntityID, pointerEvent); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(_currentHoverOverEntityID, "hoverLeaveEntity", pointerEvent); - } _currentHoverOverEntityID = UNKNOWN_ENTITY_ID; // makes it the unknown ID _lastPointerEvent = pointerEvent; diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index cb802ce768..f43b1beb54 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -1627,43 +1627,40 @@ void EntityScriptingInterface::setKeyboardFocusEntity(QUuid id) { QMetaObject::invokeMethod(qApp, "setKeyboardFocusEntity", Qt::DirectConnection, Q_ARG(EntityItemID, id)); } -// FIXME: the following methods need to be calling EntityTreeRenderer::mouseXXX methods -// Otherwise, like right now, they will not trigger entity script callbacks -// They should still work on web entities and with Interface script event handlers void EntityScriptingInterface::sendMousePressOnEntity(EntityItemID id, PointerEvent event) { - emit DependencyManager::get()->mousePressOnEntity(id, event); + emit mousePressOnEntity(id, event); } void EntityScriptingInterface::sendMouseMoveOnEntity(EntityItemID id, PointerEvent event) { - emit DependencyManager::get()->mouseMoveOnEntity(id, event); + emit mouseMoveOnEntity(id, event); } void EntityScriptingInterface::sendMouseReleaseOnEntity(EntityItemID id, PointerEvent event) { - emit DependencyManager::get()->mouseReleaseOnEntity(id, event); + emit mouseReleaseOnEntity(id, event); } void EntityScriptingInterface::sendClickDownOnEntity(EntityItemID id, PointerEvent event) { - emit DependencyManager::get()->clickDownOnEntity(id, event); + emit clickDownOnEntity(id, event); } void EntityScriptingInterface::sendHoldingClickOnEntity(EntityItemID id, PointerEvent event) { - emit DependencyManager::get()->holdingClickOnEntity(id, event); + emit holdingClickOnEntity(id, event); } void EntityScriptingInterface::sendClickReleaseOnEntity(EntityItemID id, PointerEvent event) { - emit DependencyManager::get()->clickReleaseOnEntity(id, event); + emit clickReleaseOnEntity(id, event); } void EntityScriptingInterface::sendHoverEnterEntity(EntityItemID id, PointerEvent event) { - emit DependencyManager::get()->hoverEnterEntity(id, event); + emit hoverEnterEntity(id, event); } void EntityScriptingInterface::sendHoverOverEntity(EntityItemID id, PointerEvent event) { - emit DependencyManager::get()->hoverOverEntity(id, event); + emit hoverOverEntity(id, event); } void EntityScriptingInterface::sendHoverLeaveEntity(EntityItemID id, PointerEvent event) { - emit DependencyManager::get()->hoverLeaveEntity(id, event); + emit hoverLeaveEntity(id, event); } bool EntityScriptingInterface::wantsHandControllerPointerEvents(QUuid id) { From 7f3268548c407e5113a64f6af4b913b3ee2920f2 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 12 Oct 2017 14:14:08 -0700 Subject: [PATCH 03/11] direct connection to web3doverlay --- interface/src/ui/overlays/Overlays.cpp | 43 +++++++++++++++++----- interface/src/ui/overlays/Overlays.h | 7 +--- interface/src/ui/overlays/Web3DOverlay.cpp | 38 ++++--------------- interface/src/ui/overlays/Web3DOverlay.h | 3 +- 4 files changed, 46 insertions(+), 45 deletions(-) diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index b3c9ba2a34..f35cb3066f 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -723,11 +723,11 @@ void Overlays::sendMousePressOnOverlay(const OverlayID& overlayID, const Pointer } void Overlays::sendMouseReleaseOnOverlay(const OverlayID& overlayID, const PointerEvent& event) { - emit mouseReleaseOnOverlay(overlayID, event); + mouseReleaseEvent(overlayID, event); } void Overlays::sendMouseMoveOnOverlay(const OverlayID& overlayID, const PointerEvent& event) { - emit mouseMoveOnOverlay(overlayID, event); + mouseMoveEvent(overlayID, event); } void Overlays::sendHoverEnterOverlay(const OverlayID& overlayID, const PointerEvent& event) { @@ -898,16 +898,16 @@ void Overlays::mousePressEvent(const OverlayID& overlayID, const PointerEvent& e // contextOverlays_mousePressOnOverlay is not threadsafe and mousePressEvent can be called from scripts, so use an auto connection QMetaObject::invokeMethod(DependencyManager::get().data(), "contextOverlays_mousePressOnOverlay", Q_ARG(OverlayID, overlayID), Q_ARG(PointerEvent, event)); - // Focus keyboard on web overlays - // TODO: generalize this to allow any entity to recieve keyboard focus + // TODO: generalize this to allow any overlay to recieve events auto thisOverlay = std::dynamic_pointer_cast(getOverlay(overlayID)); if (thisOverlay) { + // Focus keyboard on web overlays qApp->setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); qApp->setKeyboardFocusOverlay(overlayID); - } - // Send press to web overlays - emit mousePressOnOverlay(overlayID, event); + // Send to web overlay + QMetaObject::invokeMethod(thisOverlay.get(), "handlePointerEvent", Q_ARG(PointerEvent, event)); + } } void Overlays::hoverEnterEvent(const OverlayID& overlayID, const PointerEvent& event) { @@ -920,6 +920,13 @@ void Overlays::hoverLeaveEvent(const OverlayID& overlayID, const PointerEvent& e // Send hoverLeave to context overlay // contextOverlays_hoverLeaveOverlay is not threadsafe and hoverLeaveEvent can be called from scripts, so use an auto connection QMetaObject::invokeMethod(DependencyManager::get().data(), "contextOverlays_hoverLeaveOverlay", Q_ARG(OverlayID, overlayID), Q_ARG(PointerEvent, event)); + + // TODO: generalize this to allow any overlay to recieve events + auto thisOverlay = std::dynamic_pointer_cast(getOverlay(overlayID)); + if (thisOverlay) { + // Send to web overlay + QMetaObject::invokeMethod(thisOverlay.get(), "hoverLeaveOverlay", Q_ARG(PointerEvent, event)); + } } bool Overlays::mouseReleaseEvent(QMouseEvent* event) { @@ -929,13 +936,22 @@ bool Overlays::mouseReleaseEvent(QMouseEvent* event) { RayToOverlayIntersectionResult rayPickResult = findRayIntersectionForMouseEvent(ray); if (rayPickResult.intersects) { auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Release); - emit mouseReleaseOnOverlay(rayPickResult.overlayID, pointerEvent); + mouseReleaseEvent(rayPickResult.overlayID, pointerEvent); } _currentClickingOnOverlayID = UNKNOWN_OVERLAY_ID; return false; } +void Overlays::mouseReleaseEvent(const OverlayID& overlayID, const PointerEvent& event) { + // TODO: generalize this to allow any overlay to recieve events + auto thisOverlay = std::dynamic_pointer_cast(getOverlay(overlayID)); + if (thisOverlay) { + // Send to web overlay + QMetaObject::invokeMethod(thisOverlay.get(), "handlePointerEvent", Q_ARG(PointerEvent, event)); + } +} + bool Overlays::mouseMoveEvent(QMouseEvent* event) { PerformanceTimer perfTimer("Overlays::mouseMoveEvent"); @@ -943,7 +959,7 @@ bool Overlays::mouseMoveEvent(QMouseEvent* event) { RayToOverlayIntersectionResult rayPickResult = findRayIntersectionForMouseEvent(ray); if (rayPickResult.intersects) { auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Move); - emit mouseMoveOnOverlay(rayPickResult.overlayID, pointerEvent); + mouseMoveEvent(rayPickResult.overlayID, pointerEvent); // If previously hovering over a different overlay then leave hover on that overlay. if (_currentHoverOverOverlayID != UNKNOWN_OVERLAY_ID && rayPickResult.overlayID != _currentHoverOverOverlayID) { @@ -972,6 +988,15 @@ bool Overlays::mouseMoveEvent(QMouseEvent* event) { return false; } +void Overlays::mouseMoveEvent(const OverlayID& overlayID, const PointerEvent& event) { + // TODO: generalize this to allow any overlay to recieve events + auto thisOverlay = std::dynamic_pointer_cast(getOverlay(overlayID)); + if (thisOverlay) { + // Send to web overlay + QMetaObject::invokeMethod(thisOverlay.get(), "handlePointerEvent", Q_ARG(PointerEvent, event)); + } +} + QVector Overlays::findOverlays(const glm::vec3& center, float radius) { QVector result; //if (QThread::currentThread() != thread()) { diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index d5517bbb9d..8408830cd9 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -107,6 +107,8 @@ public: bool mouseMoveEvent(QMouseEvent* event); void mousePressEvent(const OverlayID& overlayID, const PointerEvent& event); + void mouseMoveEvent(const OverlayID& overlayID, const PointerEvent& event); + void mouseReleaseEvent(const OverlayID& overlayID, const PointerEvent& event); void hoverEnterEvent(const OverlayID& overlayID, const PointerEvent& event); void hoverLeaveEvent(const OverlayID& overlayID, const PointerEvent& event); @@ -318,11 +320,6 @@ signals: void overlayDeleted(OverlayID id); void panelDeleted(OverlayID id); - void mousePressOnOverlay(OverlayID overlayID, const PointerEvent& event); - void mouseReleaseOnOverlay(OverlayID overlayID, const PointerEvent& event); - void mouseMoveOnOverlay(OverlayID overlayID, const PointerEvent& event); - - void hoverLeaveOverlay(OverlayID overlayID, const PointerEvent& event); // FIXME: nothing connects to this signal anymore void hoverOverOverlay(OverlayID overlayID, const PointerEvent& event); diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 526890b9c1..eab202d214 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -126,11 +126,7 @@ void Web3DOverlay::destroyWebSurface() { } _webSurface->pause(); - auto overlays = &(qApp->getOverlays()); - QObject::disconnect(overlays, &Overlays::mousePressOnOverlay, this, nullptr); - QObject::disconnect(overlays, &Overlays::mouseReleaseOnOverlay, this, nullptr); - QObject::disconnect(overlays, &Overlays::mouseMoveOnOverlay, this, nullptr); - QObject::disconnect(overlays, &Overlays::hoverLeaveOverlay, this, nullptr); + QObject::disconnect(this, &Web3DOverlay::scriptEventReceived, _webSurface.data(), &OffscreenQmlSurface::emitScriptEvent); QObject::disconnect(_webSurface.data(), &OffscreenQmlSurface::webEventReceived, this, &Web3DOverlay::webEventReceived); DependencyManager::get()->release(QML, _webSurface); @@ -161,35 +157,17 @@ void Web3DOverlay::buildWebSurface() { _webSurface->resume(); }); - auto selfOverlayID = getOverlayID(); - std::weak_ptr weakSelf = std::dynamic_pointer_cast(qApp->getOverlays().getOverlay(selfOverlayID)); - auto forwardPointerEvent = [=](OverlayID overlayID, const PointerEvent& event) { - auto self = weakSelf.lock(); - if (self && overlayID == selfOverlayID) { - self->handlePointerEvent(event); - } - }; - - auto overlays = &(qApp->getOverlays()); - QObject::connect(overlays, &Overlays::mousePressOnOverlay, this, forwardPointerEvent); - QObject::connect(overlays, &Overlays::mouseReleaseOnOverlay, this, forwardPointerEvent); - QObject::connect(overlays, &Overlays::mouseMoveOnOverlay, this, forwardPointerEvent); - QObject::connect(overlays, &Overlays::hoverLeaveOverlay, this, [=](OverlayID overlayID, const PointerEvent& event) { - auto self = weakSelf.lock(); - if (!self) { - return; - } - if (overlayID == selfOverlayID && (self->_pressed || (!self->_activeTouchPoints.empty() && self->_touchBeginAccepted))) { - PointerEvent endEvent(PointerEvent::Release, event.getID(), event.getPos2D(), event.getPos3D(), event.getNormal(), event.getDirection(), - event.getButton(), event.getButtons(), event.getKeyboardModifiers()); - forwardPointerEvent(overlayID, endEvent); - } - }); - QObject::connect(this, &Web3DOverlay::scriptEventReceived, _webSurface.data(), &OffscreenQmlSurface::emitScriptEvent); QObject::connect(_webSurface.data(), &OffscreenQmlSurface::webEventReceived, this, &Web3DOverlay::webEventReceived); } +void Web3DOverlay::hoverLeaveOverlay(const PointerEvent& event) { + if ((_pressed || (!_activeTouchPoints.empty() && _touchBeginAccepted))) { + PointerEvent endEvent(PointerEvent::Release, event.getID(), event.getPos2D(), event.getPos3D(), event.getNormal(), event.getDirection(), + event.getButton(), event.getButtons(), event.getKeyboardModifiers()); + handlePointerEvent(endEvent); + } +} void Web3DOverlay::update(float deltatime) { if (_webSurface) { diff --git a/interface/src/ui/overlays/Web3DOverlay.h b/interface/src/ui/overlays/Web3DOverlay.h index de74b95b3e..c7f338f0e6 100644 --- a/interface/src/ui/overlays/Web3DOverlay.h +++ b/interface/src/ui/overlays/Web3DOverlay.h @@ -39,7 +39,8 @@ public: QObject* getEventHandler(); void setProxyWindow(QWindow* proxyWindow); - void handlePointerEvent(const PointerEvent& event); + Q_INVOKABLE void hoverLeaveOverlay(const PointerEvent& event); + Q_INVOKABLE void handlePointerEvent(const PointerEvent& event); void handlePointerEventAsTouch(const PointerEvent& event); void handlePointerEventAsMouse(const PointerEvent& event); From a48221d915dadedaccc64c0b42008b1898708a20 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 12 Oct 2017 14:51:15 -0700 Subject: [PATCH 04/11] fix context overlays --- interface/src/ui/overlays/ContextOverlayInterface.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 8cbb214857..0481564fae 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -43,10 +43,10 @@ ContextOverlayInterface::ContextOverlayInterface() { _entityPropertyFlags += PROP_REGISTRATION_POINT; _entityPropertyFlags += PROP_CERTIFICATE_ID; - auto entityTreeRenderer = DependencyManager::get().data(); - connect(entityTreeRenderer, SIGNAL(mousePressOnEntity(const EntityItemID&, const PointerEvent&)), this, SLOT(createOrDestroyContextOverlay(const EntityItemID&, const PointerEvent&))); - connect(entityTreeRenderer, SIGNAL(hoverEnterEntity(const EntityItemID&, const PointerEvent&)), this, SLOT(contextOverlays_hoverEnterEntity(const EntityItemID&, const PointerEvent&))); - connect(entityTreeRenderer, SIGNAL(hoverLeaveEntity(const EntityItemID&, const PointerEvent&)), this, SLOT(contextOverlays_hoverLeaveEntity(const EntityItemID&, const PointerEvent&))); + auto entityScriptingInterface = DependencyManager::get().data(); + connect(entityScriptingInterface, &EntityScriptingInterface::mousePressOnEntity, this, &ContextOverlayInterface::createOrDestroyContextOverlay); + connect(entityScriptingInterface, &EntityScriptingInterface::hoverEnterEntity, this, &ContextOverlayInterface::contextOverlays_hoverEnterEntity); + connect(entityScriptingInterface, &EntityScriptingInterface::hoverLeaveEntity, this, &ContextOverlayInterface::contextOverlays_hoverLeaveEntity); connect(_tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"), &TabletProxy::tabletShownChanged, this, [&]() { if (_contextOverlayJustClicked && _hmdScriptingInterface->isMounted()) { QUuid tabletFrameID = _hmdScriptingInterface->getCurrentTabletFrameID(); @@ -59,7 +59,6 @@ ContextOverlayInterface::ContextOverlayInterface() { _contextOverlayJustClicked = false; } }); - auto entityScriptingInterface = DependencyManager::get().data(); connect(entityScriptingInterface, &EntityScriptingInterface::deletingEntity, this, &ContextOverlayInterface::deletingEntity); connect(_selectionScriptingInterface.data(), &SelectionScriptingInterface::selectedItemsListChanged, &_selectionToSceneHandler, &SelectionToSceneHandler::selectedItemsListChanged); From 0d164363afb4578c38ff647188cab367575d8409 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 12 Oct 2017 15:29:29 -0700 Subject: [PATCH 05/11] cleanup mousePressOffEntity signal --- interface/src/Application.cpp | 5 ----- interface/src/Application.h | 2 +- interface/src/ui/overlays/Overlays.cpp | 5 ----- libraries/entities-renderer/src/EntityTreeRenderer.cpp | 3 ++- libraries/entities-renderer/src/EntityTreeRenderer.h | 2 -- 5 files changed, 3 insertions(+), 14 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 648339e739..35a7bbd680 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1463,11 +1463,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo } }); - // If the user clicks somewhere where there is NO entity at all, we will release focus - connect(getEntities().data(), &EntityTreeRenderer::mousePressOffEntity, [=]() { - setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); - }); - // Keyboard focus handling for Web overlays. auto overlays = &(qApp->getOverlays()); connect(overlays, &Overlays::overlayDeleted, [=](const OverlayID& overlayID) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 10b1637ad9..85700de505 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -376,7 +376,7 @@ public slots: void setKeyboardFocusHighlight(const glm::vec3& position, const glm::quat& rotation, const glm::vec3& dimensions); QUuid getKeyboardFocusEntity() const; // thread-safe - void setKeyboardFocusEntity(EntityItemID entityItemID); + Q_INVOKABLE void setKeyboardFocusEntity(EntityItemID entityItemID); OverlayID getKeyboardFocusOverlay(); void setKeyboardFocusOverlay(OverlayID overlayID); diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index f35cb3066f..1ee212a04e 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -747,11 +747,6 @@ OverlayID Overlays::getKeyboardFocusOverlay() { } void Overlays::setKeyboardFocusOverlay(OverlayID id) { - if (QThread::currentThread() != thread()) { - QMetaObject::invokeMethod(this, "setKeyboardFocusOverlay", Q_ARG(OverlayID, id)); - return; - } - qApp->setKeyboardFocusOverlay(id); } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 8cb39abf5e..33cdebafce 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -563,7 +563,8 @@ void EntityTreeRenderer::mousePressEvent(QMouseEvent* event) { _lastPointerEventValid = true; } else { - emit mousePressOffEntity(); + // If the user clicks somewhere where there is NO entity at all, we will release focus + QMetaObject::invokeMethod(qApp, "setKeyboardFocusEntity", Qt::DirectConnection, Q_ARG(EntityItemID, UNKNOWN_ENTITY_ID)); } } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index b7c0a29104..1eb44f996a 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -117,8 +117,6 @@ public: void onEntityChanged(const EntityItemID& id); signals: - void mousePressOffEntity(); - void enterEntity(const EntityItemID& entityItemID); void leaveEntity(const EntityItemID& entityItemID); void collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); From dacd48862f5deafac3d2faaff84b5f4ba7b0e8ea Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 12 Oct 2017 16:43:33 -0700 Subject: [PATCH 06/11] put back overlay signals for scripts --- interface/src/Application.cpp | 1 + interface/src/ui/overlays/Overlays.cpp | 36 ++++++++++++++++++++++++++ interface/src/ui/overlays/Overlays.h | 13 +++++++++- 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 35a7bbd680..808be5b08a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3302,6 +3302,7 @@ void Application::mouseDoublePressEvent(QMouseEvent* event) { event->buttons(), event->modifiers()); if (!_aboutToQuit) { + getOverlays().mouseDoublePressEvent(&mappedEvent); if (!_controllerScriptingInterface->areEntityClicksCaptured()) { getEntities()->mouseDoublePressEvent(&mappedEvent); } diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 1ee212a04e..1ba5c38c8e 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -884,7 +884,10 @@ bool Overlays::mousePressEvent(QMouseEvent* event) { mousePressEvent(_currentClickingOnOverlayID, pointerEvent); return true; } + // if we didn't press on an overlay, disable overlay keyboard focus qApp->setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); + // emit to scripts + emit mousePressOffOverlay(); return false; } @@ -903,12 +906,36 @@ void Overlays::mousePressEvent(const OverlayID& overlayID, const PointerEvent& e // Send to web overlay QMetaObject::invokeMethod(thisOverlay.get(), "handlePointerEvent", Q_ARG(PointerEvent, event)); } + + // emit to scripts + emit mousePressOnOverlay(overlayID, event); +} + +bool Overlays::mouseDoublePressEvent(QMouseEvent* event) { + PerformanceTimer perfTimer("Overlays::mouseDoublePressEvent"); + + PickRay ray = qApp->computePickRay(event->x(), event->y()); + RayToOverlayIntersectionResult rayPickResult = findRayIntersectionForMouseEvent(ray); + if (rayPickResult.intersects) { + _currentClickingOnOverlayID = rayPickResult.overlayID; + + auto pointerEvent = calculateOverlayPointerEvent(_currentClickingOnOverlayID, ray, rayPickResult, event, PointerEvent::Press); + // emit to scripts + emit mouseDoublePressOnOverlay(_currentClickingOnOverlayID, pointerEvent); + return true; + } + // emit to scripts + emit mouseDoublePressOffOverlay(); + return false; } void Overlays::hoverEnterEvent(const OverlayID& overlayID, const PointerEvent& event) { // Send hoverEnter to context overlay // contextOverlays_hoverEnterOverlay is not threadsafe and hoverEnterEvent can be called from scripts, so use an auto connection QMetaObject::invokeMethod(DependencyManager::get().data(), "contextOverlays_hoverEnterOverlay", Q_ARG(OverlayID, overlayID), Q_ARG(PointerEvent, event)); + + // emit to scripts + emit hoverEnterOverlay(overlayID, event); } void Overlays::hoverLeaveEvent(const OverlayID& overlayID, const PointerEvent& event) { @@ -922,6 +949,9 @@ void Overlays::hoverLeaveEvent(const OverlayID& overlayID, const PointerEvent& e // Send to web overlay QMetaObject::invokeMethod(thisOverlay.get(), "hoverLeaveOverlay", Q_ARG(PointerEvent, event)); } + + // emit to scripts + emit hoverLeaveOverlay(overlayID, event); } bool Overlays::mouseReleaseEvent(QMouseEvent* event) { @@ -945,6 +975,9 @@ void Overlays::mouseReleaseEvent(const OverlayID& overlayID, const PointerEvent& // Send to web overlay QMetaObject::invokeMethod(thisOverlay.get(), "handlePointerEvent", Q_ARG(PointerEvent, event)); } + + // emit to scripts + emit mouseReleaseOnOverlay(overlayID, event); } bool Overlays::mouseMoveEvent(QMouseEvent* event) { @@ -990,6 +1023,9 @@ void Overlays::mouseMoveEvent(const OverlayID& overlayID, const PointerEvent& ev // Send to web overlay QMetaObject::invokeMethod(thisOverlay.get(), "handlePointerEvent", Q_ARG(PointerEvent, event)); } + + // emit to scripts + emit mouseMoveOnOverlay(overlayID, event); } QVector Overlays::findOverlays(const glm::vec3& center, float radius) { diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 8408830cd9..cfc670a78c 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -103,6 +103,7 @@ public: OverlayID addOverlay(const Overlay::Pointer& overlay); bool mousePressEvent(QMouseEvent* event); + bool mouseDoublePressEvent(QMouseEvent* event); bool mouseReleaseEvent(QMouseEvent* event); bool mouseMoveEvent(QMouseEvent* event); @@ -320,8 +321,18 @@ signals: void overlayDeleted(OverlayID id); void panelDeleted(OverlayID id); - // FIXME: nothing connects to this signal anymore + // Nothing should need to connect to these signals in C++ + // They are only for scripts to connect to + void mousePressOnOverlay(OverlayID overlayID, const PointerEvent& event); + void mouseDoublePressOnOverlay(OverlayID overlayID, const PointerEvent& event); + void mouseReleaseOnOverlay(OverlayID overlayID, const PointerEvent& event); + void mouseMoveOnOverlay(OverlayID overlayID, const PointerEvent& event); + void mousePressOffOverlay(); + void mouseDoublePressOffOverlay(); + + void hoverEnterOverlay(OverlayID overlayID, const PointerEvent& event); void hoverOverOverlay(OverlayID overlayID, const PointerEvent& event); + void hoverLeaveOverlay(OverlayID overlayID, const PointerEvent& event); private: void cleanupOverlaysToDelete(); From cc8ecdc5965173fdf7231640f8c7a13614991555 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 12 Oct 2017 17:28:00 -0700 Subject: [PATCH 07/11] put back entity signals for scripts --- .../entities-renderer/src/EntityTreeRenderer.cpp | 15 +++++++-------- libraries/entities/src/EntityScriptingInterface.h | 2 ++ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 33cdebafce..e5ced01b9c 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -96,6 +96,8 @@ void EntityTreeRenderer::resetEntitiesScriptEngine() { }); connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { _entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseMoveOnEntity", event); + // FIXME: this is a duplicate of mouseMoveOnEntity, but it seems like some scripts might use this naming + _entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseMoveEvent", event); }); connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { _entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseReleaseOnEntity", event); @@ -536,6 +538,7 @@ void EntityTreeRenderer::mousePressEvent(QMouseEvent* event) { } PerformanceTimer perfTimer("EntityTreeRenderer::mousePressEvent"); + auto entityScriptingInterface = DependencyManager::get(); PickRay ray = _viewState->computePickRay(event->x(), event->y()); RayToEntityIntersectionResult rayPickResult = _getPrevRayPickResultOperator(_mouseRayPickID); if (rayPickResult.intersects) { @@ -553,7 +556,6 @@ void EntityTreeRenderer::mousePressEvent(QMouseEvent* event) { toPointerButton(*event), toPointerButtons(*event), Qt::NoModifier); // TODO -- check for modifier keys? - auto entityScriptingInterface = DependencyManager::get(); emit entityScriptingInterface->mousePressOnEntity(rayPickResult.entityID, pointerEvent); _currentClickingOnEntityID = rayPickResult.entityID; @@ -565,6 +567,7 @@ void EntityTreeRenderer::mousePressEvent(QMouseEvent* event) { } else { // If the user clicks somewhere where there is NO entity at all, we will release focus QMetaObject::invokeMethod(qApp, "setKeyboardFocusEntity", Qt::DirectConnection, Q_ARG(EntityItemID, UNKNOWN_ENTITY_ID)); + emit entityScriptingInterface->mousePressOffEntity(); } } @@ -576,6 +579,7 @@ void EntityTreeRenderer::mouseDoublePressEvent(QMouseEvent* event) { } PerformanceTimer perfTimer("EntityTreeRenderer::mouseDoublePressEvent"); + auto entityScriptingInterface = DependencyManager::get(); PickRay ray = _viewState->computePickRay(event->x(), event->y()); RayToEntityIntersectionResult rayPickResult = _getPrevRayPickResultOperator(_mouseRayPickID); if (rayPickResult.intersects) { @@ -585,7 +589,6 @@ void EntityTreeRenderer::mouseDoublePressEvent(QMouseEvent* event) { rayPickResult.surfaceNormal, ray.direction, toPointerButton(*event), toPointerButtons(*event), Qt::NoModifier); - auto entityScriptingInterface = DependencyManager::get(); emit entityScriptingInterface->mouseDoublePressOnEntity(rayPickResult.entityID, pointerEvent); _currentClickingOnEntityID = rayPickResult.entityID; @@ -593,7 +596,8 @@ void EntityTreeRenderer::mouseDoublePressEvent(QMouseEvent* event) { _lastPointerEvent = pointerEvent; _lastPointerEventValid = true; - + } else { + emit entityScriptingInterface->mouseDoublePressOffEntity(); } } @@ -662,11 +666,6 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) { emit entityScriptingInterface->mouseMoveOnEntity(rayPickResult.entityID, pointerEvent); - // FIXME: this is a duplicate of mouseMoveOnEntity, but it seems like some scripts might use this naming - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseMoveEvent", pointerEvent); - } - // handle the hover logic... // if we were previously hovering over an entity, and this new entity is not the same as our previous entity diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index b755a2eb30..97af06ee83 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -405,6 +405,8 @@ signals: void mouseDoublePressOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); void mouseMoveOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); void mouseReleaseOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); + void mousePressOffEntity(); + void mouseDoublePressOffEntity(); void clickDownOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); void holdingClickOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); From 5bfb0baf09cce15210bb2dcb831e9960058a5b3e Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 13 Oct 2017 14:38:46 -0700 Subject: [PATCH 08/11] const references --- interface/src/Application.cpp | 4 ++-- interface/src/Application.h | 4 ++-- interface/src/ui/overlays/Overlays.cpp | 6 +++--- interface/src/ui/overlays/Overlays.h | 2 +- .../entities/src/EntityScriptingInterface.cpp | 20 +++++++++---------- .../entities/src/EntityScriptingInterface.h | 20 +++++++++---------- 6 files changed, 28 insertions(+), 28 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 808be5b08a..a825330c7c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4457,7 +4457,7 @@ QUuid Application::getKeyboardFocusEntity() const { static const float FOCUS_HIGHLIGHT_EXPANSION_FACTOR = 1.05f; -void Application::setKeyboardFocusEntity(EntityItemID entityItemID) { +void Application::setKeyboardFocusEntity(const EntityItemID& entityItemID) { if (_keyboardFocusedEntity.get() != entityItemID) { _keyboardFocusedEntity.set(entityItemID); @@ -4494,7 +4494,7 @@ OverlayID Application::getKeyboardFocusOverlay() { return _keyboardFocusedOverlay.get(); } -void Application::setKeyboardFocusOverlay(OverlayID overlayID) { +void Application::setKeyboardFocusOverlay(const OverlayID& overlayID) { if (overlayID != _keyboardFocusedOverlay.get()) { _keyboardFocusedOverlay.set(overlayID); diff --git a/interface/src/Application.h b/interface/src/Application.h index 85700de505..a3176ff1e3 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -376,10 +376,10 @@ public slots: void setKeyboardFocusHighlight(const glm::vec3& position, const glm::quat& rotation, const glm::vec3& dimensions); QUuid getKeyboardFocusEntity() const; // thread-safe - Q_INVOKABLE void setKeyboardFocusEntity(EntityItemID entityItemID); + Q_INVOKABLE void setKeyboardFocusEntity(const EntityItemID& entityItemID); OverlayID getKeyboardFocusOverlay(); - void setKeyboardFocusOverlay(OverlayID overlayID); + void setKeyboardFocusOverlay(const OverlayID& overlayID); void addAssetToWorldMessageClose(); diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 1ba5c38c8e..af47b3a2ae 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -746,7 +746,7 @@ OverlayID Overlays::getKeyboardFocusOverlay() { return qApp->getKeyboardFocusOverlay(); } -void Overlays::setKeyboardFocusOverlay(OverlayID id) { +void Overlays::setKeyboardFocusOverlay(const OverlayID& id) { qApp->setKeyboardFocusOverlay(id); } @@ -885,7 +885,7 @@ bool Overlays::mousePressEvent(QMouseEvent* event) { return true; } // if we didn't press on an overlay, disable overlay keyboard focus - qApp->setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); + setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); // emit to scripts emit mousePressOffOverlay(); return false; @@ -901,7 +901,7 @@ void Overlays::mousePressEvent(const OverlayID& overlayID, const PointerEvent& e if (thisOverlay) { // Focus keyboard on web overlays qApp->setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); - qApp->setKeyboardFocusOverlay(overlayID); + setKeyboardFocusOverlay(overlayID); // Send to web overlay QMetaObject::invokeMethod(thisOverlay.get(), "handlePointerEvent", Q_ARG(PointerEvent, event)); diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index cfc670a78c..23c2bf9398 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -309,7 +309,7 @@ public slots: void sendHoverLeaveOverlay(const OverlayID& overlayID, const PointerEvent& event); OverlayID getKeyboardFocusOverlay(); - void setKeyboardFocusOverlay(OverlayID id); + void setKeyboardFocusOverlay(const OverlayID& id); signals: /**jsdoc diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index f43b1beb54..08b0a2c306 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -1623,43 +1623,43 @@ QUuid EntityScriptingInterface::getKeyboardFocusEntity() const { return result; } -void EntityScriptingInterface::setKeyboardFocusEntity(QUuid id) { +void EntityScriptingInterface::setKeyboardFocusEntity(const EntityItemID& id) { QMetaObject::invokeMethod(qApp, "setKeyboardFocusEntity", Qt::DirectConnection, Q_ARG(EntityItemID, id)); } -void EntityScriptingInterface::sendMousePressOnEntity(EntityItemID id, PointerEvent event) { +void EntityScriptingInterface::sendMousePressOnEntity(const EntityItemID& id, const PointerEvent& event) { emit mousePressOnEntity(id, event); } -void EntityScriptingInterface::sendMouseMoveOnEntity(EntityItemID id, PointerEvent event) { +void EntityScriptingInterface::sendMouseMoveOnEntity(const EntityItemID& id, const PointerEvent& event) { emit mouseMoveOnEntity(id, event); } -void EntityScriptingInterface::sendMouseReleaseOnEntity(EntityItemID id, PointerEvent event) { +void EntityScriptingInterface::sendMouseReleaseOnEntity(const EntityItemID& id, const PointerEvent& event) { emit mouseReleaseOnEntity(id, event); } -void EntityScriptingInterface::sendClickDownOnEntity(EntityItemID id, PointerEvent event) { +void EntityScriptingInterface::sendClickDownOnEntity(const EntityItemID& id, const PointerEvent& event) { emit clickDownOnEntity(id, event); } -void EntityScriptingInterface::sendHoldingClickOnEntity(EntityItemID id, PointerEvent event) { +void EntityScriptingInterface::sendHoldingClickOnEntity(const EntityItemID& id, const PointerEvent& event) { emit holdingClickOnEntity(id, event); } -void EntityScriptingInterface::sendClickReleaseOnEntity(EntityItemID id, PointerEvent event) { +void EntityScriptingInterface::sendClickReleaseOnEntity(const EntityItemID& id, const PointerEvent& event) { emit clickReleaseOnEntity(id, event); } -void EntityScriptingInterface::sendHoverEnterEntity(EntityItemID id, PointerEvent event) { +void EntityScriptingInterface::sendHoverEnterEntity(const EntityItemID& id, const PointerEvent& event) { emit hoverEnterEntity(id, event); } -void EntityScriptingInterface::sendHoverOverEntity(EntityItemID id, PointerEvent event) { +void EntityScriptingInterface::sendHoverOverEntity(const EntityItemID& id, const PointerEvent& event) { emit hoverOverEntity(id, event); } -void EntityScriptingInterface::sendHoverLeaveEntity(EntityItemID id, PointerEvent event) { +void EntityScriptingInterface::sendHoverLeaveEntity(const EntityItemID& id, const PointerEvent& event) { emit hoverLeaveEntity(id, event); } diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index 97af06ee83..1692dfdc85 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -343,19 +343,19 @@ public slots: Q_INVOKABLE QString getNestableType(QUuid id); Q_INVOKABLE QUuid getKeyboardFocusEntity() const; - Q_INVOKABLE void setKeyboardFocusEntity(QUuid id); + Q_INVOKABLE void setKeyboardFocusEntity(const EntityItemID& id); - Q_INVOKABLE void sendMousePressOnEntity(EntityItemID id, PointerEvent event); - Q_INVOKABLE void sendMouseMoveOnEntity(EntityItemID id, PointerEvent event); - Q_INVOKABLE void sendMouseReleaseOnEntity(EntityItemID id, PointerEvent event); + Q_INVOKABLE void sendMousePressOnEntity(const EntityItemID& id, const PointerEvent& event); + Q_INVOKABLE void sendMouseMoveOnEntity(const EntityItemID& id, const PointerEvent& event); + Q_INVOKABLE void sendMouseReleaseOnEntity(const EntityItemID& id, const PointerEvent& event); - Q_INVOKABLE void sendClickDownOnEntity(EntityItemID id, PointerEvent event); - Q_INVOKABLE void sendHoldingClickOnEntity(EntityItemID id, PointerEvent event); - Q_INVOKABLE void sendClickReleaseOnEntity(EntityItemID id, PointerEvent event); + Q_INVOKABLE void sendClickDownOnEntity(const EntityItemID& id, const PointerEvent& event); + Q_INVOKABLE void sendHoldingClickOnEntity(const EntityItemID& id, const PointerEvent& event); + Q_INVOKABLE void sendClickReleaseOnEntity(const EntityItemID& id, const PointerEvent& event); - Q_INVOKABLE void sendHoverEnterEntity(EntityItemID id, PointerEvent event); - Q_INVOKABLE void sendHoverOverEntity(EntityItemID id, PointerEvent event); - Q_INVOKABLE void sendHoverLeaveEntity(EntityItemID id, PointerEvent event); + Q_INVOKABLE void sendHoverEnterEntity(const EntityItemID& id, const PointerEvent& event); + Q_INVOKABLE void sendHoverOverEntity(const EntityItemID& id, const PointerEvent& event); + Q_INVOKABLE void sendHoverLeaveEntity(const EntityItemID& id, const PointerEvent& event); Q_INVOKABLE bool wantsHandControllerPointerEvents(QUuid id); From c4e6cb28cef537e81a75226027c2b0abe33001cd Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 13 Oct 2017 16:23:29 -0700 Subject: [PATCH 09/11] move contextoverlay connection to contextoverlayinterface --- interface/src/Application.cpp | 4 +++- .../ui/overlays/ContextOverlayInterface.cpp | 4 ++++ interface/src/ui/overlays/Overlays.cpp | 23 ++----------------- interface/src/ui/overlays/Overlays.h | 3 --- 4 files changed, 9 insertions(+), 25 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a825330c7c..4331740fd6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -682,7 +682,6 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); - DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); @@ -1173,7 +1172,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo // allow you to move an entity around in your hand _entityEditSender.setPacketsPerSecond(3000); // super high!! + // Overlays need to exist before we set the ContextOverlayInterface dependency _overlays.init(); // do this before scripts load + DependencyManager::set(); + // Make sure we don't time out during slow operations at startup updateHeartbeat(); diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 0481564fae..657aa3cb2c 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -61,6 +61,10 @@ ContextOverlayInterface::ContextOverlayInterface() { }); connect(entityScriptingInterface, &EntityScriptingInterface::deletingEntity, this, &ContextOverlayInterface::deletingEntity); + connect(&qApp->getOverlays(), &Overlays::mousePressOnOverlay, this, &ContextOverlayInterface::contextOverlays_mousePressOnOverlay); + connect(&qApp->getOverlays(), &Overlays::hoverEnterOverlay, this, &ContextOverlayInterface::contextOverlays_hoverEnterOverlay); + connect(&qApp->getOverlays(), &Overlays::hoverLeaveOverlay, this, &ContextOverlayInterface::contextOverlays_hoverLeaveOverlay); + connect(_selectionScriptingInterface.data(), &SelectionScriptingInterface::selectedItemsListChanged, &_selectionToSceneHandler, &SelectionToSceneHandler::selectedItemsListChanged); } diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index af47b3a2ae..d315d8ec7b 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -37,8 +37,6 @@ #include "Web3DOverlay.h" #include -#include "ui/overlays/ContextOverlayInterface.h" - Q_LOGGING_CATEGORY(trace_render_overlays, "trace.render.overlays") extern void initOverlay3DPipelines(render::ShapePlumber& plumber, bool depthTest = false); @@ -731,7 +729,7 @@ void Overlays::sendMouseMoveOnOverlay(const OverlayID& overlayID, const PointerE } void Overlays::sendHoverEnterOverlay(const OverlayID& overlayID, const PointerEvent& event) { - hoverEnterEvent(overlayID, event); + emit hoverEnterOverlay(overlayID, event); } void Overlays::sendHoverOverOverlay(const OverlayID& overlayID, const PointerEvent& event) { @@ -892,10 +890,6 @@ bool Overlays::mousePressEvent(QMouseEvent* event) { } void Overlays::mousePressEvent(const OverlayID& overlayID, const PointerEvent& event) { - // Send press to context overlay - // contextOverlays_mousePressOnOverlay is not threadsafe and mousePressEvent can be called from scripts, so use an auto connection - QMetaObject::invokeMethod(DependencyManager::get().data(), "contextOverlays_mousePressOnOverlay", Q_ARG(OverlayID, overlayID), Q_ARG(PointerEvent, event)); - // TODO: generalize this to allow any overlay to recieve events auto thisOverlay = std::dynamic_pointer_cast(getOverlay(overlayID)); if (thisOverlay) { @@ -929,20 +923,7 @@ bool Overlays::mouseDoublePressEvent(QMouseEvent* event) { return false; } -void Overlays::hoverEnterEvent(const OverlayID& overlayID, const PointerEvent& event) { - // Send hoverEnter to context overlay - // contextOverlays_hoverEnterOverlay is not threadsafe and hoverEnterEvent can be called from scripts, so use an auto connection - QMetaObject::invokeMethod(DependencyManager::get().data(), "contextOverlays_hoverEnterOverlay", Q_ARG(OverlayID, overlayID), Q_ARG(PointerEvent, event)); - - // emit to scripts - emit hoverEnterOverlay(overlayID, event); -} - void Overlays::hoverLeaveEvent(const OverlayID& overlayID, const PointerEvent& event) { - // Send hoverLeave to context overlay - // contextOverlays_hoverLeaveOverlay is not threadsafe and hoverLeaveEvent can be called from scripts, so use an auto connection - QMetaObject::invokeMethod(DependencyManager::get().data(), "contextOverlays_hoverLeaveOverlay", Q_ARG(OverlayID, overlayID), Q_ARG(PointerEvent, event)); - // TODO: generalize this to allow any overlay to recieve events auto thisOverlay = std::dynamic_pointer_cast(getOverlay(overlayID)); if (thisOverlay) { @@ -997,7 +978,7 @@ bool Overlays::mouseMoveEvent(QMouseEvent* event) { // If hovering over a new overlay then enter hover on that overlay. if (rayPickResult.overlayID != _currentHoverOverOverlayID) { - hoverEnterEvent(rayPickResult.overlayID, pointerEvent); + emit hoverEnterOverlay(rayPickResult.overlayID, pointerEvent); } // Hover over current overlay. diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 23c2bf9398..988b288741 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -110,7 +110,6 @@ public: void mousePressEvent(const OverlayID& overlayID, const PointerEvent& event); void mouseMoveEvent(const OverlayID& overlayID, const PointerEvent& event); void mouseReleaseEvent(const OverlayID& overlayID, const PointerEvent& event); - void hoverEnterEvent(const OverlayID& overlayID, const PointerEvent& event); void hoverLeaveEvent(const OverlayID& overlayID, const PointerEvent& event); void cleanupAllOverlays(); @@ -321,8 +320,6 @@ signals: void overlayDeleted(OverlayID id); void panelDeleted(OverlayID id); - // Nothing should need to connect to these signals in C++ - // They are only for scripts to connect to void mousePressOnOverlay(OverlayID overlayID, const PointerEvent& event); void mouseDoublePressOnOverlay(OverlayID overlayID, const PointerEvent& event); void mouseReleaseOnOverlay(OverlayID overlayID, const PointerEvent& event); From c6b636901a0dd0dc66f6054d99474eebfd17221a Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 16 Oct 2017 13:46:23 -0700 Subject: [PATCH 10/11] fewer undesirable couplings --- interface/src/ui/overlays/Overlays.cpp | 2 +- libraries/entities-renderer/src/EntityTreeRenderer.cpp | 2 -- libraries/entities/src/EntityScriptingInterface.cpp | 5 +++++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index e17ac3cfc8..97fc908568 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -894,7 +894,7 @@ void Overlays::mousePressEvent(const OverlayID& overlayID, const PointerEvent& e auto thisOverlay = std::dynamic_pointer_cast(getOverlay(overlayID)); if (thisOverlay) { // Focus keyboard on web overlays - qApp->setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); + DependencyManager::get()->setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); setKeyboardFocusOverlay(overlayID); // Send to web overlay diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 0f1381c8d0..89491a3910 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -567,8 +567,6 @@ void EntityTreeRenderer::mousePressEvent(QMouseEvent* event) { _lastPointerEventValid = true; } else { - // If the user clicks somewhere where there is NO entity at all, we will release focus - QMetaObject::invokeMethod(qApp, "setKeyboardFocusEntity", Qt::DirectConnection, Q_ARG(EntityItemID, UNKNOWN_ENTITY_ID)); emit entityScriptingInterface->mousePressOffEntity(); } } diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 08b0a2c306..8aa5c52b06 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -50,6 +50,11 @@ EntityScriptingInterface::EntityScriptingInterface(bool bidOnSimulationOwnership connect(nodeList.data(), &NodeList::canRezCertifiedChanged, this, &EntityScriptingInterface::canRezCertifiedChanged); connect(nodeList.data(), &NodeList::canRezTmpCertifiedChanged, this, &EntityScriptingInterface::canRezTmpCertifiedChanged); connect(nodeList.data(), &NodeList::canWriteAssetsChanged, this, &EntityScriptingInterface::canWriteAssetsChanged); + + // If the user clicks somewhere where there is no entity at all, we will release focus + connect(this, &EntityScriptingInterface::mousePressOffEntity, [=]() { + setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); + }); } void EntityScriptingInterface::queueEntityMessage(PacketType packetType, From 9bbb2eb69279a4b1c7d870fe4c026c0ca553b585 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 19 Oct 2017 14:50:00 -0700 Subject: [PATCH 11/11] austin's comments, send events directly to selected web entity --- interface/src/Application.h | 2 +- interface/src/ui/overlays/Overlays.cpp | 20 ++++-- .../src/EntityTreeRenderer.cpp | 37 ++++++++-- .../src/RenderableWebEntityItem.cpp | 71 ++++++++----------- .../src/RenderableWebEntityItem.h | 8 ++- 5 files changed, 83 insertions(+), 55 deletions(-) diff --git a/interface/src/Application.h b/interface/src/Application.h index a3176ff1e3..0aeecadde0 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -376,7 +376,7 @@ public slots: void setKeyboardFocusHighlight(const glm::vec3& position, const glm::quat& rotation, const glm::vec3& dimensions); QUuid getKeyboardFocusEntity() const; // thread-safe - Q_INVOKABLE void setKeyboardFocusEntity(const EntityItemID& entityItemID); + void setKeyboardFocusEntity(const EntityItemID& entityItemID); OverlayID getKeyboardFocusOverlay(); void setKeyboardFocusOverlay(const OverlayID& overlayID); diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 97fc908568..fd5aae4027 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -891,7 +891,10 @@ bool Overlays::mousePressEvent(QMouseEvent* event) { void Overlays::mousePressEvent(const OverlayID& overlayID, const PointerEvent& event) { // TODO: generalize this to allow any overlay to recieve events - auto thisOverlay = std::dynamic_pointer_cast(getOverlay(overlayID)); + std::shared_ptr thisOverlay; + if (getOverlayType(overlayID) == "web3d") { + thisOverlay = std::static_pointer_cast(getOverlay(overlayID)); + } if (thisOverlay) { // Focus keyboard on web overlays DependencyManager::get()->setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); @@ -925,7 +928,10 @@ bool Overlays::mouseDoublePressEvent(QMouseEvent* event) { void Overlays::hoverLeaveEvent(const OverlayID& overlayID, const PointerEvent& event) { // TODO: generalize this to allow any overlay to recieve events - auto thisOverlay = std::dynamic_pointer_cast(getOverlay(overlayID)); + std::shared_ptr thisOverlay; + if (getOverlayType(overlayID) == "web3d") { + thisOverlay = std::static_pointer_cast(getOverlay(overlayID)); + } if (thisOverlay) { // Send to web overlay QMetaObject::invokeMethod(thisOverlay.get(), "hoverLeaveOverlay", Q_ARG(PointerEvent, event)); @@ -951,7 +957,10 @@ bool Overlays::mouseReleaseEvent(QMouseEvent* event) { void Overlays::mouseReleaseEvent(const OverlayID& overlayID, const PointerEvent& event) { // TODO: generalize this to allow any overlay to recieve events - auto thisOverlay = std::dynamic_pointer_cast(getOverlay(overlayID)); + std::shared_ptr thisOverlay; + if (getOverlayType(overlayID) == "web3d") { + thisOverlay = std::static_pointer_cast(getOverlay(overlayID)); + } if (thisOverlay) { // Send to web overlay QMetaObject::invokeMethod(thisOverlay.get(), "handlePointerEvent", Q_ARG(PointerEvent, event)); @@ -999,7 +1008,10 @@ bool Overlays::mouseMoveEvent(QMouseEvent* event) { void Overlays::mouseMoveEvent(const OverlayID& overlayID, const PointerEvent& event) { // TODO: generalize this to allow any overlay to recieve events - auto thisOverlay = std::dynamic_pointer_cast(getOverlay(overlayID)); + std::shared_ptr thisOverlay; + if (getOverlayType(overlayID) == "web3d") { + thisOverlay = std::static_pointer_cast(getOverlay(overlayID)); + } if (thisOverlay) { // Send to web overlay QMetaObject::invokeMethod(thisOverlay.get(), "handlePointerEvent", Q_ARG(PointerEvent, event)); diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 89491a3910..57057297d6 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -35,6 +35,8 @@ #include "EntitiesRendererLogging.h" #include "RenderableEntityItem.h" +#include "RenderableWebEntityItem.h" + size_t std::hash::operator()(const EntityItemID& id) const { return qHash(id); } std::function EntityTreeRenderer::_entitiesShouldFadeFunction; @@ -55,6 +57,32 @@ EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterf EntityRenderer::initEntityRenderers(); _currentHoverOverEntityID = UNKNOWN_ENTITY_ID; _currentClickingOnEntityID = UNKNOWN_ENTITY_ID; + + // Forward mouse events to web entities + auto handlePointerEvent = [&](const EntityItemID& entityID, const PointerEvent& event) { + std::shared_ptr thisEntity; + auto entity = getEntity(entityID); + if (entity && entity->getType() == EntityTypes::Web) { + thisEntity = std::static_pointer_cast(renderableForEntityId(entityID)); + } + if (thisEntity) { + QMetaObject::invokeMethod(thisEntity.get(), "handlePointerEvent", Q_ARG(PointerEvent, event)); + } + }; + auto entityScriptingInterface = DependencyManager::get(); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, this, handlePointerEvent); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity, this, handlePointerEvent); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity, this, handlePointerEvent); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, this, [&](const EntityItemID& entityID, const PointerEvent& event) { + std::shared_ptr thisEntity; + auto entity = getEntity(entityID); + if (entity && entity->getType() == EntityTypes::Web) { + thisEntity = std::static_pointer_cast(renderableForEntityId(entityID)); + } + if (thisEntity) { + QMetaObject::invokeMethod(thisEntity.get(), "hoverLeaveEntity", Q_ARG(PointerEvent, event)); + } + }); } EntityTreeRenderer::~EntityTreeRenderer() { @@ -78,7 +106,6 @@ render::ItemID EntityTreeRenderer::renderableIdForEntityId(const EntityItemID& i int EntityTreeRenderer::_entitiesScriptEngineCount = 0; void EntityTreeRenderer::resetEntitiesScriptEngine() { - auto oldEngine = _entitiesScriptEngine; _entitiesScriptEngine = scriptEngineFactory(ScriptEngine::ENTITY_CLIENT_SCRIPT, NO_SCRIPT, QString("about:Entities %1").arg(++_entitiesScriptEngineCount)); _scriptingServices->registerScriptEngineWithApplicationServices(_entitiesScriptEngine); @@ -543,7 +570,7 @@ void EntityTreeRenderer::mousePressEvent(QMouseEvent* event) { auto entityScriptingInterface = DependencyManager::get(); PickRay ray = _viewState->computePickRay(event->x(), event->y()); RayToEntityIntersectionResult rayPickResult = _getPrevRayPickResultOperator(_mouseRayPickID); - if (rayPickResult.intersects) { + if (rayPickResult.intersects && rayPickResult.entity) { auto properties = rayPickResult.entity->getProperties(); QString urlString = properties.getHref(); QUrl url = QUrl(urlString, QUrl::StrictMode); @@ -582,7 +609,7 @@ void EntityTreeRenderer::mouseDoublePressEvent(QMouseEvent* event) { auto entityScriptingInterface = DependencyManager::get(); PickRay ray = _viewState->computePickRay(event->x(), event->y()); RayToEntityIntersectionResult rayPickResult = _getPrevRayPickResultOperator(_mouseRayPickID); - if (rayPickResult.intersects) { + if (rayPickResult.intersects && rayPickResult.entity) { glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult); PointerEvent pointerEvent(PointerEvent::Press, MOUSE_POINTER_ID, pos2D, rayPickResult.intersection, @@ -612,7 +639,7 @@ void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event) { auto entityScriptingInterface = DependencyManager::get(); PickRay ray = _viewState->computePickRay(event->x(), event->y()); RayToEntityIntersectionResult rayPickResult = _getPrevRayPickResultOperator(_mouseRayPickID); - if (rayPickResult.intersects) { + if (rayPickResult.intersects && rayPickResult.entity) { //qCDebug(entitiesrenderer) << "mouseReleaseEvent over entity:" << rayPickResult.entityID; glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult); @@ -656,7 +683,7 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) { auto entityScriptingInterface = DependencyManager::get(); PickRay ray = _viewState->computePickRay(event->x(), event->y()); RayToEntityIntersectionResult rayPickResult = _getPrevRayPickResultOperator(_mouseRayPickID); - if (rayPickResult.intersects) { + if (rayPickResult.intersects && rayPickResult.entity) { glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult); PointerEvent pointerEvent(PointerEvent::Move, MOUSE_POINTER_ID, pos2D, rayPickResult.intersection, diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index 1e83783828..6d9f948ae1 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -85,6 +85,10 @@ bool WebEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointe return true; } + if (_lastLocked != entity->getLocked()) { + return true; + } + return false; } @@ -135,6 +139,7 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene } _lastDPI = entity->getDPI(); + _lastLocked = entity->getLocked(); glm::vec2 windowSize = getWindowSize(entity); _webSurface->resize(QSize(windowSize.x, windowSize.y)); @@ -233,38 +238,6 @@ bool WebEntityRenderer::buildWebSurface(const TypedEntityPointer& entity) { emit entities->webEventReceived(entityItemID, message); }); - auto forwardPointerEvent = [=](const EntityItemID& entityItemID, const PointerEvent& event) { - if (entityItemID == entity->getID()) { - handlePointerEvent(entity, event); - } - }; - - auto entityScriptingInterface = DependencyManager::get(); - QObject::connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, this, forwardPointerEvent); - QObject::connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity, this, forwardPointerEvent); - QObject::connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity, this, forwardPointerEvent); - QObject::connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, this, - [=](const EntityItemID& entityItemID, const PointerEvent& event) { - if (this->_pressed && entity->getID() == entityItemID) { - // If the user mouses off the entity while the button is down, simulate a touch end. - QTouchEvent::TouchPoint point; - point.setId(event.getID()); - point.setState(Qt::TouchPointReleased); - glm::vec2 windowPos = event.getPos2D() * (METERS_TO_INCHES * _lastDPI); - QPointF windowPoint(windowPos.x, windowPos.y); - point.setScenePos(windowPoint); - point.setPos(windowPoint); - QList touchPoints; - touchPoints.push_back(point); - QTouchEvent* touchEvent = new QTouchEvent(QEvent::TouchEnd, nullptr, - Qt::NoModifier, Qt::TouchPointReleased, touchPoints); - touchEvent->setWindow(_webSurface->getWindow()); - touchEvent->setDevice(&_touchDevice); - touchEvent->setTarget(_webSurface->getRootItem()); - QCoreApplication::postEvent(_webSurface->getWindow(), touchEvent); - } - }); - return true; } @@ -294,13 +267,6 @@ void WebEntityRenderer::destroyWebSurface() { } webSurface->pause(); - auto entityScriptingInterface = DependencyManager::get(); - if (entityScriptingInterface) { - QObject::disconnect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, this, nullptr); - QObject::disconnect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity, this, nullptr); - QObject::disconnect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity, this, nullptr); - QObject::disconnect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, this, nullptr); - } webSurface.reset(); } } @@ -346,13 +312,34 @@ void WebEntityRenderer::loadSourceURL() { } } -void WebEntityRenderer::handlePointerEvent(const TypedEntityPointer& entity, const PointerEvent& event) { +void WebEntityRenderer::hoverLeaveEntity(const PointerEvent& event) { + if (!_lastLocked && _webSurface && _pressed) { + // If the user mouses off the entity while the button is down, simulate a touch end. + QTouchEvent::TouchPoint point; + point.setId(event.getID()); + point.setState(Qt::TouchPointReleased); + glm::vec2 windowPos = event.getPos2D() * (METERS_TO_INCHES * _lastDPI); + QPointF windowPoint(windowPos.x, windowPos.y); + point.setScenePos(windowPoint); + point.setPos(windowPoint); + QList touchPoints; + touchPoints.push_back(point); + QTouchEvent* touchEvent = new QTouchEvent(QEvent::TouchEnd, nullptr, + Qt::NoModifier, Qt::TouchPointReleased, touchPoints); + touchEvent->setWindow(_webSurface->getWindow()); + touchEvent->setDevice(&_touchDevice); + touchEvent->setTarget(_webSurface->getRootItem()); + QCoreApplication::postEvent(_webSurface->getWindow(), touchEvent); + } +} + +void WebEntityRenderer::handlePointerEvent(const PointerEvent& event) { // Ignore mouse interaction if we're locked - if (entity->getLocked() || !_webSurface) { + if (_lastLocked || !_webSurface) { return; } - glm::vec2 windowPos = event.getPos2D() * (METERS_TO_INCHES * entity->getDPI()); + glm::vec2 windowPos = event.getPos2D() * (METERS_TO_INCHES * _lastDPI); QPointF windowPoint(windowPos.x, windowPos.y); if (event.getType() == PointerEvent::Move) { // Forward a mouse move event to webSurface diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.h b/libraries/entities-renderer/src/RenderableWebEntityItem.h index 4b7e7e25a1..896d0c7c54 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.h +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.h @@ -18,12 +18,16 @@ class PointerEvent; namespace render { namespace entities { class WebEntityRenderer : public TypedEntityRenderer { + Q_OBJECT using Parent = TypedEntityRenderer; friend class EntityRenderer; public: WebEntityRenderer(const EntityItemPointer& entity); + Q_INVOKABLE void hoverLeaveEntity(const PointerEvent& event); + Q_INVOKABLE void handlePointerEvent(const PointerEvent& event); + protected: virtual void onRemoveFromSceneTyped(const TypedEntityPointer& entity) override; virtual bool needsRenderUpdate() const override; @@ -44,9 +48,6 @@ private: bool hasWebSurface(); void loadSourceURL(); glm::vec2 getWindowSize(const TypedEntityPointer& entity) const; - void handlePointerEvent(const TypedEntityPointer& entity, const PointerEvent& event); - -private: int _geometryId{ 0 }; enum contentType { @@ -60,6 +61,7 @@ private: bool _pressed{ false }; QString _lastSourceUrl; uint16_t _lastDPI; + bool _lastLocked; QTimer _timer; uint64_t _lastRenderTime { 0 }; };