Merge pull request #15088 from SamGondelman/create

Case 21541: Fix mouse on create in HMD
This commit is contained in:
Sam Gondelman 2019-03-05 13:07:49 -08:00 committed by GitHub
commit 94cc5b83ac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 129 additions and 213 deletions

View file

@ -1061,6 +1061,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
connect(PluginManager::getInstance().data(), &PluginManager::inputDeviceRunningChanged,
controllerScriptingInterface, &controller::ScriptingInterface::updateRunningInputDevices);
EntityTree::setEntityClicksCapturedOperator([this] {
return _controllerScriptingInterface->areEntityClicksCaptured();
});
_entityClipboard->createRootElement();
#ifdef Q_OS_WIN
@ -4392,7 +4396,6 @@ void Application::mouseMoveEvent(QMouseEvent* event) {
if (compositor.getReticleVisible() || !isHMDMode() || !compositor.getReticleOverDesktop() ||
getOverlays().getOverlayAtPoint(glm::vec2(transformedPos.x(), transformedPos.y())) != UNKNOWN_ENTITY_ID) {
getEntities()->mouseMoveEvent(&mappedEvent);
getOverlays().mouseMoveEvent(&mappedEvent);
}
_controllerScriptingInterface->emitMouseMoveEvent(&mappedEvent); // send events to any registered scripts
@ -4426,14 +4429,8 @@ void Application::mousePressEvent(QMouseEvent* event) {
#endif
QMouseEvent mappedEvent(event->type(), transformedPos, event->screenPos(), event->button(), event->buttons(), event->modifiers());
std::pair<float, QUuid> entityResult;
if (!_controllerScriptingInterface->areEntityClicksCaptured()) {
entityResult = getEntities()->mousePressEvent(&mappedEvent);
}
std::pair<float, QUuid> overlayResult = getOverlays().mousePressEvent(&mappedEvent);
QUuid focusedEntity = entityResult.first < overlayResult.first ? entityResult.second : overlayResult.second;
setKeyboardFocusEntity(getEntities()->wantsKeyboardFocus(focusedEntity) ? focusedEntity : UNKNOWN_ENTITY_ID);
QUuid result = getEntities()->mousePressEvent(&mappedEvent);
setKeyboardFocusEntity(getEntities()->wantsKeyboardFocus(result) ? result : UNKNOWN_ENTITY_ID);
_controllerScriptingInterface->emitMousePressEvent(&mappedEvent); // send events to any registered scripts
@ -4472,11 +4469,7 @@ void Application::mouseDoublePressEvent(QMouseEvent* event) {
transformedPos,
event->screenPos(), event->button(),
event->buttons(), event->modifiers());
if (!_controllerScriptingInterface->areEntityClicksCaptured()) {
getEntities()->mouseDoublePressEvent(&mappedEvent);
}
getOverlays().mouseDoublePressEvent(&mappedEvent);
getEntities()->mouseDoublePressEvent(&mappedEvent);
// if one of our scripts have asked to capture this event, then stop processing it
if (_controllerScriptingInterface->isMouseCaptured()) {
@ -4501,7 +4494,6 @@ void Application::mouseReleaseEvent(QMouseEvent* event) {
event->buttons(), event->modifiers());
getEntities()->mouseReleaseEvent(&mappedEvent);
getOverlays().mouseReleaseEvent(&mappedEvent);
_controllerScriptingInterface->emitMouseReleaseEvent(&mappedEvent); // send events to any registered scripts

View file

@ -43,14 +43,6 @@ std::unordered_map<QString, QString> Overlays::_entityToOverlayTypes;
std::unordered_map<QString, QString> Overlays::_overlayToEntityTypes;
Overlays::Overlays() {
auto pointerManager = DependencyManager::get<PointerManager>();
connect(pointerManager.data(), &PointerManager::hoverBeginOverlay, this, &Overlays::hoverEnterPointerEvent);
connect(pointerManager.data(), &PointerManager::hoverContinueOverlay, this, &Overlays::hoverOverPointerEvent);
connect(pointerManager.data(), &PointerManager::hoverEndOverlay, this, &Overlays::hoverLeavePointerEvent);
connect(pointerManager.data(), &PointerManager::triggerBeginOverlay, this, &Overlays::mousePressPointerEvent);
connect(pointerManager.data(), &PointerManager::triggerContinueOverlay, this, &Overlays::mouseMovePointerEvent);
connect(pointerManager.data(), &PointerManager::triggerEndOverlay, this, &Overlays::mouseReleasePointerEvent);
ADD_TYPE_MAP(Box, cube);
ADD_TYPE_MAP(Sphere, sphere);
_overlayToEntityTypes["rectangle3d"] = "Shape";
@ -81,13 +73,23 @@ void Overlays::cleanupAllOverlays() {
void Overlays::init() {
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>().data();
auto pointerManager = DependencyManager::get<PointerManager>();
connect(pointerManager.data(), &PointerManager::hoverBeginOverlay, entityScriptingInterface , &EntityScriptingInterface::hoverEnterEntity);
connect(pointerManager.data(), &PointerManager::hoverContinueOverlay, entityScriptingInterface, &EntityScriptingInterface::hoverOverEntity);
connect(pointerManager.data(), &PointerManager::hoverEndOverlay, entityScriptingInterface, &EntityScriptingInterface::hoverLeaveEntity);
connect(pointerManager.data(), &PointerManager::triggerBeginOverlay, entityScriptingInterface, &EntityScriptingInterface::mousePressOnEntity);
connect(pointerManager.data(), &PointerManager::triggerContinueOverlay, entityScriptingInterface, &EntityScriptingInterface::mouseMoveOnEntity);
connect(pointerManager.data(), &PointerManager::triggerEndOverlay, entityScriptingInterface, &EntityScriptingInterface::mouseReleaseOnEntity);
auto pointerManager = DependencyManager::get<PointerManager>().data();
connect(pointerManager, &PointerManager::hoverBeginOverlay, entityScriptingInterface , &EntityScriptingInterface::hoverEnterEntity);
connect(pointerManager, &PointerManager::hoverContinueOverlay, entityScriptingInterface, &EntityScriptingInterface::hoverOverEntity);
connect(pointerManager, &PointerManager::hoverEndOverlay, entityScriptingInterface, &EntityScriptingInterface::hoverLeaveEntity);
connect(pointerManager, &PointerManager::triggerBeginOverlay, entityScriptingInterface, &EntityScriptingInterface::mousePressOnEntity);
connect(pointerManager, &PointerManager::triggerContinueOverlay, entityScriptingInterface, &EntityScriptingInterface::mouseMoveOnEntity);
connect(pointerManager, &PointerManager::triggerEndOverlay, entityScriptingInterface, &EntityScriptingInterface::mouseReleaseOnEntity);
connect(entityScriptingInterface, &EntityScriptingInterface::mousePressOnEntity, this, &Overlays::mousePressOnPointerEvent);
connect(entityScriptingInterface, &EntityScriptingInterface::mousePressOffEntity, this, &Overlays::mousePressOffPointerEvent);
connect(entityScriptingInterface, &EntityScriptingInterface::mouseDoublePressOnEntity, this, &Overlays::mouseDoublePressOnPointerEvent);
connect(entityScriptingInterface, &EntityScriptingInterface::mouseDoublePressOffEntity, this, &Overlays::mouseDoublePressOffPointerEvent);
connect(entityScriptingInterface, &EntityScriptingInterface::mouseReleaseOnEntity, this, &Overlays::mouseReleasePointerEvent);
connect(entityScriptingInterface, &EntityScriptingInterface::mouseMoveOnEntity, this, &Overlays::mouseMovePointerEvent);
connect(entityScriptingInterface, &EntityScriptingInterface::hoverEnterEntity , this, &Overlays::hoverEnterPointerEvent);
connect(entityScriptingInterface, &EntityScriptingInterface::hoverOverEntity, this, &Overlays::hoverOverPointerEvent);
connect(entityScriptingInterface, &EntityScriptingInterface::hoverLeaveEntity, this, &Overlays::hoverLeavePointerEvent);
}
void Overlays::update(float deltatime) {
@ -1159,7 +1161,7 @@ bool Overlays::isAddedOverlay(const QUuid& id) {
}
void Overlays::sendMousePressOnOverlay(const QUuid& id, const PointerEvent& event) {
mousePressPointerEvent(id, event);
mousePressOnPointerEvent(id, event);
}
void Overlays::sendMouseReleaseOnOverlay(const QUuid& id, const PointerEvent& event) {
@ -1206,57 +1208,66 @@ float Overlays::height() {
return offscreenUi->getWindow()->size().height();
}
static uint32_t toPointerButtons(const QMouseEvent& event) {
uint32_t buttons = 0;
buttons |= event.buttons().testFlag(Qt::LeftButton) ? PointerEvent::PrimaryButton : 0;
buttons |= event.buttons().testFlag(Qt::RightButton) ? PointerEvent::SecondaryButton : 0;
buttons |= event.buttons().testFlag(Qt::MiddleButton) ? PointerEvent::TertiaryButton : 0;
return buttons;
}
static PointerEvent::Button toPointerButton(const QMouseEvent& event) {
switch (event.button()) {
case Qt::LeftButton:
return PointerEvent::PrimaryButton;
case Qt::RightButton:
return PointerEvent::SecondaryButton;
case Qt::MiddleButton:
return PointerEvent::TertiaryButton;
default:
return PointerEvent::NoButtons;
}
}
RayToOverlayIntersectionResult getPrevPickResult() {
RayToOverlayIntersectionResult overlayResult;
overlayResult.intersects = false;
auto pickResult = DependencyManager::get<PickManager>()->getPrevPickResultTyped<RayPickResult>(DependencyManager::get<EntityTreeRenderer>()->getMouseRayPickID());
if (pickResult) {
overlayResult.intersects = pickResult->type == IntersectionType::LOCAL_ENTITY;
if (overlayResult.intersects) {
overlayResult.intersection = pickResult->intersection;
overlayResult.distance = pickResult->distance;
overlayResult.surfaceNormal = pickResult->surfaceNormal;
overlayResult.overlayID = pickResult->objectID;
overlayResult.extraInfo = pickResult->extraInfo;
void Overlays::mousePressOnPointerEvent(const QUuid& id, const PointerEvent& event) {
auto keyboard = DependencyManager::get<Keyboard>();
// Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed
if (!keyboard->getKeyIDs().contains(id)) {
auto entity = DependencyManager::get<EntityTreeRenderer>()->getEntity(id);
if (entity && entity->isLocalEntity()) {
emit mousePressOnOverlay(id, event);
}
}
return overlayResult;
}
PointerEvent Overlays::calculateOverlayPointerEvent(const QUuid& id, const PickRay& ray,
const RayToOverlayIntersectionResult& rayPickResult, QMouseEvent* event,
PointerEvent::EventType eventType) {
glm::vec2 pos2D = RayPick::projectOntoEntityXYPlane(id, rayPickResult.intersection);
return PointerEvent(eventType, PointerManager::MOUSE_POINTER_ID, pos2D, rayPickResult.intersection, rayPickResult.surfaceNormal,
ray.direction, toPointerButton(*event), toPointerButtons(*event), event->modifiers());
void Overlays::mousePressOffPointerEvent() {
emit mousePressOffOverlay();
}
void Overlays::mouseDoublePressOnPointerEvent(const QUuid& id, const PointerEvent& event) {
auto keyboard = DependencyManager::get<Keyboard>();
// Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed
if (!keyboard->getKeyIDs().contains(id)) {
auto entity = DependencyManager::get<EntityTreeRenderer>()->getEntity(id);
if (entity && entity->isLocalEntity()) {
emit mouseDoublePressOnOverlay(id, event);
}
}
}
void Overlays::mouseDoublePressOffPointerEvent() {
emit mouseDoublePressOffOverlay();
}
void Overlays::mouseReleasePointerEvent(const QUuid& id, const PointerEvent& event) {
auto keyboard = DependencyManager::get<Keyboard>();
// Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed
if (!keyboard->getKeyIDs().contains(id)) {
auto entity = DependencyManager::get<EntityTreeRenderer>()->getEntity(id);
if (entity && entity->isLocalEntity()) {
emit mouseReleaseOnOverlay(id, event);
}
}
}
void Overlays::mouseMovePointerEvent(const QUuid& id, const PointerEvent& event) {
auto keyboard = DependencyManager::get<Keyboard>();
// Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed
if (!keyboard->getKeyIDs().contains(id)) {
auto entity = DependencyManager::get<EntityTreeRenderer>()->getEntity(id);
if (entity && entity->isLocalEntity()) {
emit mouseMoveOnOverlay(id, event);
}
}
}
void Overlays::hoverEnterPointerEvent(const QUuid& id, const PointerEvent& event) {
auto keyboard = DependencyManager::get<Keyboard>();
// Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed
if (!keyboard->getKeyIDs().contains(id)) {
emit hoverEnterOverlay(id, event);
auto entity = DependencyManager::get<EntityTreeRenderer>()->getEntity(id);
if (entity && entity->isLocalEntity()) {
emit hoverEnterOverlay(id, event);
}
}
}
@ -1264,7 +1275,10 @@ void Overlays::hoverOverPointerEvent(const QUuid& id, const PointerEvent& event)
auto keyboard = DependencyManager::get<Keyboard>();
// Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed
if (!keyboard->getKeyIDs().contains(id)) {
emit hoverOverOverlay(id, event);
auto entity = DependencyManager::get<EntityTreeRenderer>()->getEntity(id);
if (entity && entity->isLocalEntity()) {
emit hoverOverOverlay(id, event);
}
}
}
@ -1272,113 +1286,10 @@ void Overlays::hoverLeavePointerEvent(const QUuid& id, const PointerEvent& event
auto keyboard = DependencyManager::get<Keyboard>();
// Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed
if (!keyboard->getKeyIDs().contains(id)) {
emit hoverLeaveOverlay(id, event);
}
}
std::pair<float, QUuid> Overlays::mousePressEvent(QMouseEvent* event) {
PerformanceTimer perfTimer("Overlays::mousePressEvent");
PickRay ray = qApp->computePickRay(event->x(), event->y());
RayToOverlayIntersectionResult rayPickResult = getPrevPickResult();
if (rayPickResult.intersects) {
_currentClickingOnOverlayID = rayPickResult.overlayID;
PointerEvent pointerEvent = calculateOverlayPointerEvent(_currentClickingOnOverlayID, ray, rayPickResult, event, PointerEvent::Press);
mousePressPointerEvent(_currentClickingOnOverlayID, pointerEvent);
return { rayPickResult.distance, rayPickResult.overlayID };
}
emit mousePressOffOverlay();
return { FLT_MAX, UNKNOWN_ENTITY_ID };
}
void Overlays::mousePressPointerEvent(const QUuid& id, const PointerEvent& event) {
auto keyboard = DependencyManager::get<Keyboard>();
// Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed
if (!keyboard->getKeyIDs().contains(id)) {
emit mousePressOnOverlay(id, event);
}
}
bool Overlays::mouseDoublePressEvent(QMouseEvent* event) {
PerformanceTimer perfTimer("Overlays::mouseDoublePressEvent");
PickRay ray = qApp->computePickRay(event->x(), event->y());
RayToOverlayIntersectionResult rayPickResult = getPrevPickResult();
if (rayPickResult.intersects) {
_currentClickingOnOverlayID = rayPickResult.overlayID;
auto pointerEvent = calculateOverlayPointerEvent(_currentClickingOnOverlayID, ray, rayPickResult, event, PointerEvent::Press);
emit mouseDoublePressOnOverlay(_currentClickingOnOverlayID, pointerEvent);
return true;
}
emit mouseDoublePressOffOverlay();
return false;
}
bool Overlays::mouseReleaseEvent(QMouseEvent* event) {
PerformanceTimer perfTimer("Overlays::mouseReleaseEvent");
PickRay ray = qApp->computePickRay(event->x(), event->y());
RayToOverlayIntersectionResult rayPickResult = getPrevPickResult();
if (rayPickResult.intersects) {
auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Release);
mouseReleasePointerEvent(rayPickResult.overlayID, pointerEvent);
}
_currentClickingOnOverlayID = UNKNOWN_ENTITY_ID;
return false;
}
void Overlays::mouseReleasePointerEvent(const QUuid& id, const PointerEvent& event) {
auto keyboard = DependencyManager::get<Keyboard>();
// Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed
if (!keyboard->getKeyIDs().contains(id)) {
emit mouseReleaseOnOverlay(id, event);
}
}
bool Overlays::mouseMoveEvent(QMouseEvent* event) {
PerformanceTimer perfTimer("Overlays::mouseMoveEvent");
PickRay ray = qApp->computePickRay(event->x(), event->y());
RayToOverlayIntersectionResult rayPickResult = getPrevPickResult();
if (rayPickResult.intersects) {
auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Move);
mouseMovePointerEvent(rayPickResult.overlayID, pointerEvent);
// If previously hovering over a different overlay then leave hover on that overlay.
if (_currentHoverOverOverlayID != UNKNOWN_ENTITY_ID && rayPickResult.overlayID != _currentHoverOverOverlayID) {
auto pointerEvent = calculateOverlayPointerEvent(_currentHoverOverOverlayID, ray, rayPickResult, event, PointerEvent::Move);
hoverLeavePointerEvent(_currentHoverOverOverlayID, pointerEvent);
auto entity = DependencyManager::get<EntityTreeRenderer>()->getEntity(id);
if (entity && entity->isLocalEntity()) {
emit hoverLeaveOverlay(id, event);
}
// If hovering over a new overlay then enter hover on that overlay.
if (rayPickResult.overlayID != _currentHoverOverOverlayID) {
hoverEnterPointerEvent(rayPickResult.overlayID, pointerEvent);
}
// Hover over current overlay.
hoverOverPointerEvent(rayPickResult.overlayID, pointerEvent);
_currentHoverOverOverlayID = rayPickResult.overlayID;
} else {
// If previously hovering an overlay then leave hover.
if (_currentHoverOverOverlayID != UNKNOWN_ENTITY_ID) {
auto pointerEvent = calculateOverlayPointerEvent(_currentHoverOverOverlayID, ray, rayPickResult, event, PointerEvent::Move);
hoverLeavePointerEvent(_currentHoverOverOverlayID, pointerEvent);
_currentHoverOverOverlayID = UNKNOWN_ENTITY_ID;
}
}
return false;
}
void Overlays::mouseMovePointerEvent(const QUuid& id, const PointerEvent& event) {
auto keyboard = DependencyManager::get<Keyboard>();
// Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed
if (!keyboard->getKeyIDs().contains(id)) {
emit mouseMoveOnOverlay(id, event);
}
}

View file

@ -112,11 +112,6 @@ public:
const QVector<EntityItemID>& discard,
bool visibleOnly = false, bool collidableOnly = false);
std::pair<float, QUuid> mousePressEvent(QMouseEvent* event);
bool mouseDoublePressEvent(QMouseEvent* event);
bool mouseReleaseEvent(QMouseEvent* event);
bool mouseMoveEvent(QMouseEvent* event);
void cleanupAllOverlays();
mutable QScriptEngine _scriptEngine;
@ -719,9 +714,6 @@ private:
PointerEvent calculateOverlayPointerEvent(const QUuid& id, const PickRay& ray, const RayToOverlayIntersectionResult& rayPickResult,
QMouseEvent* event, PointerEvent::EventType eventType);
QUuid _currentClickingOnOverlayID;
QUuid _currentHoverOverOverlayID;
static QString entityToOverlayType(const QString& type);
static QString overlayToEntityType(const QString& type);
static std::unordered_map<QString, QString> _entityToOverlayTypes;
@ -732,12 +724,17 @@ private:
EntityItemProperties convertOverlayToEntityProperties(QVariantMap& overlayProps, std::pair<glm::quat, bool>& rotationToSave, const QString& type, bool add, const QUuid& id = QUuid());
private slots:
void mousePressPointerEvent(const QUuid& id, const PointerEvent& event);
void mouseMovePointerEvent(const QUuid& id, const PointerEvent& event);
void mousePressOnPointerEvent(const QUuid& id, const PointerEvent& event);
void mousePressOffPointerEvent();
void mouseDoublePressOnPointerEvent(const QUuid& id, const PointerEvent& event);
void mouseDoublePressOffPointerEvent();
void mouseReleasePointerEvent(const QUuid& id, const PointerEvent& event);
void mouseMovePointerEvent(const QUuid& id, const PointerEvent& event);
void hoverEnterPointerEvent(const QUuid& id, const PointerEvent& event);
void hoverOverPointerEvent(const QUuid& id, const PointerEvent& event);
void hoverLeavePointerEvent(const QUuid& id, const PointerEvent& event);
};
#define ADD_TYPE_MAP(entity, overlay) \

View file

@ -73,14 +73,14 @@ EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterf
_currentHoverOverEntityID = UNKNOWN_ENTITY_ID;
_currentClickingOnEntityID = UNKNOWN_ENTITY_ID;
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>().data();
auto pointerManager = DependencyManager::get<PointerManager>();
connect(pointerManager.data(), &PointerManager::hoverBeginEntity, entityScriptingInterface.data(), &EntityScriptingInterface::hoverEnterEntity);
connect(pointerManager.data(), &PointerManager::hoverContinueEntity, entityScriptingInterface.data(), &EntityScriptingInterface::hoverOverEntity);
connect(pointerManager.data(), &PointerManager::hoverEndEntity, entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity);
connect(pointerManager.data(), &PointerManager::triggerBeginEntity, entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity);
connect(pointerManager.data(), &PointerManager::triggerContinueEntity, entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity);
connect(pointerManager.data(), &PointerManager::triggerEndEntity, entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity);
connect(pointerManager.data(), &PointerManager::hoverBeginEntity, entityScriptingInterface, &EntityScriptingInterface::hoverEnterEntity);
connect(pointerManager.data(), &PointerManager::hoverContinueEntity, entityScriptingInterface, &EntityScriptingInterface::hoverOverEntity);
connect(pointerManager.data(), &PointerManager::hoverEndEntity, entityScriptingInterface, &EntityScriptingInterface::hoverLeaveEntity);
connect(pointerManager.data(), &PointerManager::triggerBeginEntity, entityScriptingInterface, &EntityScriptingInterface::mousePressOnEntity);
connect(pointerManager.data(), &PointerManager::triggerContinueEntity, entityScriptingInterface, &EntityScriptingInterface::mouseMoveOnEntity);
connect(pointerManager.data(), &PointerManager::triggerEndEntity, entityScriptingInterface, &EntityScriptingInterface::mouseReleaseOnEntity);
// Forward mouse events to web entities
auto handlePointerEvent = [&](const QUuid& entityID, const PointerEvent& event) {
@ -93,10 +93,10 @@ EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterf
QMetaObject::invokeMethod(thisEntity.get(), "handlePointerEvent", Q_ARG(const PointerEvent&, event));
}
};
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, this, handlePointerEvent);
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity, this, handlePointerEvent);
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity, this, handlePointerEvent);
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverEnterEntity, this, [&](const QUuid& entityID, const PointerEvent& event) {
connect(entityScriptingInterface, &EntityScriptingInterface::mousePressOnEntity, this, handlePointerEvent);
connect(entityScriptingInterface, &EntityScriptingInterface::mouseMoveOnEntity, this, handlePointerEvent);
connect(entityScriptingInterface, &EntityScriptingInterface::mouseReleaseOnEntity, this, handlePointerEvent);
connect(entityScriptingInterface, &EntityScriptingInterface::hoverEnterEntity, this, [&](const QUuid& entityID, const PointerEvent& event) {
std::shared_ptr<render::entities::WebEntityRenderer> thisEntity;
auto entity = getEntity(entityID);
if (entity && entity->isVisible() && entity->getType() == EntityTypes::Web) {
@ -106,8 +106,8 @@ EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterf
QMetaObject::invokeMethod(thisEntity.get(), "hoverEnterEntity", Q_ARG(const PointerEvent&, event));
}
});
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverOverEntity, this, handlePointerEvent);
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, this, [&](const QUuid& entityID, const PointerEvent& event) {
connect(entityScriptingInterface, &EntityScriptingInterface::hoverOverEntity, this, handlePointerEvent);
connect(entityScriptingInterface, &EntityScriptingInterface::hoverLeaveEntity, this, [&](const QUuid& entityID, const PointerEvent& event) {
std::shared_ptr<render::entities::WebEntityRenderer> thisEntity;
auto entity = getEntity(entityID);
if (entity && entity->isVisible() && entity->getType() == EntityTypes::Web) {
@ -792,11 +792,11 @@ static PointerEvent::Button toPointerButton(const QMouseEvent& event) {
}
}
std::pair<float, QUuid> EntityTreeRenderer::mousePressEvent(QMouseEvent* event) {
QUuid EntityTreeRenderer::mousePressEvent(QMouseEvent* event) {
// If we don't have a tree, or we're in the process of shutting down, then don't
// process these events.
if (!_tree || _shuttingDown) {
return { FLT_MAX, UNKNOWN_ENTITY_ID };
return UNKNOWN_ENTITY_ID;
}
PerformanceTimer perfTimer("EntityTreeRenderer::mousePressEvent");
@ -805,11 +805,13 @@ std::pair<float, QUuid> EntityTreeRenderer::mousePressEvent(QMouseEvent* event)
RayToEntityIntersectionResult rayPickResult = _getPrevRayPickResultOperator(_mouseRayPickID);
EntityItemPointer entity;
if (rayPickResult.intersects && (entity = getTree()->findEntityByID(rayPickResult.entityID))) {
auto properties = entity->getProperties();
QString urlString = properties.getHref();
QUrl url = QUrl(urlString, QUrl::StrictMode);
if (url.isValid() && !url.isEmpty()){
DependencyManager::get<AddressManager>()->handleLookupString(urlString);
if (!EntityTree::areEntityClicksCaptured()) {
auto properties = entity->getProperties();
QString urlString = properties.getHref();
QUrl url = QUrl(urlString, QUrl::StrictMode);
if (url.isValid() && !url.isEmpty()) {
DependencyManager::get<AddressManager>()->handleLookupString(urlString);
}
}
glm::vec2 pos2D = projectOntoEntityXYPlane(entity, ray, rayPickResult);
@ -827,10 +829,10 @@ std::pair<float, QUuid> EntityTreeRenderer::mousePressEvent(QMouseEvent* event)
_lastPointerEvent = pointerEvent;
_lastPointerEventValid = true;
return { rayPickResult.distance, rayPickResult.entityID };
return rayPickResult.entityID;
}
emit entityScriptingInterface->mousePressOffEntity();
return { FLT_MAX, UNKNOWN_ENTITY_ID };
return UNKNOWN_ENTITY_ID;
}
void EntityTreeRenderer::mouseDoublePressEvent(QMouseEvent* event) {

View file

@ -94,7 +94,7 @@ public:
void reloadEntityScripts();
// event handles which may generate entity related events
std::pair<float, QUuid> mousePressEvent(QMouseEvent* event);
QUuid mousePressEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
void mouseDoublePressEvent(QMouseEvent* event);
void mouseMoveEvent(QMouseEvent* event);

View file

@ -2972,6 +2972,7 @@ QStringList EntityTree::getJointNames(const QUuid& entityID) const {
std::function<QObject*(const QUuid&)> EntityTree::_getEntityObjectOperator = nullptr;
std::function<QSizeF(const QUuid&, const QString&)> EntityTree::_textSizeOperator = nullptr;
std::function<bool()> EntityTree::_areEntityClicksCapturedOperator = nullptr;
QObject* EntityTree::getEntityObject(const QUuid& id) {
if (_getEntityObjectOperator) {
@ -2987,6 +2988,13 @@ QSizeF EntityTree::textSize(const QUuid& id, const QString& text) {
return QSizeF(0.0f, 0.0f);
}
bool EntityTree::areEntityClicksCaptured() {
if (_areEntityClicksCapturedOperator) {
return _areEntityClicksCapturedOperator();
}
return false;
}
void EntityTree::updateEntityQueryAACubeWorker(SpatiallyNestablePointer object, EntityEditPacketSender* packetSender,
MovingEntitiesOperator& moveOperator, bool force, bool tellServer) {
// if the queryBox has changed, tell the entity-server

View file

@ -268,6 +268,9 @@ public:
static void setTextSizeOperator(std::function<QSizeF(const QUuid&, const QString&)> textSizeOperator) { _textSizeOperator = textSizeOperator; }
static QSizeF textSize(const QUuid& id, const QString& text);
static void setEntityClicksCapturedOperator(std::function<bool()> areEntityClicksCapturedOperator) { _areEntityClicksCapturedOperator = areEntityClicksCapturedOperator; }
static bool areEntityClicksCaptured();
std::map<QString, QString> getNamedPaths() const { return _namedPaths; }
void updateEntityQueryAACube(SpatiallyNestablePointer object, EntityEditPacketSender* packetSender,
@ -378,6 +381,7 @@ private:
static std::function<QObject*(const QUuid&)> _getEntityObjectOperator;
static std::function<QSizeF(const QUuid&, const QString&)> _textSizeOperator;
static std::function<bool()> _areEntityClicksCapturedOperator;
std::vector<int32_t> _staleProxies;

View file

@ -976,7 +976,9 @@ void ScriptEngine::addEventHandler(const EntityItemID& entityID, const QString&
using PointerHandler = std::function<void(const EntityItemID&, const PointerEvent&)>;
auto makePointerHandler = [this](QString eventName) -> PointerHandler {
return [this, eventName](const EntityItemID& entityItemID, const PointerEvent& event) {
forwardHandlerCall(entityItemID, eventName, { entityItemID.toScriptValue(this), event.toScriptValue(this) });
if (!EntityTree::areEntityClicksCaptured()) {
forwardHandlerCall(entityItemID, eventName, { entityItemID.toScriptValue(this), event.toScriptValue(this) });
}
};
};