diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c6150dcc53..a1f0291785 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1018,7 +1018,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo toggleMenuUnderReticle(); } } else if (action == controller::toInt(controller::Action::CONTEXT_MENU)) { - toggleMenuUnderReticle(); + toggleTabletUI(); } else if (action == controller::toInt(controller::Action::RETICLE_X)) { auto oldPos = getApplicationCompositor().getReticlePosition(); getApplicationCompositor().setReticlePosition({ oldPos.x + state, oldPos.y }); @@ -1484,6 +1484,11 @@ void Application::toggleMenuUnderReticle() const { offscreenUi->toggleMenu(QPoint(reticlePosition.x - X_LEFT_SHIFT, reticlePosition.y)); } +void Application::toggleTabletUI() const { + auto HMD = DependencyManager::get(); + HMD->toggleShouldShowTablet(); +} + void Application::checkChangeCursor() { QMutexLocker locker(&_changeCursorLock); if (_cursorNeedsChanging) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 5ab94465cc..27b1c9bb6e 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -455,6 +455,7 @@ private: void maybeToggleMenuVisible(QMouseEvent* event) const; void toggleMenuUnderReticle() const; + void toggleTabletUI() const; MainWindow* _window; QElapsedTimer& _sessionRunTimer; diff --git a/interface/src/scripting/HMDScriptingInterface.cpp b/interface/src/scripting/HMDScriptingInterface.cpp index fb1440ebdf..4a3e4f4587 100644 --- a/interface/src/scripting/HMDScriptingInterface.cpp +++ b/interface/src/scripting/HMDScriptingInterface.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "Application.h" diff --git a/interface/src/scripting/HMDScriptingInterface.h b/interface/src/scripting/HMDScriptingInterface.h index c9ed7f0097..1de6150d4c 100644 --- a/interface/src/scripting/HMDScriptingInterface.h +++ b/interface/src/scripting/HMDScriptingInterface.h @@ -28,6 +28,8 @@ class HMDScriptingInterface : public AbstractHMDScriptingInterface, public Depen Q_PROPERTY(glm::vec3 position READ getPosition) Q_PROPERTY(glm::quat orientation READ getOrientation) Q_PROPERTY(bool mounted READ isMounted) + Q_PROPERTY(bool showTablet READ getShouldShowTablet) + Q_PROPERTY(QUuid tabletID READ getCurrentTableUIID WRITE setCurrentTabletUIID) public: Q_INVOKABLE glm::vec3 calculateRayUICollisionPoint(const glm::vec3& position, const glm::vec3& direction) const; @@ -52,11 +54,11 @@ public: Q_INVOKABLE void disableExtraLaser() const; - /// Suppress the activation of any on-screen keyboard so that a script operation will + /// Suppress the activation of any on-screen keyboard so that a script operation will /// not be interrupted by a keyboard popup /// Returns false if there is already an active keyboard displayed. /// Clients should re-enable the keyboard when the operation is complete and ensure - /// that they balance any call to suppressKeyboard() that returns true with a corresponding + /// that they balance any call to suppressKeyboard() that returns true with a corresponding /// call to unsuppressKeyboard() within a reasonable amount of time Q_INVOKABLE bool suppressKeyboard(); @@ -79,10 +81,19 @@ public: bool isMounted() const; + void toggleShouldShowTablet() { _showTablet = !_showTablet; } + bool getShouldShowTablet() const { return _showTablet; } + + void setCurrentTabletUIID(QUuid tabletID) { _tabletUIID = tabletID; } + QUuid getCurrentTableUIID() { return _tabletUIID; } + private: + bool _showTablet { false }; + QUuid _tabletUIID; // this is the entityID of the WebEntity which is part of (a child of) the tablet-ui. + // Get the position of the HMD glm::vec3 getPosition() const; - + // Get the orientation of the HMD glm::quat getOrientation() const; diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index b17a2ecc38..fc2bf40250 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -18,7 +18,6 @@ #include #include -#include #include #include #include @@ -69,6 +68,8 @@ bool RenderableWebEntityItem::buildWebSurface(QSharedPointer qWarning() << "Too many concurrent web views to create new view"; return false; } + qDebug() << "Building web surface"; + QString javaScriptToInject; QFile webChannelFile(":qtwebchannel/qwebchannel.js"); QFile createGlobalEventBridgeFile(PathUtils::resourcesPath() + "/html/createGlobalEventBridge.js"); @@ -78,13 +79,13 @@ bool RenderableWebEntityItem::buildWebSurface(QSharedPointer QString createGlobalEventBridgeStr = QTextStream(&createGlobalEventBridgeFile).readAll(); // concatenate these js files - javaScriptToInject = webChannelStr + createGlobalEventBridgeStr; + _javaScriptToInject = webChannelStr + createGlobalEventBridgeStr; } else { qCWarning(entitiesrenderer) << "unable to find qwebchannel.js or createGlobalEventBridge.js"; } // Save the original GL context, because creating a QML surface will create a new context - QOpenGLContext * currentContext = QOpenGLContext::currentContext(); + QOpenGLContext* currentContext = QOpenGLContext::currentContext(); if (!currentContext) { return false; } @@ -117,23 +118,13 @@ bool RenderableWebEntityItem::buildWebSurface(QSharedPointer // is no longer valid _webSurface->create(currentContext); -#define AJT_TABLET_HACK + loadSourceURL(); -#ifdef AJT_TABLET_HACK - _webSurface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "qml/hifi/tablet/")); - _webSurface->load("Tablet.qml", [&](QQmlContext* context, QObject* obj) { - ; - }); - _webSurface->resume(); -#else - _webSurface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/controls/")); - _webSurface->load("WebView.qml", [&](QQmlContext* context, QObject* obj) { - context->setContextProperty("eventBridgeJavaScriptToInject", QVariant(javaScriptToInject)); - }); _webSurface->resume(); + // _connection = QObject::connect(_webSurface, &OffscreenQmlSurface::textureUpdated, [&](GLuint textureId) { + // _texture = textureId; _webSurface->getRootItem()->setProperty("url", _sourceUrl); _webSurface->getRootContext()->setContextProperty("desktop", QVariant()); -#endif // FIXME - Keyboard HMD only: Possibly add "HMDinfo" object to context for WebView.qml. // forward web events to EntityScriptingInterface @@ -170,7 +161,9 @@ bool RenderableWebEntityItem::buildWebSurface(QSharedPointer QTouchEvent* touchEvent = new QTouchEvent(QEvent::TouchEnd, nullptr, Qt::NoModifier, Qt::TouchPointReleased, touchPoints); touchEvent->setWindow(_webSurface->getWindow()); touchEvent->setDevice(&_touchDevice); - touchEvent->setTarget(_webSurface->getRootItem()); + if (_contentType == htmlContent) { + touchEvent->setTarget(_webSurface->getRootItem()); + } QCoreApplication::postEvent(_webSurface->getWindow(), touchEvent); } }); @@ -256,13 +249,49 @@ void RenderableWebEntityItem::render(RenderArgs* args) { DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texMin, texMax, glm::vec4(1.0f, 1.0f, 1.0f, fadeRatio), _geometryId); } +void RenderableWebEntityItem::loadSourceURL() { + QUrl sourceUrl(_sourceUrl); + if (sourceUrl.scheme() == "http" || sourceUrl.scheme() == "https" || + _sourceUrl.toLower().endsWith(".htm") || _sourceUrl.toLower().endsWith(".html")) { + + qDebug() << "HERE RenderableWebEntityItem::loadSourceURL http -- " << _sourceUrl; + + _contentType = htmlContent; + _webSurface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "qml/controls/")); + + QString fuh = QUrl::fromLocalFile(PathUtils::resourcesPath()).toString() + "qml/controls/" + "WebView.qml"; + qDebug() << "HERE full name is " << fuh; + + _webSurface->load("WebView.qml", [&](QQmlContext* context, QObject* obj) { + context->setContextProperty("eventBridgeJavaScriptToInject", QVariant(_javaScriptToInject)); + }); + // _webSurface->getRootItem()->setProperty("eventBridge", QVariant::fromValue(_webEntityAPIHelper)); + _webSurface->getRootItem()->setProperty("url", _sourceUrl); + _webSurface->getRootContext()->setContextProperty("desktop", QVariant()); + // _webSurface->getRootContext()->setContextProperty("webEntity", _webEntityAPIHelper); + + } else { + qDebug() << "HERE RenderableWebEntityItem::loadSourceURL qml -- " << _sourceUrl; + + _contentType = qmlContent; + _webSurface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath())); + _webSurface->load(_sourceUrl, [&](QQmlContext* context, QObject* obj) { }); + } +} + + void RenderableWebEntityItem::setSourceUrl(const QString& value) { if (_sourceUrl != value) { qDebug() << "Setting web entity source URL to " << value; _sourceUrl = value; if (_webSurface) { + qDebug() << "HERE RenderableWebEntityItem::setSourceUrl has _webSurface"; AbstractViewStateInterface::instance()->postLambdaEvent([this] { - _webSurface->getRootItem()->setProperty("url", _sourceUrl); + qDebug() << "HERE RenderableWebEntityItem::setSourceUrl in lambda"; + loadSourceURL(); + if (_contentType == htmlContent) { + _webSurface->getRootItem()->setProperty("url", _sourceUrl); + } }); } } @@ -333,7 +362,9 @@ void RenderableWebEntityItem::handlePointerEvent(const PointerEvent& event) { QTouchEvent* touchEvent = new QTouchEvent(type); touchEvent->setWindow(_webSurface->getWindow()); touchEvent->setDevice(&_touchDevice); - touchEvent->setTarget(_webSurface->getRootItem()); + if (_contentType == htmlContent) { + touchEvent->setTarget(_webSurface->getRootItem()); + } touchEvent->setTouchPoints(touchPoints); touchEvent->setTouchPointStates(touchPointState); @@ -385,6 +416,74 @@ bool RenderableWebEntityItem::isTransparent() { return fadeRatio < OPAQUE_ALPHA_THRESHOLD; } +QObject* RenderableWebEntityItem::getRootItem() { + if (_webSurface) { + return dynamic_cast(_webSurface->getRootItem()); + } + + qDebug() << "HERE no _websurface"; + return nullptr; +} + + +// UTF-8 encoded symbols +static const uint8_t UPWARDS_WHITE_ARROW_FROM_BAR[] = { 0xE2, 0x87, 0xAA, 0x00 }; // shift +static const uint8_t LEFT_ARROW[] = { 0xE2, 0x86, 0x90, 0x00 }; // backspace +static const uint8_t LEFTWARD_WHITE_ARROW[] = { 0xE2, 0x87, 0xA6, 0x00 }; // left arrow +static const uint8_t RIGHTWARD_WHITE_ARROW[] = { 0xE2, 0x87, 0xA8, 0x00 }; // right arrow +static const uint8_t ASTERISIM[] = { 0xE2, 0x81, 0x82, 0x00 }; // symbols +static const uint8_t RETURN_SYMBOL[] = { 0xE2, 0x8F, 0x8E, 0x00 }; // return +static const char PUNCTUATION_STRING[] = "&123"; +static const char ALPHABET_STRING[] = "abc"; + +static bool equals(const QByteArray& byteArray, const uint8_t* ptr) { + int i; + for (i = 0; i < byteArray.size(); i++) { + if ((char)ptr[i] != byteArray[i]) { + return false; + } + } + return ptr[i] == 0x00; +} + +void RenderableWebEntityItem::synthesizeKeyPress(QString key) { + auto utf8Key = key.toUtf8(); + + int scanCode = (int)utf8Key[0]; + QString keyString = key; + if (equals(utf8Key, UPWARDS_WHITE_ARROW_FROM_BAR) || equals(utf8Key, ASTERISIM) || + equals(utf8Key, (uint8_t*)PUNCTUATION_STRING) || equals(utf8Key, (uint8_t*)ALPHABET_STRING)) { + return; // ignore + } else if (equals(utf8Key, LEFT_ARROW)) { + scanCode = Qt::Key_Backspace; + keyString = "\x08"; + } else if (equals(utf8Key, RETURN_SYMBOL)) { + scanCode = Qt::Key_Return; + keyString = "\x0d"; + } else if (equals(utf8Key, LEFTWARD_WHITE_ARROW)) { + scanCode = Qt::Key_Left; + keyString = ""; + } else if (equals(utf8Key, RIGHTWARD_WHITE_ARROW)) { + scanCode = Qt::Key_Right; + keyString = ""; + } + + QKeyEvent* pressEvent = new QKeyEvent(QEvent::KeyPress, scanCode, Qt::NoModifier, keyString); + QKeyEvent* releaseEvent = new QKeyEvent(QEvent::KeyRelease, scanCode, Qt::NoModifier, keyString); + QCoreApplication::postEvent(getEventHandler(), pressEvent); + QCoreApplication::postEvent(getEventHandler(), releaseEvent); +} + +// void RenderableWebEntityItem::setKeyboardRaised(bool raised) { +// +// // raise the keyboard only while in HMD mode and it's being requested. +// bool value = AbstractViewStateInterface::instance()->isHMDMode() && raised; +// +// if (_contentType == htmlContent) { +// _webSurface->getRootItem()->setProperty("keyboardRaised", QVariant(value)); +// } +// } + void RenderableWebEntityItem::emitScriptEvent(const QVariant& message) { if (_webSurface) { _webSurface->emitScriptEvent(message); diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.h b/libraries/entities-renderer/src/RenderableWebEntityItem.h index c2e3ae7f9f..351bbbec87 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.h +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.h @@ -16,6 +16,7 @@ #include #include +#include #include "RenderableEntityItem.h" @@ -33,6 +34,7 @@ public: ~RenderableWebEntityItem(); virtual void render(RenderArgs* args) override; + void loadSourceURL(); virtual void setSourceUrl(const QString& value) override; virtual bool wantsHandControllerPointerEvents() const override { return true; } @@ -51,6 +53,11 @@ public: virtual bool isTransparent() override; + public: + void synthesizeKeyPress(QString key); + + QObject* getRootItem() override; + private: bool buildWebSurface(QSharedPointer renderer); void destroyWebSurface(); @@ -69,6 +76,14 @@ private: QMetaObject::Connection _mouseReleaseConnection; QMetaObject::Connection _mouseMoveConnection; QMetaObject::Connection _hoverLeaveConnection; + + QString _javaScriptToInject; + + enum contentType { + htmlContent, + qmlContent + }; + contentType _contentType; int _geometryId { 0 }; }; diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 43947708ba..98c403d630 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -25,7 +25,7 @@ #include "QVariantGLM.h" #include "SimulationOwner.h" #include "ZoneEntityItem.h" - +#include "WebEntityItem.h" EntityScriptingInterface::EntityScriptingInterface(bool bidOnSimulationOwnership) : _entityTree(NULL), @@ -1453,3 +1453,13 @@ void EntityScriptingInterface::setCostMultiplier(float value) { costMultiplier = value; } +QObject* EntityScriptingInterface::getWebViewRoot(const QUuid& entityID) { + if (auto entity = checkForTreeEntityAndTypeMatch(entityID, EntityTypes::Web)) { + auto webEntity = std::dynamic_pointer_cast(entity); + QObject* root = webEntity->getRootItem(); + qDebug() << "HERE getWebViewRoot root =" << ((void*) root); + return root; + } else { + return nullptr; + } +} diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index aa6ea0fcff..63a9c59cb4 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -276,6 +276,8 @@ public slots: Q_INVOKABLE void emitScriptEvent(const EntityItemID& entityID, const QVariant& message); + Q_INVOKABLE QObject* getWebViewRoot(const QUuid& entityID); + signals: void collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); diff --git a/libraries/entities/src/WebEntityItem.h b/libraries/entities/src/WebEntityItem.h index 5a8097a9f1..1f5644927d 100644 --- a/libraries/entities/src/WebEntityItem.h +++ b/libraries/entities/src/WebEntityItem.h @@ -59,6 +59,8 @@ public: void setDPI(uint16_t value); uint16_t getDPI() const; + virtual QObject* getRootItem() { return nullptr; } + protected: QString _sourceUrl; uint16_t _dpi; diff --git a/scripts/defaultScripts.js b/scripts/defaultScripts.js index 90a77b508d..a30ad10121 100644 --- a/scripts/defaultScripts.js +++ b/scripts/defaultScripts.js @@ -34,7 +34,8 @@ var DEFAULT_SCRIPTS = [ "system/firstPersonHMD.js", "system/snapshot.js", "system/help.js", - "system/bubble.js" + "system/bubble.js", + "system/tablet-ui/tablet-ui.js" ]; // add a menu item for debugging diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index ff1407cbf0..9dee19e44e 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -1267,6 +1267,9 @@ function MyController(hand) { var grabbableProps = entityPropertiesCache.getGrabbableProps(entityID); var grabProps = entityPropertiesCache.getGrabProps(entityID); var props = entityPropertiesCache.getProps(entityID); + if (!props) { + return false; + } var physical = propsArePhysical(props); var grabbable = false; var debug = (WANT_DEBUG_SEARCH_NAME && props.name === WANT_DEBUG_SEARCH_NAME); @@ -1546,7 +1549,7 @@ function MyController(hand) { Entities.sendHoverOverEntity(entity, pointerEvent); } - if (this.triggerSmoothedGrab() && !isEditing()) { + if (this.triggerSmoothedGrab() && (!isEditing() || name == "WebTablet Web")) { this.grabbedEntity = entity; this.setState(STATE_ENTITY_TOUCHING, "begin touching entity '" + name + "'"); return; diff --git a/scripts/system/libraries/WebTablet.js b/scripts/system/libraries/WebTablet.js index 0c21ea22ae..703ed40c95 100644 --- a/scripts/system/libraries/WebTablet.js +++ b/scripts/system/libraries/WebTablet.js @@ -39,54 +39,72 @@ function calcSpawnInfo() { } // ctor -WebTablet = function (url, width, dpi, clientOnly) { +WebTablet = function (url, width, dpi, location, clientOnly) { var ASPECT = 4.0 / 3.0; var WIDTH = width || DEFAULT_WIDTH; var HEIGHT = WIDTH * ASPECT; var DEPTH = 0.025; var DPI = dpi || DEFAULT_DPI; + var _this = this; - var spawnInfo = calcSpawnInfo(); - - var tabletEntityPosition = spawnInfo.position; - var tabletEntityRotation = spawnInfo.rotation; - this.tabletEntityID = Entities.addEntity({ - name: "tablet", + var tabletProperties = { + name: "WebTablet Tablet", type: "Model", modelURL: TABLET_URL, - position: tabletEntityPosition, - rotation: tabletEntityRotation, userData: JSON.stringify({ "grabbableKey": {"grabbable": true} }), dimensions: {x: WIDTH, y: HEIGHT, z: DEPTH}, parentID: MyAvatar.sessionUUID, parentJointIndex: -2 - }, clientOnly); + } + + if (location) { + tabletProperties.localPosition = location.localPosition; + tabletProperties.localRotation = location.localRotation; + } else { + var spawnInfo = calcSpawnInfo(); + tabletProperties.position = spawnInfo.position; + tabletProperties.rotation = spawnInfo.rotation; + } + + this.tabletEntityID = Entities.addEntity(tabletProperties, clientOnly); var WEB_ENTITY_REDUCTION_FACTOR = {x: 0.78, y: 0.85}; var WEB_ENTITY_Z_OFFSET = -0.01; - var webEntityRotation = Quat.multiply(spawnInfo.rotation, Quat.angleAxis(180, Y_AXIS)); - var webEntityPosition = Vec3.sum(spawnInfo.position, Vec3.multiply(WEB_ENTITY_Z_OFFSET, Quat.getFront(webEntityRotation))); + this.createWebEntity = function(url) { + if (_this.webEntityID) { + Entities.deleteEntity(_this.webEntityID); + } + _this.webEntityID = Entities.addEntity({ + name: "WebTablet Web", + type: "Web", + sourceUrl: url, + dimensions: {x: WIDTH * WEB_ENTITY_REDUCTION_FACTOR.x, + y: HEIGHT * WEB_ENTITY_REDUCTION_FACTOR.y, + z: 0.1}, + localPosition: { x: 0, y: 0, z: WEB_ENTITY_Z_OFFSET }, + localRotation: Quat.angleAxis(180, Y_AXIS), + shapeType: "box", + dpi: DPI, + parentID: _this.tabletEntityID, + parentJointIndex: -1 + }, clientOnly); + } - this.webEntityID = Entities.addEntity({ - name: "web", - type: "Web", - sourceUrl: url, - dimensions: {x: WIDTH * WEB_ENTITY_REDUCTION_FACTOR.x, - y: HEIGHT * WEB_ENTITY_REDUCTION_FACTOR.y, - z: 0.1}, - position: webEntityPosition, - rotation: webEntityRotation, - shapeType: "box", - dpi: DPI, - parentID: this.tabletEntityID, - parentJointIndex: -1 - }, clientOnly); + this.createWebEntity(url); this.state = "idle"; + + this.getRoot = function() { + return Entities.getWebViewRoot(_this.webEntityID); + } + + this.getLocation = function() { + return Entities.getEntityProperties(_this.tabletEntityID, ["localPosition", "localRotation"]); + }; }; WebTablet.prototype.destroy = function () { diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index d31f4cb722..887073aa98 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -1032,9 +1032,20 @@ SelectionDisplay = (function() { var pickRay = controllerComputePickRay(); if (pickRay) { var entityIntersection = Entities.findRayIntersection(pickRay, true); + + var overlayIntersection = Overlays.findRayIntersection(pickRay); if (entityIntersection.intersects && (!overlayIntersection.intersects || (entityIntersection.distance < overlayIntersection.distance))) { + + // if (entityIntersection.properties.name == "WebTablet Web") { + // return; + // } + + if (HMD.tabletID == entityIntersection.entityID) { + return; + } + selectionManager.setSelections([entityIntersection.entityID]); } } diff --git a/scripts/system/marketplaces/marketplace.js b/scripts/system/marketplaces/marketplace.js index 894dae7eac..4f024fdb20 100644 --- a/scripts/system/marketplaces/marketplace.js +++ b/scripts/system/marketplaces/marketplace.js @@ -44,7 +44,20 @@ function shouldShowWebTablet() { function showMarketplace(marketplaceID) { if (shouldShowWebTablet()) { updateButtonState(true); - marketplaceWebTablet = new WebTablet("https://metaverse.highfidelity.com/marketplace", null, null, true); + + print("HERE shouldShowWebTablet"); + if (HMD.tabletID) { + print("HERE shouldShowWebTablet tabletID is ", HMD.tabletID); + UIWebTablet.createWebEntity("https://metaverse.highfidelity.com/marketplace"); + HMD.tabletID = UIWebTablet.webEntityID; + } else { + print("HERE shouldShowWebTablet making new tablet"); + marketplaceWebTablet = new WebTablet("https://metaverse.highfidelity.com/marketplace", + null, // width + null, // dpi + null, // location + true); // client-only + } Settings.setValue(persistenceKey, marketplaceWebTablet.pickle()); } else { var url = MARKETPLACE_URL; diff --git a/scripts/system/tablet-ui/tablet-ui.js b/scripts/system/tablet-ui/tablet-ui.js new file mode 100644 index 0000000000..f604c90b1d --- /dev/null +++ b/scripts/system/tablet-ui/tablet-ui.js @@ -0,0 +1,77 @@ +"use strict"; + +// +// tablet-ui.js +// +// scripts/system/tablet-ui/ +// +// Created by Seth Alves 2016-9-29 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +/* global Script, HMD, WebTablet, UIWebTablet */ + +(function() { // BEGIN LOCAL_SCOPE + var tabletShown = false; + var tabletLocation = null; + + Script.include("../libraries/WebTablet.js"); + + function showTabletUI() { + tabletShown = true; + print("show tablet-ui"); + // var toolBar = Toolbars.getToolbar("com.highfidelity.interface.toolbar.system"); + UIWebTablet = new WebTablet("qml/desktop/TabletUI.qml", null, null, tabletLocation); + HMD.tabletID = UIWebTablet.webEntityID; + + var setUpTabletUI = function() { + var root = UIWebTablet.getRoot(); + if (!root) { + print("HERE no root yet"); + Script.setTimeout(setUpTabletUI, 100); + return; + } + print("HERE got root", root); + var buttons = Toolbars.getToolbarButtons("com.highfidelity.interface.toolbar.system"); + print("HERE got buttons: ", buttons.length); + for (var i = 0; i < buttons.length; i++) { + print("HERE hooking up button: ", buttons[i].objectName); + Toolbars.hookUpButtonClone("com.highfidelity.interface.toolbar.system", root, buttons[i]); + } + // UserActivityLogger.openedTabletUI(); + } + + Script.setTimeout(setUpTabletUI, 100); + } + + function hideTabletUI() { + tabletShown = false; + print("hide tablet-ui"); + if (UIWebTablet) { + if (UIWebTablet.onClose) { + UIWebTablet.onClose(); + } + Toolbars.destroyButtonClones("com.highfidelity.interface.toolbar.system"); + + tabletLocation = UIWebTablet.getLocation(); + UIWebTablet.destroy(); + UIWebTablet = null; + HMD.tabletID = null; + } + } + + function updateShowTablet() { + if (HMD.showTablet && !tabletShown) { + showTabletUI(); + } else if (!HMD.showTablet && tabletShown) { + hideTabletUI(); + } + } + + Script.update.connect(updateShowTablet); + // Script.setInterval(updateShowTablet, 1000); + +}()); // END LOCAL_SCOPE