mirror of
https://github.com/overte-org/overte.git
synced 2025-08-04 08:03:34 +02:00
HUD events WIP, fix entity/overlay hover, no hover for empty renderState
This commit is contained in:
parent
76eb4c656e
commit
3c779f1528
16 changed files with 138 additions and 20 deletions
|
@ -1811,6 +1811,12 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
||||||
connect(&_myCamera, &Camera::modeUpdated, this, &Application::cameraModeChanged);
|
connect(&_myCamera, &Camera::modeUpdated, this, &Application::cameraModeChanged);
|
||||||
|
|
||||||
DependencyManager::get<PickManager>()->setShouldPickHUDOperator([&]() { return DependencyManager::get<HMDScriptingInterface>()->isHMDMode(); });
|
DependencyManager::get<PickManager>()->setShouldPickHUDOperator([&]() { return DependencyManager::get<HMDScriptingInterface>()->isHMDMode(); });
|
||||||
|
DependencyManager::get<PickManager>()->setCalculatePos2DFromHUDOperator([&](const glm::vec3& intersection) {
|
||||||
|
const glm::vec2 MARGIN(25.0f);
|
||||||
|
glm::vec2 maxPos = _controllerScriptingInterface->getViewportDimensions() - MARGIN;
|
||||||
|
glm::vec2 pos2D = DependencyManager::get<HMDScriptingInterface>()->overlayFromWorldPoint(intersection);
|
||||||
|
return glm::max(MARGIN, glm::min(pos2D, maxPos));
|
||||||
|
});
|
||||||
|
|
||||||
// Setup the mouse ray pick and related operators
|
// Setup the mouse ray pick and related operators
|
||||||
DependencyManager::get<EntityTreeRenderer>()->setMouseRayPickID(DependencyManager::get<PickManager>()->addPick(PickQuery::Ray, std::make_shared<MouseRayPick>(
|
DependencyManager::get<EntityTreeRenderer>()->setMouseRayPickID(DependencyManager::get<PickManager>()->addPick(PickQuery::Ray, std::make_shared<MouseRayPick>(
|
||||||
|
|
|
@ -301,6 +301,8 @@ PointerEvent LaserPointer::buildPointerEvent(const PickedObject& target, const Q
|
||||||
pos2D = projectOntoEntityXYPlane(target.objectID, intersection);
|
pos2D = projectOntoEntityXYPlane(target.objectID, intersection);
|
||||||
} else if (target.type == OVERLAY) {
|
} else if (target.type == OVERLAY) {
|
||||||
pos2D = projectOntoOverlayXYPlane(target.objectID, intersection);
|
pos2D = projectOntoOverlayXYPlane(target.objectID, intersection);
|
||||||
|
} else if (target.type == HUD) {
|
||||||
|
pos2D = DependencyManager::get<PickManager>()->calculatePos2DFromHUD(intersection);
|
||||||
}
|
}
|
||||||
return PointerEvent(PointerEvent::Move, id, pos2D, intersection, surfaceNormal, direction, PointerEvent::NoButtons);
|
return PointerEvent(PointerEvent::Move, id, pos2D, intersection, surfaceNormal, direction, PointerEvent::NoButtons);
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,9 @@ public:
|
||||||
protected:
|
protected:
|
||||||
PointerEvent buildPointerEvent(const PickedObject& target, const QVariantMap& pickResult) const override;
|
PointerEvent buildPointerEvent(const PickedObject& target, const QVariantMap& pickResult) const override;
|
||||||
|
|
||||||
|
bool shouldHover() override { return _currentRenderState != ""; }
|
||||||
|
bool shouldTrigger() override { return _currentRenderState != ""; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PointerTriggers _triggers;
|
PointerTriggers _triggers;
|
||||||
float _laserLength { 0.0f };
|
float _laserLength { 0.0f };
|
||||||
|
|
|
@ -46,7 +46,7 @@ extern void initOverlay3DPipelines(render::ShapePlumber& plumber, bool depthTest
|
||||||
Overlays::Overlays() {
|
Overlays::Overlays() {
|
||||||
auto pointerManager = DependencyManager::get<PointerManager>();
|
auto pointerManager = DependencyManager::get<PointerManager>();
|
||||||
connect(pointerManager.data(), &PointerManager::hoverBeginOverlay, this, &Overlays::hoverEnterOverlay);
|
connect(pointerManager.data(), &PointerManager::hoverBeginOverlay, this, &Overlays::hoverEnterOverlay);
|
||||||
connect(pointerManager.data(), &PointerManager::hoverContinueOverlay, this, &Overlays::hoverOverOverlay);
|
connect(pointerManager.data(), &PointerManager::hoverContinueOverlay, this, &Overlays::hoverOverPointerEvent);
|
||||||
connect(pointerManager.data(), &PointerManager::hoverEndOverlay, this, &Overlays::hoverLeavePointerEvent);
|
connect(pointerManager.data(), &PointerManager::hoverEndOverlay, this, &Overlays::hoverLeavePointerEvent);
|
||||||
connect(pointerManager.data(), &PointerManager::triggerBeginOverlay, this, &Overlays::mousePressPointerEvent);
|
connect(pointerManager.data(), &PointerManager::triggerBeginOverlay, this, &Overlays::mousePressPointerEvent);
|
||||||
connect(pointerManager.data(), &PointerManager::triggerContinueOverlay, this, &Overlays::mouseMovePointerEvent);
|
connect(pointerManager.data(), &PointerManager::triggerContinueOverlay, this, &Overlays::mouseMovePointerEvent);
|
||||||
|
@ -745,7 +745,7 @@ void Overlays::sendHoverEnterOverlay(const OverlayID& overlayID, const PointerEv
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlays::sendHoverOverOverlay(const OverlayID& overlayID, const PointerEvent& event) {
|
void Overlays::sendHoverOverOverlay(const OverlayID& overlayID, const PointerEvent& event) {
|
||||||
emit hoverOverOverlay(overlayID, event);
|
hoverOverPointerEvent(overlayID, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlays::sendHoverLeaveOverlay(const OverlayID& overlayID, const PointerEvent& event) {
|
void Overlays::sendHoverLeaveOverlay(const OverlayID& overlayID, const PointerEvent& event) {
|
||||||
|
@ -940,6 +940,21 @@ bool Overlays::mouseDoublePressEvent(QMouseEvent* event) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Overlays::hoverOverPointerEvent(const OverlayID& overlayID, const PointerEvent& event) {
|
||||||
|
// TODO: generalize this to allow any overlay to recieve events
|
||||||
|
std::shared_ptr<Web3DOverlay> thisOverlay;
|
||||||
|
if (getOverlayType(overlayID) == "web3d") {
|
||||||
|
thisOverlay = std::static_pointer_cast<Web3DOverlay>(getOverlay(overlayID));
|
||||||
|
}
|
||||||
|
if (thisOverlay) {
|
||||||
|
// Send to web overlay
|
||||||
|
QMetaObject::invokeMethod(thisOverlay.get(), "handlePointerEvent", Q_ARG(PointerEvent, event));
|
||||||
|
}
|
||||||
|
|
||||||
|
// emit to scripts
|
||||||
|
emit hoverOverOverlay(overlayID, event);
|
||||||
|
}
|
||||||
|
|
||||||
void Overlays::hoverLeavePointerEvent(const OverlayID& overlayID, const PointerEvent& event) {
|
void Overlays::hoverLeavePointerEvent(const OverlayID& overlayID, const PointerEvent& event) {
|
||||||
// TODO: generalize this to allow any overlay to recieve events
|
// TODO: generalize this to allow any overlay to recieve events
|
||||||
std::shared_ptr<Web3DOverlay> thisOverlay;
|
std::shared_ptr<Web3DOverlay> thisOverlay;
|
||||||
|
@ -1005,7 +1020,7 @@ bool Overlays::mouseMoveEvent(QMouseEvent* event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hover over current overlay.
|
// Hover over current overlay.
|
||||||
emit hoverOverOverlay(rayPickResult.overlayID, pointerEvent);
|
hoverOverPointerEvent(rayPickResult.overlayID, pointerEvent);
|
||||||
|
|
||||||
_currentHoverOverOverlayID = rayPickResult.overlayID;
|
_currentHoverOverOverlayID = rayPickResult.overlayID;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -308,6 +308,7 @@ public slots:
|
||||||
void mousePressPointerEvent(const OverlayID& overlayID, const PointerEvent& event);
|
void mousePressPointerEvent(const OverlayID& overlayID, const PointerEvent& event);
|
||||||
void mouseMovePointerEvent(const OverlayID& overlayID, const PointerEvent& event);
|
void mouseMovePointerEvent(const OverlayID& overlayID, const PointerEvent& event);
|
||||||
void mouseReleasePointerEvent(const OverlayID& overlayID, const PointerEvent& event);
|
void mouseReleasePointerEvent(const OverlayID& overlayID, const PointerEvent& event);
|
||||||
|
void hoverOverPointerEvent(const OverlayID& overlayID, const PointerEvent& event);
|
||||||
void hoverLeavePointerEvent(const OverlayID& overlayID, const PointerEvent& event);
|
void hoverLeavePointerEvent(const OverlayID& overlayID, const PointerEvent& event);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
|
@ -83,6 +83,7 @@ EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterf
|
||||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, this, handlePointerEvent);
|
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, this, handlePointerEvent);
|
||||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity, this, handlePointerEvent);
|
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity, this, handlePointerEvent);
|
||||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity, this, handlePointerEvent);
|
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity, this, handlePointerEvent);
|
||||||
|
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverOverEntity, this, handlePointerEvent);
|
||||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, this, [&](const EntityItemID& entityID, const PointerEvent& event) {
|
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, this, [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||||
std::shared_ptr<render::entities::WebEntityRenderer> thisEntity;
|
std::shared_ptr<render::entities::WebEntityRenderer> thisEntity;
|
||||||
auto entity = getEntity(entityID);
|
auto entity = getEntity(entityID);
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
PickManager::PickManager() {
|
PickManager::PickManager() {
|
||||||
setShouldPickHUDOperator([]() { return false; });
|
setShouldPickHUDOperator([]() { return false; });
|
||||||
|
setCalculatePos2DFromHUDOperator([](const glm::vec3& intersection) { return glm::vec2(NAN); });
|
||||||
}
|
}
|
||||||
|
|
||||||
QUuid PickManager::addPick(PickQuery::PickType type, const std::shared_ptr<PickQuery> pick) {
|
QUuid PickManager::addPick(PickQuery::PickType type, const std::shared_ptr<PickQuery> pick) {
|
||||||
|
|
|
@ -34,9 +34,12 @@ public:
|
||||||
void setIncludeItems(const QUuid& uid, const QVector<QUuid>& include) const;
|
void setIncludeItems(const QUuid& uid, const QVector<QUuid>& include) const;
|
||||||
|
|
||||||
void setShouldPickHUDOperator(std::function<bool()> shouldPickHUDOperator) { _shouldPickHUDOperator = shouldPickHUDOperator; }
|
void setShouldPickHUDOperator(std::function<bool()> shouldPickHUDOperator) { _shouldPickHUDOperator = shouldPickHUDOperator; }
|
||||||
|
void setCalculatePos2DFromHUDOperator(std::function<glm::vec2(const glm::vec3&)> calculatePos2DFromHUDOperator) { _calculatePos2DFromHUDOperator = calculatePos2DFromHUDOperator; }
|
||||||
|
glm::vec2 calculatePos2DFromHUD(const glm::vec3& intersection) { return _calculatePos2DFromHUDOperator(intersection); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::function<bool()> _shouldPickHUDOperator;
|
std::function<bool()> _shouldPickHUDOperator;
|
||||||
|
std::function<glm::vec2(const glm::vec3&)> _calculatePos2DFromHUDOperator;
|
||||||
|
|
||||||
std::shared_ptr<PickQuery> findPick(const QUuid& uid) const;
|
std::shared_ptr<PickQuery> findPick(const QUuid& uid) const;
|
||||||
QHash<PickQuery::PickType, QHash<QUuid, std::shared_ptr<PickQuery>>> _picks;
|
QHash<PickQuery::PickType, QHash<QUuid, std::shared_ptr<PickQuery>>> _picks;
|
||||||
|
|
|
@ -56,7 +56,7 @@ void Pointer::update() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pointer::generatePointerEvents(const QVariantMap& pickResult) {
|
void Pointer::generatePointerEvents(const QVariantMap& pickResult) {
|
||||||
// TODO: avatars/HUD?
|
// TODO: avatars?
|
||||||
auto pointerManager = DependencyManager::get<PointerManager>();
|
auto pointerManager = DependencyManager::get<PointerManager>();
|
||||||
|
|
||||||
// Hover events
|
// Hover events
|
||||||
|
@ -65,7 +65,7 @@ void Pointer::generatePointerEvents(const QVariantMap& pickResult) {
|
||||||
hoveredEvent.setType(PointerEvent::Move);
|
hoveredEvent.setType(PointerEvent::Move);
|
||||||
// TODO: set buttons on hover events
|
// TODO: set buttons on hover events
|
||||||
hoveredEvent.setButton(PointerEvent::NoButtons);
|
hoveredEvent.setButton(PointerEvent::NoButtons);
|
||||||
if (_enabled && _hover) {
|
if (_enabled && _hover && shouldHover()) {
|
||||||
if (hoveredObject.type == OVERLAY) {
|
if (hoveredObject.type == OVERLAY) {
|
||||||
if (_prevHoveredObject.type == OVERLAY) {
|
if (_prevHoveredObject.type == OVERLAY) {
|
||||||
if (hoveredObject.objectID == _prevHoveredObject.objectID) {
|
if (hoveredObject.objectID == _prevHoveredObject.objectID) {
|
||||||
|
@ -79,6 +79,8 @@ void Pointer::generatePointerEvents(const QVariantMap& pickResult) {
|
||||||
emit pointerManager->hoverBeginOverlay(hoveredObject.objectID, hoveredEvent);
|
emit pointerManager->hoverBeginOverlay(hoveredObject.objectID, hoveredEvent);
|
||||||
if (_prevHoveredObject.type == ENTITY) {
|
if (_prevHoveredObject.type == ENTITY) {
|
||||||
emit pointerManager->hoverEndEntity(_prevHoveredObject.objectID, hoveredEvent);
|
emit pointerManager->hoverEndEntity(_prevHoveredObject.objectID, hoveredEvent);
|
||||||
|
} else if (_prevHoveredObject.type == HUD) {
|
||||||
|
emit pointerManager->hoverEndHUD(_prevHoveredObject.objectID, hoveredEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,6 +99,22 @@ void Pointer::generatePointerEvents(const QVariantMap& pickResult) {
|
||||||
emit pointerManager->hoverBeginEntity(hoveredObject.objectID, hoveredEvent);
|
emit pointerManager->hoverBeginEntity(hoveredObject.objectID, hoveredEvent);
|
||||||
if (_prevHoveredObject.type == OVERLAY) {
|
if (_prevHoveredObject.type == OVERLAY) {
|
||||||
emit pointerManager->hoverEndOverlay(_prevHoveredObject.objectID, hoveredEvent);
|
emit pointerManager->hoverEndOverlay(_prevHoveredObject.objectID, hoveredEvent);
|
||||||
|
} else if (_prevHoveredObject.type == HUD) {
|
||||||
|
emit pointerManager->hoverEndHUD(_prevHoveredObject.objectID, hoveredEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hoveredObject.type == HUD) {
|
||||||
|
if (_prevHoveredObject.type == HUD) {
|
||||||
|
// There's only one HUD
|
||||||
|
emit pointerManager->hoverContinueHUD(hoveredObject.objectID, hoveredEvent);
|
||||||
|
} else {
|
||||||
|
emit pointerManager->hoverBeginHUD(hoveredObject.objectID, hoveredEvent);
|
||||||
|
if (_prevHoveredObject.type == ENTITY) {
|
||||||
|
emit pointerManager->hoverEndEntity(_prevHoveredObject.objectID, hoveredEvent);
|
||||||
|
} else if (_prevHoveredObject.type == OVERLAY) {
|
||||||
|
emit pointerManager->hoverEndOverlay(_prevHoveredObject.objectID, hoveredEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,8 +125,8 @@ void Pointer::generatePointerEvents(const QVariantMap& pickResult) {
|
||||||
Buttons newButtons;
|
Buttons newButtons;
|
||||||
Buttons sameButtons;
|
Buttons sameButtons;
|
||||||
// NOTE: After this loop: _prevButtons = buttons that were removed
|
// NOTE: After this loop: _prevButtons = buttons that were removed
|
||||||
// If !_enabled, release all buttons
|
// If switching to disabled or should stop triggering, release all buttons
|
||||||
if (_enabled) {
|
if (_enabled && shouldTrigger()) {
|
||||||
buttons = getPressedButtons();
|
buttons = getPressedButtons();
|
||||||
for (const std::string& button : buttons) {
|
for (const std::string& button : buttons) {
|
||||||
if (_prevButtons.find(button) == _prevButtons.end()) {
|
if (_prevButtons.find(button) == _prevButtons.end()) {
|
||||||
|
@ -130,6 +148,8 @@ void Pointer::generatePointerEvents(const QVariantMap& pickResult) {
|
||||||
emit pointerManager->triggerBeginEntity(hoveredObject.objectID, hoveredEvent);
|
emit pointerManager->triggerBeginEntity(hoveredObject.objectID, hoveredEvent);
|
||||||
} else if (hoveredObject.type == OVERLAY) {
|
} else if (hoveredObject.type == OVERLAY) {
|
||||||
emit pointerManager->triggerBeginOverlay(hoveredObject.objectID, hoveredEvent);
|
emit pointerManager->triggerBeginOverlay(hoveredObject.objectID, hoveredEvent);
|
||||||
|
} else if (hoveredObject.type == HUD) {
|
||||||
|
emit pointerManager->triggerBeginHUD(hoveredObject.objectID, hoveredEvent);
|
||||||
}
|
}
|
||||||
_triggeredObjects[button] = hoveredObject;
|
_triggeredObjects[button] = hoveredObject;
|
||||||
}
|
}
|
||||||
|
@ -143,6 +163,8 @@ void Pointer::generatePointerEvents(const QVariantMap& pickResult) {
|
||||||
emit pointerManager->triggerContinueEntity(_triggeredObjects[button].objectID, triggeredEvent);
|
emit pointerManager->triggerContinueEntity(_triggeredObjects[button].objectID, triggeredEvent);
|
||||||
} else if (_triggeredObjects[button].type == OVERLAY) {
|
} else if (_triggeredObjects[button].type == OVERLAY) {
|
||||||
emit pointerManager->triggerContinueOverlay(_triggeredObjects[button].objectID, triggeredEvent);
|
emit pointerManager->triggerContinueOverlay(_triggeredObjects[button].objectID, triggeredEvent);
|
||||||
|
} else if (_triggeredObjects[button].type == HUD) {
|
||||||
|
emit pointerManager->triggerContinueHUD(_triggeredObjects[button].objectID, triggeredEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,6 +177,8 @@ void Pointer::generatePointerEvents(const QVariantMap& pickResult) {
|
||||||
emit pointerManager->triggerEndEntity(_triggeredObjects[button].objectID, triggeredEvent);
|
emit pointerManager->triggerEndEntity(_triggeredObjects[button].objectID, triggeredEvent);
|
||||||
} else if (_triggeredObjects[button].type == OVERLAY) {
|
} else if (_triggeredObjects[button].type == OVERLAY) {
|
||||||
emit pointerManager->triggerEndOverlay(_triggeredObjects[button].objectID, triggeredEvent);
|
emit pointerManager->triggerEndOverlay(_triggeredObjects[button].objectID, triggeredEvent);
|
||||||
|
} else if (_triggeredObjects[button].type == HUD) {
|
||||||
|
emit pointerManager->triggerEndHUD(_triggeredObjects[button].objectID, triggeredEvent);
|
||||||
}
|
}
|
||||||
_triggeredObjects.erase(button);
|
_triggeredObjects.erase(button);
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,9 +71,6 @@ public:
|
||||||
|
|
||||||
using Buttons = std::unordered_set<std::string>;
|
using Buttons = std::unordered_set<std::string>;
|
||||||
|
|
||||||
virtual PickedObject getHoveredObject(const QVariantMap& pickResult) = 0;
|
|
||||||
virtual Buttons getPressedButtons() = 0;
|
|
||||||
|
|
||||||
QUuid getRayUID() { return _pickUID; }
|
QUuid getRayUID() { return _pickUID; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -83,6 +80,12 @@ protected:
|
||||||
|
|
||||||
virtual PointerEvent buildPointerEvent(const PickedObject& target, const QVariantMap& pickResult) const = 0;
|
virtual PointerEvent buildPointerEvent(const PickedObject& target, const QVariantMap& pickResult) const = 0;
|
||||||
|
|
||||||
|
virtual PickedObject getHoveredObject(const QVariantMap& pickResult) = 0;
|
||||||
|
virtual Buttons getPressedButtons() = 0;
|
||||||
|
|
||||||
|
virtual bool shouldHover() = 0;
|
||||||
|
virtual bool shouldTrigger() = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PickedObject _prevHoveredObject;
|
PickedObject _prevHoveredObject;
|
||||||
Buttons _prevButtons;
|
Buttons _prevButtons;
|
||||||
|
|
|
@ -58,6 +58,13 @@ signals:
|
||||||
void hoverBeginEntity(const QUuid& id, const PointerEvent& pointerEvent);
|
void hoverBeginEntity(const QUuid& id, const PointerEvent& pointerEvent);
|
||||||
void hoverContinueEntity(const QUuid& id, const PointerEvent& pointerEvent);
|
void hoverContinueEntity(const QUuid& id, const PointerEvent& pointerEvent);
|
||||||
void hoverEndEntity(const QUuid& id, const PointerEvent& pointerEvent);
|
void hoverEndEntity(const QUuid& id, const PointerEvent& pointerEvent);
|
||||||
|
|
||||||
|
void triggerBeginHUD(const QUuid& id, const PointerEvent& pointerEvent);
|
||||||
|
void triggerContinueHUD(const QUuid& id, const PointerEvent& pointerEvent);
|
||||||
|
void triggerEndHUD(const QUuid& id, const PointerEvent& pointerEvent);
|
||||||
|
void hoverBeginHUD(const QUuid& id, const PointerEvent& pointerEvent);
|
||||||
|
void hoverContinueHUD(const QUuid& id, const PointerEvent& pointerEvent);
|
||||||
|
void hoverEndHUD(const QUuid& id, const PointerEvent& pointerEvent);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_pointers_PointerManager_h
|
#endif // hifi_pointers_PointerManager_h
|
||||||
|
|
|
@ -41,6 +41,11 @@ PointerEvent::PointerEvent(EventType type, uint32_t id,
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PointerEvent::setButton(Button button) {
|
||||||
|
_button = button;
|
||||||
|
_buttons |= button;
|
||||||
|
}
|
||||||
|
|
||||||
QScriptValue PointerEvent::toScriptValue(QScriptEngine* engine, const PointerEvent& event) {
|
QScriptValue PointerEvent::toScriptValue(QScriptEngine* engine, const PointerEvent& event) {
|
||||||
QScriptValue obj = engine->newObject();
|
QScriptValue obj = engine->newObject();
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ public:
|
||||||
bool shouldFocus() const { return _shouldFocus; }
|
bool shouldFocus() const { return _shouldFocus; }
|
||||||
|
|
||||||
void setType(EventType type) { _type = type; }
|
void setType(EventType type) { _type = type; }
|
||||||
void setButton(Button button) { _button = button; }
|
void setButton(Button button);
|
||||||
void setShouldFocus(bool focus) { _shouldFocus = focus; }
|
void setShouldFocus(bool focus) { _shouldFocus = focus; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
set(TARGET_NAME ui)
|
set(TARGET_NAME ui)
|
||||||
setup_hifi_library(OpenGL Network Qml Quick Script WebChannel WebEngine WebSockets XmlPatterns)
|
setup_hifi_library(OpenGL Network Qml Quick Script WebChannel WebEngine WebSockets XmlPatterns)
|
||||||
link_hifi_libraries(shared networking gl audio)
|
link_hifi_libraries(shared networking gl audio pointers)
|
||||||
|
include_hifi_library_headers(controllers)
|
||||||
|
|
||||||
# Required for some low level GL interaction in the OffscreenQMLSurface
|
# Required for some low level GL interaction in the OffscreenQMLSurface
|
||||||
target_opengl()
|
target_opengl()
|
||||||
|
|
|
@ -49,6 +49,8 @@
|
||||||
|
|
||||||
#include "Logging.h"
|
#include "Logging.h"
|
||||||
|
|
||||||
|
#include <pointers/PointerManager.h>
|
||||||
|
|
||||||
Q_LOGGING_CATEGORY(trace_render_qml, "trace.render.qml")
|
Q_LOGGING_CATEGORY(trace_render_qml, "trace.render.qml")
|
||||||
Q_LOGGING_CATEGORY(trace_render_qml_gl, "trace.render.qml.gl")
|
Q_LOGGING_CATEGORY(trace_render_qml_gl, "trace.render.qml.gl")
|
||||||
Q_LOGGING_CATEGORY(offscreenFocus, "hifi.offscreen.focus")
|
Q_LOGGING_CATEGORY(offscreenFocus, "hifi.offscreen.focus")
|
||||||
|
@ -529,6 +531,13 @@ bool OffscreenQmlSurface::allowNewFrame(uint8_t fps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
OffscreenQmlSurface::OffscreenQmlSurface() {
|
OffscreenQmlSurface::OffscreenQmlSurface() {
|
||||||
|
auto pointerManager = DependencyManager::get<PointerManager>();
|
||||||
|
connect(pointerManager.data(), &PointerManager::hoverBeginHUD, this, &OffscreenQmlSurface::handlePointerEvent);
|
||||||
|
connect(pointerManager.data(), &PointerManager::hoverContinueHUD, this, &OffscreenQmlSurface::handlePointerEvent);
|
||||||
|
connect(pointerManager.data(), &PointerManager::hoverEndHUD, this, &OffscreenQmlSurface::handlePointerEvent);
|
||||||
|
connect(pointerManager.data(), &PointerManager::triggerBeginHUD, this, &OffscreenQmlSurface::handlePointerEvent);
|
||||||
|
connect(pointerManager.data(), &PointerManager::triggerContinueHUD, this, &OffscreenQmlSurface::handlePointerEvent);
|
||||||
|
connect(pointerManager.data(), &PointerManager::triggerEndHUD, this, &OffscreenQmlSurface::handlePointerEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
OffscreenQmlSurface::~OffscreenQmlSurface() {
|
OffscreenQmlSurface::~OffscreenQmlSurface() {
|
||||||
|
@ -932,14 +941,8 @@ bool OffscreenQmlSurface::eventFilter(QObject* originalDestination, QEvent* even
|
||||||
transformedPos,
|
transformedPos,
|
||||||
mouseEvent->screenPos(), mouseEvent->button(),
|
mouseEvent->screenPos(), mouseEvent->button(),
|
||||||
mouseEvent->buttons(), mouseEvent->modifiers());
|
mouseEvent->buttons(), mouseEvent->modifiers());
|
||||||
if (event->type() == QEvent::MouseMove) {
|
if (sendMouseEvent(mappedEvent)) {
|
||||||
// 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
|
return true;
|
||||||
// need to investigate into why this crash is happening.
|
|
||||||
//_qmlContext->setContextProperty("lastMousePosition", transformedPos);
|
|
||||||
}
|
|
||||||
mappedEvent.ignore();
|
|
||||||
if (QCoreApplication::sendEvent(_quickWindow, &mappedEvent)) {
|
|
||||||
return mappedEvent.isAccepted();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -951,6 +954,44 @@ bool OffscreenQmlSurface::eventFilter(QObject* originalDestination, QEvent* even
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OffscreenQmlSurface::handlePointerEvent(const QUuid& id, const PointerEvent& event) {
|
||||||
|
if (_paused) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QEvent::Type type;
|
||||||
|
switch (event.getType()) {
|
||||||
|
case PointerEvent::Press:
|
||||||
|
type = QEvent::Type::MouseButtonPress;
|
||||||
|
break;
|
||||||
|
case PointerEvent::DoublePress:
|
||||||
|
type = QEvent::Type::MouseButtonDblClick;
|
||||||
|
break;
|
||||||
|
case PointerEvent::Release:
|
||||||
|
type = QEvent::Type::MouseButtonRelease;
|
||||||
|
break;
|
||||||
|
case PointerEvent::Move:
|
||||||
|
type = QEvent::Type::MouseMove;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
QPointF screenPos(event.getPos2D().x, event.getPos2D().y);
|
||||||
|
QMouseEvent mouseEvent(type, screenPos, Qt::MouseButton(event.getButton()), Qt::MouseButtons(event.getButtons()), event.getKeyboardModifiers());
|
||||||
|
sendMouseEvent(mouseEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OffscreenQmlSurface::sendMouseEvent(QMouseEvent& mouseEvent) {
|
||||||
|
if (mouseEvent.type() == QEvent::MouseMove) {
|
||||||
|
// 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", mouseEvent.localPos());
|
||||||
|
}
|
||||||
|
mouseEvent.ignore();
|
||||||
|
if (QCoreApplication::sendEvent(_quickWindow, &mouseEvent)) {
|
||||||
|
return mouseEvent.isAccepted();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void OffscreenQmlSurface::pause() {
|
void OffscreenQmlSurface::pause() {
|
||||||
_paused = true;
|
_paused = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,8 @@ class QQmlContext;
|
||||||
class QQmlComponent;
|
class QQmlComponent;
|
||||||
class QQuickWindow;
|
class QQuickWindow;
|
||||||
class QQuickItem;
|
class QQuickItem;
|
||||||
|
class QMouseEvent;
|
||||||
|
class PointerEvent;
|
||||||
|
|
||||||
// GPU resources are typically buffered for one copy being used by the renderer,
|
// GPU resources are typically buffered for one copy being used by the renderer,
|
||||||
// one copy in flight, and one copy being used by the receiver
|
// one copy in flight, and one copy being used by the receiver
|
||||||
|
@ -135,6 +137,7 @@ private:
|
||||||
private slots:
|
private slots:
|
||||||
void updateQuick();
|
void updateQuick();
|
||||||
void onFocusObjectChanged(QObject* newFocus);
|
void onFocusObjectChanged(QObject* newFocus);
|
||||||
|
void handlePointerEvent(const QUuid& id, const PointerEvent& event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QQuickWindow* _quickWindow { nullptr };
|
QQuickWindow* _quickWindow { nullptr };
|
||||||
|
@ -161,6 +164,8 @@ private:
|
||||||
QWindow* _proxyWindow { nullptr };
|
QWindow* _proxyWindow { nullptr };
|
||||||
|
|
||||||
QQuickItem* _currentFocusItem { nullptr };
|
QQuickItem* _currentFocusItem { nullptr };
|
||||||
|
|
||||||
|
bool sendMouseEvent(QMouseEvent& mouseEvent);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue