simplify keyboard focus highlight

This commit is contained in:
SamGondelman 2019-01-26 22:49:12 -08:00
parent 8f0bd2449b
commit 0dd729232b
6 changed files with 36 additions and 151 deletions

View file

@ -1874,23 +1874,12 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
// If the user clicks an an entity, we will check that it's an unlocked web entity, and if so, set the focus to it
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity,
[this](const EntityItemID& entityItemID, const PointerEvent& event) {
if (event.shouldFocus()) {
if (getEntities()->wantsKeyboardFocus(entityItemID)) {
setKeyboardFocusLocalEntity(UNKNOWN_ENTITY_ID);
setKeyboardFocusEntity(entityItemID);
} else {
setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
}
}
});
connect(&_overlays, &Overlays::mousePressOnOverlay, [this](const QUuid& id, const PointerEvent& event) {
[this](const QUuid& id, const PointerEvent& event) {
if (event.shouldFocus()) {
if (getEntities()->wantsKeyboardFocus(id)) {
setKeyboardFocusLocalEntity(id);
setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
setKeyboardFocusEntity(id);
} else {
setKeyboardFocusLocalEntity(UNKNOWN_ENTITY_ID);
setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
}
}
});
@ -1971,13 +1960,12 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
// Keyboard focus handling for local Web entities.
connect(&qApp->getOverlays(), &Overlays::overlayDeleted, [this](const QUuid& id) {
if (id == _keyboardFocusedLocalEntity.get()) {
setKeyboardFocusLocalEntity(UNKNOWN_ENTITY_ID);
if (id == _keyboardFocusedEntity.get()) {
setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
}
});
connect(this, &Application::aboutToQuit, [this]() {
setKeyboardFocusLocalEntity(UNKNOWN_ENTITY_ID);
setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
});
@ -3801,27 +3789,6 @@ bool Application::handleKeyEventForFocusedEntity(QEvent* event) {
}
}
if (!_keyboardFocusedLocalEntity.get().isInvalidID()) {
switch (event->type()) {
case QEvent::KeyPress:
case QEvent::KeyRelease: {
auto eventHandler = getEntities()->getEventHandler(_keyboardFocusedEntity.get());
if (eventHandler) {
event->setAccepted(false);
QCoreApplication::sendEvent(eventHandler, event);
if (event->isAccepted()) {
_lastAcceptedKeyPress = usecTimestampNow();
return true;
}
}
}
break;
default:
break;
}
}
return false;
}
@ -4332,8 +4299,8 @@ void Application::mouseMoveEvent(QMouseEvent* event) {
if (compositor.getReticleVisible() || !isHMDMode() || !compositor.getReticleOverDesktop() ||
!getOverlays().getOverlayAtPoint(glm::vec2(transformedPos.x(), transformedPos.y())).isNull()) {
getOverlays().mouseMoveEvent(&mappedEvent);
getEntities()->mouseMoveEvent(&mappedEvent);
getOverlays().mouseMoveEvent(&mappedEvent);
}
_controllerScriptingInterface->emitMouseMoveEvent(&mappedEvent); // send events to any registered scripts
@ -4370,10 +4337,10 @@ void Application::mousePressEvent(QMouseEvent* event) {
event->screenPos(), event->button(),
event->buttons(), event->modifiers());
getOverlays().mousePressEvent(&mappedEvent);
if (!_controllerScriptingInterface->areEntityClicksCaptured()) {
getEntities()->mousePressEvent(&mappedEvent);
}
getOverlays().mousePressEvent(&mappedEvent);
_controllerScriptingInterface->emitMousePressEvent(&mappedEvent); // send events to any registered scripts
@ -4413,10 +4380,10 @@ void Application::mouseDoublePressEvent(QMouseEvent* event) {
event->screenPos(), event->button(),
event->buttons(), event->modifiers());
getOverlays().mouseDoublePressEvent(&mappedEvent);
if (!_controllerScriptingInterface->areEntityClicksCaptured()) {
getEntities()->mouseDoublePressEvent(&mappedEvent);
}
getOverlays().mouseDoublePressEvent(&mappedEvent);
// if one of our scripts have asked to capture this event, then stop processing it
if (_controllerScriptingInterface->isMouseCaptured()) {
@ -4440,8 +4407,8 @@ void Application::mouseReleaseEvent(QMouseEvent* event) {
event->screenPos(), event->button(),
event->buttons(), event->modifiers());
getOverlays().mouseReleaseEvent(&mappedEvent);
getEntities()->mouseReleaseEvent(&mappedEvent);
getOverlays().mouseReleaseEvent(&mappedEvent);
_controllerScriptingInterface->emitMouseReleaseEvent(&mappedEvent); // send events to any registered scripts
@ -4902,12 +4869,11 @@ void Application::idle() {
// Update focus highlight for entities
{
if (!_keyboardFocusedEntity.get().isInvalidID() || !_keyboardFocusedLocalEntity.get().isInvalidID()) {
if (!_keyboardFocusedEntity.get().isInvalidID()) {
const quint64 LOSE_FOCUS_AFTER_ELAPSED_TIME = 30 * USECS_PER_SECOND; // if idle for 30 seconds, drop focus
quint64 elapsedSinceAcceptedKeyPress = usecTimestampNow() - _lastAcceptedKeyPress;
if (elapsedSinceAcceptedKeyPress > LOSE_FOCUS_AFTER_ELAPSED_TIME) {
setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
setKeyboardFocusLocalEntity(UNKNOWN_ENTITY_ID);
} else {
// update position of highlight object
if (!_keyboardFocusedEntity.get().isInvalidID()) {
@ -4918,14 +4884,6 @@ void Application::idle() {
properties.setRotation(entity->getWorldOrientation());
DependencyManager::get<EntityScriptingInterface>()->editEntity(_keyboardFocusHighlightID, properties);
}
} else {
auto entity = getEntities()->getTree()->findEntityByID(_keyboardFocusedEntity.get());
if (entity && !_keyboardFocusHighlightID.isNull()) {
EntityItemProperties properties;
properties.setPosition(entity->getWorldPosition());
properties.setRotation(entity->getWorldOrientation());
DependencyManager::get<EntityScriptingInterface>()->editEntity(_keyboardFocusHighlightID, properties);
}
}
}
}
@ -5758,10 +5716,16 @@ QUuid Application::getKeyboardFocusEntity() const {
static const float FOCUS_HIGHLIGHT_EXPANSION_FACTOR = 1.05f;
void Application::setKeyboardFocusEntity(const EntityItemID& entityItemID) {
if (qApp->getLoginDialogPoppedUp()) {
return;
}
if (_keyboardFocusedEntity.get() != entityItemID) {
if (qApp->getLoginDialogPoppedUp() && !_loginDialogID.isNull()) {
if (entityItemID == _loginDialogID) {
emit loginDialogFocusEnabled();
} else {
// that's the only entity we want in focus;
return;
}
}
_keyboardFocusedEntity.set(entityItemID);
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
@ -5793,52 +5757,6 @@ void Application::setKeyboardFocusEntity(const EntityItemID& entityItemID) {
}
}
EntityItemID Application::getKeyboardFocusLocalEntity() {
return _keyboardFocusedLocalEntity.get();
}
void Application::setKeyboardFocusLocalEntity(const EntityItemID& entityItemID) {
if (entityItemID != _keyboardFocusedLocalEntity.get()) {
if (qApp->getLoginDialogPoppedUp() && !_loginDialogID.isNull()) {
if (entityItemID == _loginDialogID) {
emit loginDialogFocusEnabled();
} else {
// that's the only entity we want in focus;
return;
}
}
_keyboardFocusedLocalEntity.set(entityItemID);
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
if (entityItemID == UNKNOWN_ENTITY_ID) {
EntityItemProperties properties;
properties.setVisible(false);
entityScriptingInterface->editEntity(_keyboardFocusHighlightID, properties);
return;
}
auto properties = entityScriptingInterface->getEntityProperties(entityItemID);
if (!properties.getLocked() && properties.getVisible()) {
auto entities = getEntities();
auto entityId = _keyboardFocusedLocalEntity.get();
if (entities->wantsKeyboardFocus(entityId)) {
entities->setProxyWindow(entityId, _window->windowHandle());
if (_keyboardMouseDevice->isActive()) {
_keyboardMouseDevice->pluginFocusOutEvent();
}
_lastAcceptedKeyPress = usecTimestampNow();
auto entity = getEntities()->getEntity(entityId);
if (entity) {
setKeyboardFocusHighlight(entity->getWorldPosition(), entity->getWorldOrientation(),
entity->getScaledDimensions() * FOCUS_HIGHLIGHT_EXPANSION_FACTOR);
}
}
}
}
}
void Application::updateDialogs(float deltaTime) const {
PerformanceTimer perfTimer("updateDialogs");
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
@ -8784,7 +8702,7 @@ void Application::createLoginDialog() {
entityScriptingInterface->editEntity(keyboard->getAnchorID(), properties);
keyboard->setResetKeyboardPositionOnRaise(false);
}
setKeyboardFocusLocalEntity(_loginDialogID);
setKeyboardFocusEntity(_loginDialogID);
emit loginDialogFocusEnabled();
getApplicationCompositor().getReticleInterface()->setAllowMouseCapture(false);
getApplicationCompositor().getReticleInterface()->setVisible(false);

View file

@ -439,9 +439,6 @@ public slots:
QUuid getKeyboardFocusEntity() const; // thread-safe
void setKeyboardFocusEntity(const EntityItemID& entityItemID);
EntityItemID getKeyboardFocusLocalEntity();
void setKeyboardFocusLocalEntity(const EntityItemID& id);
void addAssetToWorldMessageClose();
void loadLODToolsDialog();
@ -720,7 +717,6 @@ private:
DialogsManagerScriptingInterface* _dialogsManagerScriptingInterface = new DialogsManagerScriptingInterface();
ThreadSafeValueCache<EntityItemID> _keyboardFocusedEntity;
ThreadSafeValueCache<EntityItemID> _keyboardFocusedLocalEntity;
quint64 _lastAcceptedKeyPress = 0;
bool _isForeground = true; // starts out assumed to be in foreground
bool _isGLInitialized { false };

View file

@ -57,7 +57,7 @@ void DialogsManager::showAddressBar() {
if (!hmd->getShouldShowTablet()) {
hmd->openTablet();
}
qApp->setKeyboardFocusLocalEntity(hmd->getCurrentTabletScreenID());
qApp->setKeyboardFocusEntity(hmd->getCurrentTabletScreenID());
setAddressBarVisible(true);
}
@ -70,7 +70,7 @@ void DialogsManager::hideAddressBar() {
tablet->gotoHomeScreen();
hmd->closeTablet();
}
qApp->setKeyboardFocusLocalEntity(UNKNOWN_ENTITY_ID);
qApp->setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
setAddressBarVisible(false);
}

View file

@ -75,8 +75,8 @@ public:
* @hifi-interface
* @hifi-client-entity
*
* @property {Uuid} keyboardFocusOverlay - Get or set the {@link Entities.EntityTypes|Web} local entity that has keyboard focus.
* If no local entity has keyboard focus, get returns <code>null</code>; set to <code>null</code> or {@link Uuid|Uuid.NULL} to
* @property {Uuid} keyboardFocusOverlay - Get or set the {@link Entities.EntityTypes|Web} entity that has keyboard focus.
* If no entity has keyboard focus, get returns <code>null</code>; set to <code>null</code> or {@link Uuid|Uuid.NULL} to
* clear keyboard focus.
*/
@ -552,20 +552,20 @@ public slots:
void sendHoverLeaveOverlay(const QUuid& id, const PointerEvent& event);
/**jsdoc
* Get the ID of the Web3D local entity that has keyboard focus.
* Get the ID of the Web3D entity that has keyboard focus.
* @function Overlays.getKeyboardFocusOverlay
* @returns {Uuid} The ID of the {@link Entities.EntityTypes|Web} overlay that has focus, if any, otherwise
* <code>null</code>.
*/
EntityItemID getKeyboardFocusOverlay() { return DependencyManager::get<EntityScriptingInterface>()->getKeyboardFocusLocalEntity(); }
QUuid getKeyboardFocusOverlay() { return DependencyManager::get<EntityScriptingInterface>()->getKeyboardFocusEntity(); }
/**jsdoc
* Set the Web3D local entity that has keyboard focus.
* Set the Web3D entity that has keyboard focus.
* @function Overlays.setKeyboardFocusOverlay
* @param {Uuid} id - The ID of the {@link Entities.EntityTypes|Web} overlay to set keyboard focus to. Use
* @param {Uuid} id - The ID of the {@link Entities.EntityTypes|Web} entity to set keyboard focus to. Use
* <code>null</code> or {@link Uuid|Uuid.NULL} to unset keyboard focus from an overlay.
*/
void setKeyboardFocusOverlay(const EntityItemID& id) { DependencyManager::get<EntityScriptingInterface>()->setKeyboardFocusLocalEntity(id); }
void setKeyboardFocusOverlay(const QUuid& id) { DependencyManager::get<EntityScriptingInterface>()->setKeyboardFocusEntity(id); }
signals:
/**jsdoc

View file

@ -58,7 +58,7 @@ EntityScriptingInterface::EntityScriptingInterface(bool bidOnSimulationOwnership
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, [=]() {
connect(this, &EntityScriptingInterface::mousePressOffEntity, [this]() {
setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
});
@ -2160,18 +2160,8 @@ QUuid EntityScriptingInterface::getKeyboardFocusEntity() const {
return result;
}
void EntityScriptingInterface::setKeyboardFocusEntity(const EntityItemID& id) {
QMetaObject::invokeMethod(qApp, "setKeyboardFocusEntity", Qt::DirectConnection, Q_ARG(EntityItemID, id));
}
QUuid EntityScriptingInterface::getKeyboardFocusLocalEntity() const {
QUuid result;
QMetaObject::invokeMethod(qApp, "getKeyboardFocusLocalEntity", Qt::DirectConnection, Q_RETURN_ARG(QUuid, result));
return result;
}
void EntityScriptingInterface::setKeyboardFocusLocalEntity(const EntityItemID& id) {
QMetaObject::invokeMethod(qApp, "setKeyboardFocusLocalEntity", Qt::DirectConnection, Q_ARG(EntityItemID, id));
void EntityScriptingInterface::setKeyboardFocusEntity(const QUuid& id) {
QMetaObject::invokeMethod(qApp, "setKeyboardFocusEntity", Qt::DirectConnection, Q_ARG(const QUuid&, id));
}
void EntityScriptingInterface::sendMousePressOnEntity(const EntityItemID& id, const PointerEvent& event) {

View file

@ -115,15 +115,11 @@ public:
* @property {Uuid} keyboardFocusEntity - Get or set the {@link Entities.EntityType|Web} entity that has keyboard focus.
* If no entity has keyboard focus, get returns <code>null</code>; set to <code>null</code> or {@link Uuid|Uuid.NULL} to
* clear keyboard focus.
* @property {Uuid} keyboardFocusLocalEntity - Get or set the {@link Entities.EntityType|Web} local entity that has keyboard focus.
* If no local entity has keyboard focus, get returns <code>null</code>; set to <code>null</code> or {@link Uuid|Uuid.NULL} to
* clear keyboard focus.
*/
/// handles scripting of Entity commands from JS passed to assigned clients
class EntityScriptingInterface : public OctreeScriptingInterface, public Dependency {
Q_OBJECT
Q_PROPERTY(QUuid keyboardFocusEntity READ getKeyboardFocusEntity WRITE setKeyboardFocusEntity)
Q_PROPERTY(QUuid keyboardFocusLocalEntity READ getKeyboardFocusLocalEntity WRITE setKeyboardFocusLocalEntity)
friend EntityPropertyMetadataRequest;
public:
@ -1415,7 +1411,7 @@ public slots:
/**jsdoc
* Get the type &mdash; entity or avatar &mdash; of an in-world item.
* @function Entities.getNestableType
* @param {Uuid} entityID - The ID of the item to get the type of.
* @param {Uuid} id - The ID of the item to get the type of.
* @returns {string} The type of the item: <code>"entity"</code> if the item is an entity, <code>"avatar"</code>
* if the item is an avatar; otherwise <code>"unknown"</code> if the item cannot be found.
* @example <caption>Print some nestable types.</caption>
@ -1428,7 +1424,7 @@ public slots:
* print(Entities.getNestableType(entity)); // "entity"
* print(Entities.getNestableType(Uuid.generate())); // "unknown"
*/
Q_INVOKABLE QString getNestableType(const QUuid& entityID);
Q_INVOKABLE QString getNestableType(const QUuid& id);
/**jsdoc
* Get the ID of the {@link Entities.EntityType|Web} entity that has keyboard focus.
@ -1440,25 +1436,10 @@ public slots:
/**jsdoc
* Set the {@link Entities.EntityType|Web} entity that has keyboard focus.
* @function Entities.setKeyboardFocusEntity
* @param {Uuid} entityID - The ID of the {@link Entities.EntityType|Web} entity to set keyboard focus to. Use
* @param {Uuid} id - The ID of the {@link Entities.EntityType|Web} entity to set keyboard focus to. Use
* <code>null</code> or {@link Uuid|Uuid.NULL} to unset keyboard focus from an entity.
*/
Q_INVOKABLE void setKeyboardFocusEntity(const EntityItemID& id);
/**jsdoc
* Get the ID of the {@link Entities.EntityType|Web} local entity that has keyboard focus.
* @function Entities.getKeyboardFocusEntity
* @returns {Uuid} The ID of the {@link Entities.EntityType|Web} local entity that has focus, if any, otherwise <code>null</code>.
*/
Q_INVOKABLE QUuid getKeyboardFocusLocalEntity() const;
/**jsdoc
* Set the {@link Entities.EntityType|Web} local entity that has keyboard focus.
* @function Entities.setKeyboardFocusEntity
* @param {Uuid} entityID - The ID of the {@link Entities.EntityType|Web} local entity to set keyboard focus to. Use
* <code>null</code> or {@link Uuid|Uuid.NULL} to unset keyboard focus from an entity.
*/
Q_INVOKABLE void setKeyboardFocusLocalEntity(const EntityItemID& id);
Q_INVOKABLE void setKeyboardFocusEntity(const QUuid& id);
/**jsdoc
* Emit a {@link Entities.mousePressOnEntity|mousePressOnEntity} event.