mirror of
https://github.com/overte-org/overte.git
synced 2025-04-22 19:13:38 +02:00
austin's comments, send events directly to selected web entity
This commit is contained in:
parent
c6b636901a
commit
9bbb2eb692
5 changed files with 83 additions and 55 deletions
|
@ -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);
|
||||
|
|
|
@ -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<Web3DOverlay>(getOverlay(overlayID));
|
||||
std::shared_ptr<Web3DOverlay> thisOverlay;
|
||||
if (getOverlayType(overlayID) == "web3d") {
|
||||
thisOverlay = std::static_pointer_cast<Web3DOverlay>(getOverlay(overlayID));
|
||||
}
|
||||
if (thisOverlay) {
|
||||
// Focus keyboard on web overlays
|
||||
DependencyManager::get<EntityScriptingInterface>()->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<Web3DOverlay>(getOverlay(overlayID));
|
||||
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(), "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<Web3DOverlay>(getOverlay(overlayID));
|
||||
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));
|
||||
|
@ -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<Web3DOverlay>(getOverlay(overlayID));
|
||||
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));
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
#include "EntitiesRendererLogging.h"
|
||||
#include "RenderableEntityItem.h"
|
||||
|
||||
#include "RenderableWebEntityItem.h"
|
||||
|
||||
size_t std::hash<EntityItemID>::operator()(const EntityItemID& id) const { return qHash(id); }
|
||||
std::function<bool()> 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<render::entities::WebEntityRenderer> thisEntity;
|
||||
auto entity = getEntity(entityID);
|
||||
if (entity && entity->getType() == EntityTypes::Web) {
|
||||
thisEntity = std::static_pointer_cast<render::entities::WebEntityRenderer>(renderableForEntityId(entityID));
|
||||
}
|
||||
if (thisEntity) {
|
||||
QMetaObject::invokeMethod(thisEntity.get(), "handlePointerEvent", Q_ARG(PointerEvent, event));
|
||||
}
|
||||
};
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
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<render::entities::WebEntityRenderer> thisEntity;
|
||||
auto entity = getEntity(entityID);
|
||||
if (entity && entity->getType() == EntityTypes::Web) {
|
||||
thisEntity = std::static_pointer_cast<render::entities::WebEntityRenderer>(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<EntityScriptingInterface>();
|
||||
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<EntityScriptingInterface>();
|
||||
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<EntityScriptingInterface>();
|
||||
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<EntityScriptingInterface>();
|
||||
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,
|
||||
|
|
|
@ -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<EntityScriptingInterface>();
|
||||
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<QTouchEvent::TouchPoint> 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<EntityScriptingInterface>();
|
||||
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<QTouchEvent::TouchPoint> 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
|
||||
|
|
|
@ -18,12 +18,16 @@ class PointerEvent;
|
|||
namespace render { namespace entities {
|
||||
|
||||
class WebEntityRenderer : public TypedEntityRenderer<WebEntityItem> {
|
||||
Q_OBJECT
|
||||
using Parent = TypedEntityRenderer<WebEntityItem>;
|
||||
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 };
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue