From 1d7ff1ca1cd9f4991d0f8586ecf59e3b1bf4fdcd Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 13 Nov 2017 16:45:00 -0800 Subject: [PATCH] use mouse events for offscreenui because touch events aren't working with the eventFilter, cleanup --- .../src/raypick/PickScriptingInterface.cpp | 7 +++++- .../src/raypick/PointerScriptingInterface.h | 4 ++-- interface/src/raypick/RayPick.cpp | 6 ++--- interface/src/raypick/StylusPick.cpp | 7 +++--- interface/src/raypick/StylusPick.h | 11 ++++----- interface/src/ui/overlays/Web3DOverlay.cpp | 8 +++++-- .../src/RenderableWebEntityItem.cpp | 8 +++++-- libraries/pointers/src/pointers/Pointer.cpp | 16 +++++++++---- libraries/ui/src/OffscreenUi.cpp | 11 +++++---- libraries/ui/src/ui/OffscreenQmlSurface.cpp | 23 ++++++++++++++----- 10 files changed, 66 insertions(+), 35 deletions(-) diff --git a/interface/src/raypick/PickScriptingInterface.cpp b/interface/src/raypick/PickScriptingInterface.cpp index dad4cde3b7..2ec4d3d33e 100644 --- a/interface/src/raypick/PickScriptingInterface.cpp +++ b/interface/src/raypick/PickScriptingInterface.cpp @@ -105,7 +105,12 @@ unsigned int PickScriptingInterface::createStylusPick(const QVariant& properties filter = PickFilter(propMap["filter"].toUInt()); } - return DependencyManager::get()->addPick(PickQuery::Stylus, std::make_shared(filter, side, enabled)); + float maxDistance = 0.0f; + if (propMap["maxDistance"].isValid()) { + maxDistance = propMap["maxDistance"].toFloat(); + } + + return DependencyManager::get()->addPick(PickQuery::Stylus, std::make_shared(side, filter, maxDistance, enabled)); } void PickScriptingInterface::enablePick(unsigned int uid) { diff --git a/interface/src/raypick/PointerScriptingInterface.h b/interface/src/raypick/PointerScriptingInterface.h index 25b2c4b4b1..9d157f2a32 100644 --- a/interface/src/raypick/PointerScriptingInterface.h +++ b/interface/src/raypick/PointerScriptingInterface.h @@ -31,11 +31,11 @@ public: Q_INVOKABLE QVariantMap getPrevPickResult(unsigned int uid) const; Q_INVOKABLE void setPrecisionPicking(unsigned int uid, bool precisionPicking) const { DependencyManager::get()->setPrecisionPicking(uid, precisionPicking); } - Q_INVOKABLE void setLaserLength(unsigned int uid, float laserLength) const { DependencyManager::get()->setLength(uid, laserLength); } + Q_INVOKABLE void setLength(unsigned int uid, float length) const { DependencyManager::get()->setLength(uid, length); } Q_INVOKABLE void setIgnoreItems(unsigned int uid, const QScriptValue& ignoreEntities) const; Q_INVOKABLE void setIncludeItems(unsigned int uid, const QScriptValue& includeEntities) const; - Q_INVOKABLE void setLockEndUUID(unsigned int uid, const QUuid& objectID, bool isOverlay) const { DependencyManager::get()->setLockEndUUID(uid, objectID, isOverlay); } + Q_INVOKABLE void setLockEndUUID(unsigned int uid, const QUuid& objectID, bool isOverlay, const glm::mat4& offsetMat = glm::mat4()) const { DependencyManager::get()->setLockEndUUID(uid, objectID, isOverlay, offsetMat); } Q_INVOKABLE bool isLeftHand(unsigned int uid) { return DependencyManager::get()->isLeftHand(uid); } Q_INVOKABLE bool isRightHand(unsigned int uid) { return DependencyManager::get()->isRightHand(uid); } diff --git a/interface/src/raypick/RayPick.cpp b/interface/src/raypick/RayPick.cpp index 7689b295db..2f6e69bc7e 100644 --- a/interface/src/raypick/RayPick.cpp +++ b/interface/src/raypick/RayPick.cpp @@ -60,8 +60,7 @@ glm::vec3 RayPick::intersectRayWithXYPlane(const glm::vec3& origin, const glm::v glm::vec3 RayPick::intersectRayWithOverlayXYPlane(const QUuid& overlayID, const glm::vec3& origin, const glm::vec3& direction) { glm::vec3 position = vec3FromVariant(qApp->getOverlays().getProperty(overlayID, "position").value); glm::quat rotation = quatFromVariant(qApp->getOverlays().getProperty(overlayID, "rotation").value); - const glm::vec3 DEFAULT_REGISTRATION_POINT = glm::vec3(0.5f); - return intersectRayWithXYPlane(origin, direction, position, rotation, DEFAULT_REGISTRATION_POINT); + return intersectRayWithXYPlane(origin, direction, position, rotation, ENTITY_ITEM_DEFAULT_REGISTRATION_POINT); } glm::vec3 RayPick::intersectRayWithEntityXYPlane(const QUuid& entityID, const glm::vec3& origin, const glm::vec3& direction) { @@ -98,8 +97,7 @@ glm::vec2 RayPick::projectOntoOverlayXYPlane(const QUuid& overlayID, const glm:: dimensions = glm::vec3(vec2FromVariant(qApp->getOverlays().getProperty(overlayID, "dimensions").value), 0.01); } - const glm::vec3 DEFAULT_REGISTRATION_POINT = glm::vec3(0.5f); - return projectOntoXYPlane(worldPos, position, rotation, dimensions, DEFAULT_REGISTRATION_POINT, unNormalized); + return projectOntoXYPlane(worldPos, position, rotation, dimensions, ENTITY_ITEM_DEFAULT_REGISTRATION_POINT, unNormalized); } glm::vec2 RayPick::projectOntoEntityXYPlane(const QUuid& entityID, const glm::vec3& worldPos, bool unNormalized) { diff --git a/interface/src/raypick/StylusPick.cpp b/interface/src/raypick/StylusPick.cpp index f2b650b5bf..81e775432b 100644 --- a/interface/src/raypick/StylusPick.cpp +++ b/interface/src/raypick/StylusPick.cpp @@ -26,7 +26,7 @@ using namespace bilateral; static Setting::Handle USE_FINGER_AS_STYLUS("preferAvatarFingerOverStylus", false); static const float WEB_STYLUS_LENGTH = 0.2f; static const float WEB_TOUCH_Y_OFFSET = 0.105f; // how far forward (or back with a negative number) to slide stylus in hand -static const glm::vec3 TIP_OFFSET{ 0.0f, WEB_STYLUS_LENGTH - WEB_TOUCH_Y_OFFSET, 0.0f }; +static const glm::vec3 TIP_OFFSET = glm::vec3(0.0f, WEB_STYLUS_LENGTH - WEB_TOUCH_Y_OFFSET, 0.0f); struct SideData { QString avatarJoint; @@ -65,8 +65,8 @@ bool StylusPickResult::checkOrFilterAgainstMaxDistance(float maxDistance) { return distance < maxDistance; } -StylusPick::StylusPick(const PickFilter& filter, Side side, bool enabled) : - Pick(filter, 0.0f, enabled), +StylusPick::StylusPick(Side side, const PickFilter& filter, float maxDistance, bool enabled) : + Pick(filter, maxDistance, enabled), _side(side) { } @@ -150,7 +150,6 @@ PickResultPointer StylusPick::getEntityIntersection(const StylusTip& pick) { } auto entity = qApp->getEntities()->getTree()->findEntityByEntityItemID(target); - // Don't interact with non-3D or invalid overlays if (!entity) { continue; } diff --git a/interface/src/raypick/StylusPick.h b/interface/src/raypick/StylusPick.h index 9b465b9cc8..949d9d24c6 100644 --- a/interface/src/raypick/StylusPick.h +++ b/interface/src/raypick/StylusPick.h @@ -58,7 +58,7 @@ public: class StylusPick : public Pick { using Side = bilateral::Side; public: - StylusPick(const PickFilter& filter, Side side, bool enabled); + StylusPick(Side side, const PickFilter& filter, float maxDistance, bool enabled); StylusTip getMathematicalPick() const override; PickResultPointer getDefaultResult(const QVariantMap& pickVariant) const override; @@ -67,12 +67,11 @@ public: PickResultPointer getAvatarIntersection(const StylusTip& pick) override; PickResultPointer getHUDIntersection(const StylusTip& pick) override; + bool isLeftHand() const override { return _side == Side::Left; } + bool isRightHand() const override { return _side == Side::Right; } + private: const Side _side; }; -#endif // hifi_StylusPick_h - - - - +#endif // hifi_StylusPick_h \ No newline at end of file diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index da579681a3..127327ef79 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -341,7 +341,9 @@ void Web3DOverlay::hoverEnterOverlay(const PointerEvent& event) { if (_inputMode == Mouse) { handlePointerEvent(event); } else if (_webSurface) { - _webSurface->hoverBeginEvent(event, _touchDevice); + PointerEvent webEvent = event; + webEvent.setPos2D(event.getPos2D() * (METERS_TO_INCHES * _dpi)); + _webSurface->hoverBeginEvent(webEvent, _touchDevice); } } @@ -354,7 +356,9 @@ void Web3DOverlay::hoverLeaveOverlay(const PointerEvent& event) { PointerEvent endMoveEvent(PointerEvent::Move, event.getID()); handlePointerEvent(endMoveEvent); } else if (_webSurface) { - _webSurface->hoverEndEvent(event, _touchDevice); + PointerEvent webEvent = event; + webEvent.setPos2D(event.getPos2D() * (METERS_TO_INCHES * _dpi)); + _webSurface->hoverEndEvent(webEvent, _touchDevice); } } diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index 95ab51628b..beca8a3d67 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -316,13 +316,17 @@ void WebEntityRenderer::loadSourceURL() { void WebEntityRenderer::hoverEnterEntity(const PointerEvent& event) { if (!_lastLocked && _webSurface) { - _webSurface->hoverBeginEvent(event, _touchDevice); + PointerEvent webEvent = event; + webEvent.setPos2D(event.getPos2D() * (METERS_TO_INCHES * _lastDPI)); + _webSurface->hoverBeginEvent(webEvent, _touchDevice); } } void WebEntityRenderer::hoverLeaveEntity(const PointerEvent& event) { if (!_lastLocked && _webSurface) { - _webSurface->hoverEndEvent(event, _touchDevice); + PointerEvent webEvent = event; + webEvent.setPos2D(event.getPos2D() * (METERS_TO_INCHES * _lastDPI)); + _webSurface->hoverEndEvent(webEvent, _touchDevice); } } diff --git a/libraries/pointers/src/pointers/Pointer.cpp b/libraries/pointers/src/pointers/Pointer.cpp index 4138ae5e4c..d2b8310af6 100644 --- a/libraries/pointers/src/pointers/Pointer.cpp +++ b/libraries/pointers/src/pointers/Pointer.cpp @@ -163,11 +163,8 @@ void Pointer::generatePointerEvents(unsigned int pointerID, const PickResultPoin } } } - } - if (_hover) { - // send hoverEnd events if we disable the pointer, disable hovering, or actually stop hovering over an object - if ((!_enabled && _prevEnabled) || (!doHover && _prevDoHover) || (hoveredObject.type == NONE && _prevHoveredObject.type != NONE)) { + if (hoveredObject.type == NONE) { if (_prevHoveredObject.type == ENTITY) { emit pointerManager->hoverEndEntity(_prevHoveredObject.objectID, hoveredEvent); } else if (_prevHoveredObject.type == OVERLAY) { @@ -178,6 +175,17 @@ void Pointer::generatePointerEvents(unsigned int pointerID, const PickResultPoin } } + // send hoverEnd events if we disable the pointer or disable hovering + if (_hover && (!_enabled && _prevEnabled) || (!doHover && _prevDoHover)) { + if (_prevHoveredObject.type == ENTITY) { + emit pointerManager->hoverEndEntity(_prevHoveredObject.objectID, hoveredEvent); + } else if (_prevHoveredObject.type == OVERLAY) { + emit pointerManager->hoverEndOverlay(_prevHoveredObject.objectID, hoveredEvent); + } else if (_prevHoveredObject.type == HUD) { + emit pointerManager->hoverEndHUD(hoveredEvent); + } + } + // Trigger begin const std::string SHOULD_FOCUS_BUTTON = "Focus"; for (const std::string& button : newButtons) { diff --git a/libraries/ui/src/OffscreenUi.cpp b/libraries/ui/src/OffscreenUi.cpp index 32a02774c0..38a5f6d4f3 100644 --- a/libraries/ui/src/OffscreenUi.cpp +++ b/libraries/ui/src/OffscreenUi.cpp @@ -1109,16 +1109,19 @@ bool OffscreenUi::eventFilter(QObject* originalDestination, QEvent* event) { case QEvent::MouseMove: { QMouseEvent* mouseEvent = static_cast(event); QPointF transformedPos = mapToVirtualScreen(mouseEvent->localPos()); - PointerEvent pointerEvent(choosePointerEventType(mouseEvent->type()), PointerManager::MOUSE_POINTER_ID, glm::vec2(transformedPos.x(), transformedPos.y()), - PointerEvent::Button(mouseEvent->button()), mouseEvent->buttons(), mouseEvent->modifiers()); - result = OffscreenQmlSurface::handlePointerEvent(pointerEvent, _touchDevice); + // FIXME: touch events are always being accepted. Use mouse events on the OffScreenUi for now, and investigate properly switching to touch events + // (using handlePointerEvent) later + QMouseEvent mappedEvent(mouseEvent->type(), transformedPos, mouseEvent->screenPos(), mouseEvent->button(), mouseEvent->buttons(), mouseEvent->modifiers()); + mappedEvent.ignore(); + if (QCoreApplication::sendEvent(getWindow(), &mappedEvent)) { + return mappedEvent.isAccepted(); + } break; } default: break; } - // Check if this is a key press/release event that might need special attention auto type = event->type(); if (type != QEvent::KeyPress && type != QEvent::KeyRelease) { diff --git a/libraries/ui/src/ui/OffscreenQmlSurface.cpp b/libraries/ui/src/ui/OffscreenQmlSurface.cpp index 4a187e4b61..b3203eb003 100644 --- a/libraries/ui/src/ui/OffscreenQmlSurface.cpp +++ b/libraries/ui/src/ui/OffscreenQmlSurface.cpp @@ -1031,6 +1031,7 @@ bool OffscreenQmlSurface::handlePointerEvent(const PointerEvent& event, class QT touchEvent.setTarget(_rootItem); touchEvent.setTouchPoints(touchPoints); touchEvent.setTouchPointStates(touchPointStates); + touchEvent.ignore(); } // Send mouse events to the surface so that HTML dialog elements work with mouse press and hover. @@ -1046,29 +1047,39 @@ bool OffscreenQmlSurface::handlePointerEvent(const PointerEvent& event, class QT buttons |= Qt::LeftButton; } - bool eventsAccepted = false; + bool eventSent = false; + bool eventsAccepted = true; if (event.getType() == PointerEvent::Move) { QMouseEvent mouseEvent(QEvent::MouseMove, windowPoint, windowPoint, windowPoint, button, buttons, event.getKeyboardModifiers()); // TODO - this line necessary for the QML Tooltop to work (which is not currently being used), but it causes interface to crash on launch on a fresh install // need to investigate into why this crash is happening. //_qmlContext->setContextProperty("lastMousePosition", windowPoint); - QCoreApplication::sendEvent(_quickWindow, &mouseEvent); - eventsAccepted &= mouseEvent.isAccepted(); + mouseEvent.ignore(); + if (QCoreApplication::sendEvent(_quickWindow, &mouseEvent)) { + eventSent = true; + eventsAccepted &= mouseEvent.isAccepted(); + } } if (touchType == QEvent::TouchBegin) { _touchBeginAccepted = QCoreApplication::sendEvent(_quickWindow, &touchEvent); + if (_touchBeginAccepted) { + eventSent = true; + eventsAccepted &= touchEvent.isAccepted(); + } } else if (_touchBeginAccepted) { - QCoreApplication::sendEvent(_quickWindow, &touchEvent); + if (QCoreApplication::sendEvent(_quickWindow, &touchEvent)) { + eventSent = true; + eventsAccepted &= touchEvent.isAccepted(); + } } - eventsAccepted &= touchEvent.isAccepted(); if (removeTouchPoint) { _activeTouchPoints.erase(event.getID()); } - return eventsAccepted; + return eventSent && eventsAccepted; } void OffscreenQmlSurface::pause() {