diff --git a/interface/resources/qml/hifi/tablet/Tablet.qml b/interface/resources/qml/hifi/tablet/Tablet.qml index 4ea1891737..05952c82f6 100644 --- a/interface/resources/qml/hifi/tablet/Tablet.qml +++ b/interface/resources/qml/hifi/tablet/Tablet.qml @@ -10,25 +10,41 @@ Item { width: 480 height: 720 + // used to look up a button by its uuid + function findButtonIndex(uuid) { + if (!uuid) { + return -1; + } + + for (var i in flowMain.children) { + var child = flowMain.children[i]; + if (child.uuid === uuid) { + return i; + } + } + return -1; + } + // called by C++ code when a button should be added to the tablet function addButtonProxy(properties) { var component = Qt.createComponent("TabletButton.qml"); var button = component.createObject(flowMain); - if (properties.icon) { - button.icon = properties.icon; - } - if (properties.color) { - button.color = properties.color; - } - if (properties.text) { - button.text = properties.text; - } + + // copy all properites to button + var keys = Object.keys(properties).forEach(function (key) { + button[key] = properties[key]; + }); + return button; } // called by C++ code when a button should be removed from the tablet function removeButtonProxy(properties) { - console.log("TABLET_UI_HACK: removeButtonProxy, NOT IMPLEMENTED!, properties = " + JSON.stringify(properties)); + var index = findButtonIndex(properties.uuid); + if (index < 0) { + console.log("Warning: Tablet.qml could not find button with uuid = " + properties.uuid); + } + flowMain.children[index].destroy(); } Rectangle { diff --git a/interface/resources/qml/hifi/tablet/TabletButton.qml b/interface/resources/qml/hifi/tablet/TabletButton.qml index 92a7ee2865..bcd693a0a3 100644 --- a/interface/resources/qml/hifi/tablet/TabletButton.qml +++ b/interface/resources/qml/hifi/tablet/TabletButton.qml @@ -6,6 +6,7 @@ Item { property string color: "#1080B8" property string text: "EDIT" property string icon: "icons/edit-icon.svg" + property var uuid; width: 132 height: 132 diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index cba6842ba9..a29d2c0b8e 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -361,6 +361,13 @@ void RenderableWebEntityItem::destroyWebSurface() { --_currentWebCount; QQuickItem* rootItem = _webSurface->getRootItem(); + + // TABLET_UI_HACK: move this to overlays as well! + if (rootItem && rootItem->objectName() == "tablet") { + auto tabletScriptingInterface = DependencyManager::get(); + tabletScriptingInterface->setQmlTablet("com.highfidelity.interface.tablet.system", nullptr); + } + if (rootItem) { QObject* obj = rootItem->findChild("webEngineView"); if (obj) { diff --git a/libraries/script-engine/src/TabletScriptingInterface.cpp b/libraries/script-engine/src/TabletScriptingInterface.cpp index 1bcdfc6013..032d8ce671 100644 --- a/libraries/script-engine/src/TabletScriptingInterface.cpp +++ b/libraries/script-engine/src/TabletScriptingInterface.cpp @@ -12,7 +12,7 @@ QObject* TabletScriptingInterface::getTablet(const QString& tabletId) { - std::lock_guard guard(_tabletProxiesMutex); + std::lock_guard guard(_mutex); // look up tabletId in the map. auto iter = _tabletProxies.find(tabletId); @@ -36,7 +36,6 @@ void TabletScriptingInterface::setQmlTablet(QString tabletId, QQuickItem* qmlTab } } - // // TabletProxy // @@ -64,24 +63,27 @@ static void addButtonProxyToQmlTablet(QQuickItem* qmlTablet, TabletButtonProxy* return; } QObject::connect(qmlButton, SIGNAL(clicked()), buttonProxy, SLOT(clickedSlot())); + buttonProxy->setQmlButton(qobject_cast(qmlButton)); } void TabletProxy::setQmlTablet(QQuickItem* qmlTablet) { + std::lock_guard guard(_mutex); if (qmlTablet) { _qmlTablet = qmlTablet; - std::lock_guard guard(_tabletButtonProxiesMutex); for (auto& buttonProxy : _tabletButtonProxies) { addButtonProxyToQmlTablet(_qmlTablet, buttonProxy.data()); } } else { + for (auto& buttonProxy : _tabletButtonProxies) { + buttonProxy->setQmlButton(nullptr); + } _qmlTablet = nullptr; } - } QObject* TabletProxy::addButton(const QVariant& properties) { auto tabletButtonProxy = QSharedPointer(new TabletButtonProxy(properties.toMap())); - std::lock_guard guard(_tabletButtonProxiesMutex); + std::lock_guard guard(_mutex); _tabletButtonProxies.push_back(tabletButtonProxy); if (_qmlTablet) { addButtonProxyToQmlTablet(_qmlTablet, tabletButtonProxy.data()); @@ -90,11 +92,12 @@ QObject* TabletProxy::addButton(const QVariant& properties) { } void TabletProxy::removeButton(QObject* tabletButtonProxy) { - std::lock_guard guard(_tabletButtonProxiesMutex); + std::lock_guard guard(_mutex); auto iter = std::find(_tabletButtonProxies.begin(), _tabletButtonProxies.end(), tabletButtonProxy); if (iter != _tabletButtonProxies.end()) { if (_qmlTablet) { - QMetaObject::invokeMethod(_qmlTablet, "removeButton", Qt::AutoConnection, Q_ARG(QVariant, (*iter)->getProperties())); + (*iter)->setQmlButton(nullptr); + QMetaObject::invokeMethod(_qmlTablet, "removeButtonProxy", Qt::AutoConnection, Q_ARG(QVariant, (*iter)->getProperties())); } _tabletButtonProxies.erase(iter); } else { @@ -106,28 +109,18 @@ void TabletProxy::removeButton(QObject* tabletButtonProxy) { // TabletButtonProxy // -TabletButtonProxy::TabletButtonProxy(const QVariantMap& properties) : _properties(properties) { - ; +const QString UUID_KEY = "uuid"; + +TabletButtonProxy::TabletButtonProxy(const QVariantMap& properties) : _uuid(QUuid::createUuid()), _properties(properties) { + // this is used to uniquely identify this button. + _properties[UUID_KEY] = _uuid; } -void TabletButtonProxy::setInitRequestHandler(const QScriptValue& handler) { - _initRequestHandler = handler; +void TabletButtonProxy::setQmlButton(QQuickItem* qmlButton) { + std::lock_guard guard(_mutex); + _qmlButton = qmlButton; } -// TABLET_UI_HACK remove -/* -static QString IMAGE_URL_KEY = "imageUrl"; -static QString IMAGE_URL_DEFAULT = ""; - -QString TabletButtonProxy::getImageUrl() const { - std::lock_guard guard(_propertiesMutex); - return _properties.value(IMAGE_URL_KEY, IMAGE_URL_DEFAULT).toString(); -} - -void TabletButtonProxy::setImageUrl(QString imageUrl) { - std::lock_guard guard(_propertiesMutex); - _properties[IMAGE_URL_KEY] = imageUrl; -} -*/ +// TABLET_UI_HACK TODO: add property accessors, and forward property changes to the _qmlButton if present. #include "TabletScriptingInterface.moc" diff --git a/libraries/script-engine/src/TabletScriptingInterface.h b/libraries/script-engine/src/TabletScriptingInterface.h index 13d7219306..262a496f1a 100644 --- a/libraries/script-engine/src/TabletScriptingInterface.h +++ b/libraries/script-engine/src/TabletScriptingInterface.h @@ -11,10 +11,11 @@ #include -#include +#include #include #include #include +#include #include @@ -39,7 +40,7 @@ public: void setQmlTablet(QString tabletId, QQuickItem* qmlTablet); protected: - std::mutex _tabletProxiesMutex; + std::mutex _mutex; std::map> _tabletProxies; }; @@ -73,7 +74,7 @@ public: QString getName() const { return _name; } protected: QString _name; - std::mutex _tabletButtonProxiesMutex; + std::mutex _mutex; std::vector> _tabletButtonProxies; QQuickItem* _qmlTablet { nullptr }; }; @@ -87,11 +88,7 @@ class TabletButtonProxy : public QObject { public: TabletButtonProxy(const QVariantMap& properties); - /**jsdoc - * @function TabletButtonProxy#setInitRequestHandler - * @param handler {Function} A function used by the system to request the current button state from JavaScript. - */ - Q_INVOKABLE void setInitRequestHandler(const QScriptValue& handler); + void setQmlButton(QQuickItem* qmlButton); const QVariantMap& getProperties() const { return _properties; } @@ -107,9 +104,10 @@ signals: void clicked(); protected: - mutable std::mutex _propertiesMutex; + QUuid _uuid; + mutable std::mutex _mutex; + QQuickItem* _qmlButton { nullptr }; QVariantMap _properties; - QScriptValue _initRequestHandler; }; #endif // hifi_TabletScriptingInterface_h