From c6df5739337fb4938b77260879a37ec7768d3aa0 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 26 Jun 2015 10:50:31 -0700 Subject: [PATCH 1/5] fix some OS X warnings, add description to tooltip --- interface/resources/qml/Tooltip.qml | 12 ++-- interface/src/avatar/AvatarManager.cpp | 28 ++++---- interface/src/ui/ApplicationCompositor.cpp | 72 +++++++++++-------- interface/src/ui/ApplicationCompositor.h | 11 +-- interface/src/ui/LogDialog.cpp | 4 +- .../src/RenderablePolyVoxEntityItem.cpp | 6 +- libraries/render-utils/src/ProgramObject.h | 4 +- libraries/shared/src/GLMHelpers.h | 4 +- libraries/ui/src/Tooltip.cpp | 32 ++++++--- libraries/ui/src/Tooltip.h | 17 +++-- 10 files changed, 113 insertions(+), 77 deletions(-) diff --git a/interface/resources/qml/Tooltip.qml b/interface/resources/qml/Tooltip.qml index 169e5fe211..1a551a4cae 100644 --- a/interface/resources/qml/Tooltip.qml +++ b/interface/resources/qml/Tooltip.qml @@ -18,7 +18,7 @@ Hifi.Tooltip { offsetX = (lastMousePosition.x > surfaceSize.width/2) ? -root.width : 0 offsetY = (lastMousePosition.y > surfaceSize.height/2) ? -root.height : 0 } - + Rectangle { id: border color: "#7f000000" @@ -42,10 +42,10 @@ Hifi.Tooltip { anchors.left: parent.left anchors.right: parent.right font.pixelSize: hifi.fonts.pixelSize / 2 - text: root.text + text: root.title wrapMode: Text.WrapAnywhere - - /* Uncomment for debugging to see the extent of the + + /* Uncomment for debugging to see the extent of the Rectangle { anchors.fill: parent color: "#7fff00ff" @@ -68,9 +68,9 @@ Hifi.Tooltip { anchors.left: parent.left anchors.right: parent.right font.pixelSize: hifi.fonts.pixelSize / 2 - text: root.text + text: root.description wrapMode: Text.WrapAnywhere } } } -} \ No newline at end of file +} diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 88f550d68c..25f768d037 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -13,14 +13,14 @@ #include -#ifdef __GNUC__ +#if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdouble-promotion" #endif #include -#ifdef __GNUC__ +#if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic pop #endif @@ -74,19 +74,19 @@ void AvatarManager::init() { render::ScenePointer scene = Application::getInstance()->getMain3DScene(); render::PendingChanges pendingChanges; - _myAvatar->addToScene(_myAvatar, scene, pendingChanges); + _myAvatar->addToScene(_myAvatar, scene, pendingChanges); scene->enqueuePendingChanges(pendingChanges); } void AvatarManager::updateMyAvatar(float deltaTime) { bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "AvatarManager::updateMyAvatar()"); - + _myAvatar->update(deltaTime); - + quint64 now = usecTimestampNow(); quint64 dt = now - _lastSendAvatarDataTime; - + if (dt > MIN_TIME_BETWEEN_MY_AVATAR_DATA_SENDS) { // send head/hand data to the avatar mixer and voxel server PerformanceTimer perfTimer("send"); @@ -103,12 +103,12 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { PerformanceWarning warn(showWarnings, "Application::updateAvatars()"); PerformanceTimer perfTimer("otherAvatars"); - + // simulate avatars AvatarHash::iterator avatarIterator = _avatarHash.begin(); while (avatarIterator != _avatarHash.end()) { auto avatar = std::dynamic_pointer_cast(avatarIterator.value()); - + if (avatar == _myAvatar || !avatar->isInitialized()) { // DO NOT update _myAvatar! Its update has already been done earlier in the main loop. // DO NOT update or fade out uninitialized Avatars @@ -122,17 +122,17 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { ++avatarIterator; } } - + // simulate avatar fades simulateAvatarFades(deltaTime); } void AvatarManager::simulateAvatarFades(float deltaTime) { QVector::iterator fadingIterator = _avatarFades.begin(); - + const float SHRINK_RATE = 0.9f; const float MIN_FADE_SCALE = 0.001f; - + render::ScenePointer scene = Application::getInstance()->getMain3DScene(); render::PendingChanges pendingChanges; while (fadingIterator != _avatarFades.end()) { @@ -153,12 +153,12 @@ AvatarSharedPointer AvatarManager::newSharedAvatar() { return AvatarSharedPointer(std::make_shared()); } -// virtual +// virtual AvatarSharedPointer AvatarManager::addAvatar(const QUuid& sessionUUID, const QWeakPointer& mixerWeakPointer) { auto avatar = std::dynamic_pointer_cast(AvatarHashMap::addAvatar(sessionUUID, mixerWeakPointer)); render::ScenePointer scene = Application::getInstance()->getMain3DScene(); render::PendingChanges pendingChanges; - avatar->addToScene(avatar, scene, pendingChanges); + avatar->addToScene(avatar, scene, pendingChanges); scene->enqueuePendingChanges(pendingChanges); return avatar; } @@ -177,7 +177,7 @@ void AvatarManager::removeAvatarMotionState(AvatarSharedPointer avatar) { } } -// virtual +// virtual void AvatarManager::removeAvatar(const QUuid& sessionUUID) { AvatarHash::iterator avatarIterator = _avatarHash.find(sessionUUID); if (avatarIterator != _avatarHash.end()) { diff --git a/interface/src/ui/ApplicationCompositor.cpp b/interface/src/ui/ApplicationCompositor.cpp index 7b55de6dd8..d37a47a4ba 100644 --- a/interface/src/ui/ApplicationCompositor.cpp +++ b/interface/src/ui/ApplicationCompositor.cpp @@ -117,7 +117,7 @@ ApplicationCompositor::ApplicationCompositor() { memset(_magSizeMult, 0, sizeof(_magSizeMult)); auto geometryCache = DependencyManager::get(); - + _reticleQuad = geometryCache->allocateID(); _magnifierQuad = geometryCache->allocateID(); _magnifierBorder = geometryCache->allocateID(); @@ -128,9 +128,22 @@ ApplicationCompositor::ApplicationCompositor() { _hoverItemId = entityItemID; _hoverItemEnterUsecs = usecTimestampNow(); auto properties = entityScriptingInterface->getEntityProperties(_hoverItemId); - _hoverItemHref = properties.getHref(); + + // check the format of this href string before we parse it + QString hrefString = properties.getHref(); + if (!hrefString.startsWith("hifi:")) { + hrefString.prepend("hifi://"); + } + + // parse out a QUrl from the hrefString + QUrl href = QUrl(hrefString); + + _hoverItemTitle = href.host(); + _hoverItemDescription = properties.getDescription(); + auto cursor = Cursor::Manager::instance().getCursor(); - if (!_hoverItemHref.isEmpty()) { + + if (!href.isEmpty()) { cursor->setIcon(Cursor::Icon::LINK); } else { cursor->setIcon(Cursor::Icon::DEFAULT); @@ -141,7 +154,10 @@ ApplicationCompositor::ApplicationCompositor() { connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, [=](const EntityItemID& entityItemID, const MouseEvent& event) { if (_hoverItemId == entityItemID) { _hoverItemId = _noItemId; - _hoverItemHref.clear(); + + _hoverItemTitle.clear(); + _hoverItemDescription.clear(); + auto cursor = Cursor::Manager::instance().getCursor(); cursor->setIcon(Cursor::Icon::DEFAULT); if (!_tooltipId.isEmpty()) { @@ -314,7 +330,7 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int batch.setModelTransform(reticleXfm); geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad); } - + renderArgs->_context->render(batch); } @@ -324,7 +340,7 @@ void ApplicationCompositor::computeHmdPickRay(glm::vec2 cursorPos, glm::vec3& or const glm::vec2 projection = screenToSpherical(cursorPos); // The overlay space orientation of the mouse coordinates const glm::quat orientation(glm::vec3(-projection.y, projection.x, 0.0f)); - // FIXME We now have the direction of the ray FROM THE DEFAULT HEAD POSE. + // FIXME We now have the direction of the ray FROM THE DEFAULT HEAD POSE. // Now we need to account for the actual camera position relative to the overlay glm::vec3 overlaySpaceDirection = glm::normalize(orientation * IDENTITY_FRONT); @@ -377,7 +393,7 @@ QPoint ApplicationCompositor::getPalmClickLocation(const PalmData *palm) const { //Finds the collision point of a world space ray bool ApplicationCompositor::calculateRayUICollisionPoint(const glm::vec3& position, const glm::vec3& direction, glm::vec3& result) const { MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); - + glm::quat inverseOrientation = glm::inverse(myAvatar->getOrientation()); glm::vec3 relativePosition = inverseOrientation * (position - myAvatar->getDefaultEyePosition()); @@ -409,7 +425,7 @@ void ApplicationCompositor::renderPointers(gpu::Batch& batch) { renderControllerPointers(batch); } } - + void ApplicationCompositor::renderControllerPointers(gpu::Batch& batch) { MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); @@ -517,7 +533,7 @@ void ApplicationCompositor::renderControllerPointers(gpu::Batch& batch) { DependencyManager::get()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, glm::vec4(RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2], 1.0f)); - + } } @@ -527,10 +543,10 @@ void ApplicationCompositor::renderMagnifier(gpu::Batch& batch, const glm::vec2& return; } auto canvasSize = qApp->getCanvasSize(); - + const int widgetWidth = canvasSize.x; const int widgetHeight = canvasSize.y; - + const float halfWidth = (MAGNIFY_WIDTH / _textureAspectRatio) * sizeMult / 2.0f; const float halfHeight = MAGNIFY_HEIGHT * sizeMult / 2.0f; // Magnification Texture Coordinates @@ -538,7 +554,7 @@ void ApplicationCompositor::renderMagnifier(gpu::Batch& batch, const glm::vec2& const float magnifyURight = (magPos.x + halfWidth) / (float)widgetWidth; const float magnifyVTop = 1.0f - (magPos.y - halfHeight) / (float)widgetHeight; const float magnifyVBottom = 1.0f - (magPos.y + halfHeight) / (float)widgetHeight; - + const float newHalfWidth = halfWidth * MAGNIFY_MULT; const float newHalfHeight = halfHeight * MAGNIFY_MULT; //Get yaw / pitch value for the corners @@ -546,7 +562,7 @@ void ApplicationCompositor::renderMagnifier(gpu::Batch& batch, const glm::vec2& magPos.y - newHalfHeight)); const glm::vec2 bottomRightYawPitch = overlayToSpherical(glm::vec2(magPos.x + newHalfWidth, magPos.y + newHalfHeight)); - + const glm::vec3 bottomLeft = getPoint(topLeftYawPitch.x, bottomRightYawPitch.y); const glm::vec3 bottomRight = getPoint(bottomRightYawPitch.x, bottomRightYawPitch.y); const glm::vec3 topLeft = getPoint(topLeftYawPitch.x, topLeftYawPitch.y); @@ -569,7 +585,7 @@ void ApplicationCompositor::renderMagnifier(gpu::Batch& batch, const glm::vec2& _previousMagnifierTopLeft = topLeft; _previousMagnifierTopRight = topRight; } - + glPushMatrix(); { if (showBorder) { glDisable(GL_TEXTURE_2D); @@ -581,12 +597,12 @@ void ApplicationCompositor::renderMagnifier(gpu::Batch& batch, const glm::vec2& glm::vec4 magnifierColor = { 1.0f, 1.0f, 1.0f, _alpha }; DependencyManager::get()->renderQuad(bottomLeft, bottomRight, topRight, topLeft, - glm::vec2(magnifyULeft, magnifyVBottom), - glm::vec2(magnifyURight, magnifyVBottom), - glm::vec2(magnifyURight, magnifyVTop), + glm::vec2(magnifyULeft, magnifyVBottom), + glm::vec2(magnifyURight, magnifyVBottom), + glm::vec2(magnifyURight, magnifyVTop), glm::vec2(magnifyULeft, magnifyVTop), magnifierColor, _magnifierQuad); - + } glPopMatrix(); } @@ -611,8 +627,8 @@ void ApplicationCompositor::buildHemiVertices( } //UV mapping source: http://www.mvps.org/directx/articles/spheremap.htm - - vec3 pos; + + vec3 pos; vec2 uv; // Compute vertices positions and texture UV coordinate // Create and write to buffer @@ -631,13 +647,13 @@ void ApplicationCompositor::buildHemiVertices( _hemiVertices->append(sizeof(vec4), (gpu::Byte*)&color); } } - + // Compute number of indices needed static const int VERTEX_PER_TRANGLE = 3; static const int TRIANGLE_PER_RECTANGLE = 2; int numberOfRectangles = (slices - 1) * (stacks - 1); _hemiIndexCount = numberOfRectangles * TRIANGLE_PER_RECTANGLE * VERTEX_PER_TRANGLE; - + // Compute indices order std::vector indices; for (int i = 0; i < stacks - 1; i++) { @@ -694,7 +710,7 @@ glm::vec2 ApplicationCompositor::directionToSpherical(const glm::vec3& direction } // Compute pitch result.y = angleBetween(IDENTITY_UP, direction) - PI_OVER_TWO; - + return result; } @@ -710,7 +726,7 @@ glm::vec2 ApplicationCompositor::screenToSpherical(const glm::vec2& screenPos) { result.y = (screenPos.y / screenSize.y - 0.5f); result.x *= MOUSE_YAW_RANGE; result.y *= MOUSE_PITCH_RANGE; - + return result; } @@ -720,7 +736,7 @@ glm::vec2 ApplicationCompositor::sphericalToScreen(const glm::vec2& sphericalPos result /= MOUSE_RANGE; result += 0.5f; result *= qApp->getCanvasSize(); - return result; + return result; } glm::vec2 ApplicationCompositor::sphericalToOverlay(const glm::vec2& sphericalPos) const { @@ -737,7 +753,7 @@ glm::vec2 ApplicationCompositor::overlayToSpherical(const glm::vec2& overlayPos glm::vec2 result = overlayPos; result /= qApp->getCanvasSize(); result -= 0.5f; - result *= _textureFov; + result *= _textureFov; result.x *= _textureAspectRatio; result.x *= -1.0f; return result; @@ -754,10 +770,10 @@ glm::vec2 ApplicationCompositor::overlayToScreen(const glm::vec2& overlayPos) co void ApplicationCompositor::updateTooltips() { if (_hoverItemId != _noItemId) { quint64 hoverDuration = usecTimestampNow() - _hoverItemEnterUsecs; - if (_hoverItemEnterUsecs != UINT64_MAX && !_hoverItemHref.isEmpty() && hoverDuration > TOOLTIP_DELAY) { + if (_hoverItemEnterUsecs != UINT64_MAX && !_hoverItemTitle.isEmpty() && hoverDuration > TOOLTIP_DELAY) { // TODO Enable and position the tooltip _hoverItemEnterUsecs = UINT64_MAX; - _tooltipId = Tooltip::showTip("URL: " + _hoverItemHref); + _tooltipId = Tooltip::showTip(_hoverItemTitle, _hoverItemDescription); } } } diff --git a/interface/src/ui/ApplicationCompositor.h b/interface/src/ui/ApplicationCompositor.h index fc0b37127f..0f89f81d26 100644 --- a/interface/src/ui/ApplicationCompositor.h +++ b/interface/src/ui/ApplicationCompositor.h @@ -42,7 +42,7 @@ public: QPoint getPalmClickLocation(const PalmData *palm) const; bool calculateRayUICollisionPoint(const glm::vec3& position, const glm::vec3& direction, glm::vec3& result) const; - + bool hasMagnifier() const { return _magnifier; } void toggleMagnifier() { _magnifier = !_magnifier; } @@ -68,7 +68,7 @@ public: static glm::vec3 sphericalToDirection(const glm::vec2 & sphericalPos); static glm::vec2 screenToSpherical(const glm::vec2 & screenPos); static glm::vec2 sphericalToScreen(const glm::vec2 & sphericalPos); - + private: void displayOverlayTextureStereo(RenderArgs* renderArgs, float aspectRatio, float fov); void bindCursorTexture(gpu::Batch& batch, uint8_t cursorId = 0); @@ -83,9 +83,10 @@ private: // Support for hovering and tooltips static EntityItemID _noItemId; - EntityItemID _hoverItemId{ _noItemId }; - QString _hoverItemHref; - quint64 _hoverItemEnterUsecs{ 0 }; + EntityItemID _hoverItemId { _noItemId }; + QString _hoverItemTitle; + QString _hoverItemDescription; + quint64 _hoverItemEnterUsecs { 0 }; float _hmdUIAngularSize = DEFAULT_HMD_UI_ANGULAR_SIZE; float _textureFov{ glm::radians(DEFAULT_HMD_UI_ANGULAR_SIZE) }; diff --git a/interface/src/ui/LogDialog.cpp b/interface/src/ui/LogDialog.cpp index 008ad354e9..d7d1eef74a 100644 --- a/interface/src/ui/LogDialog.cpp +++ b/interface/src/ui/LogDialog.cpp @@ -11,7 +11,7 @@ #include "InterfaceConfig.h" -#ifdef __GNUC__ +#if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdouble-promotion" #endif @@ -20,7 +20,7 @@ #include #include -#ifdef __GNUC__ +#if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic pop #endif diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index a7aa07ac35..46cfcefa40 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -11,7 +11,7 @@ #include -#ifdef __GNUC__ +#if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdouble-promotion" #endif @@ -19,7 +19,7 @@ #include #include -#ifdef __GNUC__ +#if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic pop #endif @@ -458,7 +458,7 @@ bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& o const glm::vec3& direction, bool& keepSearching, OctreeElement*& element, - float& distance, BoxFace& face, + float& distance, BoxFace& face, void** intersectedObject, bool precisionPicking) const { diff --git a/libraries/render-utils/src/ProgramObject.h b/libraries/render-utils/src/ProgramObject.h index bfcf89afc4..2b7dad71a5 100644 --- a/libraries/render-utils/src/ProgramObject.h +++ b/libraries/render-utils/src/ProgramObject.h @@ -12,14 +12,14 @@ #ifndef hifi_ProgramObject_h #define hifi_ProgramObject_h -#ifdef __GNUC__ +#if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdouble-promotion" #endif #include -#ifdef __GNUC__ +#if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic pop #endif diff --git a/libraries/shared/src/GLMHelpers.h b/libraries/shared/src/GLMHelpers.h index 5d2742feae..6874f3b391 100644 --- a/libraries/shared/src/GLMHelpers.h +++ b/libraries/shared/src/GLMHelpers.h @@ -28,7 +28,7 @@ using glm::vec3; using glm::vec4; using glm::quat; -#ifdef __GNUC__ +#if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdouble-promotion" #endif @@ -37,7 +37,7 @@ using glm::quat; #include #include -#ifdef __GNUC__ +#if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic pop #endif diff --git a/libraries/ui/src/Tooltip.cpp b/libraries/ui/src/Tooltip.cpp index 35b17b74a2..62fd11df7e 100644 --- a/libraries/ui/src/Tooltip.cpp +++ b/libraries/ui/src/Tooltip.cpp @@ -18,14 +18,25 @@ Tooltip::Tooltip(QQuickItem* parent) : QQuickItem(parent) { Tooltip::~Tooltip() { } -QString Tooltip::text() const { - return _text; +const QString& Tooltip::getTitle() const { + return _title; } -void Tooltip::setText(const QString& arg) { - if (arg != _text) { - _text = arg; - emit textChanged(); +const QString& Tooltip::getDescription() const { + return _description; +} + +void Tooltip::setTitle(const QString& title) { + if (title != _title) { + _title = title; + emit titleChanged(); + } +} + +void Tooltip::setDescription(const QString& description) { + if (description != _description) { + _description = description; + emit descriptionChanged(); } } @@ -33,11 +44,14 @@ void Tooltip::setVisible(bool visible) { QQuickItem::setVisible(visible); } -QString Tooltip::showTip(const QString& text) { +QString Tooltip::showTip(const QString& title, const QString& description) { const QString newTipId = QUuid().createUuid().toString(); + + qDebug() << "THE NEW TIP ID IS" << newTipId; Tooltip::show([&](QQmlContext*, QObject* object) { object->setObjectName(newTipId); - object->setProperty("text", text); + object->setProperty("title", title); + object->setProperty("description", description); }); return newTipId; } @@ -48,4 +62,4 @@ void Tooltip::closeTip(const QString& tipId) { if (that) { that->deleteLater(); } -} \ No newline at end of file +} diff --git a/libraries/ui/src/Tooltip.h b/libraries/ui/src/Tooltip.h index 7292fe9399..447bd1dad1 100644 --- a/libraries/ui/src/Tooltip.h +++ b/libraries/ui/src/Tooltip.h @@ -20,26 +20,31 @@ class Tooltip : public QQuickItem HIFI_QML_DECL private: - Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) + Q_PROPERTY(QString title READ getTitle WRITE setTitle NOTIFY titleChanged) + Q_PROPERTY(QString description READ getDescription WRITE setDescription NOTIFY descriptionChanged) public: Tooltip(QQuickItem* parent = 0); virtual ~Tooltip(); - QString text() const; + const QString& getTitle() const; + const QString& getDescription() const; - static QString showTip(const QString& text); + static QString showTip(const QString& title, const QString& description); static void closeTip(const QString& tipId); public slots: virtual void setVisible(bool v); - void setText(const QString& arg); + void setTitle(const QString& title); + void setDescription(const QString& description); signals: - void textChanged(); + void titleChanged(); + void descriptionChanged(); private: - QString _text; + QString _title; + QString _description; }; #endif // hifi_Tooltip_h From 522b715628fc18fea778f3e6218bf7fd2867cec6 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 26 Jun 2015 11:41:34 -0700 Subject: [PATCH 2/5] remove comment, styling cleanup --- interface/src/ui/ApplicationCompositor.cpp | 5 +++-- libraries/ui/src/OffscreenUi.h | 6 +++--- libraries/ui/src/Tooltip.cpp | 7 +++++-- libraries/ui/src/Tooltip.h | 1 + 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/interface/src/ui/ApplicationCompositor.cpp b/interface/src/ui/ApplicationCompositor.cpp index d37a47a4ba..b3af3ec8f8 100644 --- a/interface/src/ui/ApplicationCompositor.cpp +++ b/interface/src/ui/ApplicationCompositor.cpp @@ -17,8 +17,9 @@ #include #include -#include -#include + +#include "CursorManager.h" +#include "HyperLinkTooltip.h" #include "Application.h" diff --git a/libraries/ui/src/OffscreenUi.h b/libraries/ui/src/OffscreenUi.h index 4d0044e775..c7fd205236 100644 --- a/libraries/ui/src/OffscreenUi.h +++ b/libraries/ui/src/OffscreenUi.h @@ -59,7 +59,7 @@ private: void x::load(std::function f) { \ auto offscreenUi = DependencyManager::get(); \ offscreenUi->load(QML, f); \ - } + } #define HIFI_QML_DEF_LAMBDA(x, f) \ const QUrl x::QML = QUrl(#x ".qml"); \ @@ -79,7 +79,7 @@ private: void x::load() { \ auto offscreenUi = DependencyManager::get(); \ offscreenUi->load(QML, f); \ - } + } class OffscreenUi : public OffscreenQmlSurface, public Dependency { Q_OBJECT @@ -97,7 +97,7 @@ public: static void messageBox(const QString& title, const QString& text, ButtonCallback f, - QMessageBox::Icon icon, + QMessageBox::Icon icon, QMessageBox::StandardButtons buttons); static void information(const QString& title, const QString& text, diff --git a/libraries/ui/src/Tooltip.cpp b/libraries/ui/src/Tooltip.cpp index 62fd11df7e..481ed39d5b 100644 --- a/libraries/ui/src/Tooltip.cpp +++ b/libraries/ui/src/Tooltip.cpp @@ -1,5 +1,6 @@ // // Tooltip.cpp +// libraries/ui/src // // Created by Bradley Austin Davis on 2015/04/14 // Copyright 2015 High Fidelity, Inc. @@ -8,14 +9,17 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include "Tooltip.h" -#include + +#include HIFI_QML_DEF(Tooltip) Tooltip::Tooltip(QQuickItem* parent) : QQuickItem(parent) { + } Tooltip::~Tooltip() { + } const QString& Tooltip::getTitle() const { @@ -47,7 +51,6 @@ void Tooltip::setVisible(bool visible) { QString Tooltip::showTip(const QString& title, const QString& description) { const QString newTipId = QUuid().createUuid().toString(); - qDebug() << "THE NEW TIP ID IS" << newTipId; Tooltip::show([&](QQmlContext*, QObject* object) { object->setObjectName(newTipId); object->setProperty("title", title); diff --git a/libraries/ui/src/Tooltip.h b/libraries/ui/src/Tooltip.h index 447bd1dad1..5671ad95c7 100644 --- a/libraries/ui/src/Tooltip.h +++ b/libraries/ui/src/Tooltip.h @@ -1,5 +1,6 @@ // // Tooltip.h +// libraries/ui/src // // Created by Bradley Austin Davis on 2015/04/14 // Copyright 2015 High Fidelity, Inc. From 18e2b62ecc649257f663fe9b3edac19a51d1faa7 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 26 Jun 2015 14:12:26 -0700 Subject: [PATCH 3/5] initial image replacement for hyperlink preview --- interface/resources/qml/Tooltip.qml | 4 +- interface/src/ui/ApplicationCompositor.cpp | 2 +- libraries/networking/src/AddressManager.cpp | 2 - libraries/networking/src/AddressManager.h | 2 + libraries/ui/src/Tooltip.cpp | 79 ++++++++++++++++++--- libraries/ui/src/Tooltip.h | 17 ++++- 6 files changed, 91 insertions(+), 15 deletions(-) diff --git a/interface/resources/qml/Tooltip.qml b/interface/resources/qml/Tooltip.qml index 1a551a4cae..febd87478f 100644 --- a/interface/resources/qml/Tooltip.qml +++ b/interface/resources/qml/Tooltip.qml @@ -55,7 +55,9 @@ Hifi.Tooltip { Image { id: tooltipPic - source: "../images/NoPictureProvided.svg" + source: root.imageURL + height: 180 + width: 320 anchors.left: parent.left anchors.right: parent.right verticalAlignment: Image.AlignVCenter diff --git a/interface/src/ui/ApplicationCompositor.cpp b/interface/src/ui/ApplicationCompositor.cpp index b3af3ec8f8..98da0bfa2f 100644 --- a/interface/src/ui/ApplicationCompositor.cpp +++ b/interface/src/ui/ApplicationCompositor.cpp @@ -19,7 +19,7 @@ #include #include "CursorManager.h" -#include "HyperLinkTooltip.h" +#include "Tooltip.h" #include "Application.h" diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 591b844aed..21bbbc82f6 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -340,8 +340,6 @@ void AddressManager::handleAPIError(QNetworkReply& errorReply) { emit lookupResultsFinished(); } -const QString GET_PLACE = "/api/v1/places/%1"; - void AddressManager::attemptPlaceNameLookup(const QString& lookupString, const QString& overridePath, LookupTrigger trigger) { // assume this is a place name and see if we can get any info on it QString placeName = QUrl::toPercentEncoding(lookupString); diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index 6d9ff01be2..def9eb6042 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -26,6 +26,8 @@ const QString HIFI_URL_SCHEME = "hifi"; const QString DEFAULT_HIFI_ADDRESS = "hifi://entry"; const QString INDEX_PATH = "/"; +const QString GET_PLACE = "/api/v1/places/%1"; + typedef const glm::vec3& (*PositionGetter)(); typedef glm::quat (*OrientationGetter)(); diff --git a/libraries/ui/src/Tooltip.cpp b/libraries/ui/src/Tooltip.cpp index 481ed39d5b..7a2b1d663e 100644 --- a/libraries/ui/src/Tooltip.cpp +++ b/libraries/ui/src/Tooltip.cpp @@ -10,26 +10,22 @@ // #include "Tooltip.h" +#include #include +#include +#include + HIFI_QML_DEF(Tooltip) Tooltip::Tooltip(QQuickItem* parent) : QQuickItem(parent) { - + connect(this, &Tooltip::titleChanged, this, &Tooltip::requestHyperlinkImage); } Tooltip::~Tooltip() { } -const QString& Tooltip::getTitle() const { - return _title; -} - -const QString& Tooltip::getDescription() const { - return _description; -} - void Tooltip::setTitle(const QString& title) { if (title != _title) { _title = title; @@ -44,6 +40,13 @@ void Tooltip::setDescription(const QString& description) { } } +void Tooltip::setImageURL(const QString& imageURL) { + if (imageURL != _imageURL) { + _imageURL = imageURL; + emit imageURLChanged(); + } +} + void Tooltip::setVisible(bool visible) { QQuickItem::setVisible(visible); } @@ -56,6 +59,7 @@ QString Tooltip::showTip(const QString& title, const QString& description) { object->setProperty("title", title); object->setProperty("description", description); }); + return newTipId; } @@ -66,3 +70,60 @@ void Tooltip::closeTip(const QString& tipId) { that->deleteLater(); } } + +void Tooltip::requestHyperlinkImage() { + if (!_title.isEmpty()) { + // we need to decide if this is a place name - if so we should ask the API for the associated image + // and description (if we weren't given one via the entity properties) + const QString PLACE_NAME_REGEX_STRING = "^[0-9A-Za-z](([0-9A-Za-z]|-(?!-))*[^\\W_]$|$)"; + + QRegExp placeNameRegex(PLACE_NAME_REGEX_STRING); + if (placeNameRegex.indexIn(_title) != -1) { + // we possibly have a valid place name - so ask the API for the associated info + AccountManager& accountManager = AccountManager::getInstance(); + + JSONCallbackParameters callbackParams; + callbackParams.jsonCallbackReceiver = this; + callbackParams.jsonCallbackMethod = "handleAPIResponse"; + + accountManager.sendRequest(GET_PLACE.arg(_title), + AccountManagerAuth::None, + QNetworkAccessManager::GetOperation, + callbackParams); + } + } +} + +void Tooltip::handleAPIResponse(QNetworkReply& requestReply) { + // did a preview image come back? + QJsonObject responseObject = QJsonDocument::fromJson(requestReply.readAll()).object(); + QJsonObject dataObject = responseObject["data"].toObject(); + + const QString PLACE_KEY = "place"; + + if (dataObject.contains(PLACE_KEY)) { + QJsonObject placeObject = dataObject[PLACE_KEY].toObject(); + + const QString PREVIEWS_KEY = "previews"; + const QString LOBBY_KEY = "lobby"; + + if (placeObject.contains(PREVIEWS_KEY) && placeObject[PREVIEWS_KEY].toObject().contains(LOBBY_KEY)) { + // we have previews - time to change the image URL + setImageURL(placeObject[PREVIEWS_KEY].toObject()[LOBBY_KEY].toString()); + } + + if (_description.isEmpty()) { + const QString DESCRIPTION_KEY = "description"; + // we have an empty description - did a non-empty desciption come back? + if (placeObject.contains(DESCRIPTION_KEY)) { + QString placeDescription = placeObject[DESCRIPTION_KEY].toString(); + + if (!placeDescription.isEmpty()) { + // we got a non-empty description so change our description to that + setDescription(placeDescription); + } + } + } + } + +} diff --git a/libraries/ui/src/Tooltip.h b/libraries/ui/src/Tooltip.h index 5671ad95c7..112f782d27 100644 --- a/libraries/ui/src/Tooltip.h +++ b/libraries/ui/src/Tooltip.h @@ -13,6 +13,8 @@ #ifndef hifi_Tooltip_h #define hifi_Tooltip_h +#include + #include "OffscreenQmlDialog.h" class Tooltip : public QQuickItem @@ -23,29 +25,40 @@ class Tooltip : public QQuickItem private: Q_PROPERTY(QString title READ getTitle WRITE setTitle NOTIFY titleChanged) Q_PROPERTY(QString description READ getDescription WRITE setDescription NOTIFY descriptionChanged) + Q_PROPERTY(QString imageURL READ getImageURL WRITE setImageURL NOTIFY imageURLChanged) public: Tooltip(QQuickItem* parent = 0); virtual ~Tooltip(); - const QString& getTitle() const; - const QString& getDescription() const; + const QString& getTitle() const { return _title; } + const QString& getDescription() const { return _description; } + const QString& getImageURL() const { return _imageURL; } static QString showTip(const QString& title, const QString& description); static void closeTip(const QString& tipId); public slots: virtual void setVisible(bool v); + void setTitle(const QString& title); void setDescription(const QString& description); + void setImageURL(const QString& imageURL); signals: void titleChanged(); void descriptionChanged(); + void imageURLChanged(); + +private slots: + void handleAPIResponse(QNetworkReply& requestReply); private: + void requestHyperlinkImage(); + QString _title; QString _description; + QString _imageURL { "../images/NoPictureProvided.svg" }; }; #endif // hifi_Tooltip_h From 7e19a540fdbf654e1e87daee6f029e58c2ee1ebb Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 26 Jun 2015 14:13:23 -0700 Subject: [PATCH 4/5] add the new placeholder image --- .../images/{NoPictureProvided.svg => no-picture-provided.svg} | 0 libraries/ui/src/Tooltip.h | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename interface/resources/images/{NoPictureProvided.svg => no-picture-provided.svg} (100%) diff --git a/interface/resources/images/NoPictureProvided.svg b/interface/resources/images/no-picture-provided.svg similarity index 100% rename from interface/resources/images/NoPictureProvided.svg rename to interface/resources/images/no-picture-provided.svg diff --git a/libraries/ui/src/Tooltip.h b/libraries/ui/src/Tooltip.h index 112f782d27..d1c7330a74 100644 --- a/libraries/ui/src/Tooltip.h +++ b/libraries/ui/src/Tooltip.h @@ -58,7 +58,7 @@ private: QString _title; QString _description; - QString _imageURL { "../images/NoPictureProvided.svg" }; + QString _imageURL { "../images/no-picture-provided.svg" }; }; #endif // hifi_Tooltip_h From a0df52e8609c1e5559f466e74695e09a59b65356 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 26 Jun 2015 14:17:54 -0700 Subject: [PATCH 5/5] add note for UI link --- libraries/ui/src/Tooltip.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/ui/src/Tooltip.cpp b/libraries/ui/src/Tooltip.cpp index 7a2b1d663e..56ba8a95b9 100644 --- a/libraries/ui/src/Tooltip.cpp +++ b/libraries/ui/src/Tooltip.cpp @@ -79,6 +79,10 @@ void Tooltip::requestHyperlinkImage() { QRegExp placeNameRegex(PLACE_NAME_REGEX_STRING); if (placeNameRegex.indexIn(_title) != -1) { + // NOTE: I'm currently not 100% sure why the UI library needs networking, but it's linked for now + // so I'm leveraging that here to get the place preview. We could also do this from the interface side + // should the network link be removed from UI at a later date. + // we possibly have a valid place name - so ask the API for the associated info AccountManager& accountManager = AccountManager::getInstance();