} void TabletProxy::loadWebScreenOnTop(const QVariant& url) { loadWebScreenOnTop(url, "");} void TabletProxy::loadWebScreenOnTop(const QVariant& url, const QString& injectJavaScriptUrl) { QObject* root = nullptr; if (!_toolbarMode && _qmlTabletRoot) { root = _qmlTabletRoot; } else if (_toolbarMode && _desktopWindow) { root = _desktopWindow->asQuickItem(); } if (root) { QMetaObject::invokeMethod(root, "loadQMLOnTop", Q_ARG(const QVariant&, QVariant(WEB_VIEW_SOURCE_URL))); QMetaObject::invokeMethod(root, "setShown", Q_ARG(const QVariant&, QVariant(true))); QMetaObject::invokeMethod(root, "loadWebOnTop", Q_ARG(const QVariant&, QVariant(url)), Q_ARG(const QVariant&, QVariant(injectJavaScriptUrl))); } _state = State::Web;} void TabletProxy::gotoWebScreen(const QString& url, const QString& injectedJavaScriptUrl) { QObject* root = nullptr; if (!_toolbarMode && _qmlTabletRoot) { root = _qmlTabletRoot; } else if (_toolbarMode && _desktopWindow) { root = _desktopWindow->asQuickItem(); } if (root) { removeButtonsFromHomeScreen(); QMetaObject::invokeMethod(root, "loadWebBase"); QMetaObject::invokeMethod(root, "setShown", Q_ARG(const QVariant&, QVariant(true))); QMetaObject::invokeMethod(root, "loadWebUrl", Q_ARG(const QVariant&, QVariant(url)), Q_ARG(const QVariant&, QVariant(injectedJavaScriptUrl))); } _state = State::Web; emit screenChanged(QVariant("Web"), QVariant(url)); _currentPathLoaded = QVariant(url);} QObject* TabletProxy::addButton(const QVariant& properties) { auto tabletButtonProxy = QSharedPointer<TabletButtonProxy>(new TabletButtonProxy(properties.toMap())); std::unique_lock<std::mutex> guard(_tabletMutex); _tabletButtonProxies.push_back(tabletButtonProxy); if (!_toolbarMode && _qmlTabletRoot) { auto tablet = getQmlTablet(); if (tablet) { addButtonProxyToQmlTablet(tablet, tabletButtonProxy.data()); } else { qCCritical(scriptengine) << "Could not find tablet in TabletRoot.qml"; } } else if (_toolbarMode) { auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>(); QObject* toolbarProxy = tabletScriptingInterface->getSystemToolbarProxy(); Qt::ConnectionType connectionType = Qt::AutoConnection; if (QThread::currentThread() != toolbarProxy->thread()) { connectionType = Qt::BlockingQueuedConnection; } guard.unlock(); // copy properties from tablet button proxy to toolbar button proxy. QObject* toolbarButtonProxy = nullptr; bool hasResult = QMetaObject::invokeMethod(toolbarProxy, "addButton", connectionType, Q_RETURN_ARG(QObject*, toolbarButtonProxy), Q_ARG(QVariant, tabletButtonProxy->getProperties())); if (hasResult) { tabletButtonProxy->setToolbarButtonProxy(toolbarButtonProxy); } else { qCWarning(scriptengine) << "ToolbarProxy addButton has no result"; } } return tabletButtonProxy.data();} bool TabletProxy::onHomeScreen() { return _state == State::Home;} void TabletProxy::removeButton(QObject* tabletButtonProxy) { std::unique_lock<std::mutex> guard(_tabletMutex); auto tablet = getQmlTablet(); if (!tablet) { qCCritical(scriptengine) << "Could not find tablet in TabletRoot.qml"; } QSharedPointer<TabletButtonProxy> buttonProxy; { auto iter = std::find(_tabletButtonProxies.begin(), _tabletButtonProxies.end(), tabletButtonProxy); if (iter == _tabletButtonProxies.end()) { qCWarning(scriptengine) << "TabletProxy::removeButton() could not find button " << tabletButtonProxy; return; } buttonProxy = *iter; _tabletButtonProxies.erase(iter); } if (!_toolbarMode && _qmlTabletRoot) { buttonProxy->setQmlButton(nullptr); if (tablet) { guard.unlock(); QMetaObject::invokeMethod(tablet, "removeButtonProxy", Qt::AutoConnection, Q_ARG(QVariant, buttonProxy->getProperties())); } } else if (_toolbarMode) { auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>(); QObject* toolbarProxy = tabletScriptingInterface->getSystemToolbarProxy(); // remove button from toolbarProxy guard.unlock(); QMetaObject::invokeMethod(toolbarProxy, "removeButton", Qt::AutoConnection, Q_ARG(QVariant, buttonProxy->getUuid().toString())); buttonProxy->setToolbarButtonProxy(nullptr); }} void TabletProxy::updateAudioBar(const double micLevel) { auto tablet = getQmlTablet(); if (!tablet) { //qCCritical(scriptengine) << "Could not find tablet in TabletRoot.qml"; } else { QMetaObject::invokeMethod(tablet, "setMicLevel", Qt::AutoConnection, Q_ARG(QVariant, QVariant(micLevel))); }} void TabletProxy::emitScriptEvent(QVariant msg) { if (!_toolbarMode && _qmlOffscreenSurface) { QMetaObject::invokeMethod(_qmlOffscreenSurface, "emitScriptEvent", Qt::AutoConnection, Q_ARG(QVariant, msg)); } else if (_toolbarMode && _desktopWindow) { QMetaObject::invokeMethod(_desktopWindow, "emitScriptEvent", Qt::AutoConnection, Q_ARG(QVariant, msg)); }} void TabletProxy::sendToQml(QVariant msg) { if (!_toolbarMode && _qmlOffscreenSurface) { QMetaObject::invokeMethod(_qmlOffscreenSurface, "sendToQml", Qt::AutoConnection, Q_ARG(QVariant, msg)); } else if (_toolbarMode && _desktopWindow) { QMetaObject::invokeMethod(_desktopWindow, "sendToQml", Qt::AutoConnection, Q_ARG(QVariant, msg)); }} void TabletProxy::addButtonsToHomeScreen() { auto tablet = getQmlTablet(); if (!tablet || _toolbarMode) { return; } auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>(); for (auto& buttonProxy : _tabletButtonProxies) { addButtonProxyToQmlTablet(tablet, buttonProxy.data()); } auto loader = _qmlTabletRoot->findChild<QQuickItem*>("loader"); QObject::disconnect(loader, SIGNAL(loaded()), this, SLOT(addButtonsToHomeScreen()));} QObject* TabletProxy::getTabletSurface() { return _qmlOffscreenSurface;} void TabletProxy::removeButtonsFromHomeScreen() { auto tablet = getQmlTablet(); for (auto& buttonProxy : _tabletButtonProxies) { if (tablet) { QMetaObject::invokeMethod(tablet, "removeButtonProxy", Qt::AutoConnection, Q_ARG(QVariant, buttonProxy->getProperties())); } buttonProxy->setQmlButton(nullptr); }} void TabletProxy::desktopWindowClosed() { gotoHomeScreen();} void TabletProxy::addButtonsToToolbar() { auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>(); QObject* toolbarProxy = tabletScriptingInterface->getSystemToolbarProxy(); Qt::ConnectionType connectionType = Qt::AutoConnection; if (QThread::currentThread() != toolbarProxy->thread()) { connectionType = Qt::BlockingQueuedConnection; } for (auto& buttonProxy : _tabletButtonProxies) { // copy properties from tablet button proxy to toolbar button proxy. QObject* toolbarButtonProxy = nullptr; bool hasResult = QMetaObject::invokeMethod(toolbarProxy, "addButton", connectionType, Q_RETURN_ARG(QObject*, toolbarButtonProxy), Q_ARG(QVariant, buttonProxy->getProperties())); if (hasResult) { buttonProxy->setToolbarButtonProxy(toolbarButtonProxy); } else { qCWarning(scriptengine) << "ToolbarProxy addButton has no result"; } } // make the toolbar visible QMetaObject::invokeMethod(toolbarProxy, "writeProperty", Qt::AutoConnection, Q_ARG(QString, "visible"), Q_ARG(QVariant, QVariant(true)));} void TabletProxy::removeButtonsFromToolbar() { auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>(); QObject* toolbarProxy = tabletScriptingInterface->getSystemToolbarProxy(); for (auto& buttonProxy : _tabletButtonProxies) { // remove button from toolbarProxy QMetaObject::invokeMethod(toolbarProxy, "removeButton", Qt::AutoConnection, Q_ARG(QVariant, buttonProxy->getUuid().toString())); buttonProxy->setToolbarButtonProxy(nullptr); }} QQuickItem* TabletProxy::getQmlTablet() const { if (!_qmlTabletRoot) { return nullptr; } auto loader = _qmlTabletRoot->findChild<QQuickItem*>("loader"); if (!loader) { return nullptr; } auto tablet = loader->findChild<QQuickItem*>("tablet"); if (!tablet) { return nullptr; } return tablet;} QQuickItem* TabletProxy::getQmlMenu() const { if (!_qmlTabletRoot) { return nullptr; } auto loader = _qmlTabletRoot->findChild<QQuickItem*>("loader"); if (!loader) { return nullptr; } QQuickItem* VrMenu = loader->findChild<QQuickItem*>("tabletMenu"); if (!VrMenu) { return nullptr; } QQuickItem* menuList = VrMenu->findChild<QQuickItem*>("tabletMenuHandlerItem"); if (!menuList) { return nullptr; } return menuList;} //// TabletButtonProxy// const QString UUID_KEY = "uuid";const QString OBJECT_NAME_KEY = "objectName";const QString STABLE_ORDER_KEY = "stableOrder";static int s_stableOrder = 1; TabletButtonProxy::TabletButtonProxy(const QVariantMap& properties) : _uuid(QUuid::createUuid()), _stableOrder(++s_stableOrder), _properties(properties) { // this is used to uniquely identify this button. _properties[UUID_KEY] = _uuid; _properties[OBJECT_NAME_KEY] = _uuid.toString(); _properties[STABLE_ORDER_KEY] = _stableOrder;} void TabletButtonProxy::setQmlButton(QQuickItem* qmlButton) { std::lock_guard<std::mutex> guard(_buttonMutex); _qmlButton = qmlButton;} void TabletButtonProxy::setToolbarButtonProxy(QObject* toolbarButtonProxy) { std::lock_guard<std::mutex> guard(_buttonMutex); _toolbarButtonProxy = toolbarButtonProxy; if (_toolbarButtonProxy) { QObject::connect(_toolbarButtonProxy, SIGNAL(clicked()), this, SLOT(clickedSlot())); }} QVariantMap TabletButtonProxy::getProperties() const { std::lock_guard<std::mutex> guard(_buttonMutex); return _properties;} void TabletButtonProxy::editProperties(QVariantMap properties) { std::lock_guard<std::mutex> guard(_buttonMutex); QVariantMap::const_iterator iter = properties.constBegin(); while (iter != properties.constEnd()) { _properties[iter.key()] = iter.value(); if (_qmlButton) { QMetaObject::invokeMethod(_qmlButton, "changeProperty", Qt::AutoConnection, Q_ARG(QVariant, QVariant(iter.key())), Q_ARG(QVariant, iter.value())); } ++iter; } if (_toolbarButtonProxy) { QMetaObject::invokeMethod(_toolbarButtonProxy, "editProperties", Qt::AutoConnection, Q_ARG(QVariantMap, properties)); }} #include "TabletScriptingInterface.moc"Lines 501–802 of 802. Previous lines
} void TabletProxy::loadWebScreenOnTop(const QVariant& url) { loadWebScreenOnTop(url, ""); } void TabletProxy::loadWebScreenOnTop(const QVariant& url, const QString& injectJavaScriptUrl) { QObject* root = nullptr; if (!_toolbarMode && _qmlTabletRoot) { root = _qmlTabletRoot; } else if (_toolbarMode && _desktopWindow) { root = _desktopWindow->asQuickItem(); } if (root) { QMetaObject::invokeMethod(root, "loadQMLOnTop", Q_ARG(const QVariant&, QVariant(WEB_VIEW_SOURCE_URL))); QMetaObject::invokeMethod(root, "setShown", Q_ARG(const QVariant&, QVariant(true))); QMetaObject::invokeMethod(root, "loadWebOnTop", Q_ARG(const QVariant&, QVariant(url)), Q_ARG(const QVariant&, QVariant(injectJavaScriptUrl))); } _state = State::Web; } void TabletProxy::gotoWebScreen(const QString& url, const QString& injectedJavaScriptUrl) { QObject* root = nullptr; if (!_toolbarMode && _qmlTabletRoot) { root = _qmlTabletRoot; } else if (_toolbarMode && _desktopWindow) { root = _desktopWindow->asQuickItem(); } if (root) { removeButtonsFromHomeScreen(); QMetaObject::invokeMethod(root, "loadWebBase"); QMetaObject::invokeMethod(root, "setShown", Q_ARG(const QVariant&, QVariant(true))); QMetaObject::invokeMethod(root, "loadWebUrl", Q_ARG(const QVariant&, QVariant(url)), Q_ARG(const QVariant&, QVariant(injectedJavaScriptUrl))); } _state = State::Web; emit screenChanged(QVariant("Web"), QVariant(url)); _currentPathLoaded = QVariant(url); } QObject* TabletProxy::addButton(const QVariant& properties) { auto tabletButtonProxy = QSharedPointer<TabletButtonProxy>(new TabletButtonProxy(properties.toMap())); std::unique_lock<std::mutex> guard(_tabletMutex); _tabletButtonProxies.push_back(tabletButtonProxy); if (!_toolbarMode && _qmlTabletRoot) { auto tablet = getQmlTablet(); if (tablet) { addButtonProxyToQmlTablet(tablet, tabletButtonProxy.data()); } else { qCCritical(scriptengine) << "Could not find tablet in TabletRoot.qml"; } } else if (_toolbarMode) { auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>(); QObject* toolbarProxy = tabletScriptingInterface->getSystemToolbarProxy(); Qt::ConnectionType connectionType = Qt::AutoConnection; if (QThread::currentThread() != toolbarProxy->thread()) { connectionType = Qt::BlockingQueuedConnection; } guard.unlock(); // copy properties from tablet button proxy to toolbar button proxy. QObject* toolbarButtonProxy = nullptr; bool hasResult = QMetaObject::invokeMethod(toolbarProxy, "addButton", connectionType, Q_RETURN_ARG(QObject*, toolbarButtonProxy), Q_ARG(QVariant, tabletButtonProxy->getProperties())); if (hasResult) { tabletButtonProxy->setToolbarButtonProxy(toolbarButtonProxy); } else { qCWarning(scriptengine) << "ToolbarProxy addButton has no result"; } } return tabletButtonProxy.data(); } bool TabletProxy::onHomeScreen() { return _state == State::Home; } void TabletProxy::removeButton(QObject* tabletButtonProxy) { std::unique_lock<std::mutex> guard(_tabletMutex); auto tablet = getQmlTablet(); if (!tablet) { qCCritical(scriptengine) << "Could not find tablet in TabletRoot.qml"; } QSharedPointer<TabletButtonProxy> buttonProxy; { auto iter = std::find(_tabletButtonProxies.begin(), _tabletButtonProxies.end(), tabletButtonProxy); if (iter == _tabletButtonProxies.end()) { qCWarning(scriptengine) << "TabletProxy::removeButton() could not find button " << tabletButtonProxy; return; } buttonProxy = *iter; _tabletButtonProxies.erase(iter); } if (!_toolbarMode && _qmlTabletRoot) { buttonProxy->setQmlButton(nullptr); if (tablet) { guard.unlock(); QMetaObject::invokeMethod(tablet, "removeButtonProxy", Qt::AutoConnection, Q_ARG(QVariant, buttonProxy->getProperties())); } } else if (_toolbarMode) { auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>(); QObject* toolbarProxy = tabletScriptingInterface->getSystemToolbarProxy(); // remove button from toolbarProxy guard.unlock(); QMetaObject::invokeMethod(toolbarProxy, "removeButton", Qt::AutoConnection, Q_ARG(QVariant, buttonProxy->getUuid().toString())); buttonProxy->setToolbarButtonProxy(nullptr); } } void TabletProxy::updateAudioBar(const double micLevel) { auto tablet = getQmlTablet(); if (!tablet) { //qCCritical(scriptengine) << "Could not find tablet in TabletRoot.qml"; } else { QMetaObject::invokeMethod(tablet, "setMicLevel", Qt::AutoConnection, Q_ARG(QVariant, QVariant(micLevel))); } } void TabletProxy::emitScriptEvent(QVariant msg) { if (!_toolbarMode && _qmlOffscreenSurface) { QMetaObject::invokeMethod(_qmlOffscreenSurface, "emitScriptEvent", Qt::AutoConnection, Q_ARG(QVariant, msg)); } else if (_toolbarMode && _desktopWindow) { QMetaObject::invokeMethod(_desktopWindow, "emitScriptEvent", Qt::AutoConnection, Q_ARG(QVariant, msg)); } } void TabletProxy::sendToQml(QVariant msg) { if (!_toolbarMode && _qmlOffscreenSurface) { QMetaObject::invokeMethod(_qmlOffscreenSurface, "sendToQml", Qt::AutoConnection, Q_ARG(QVariant, msg)); } else if (_toolbarMode && _desktopWindow) { QMetaObject::invokeMethod(_desktopWindow, "sendToQml", Qt::AutoConnection, Q_ARG(QVariant, msg)); } } void TabletProxy::addButtonsToHomeScreen() { auto tablet = getQmlTablet(); if (!tablet || _toolbarMode) { return; } auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>(); for (auto& buttonProxy : _tabletButtonProxies) { addButtonProxyToQmlTablet(tablet, buttonProxy.data()); } auto loader = _qmlTabletRoot->findChild<QQuickItem*>("loader"); QObject::disconnect(loader, SIGNAL(loaded()), this, SLOT(addButtonsToHomeScreen())); } QObject* TabletProxy::getTabletSurface() { return _qmlOffscreenSurface; } void TabletProxy::removeButtonsFromHomeScreen() { auto tablet = getQmlTablet(); for (auto& buttonProxy : _tabletButtonProxies) { if (tablet) { QMetaObject::invokeMethod(tablet, "removeButtonProxy", Qt::AutoConnection, Q_ARG(QVariant, buttonProxy->getProperties())); } buttonProxy->setQmlButton(nullptr); } } void TabletProxy::desktopWindowClosed() { gotoHomeScreen(); } void TabletProxy::addButtonsToToolbar() { auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>(); QObject* toolbarProxy = tabletScriptingInterface->getSystemToolbarProxy(); Qt::ConnectionType connectionType = Qt::AutoConnection; if (QThread::currentThread() != toolbarProxy->thread()) { connectionType = Qt::BlockingQueuedConnection; } for (auto& buttonProxy : _tabletButtonProxies) { // copy properties from tablet button proxy to toolbar button proxy. QObject* toolbarButtonProxy = nullptr; bool hasResult = QMetaObject::invokeMethod(toolbarProxy, "addButton", connectionType, Q_RETURN_ARG(QObject*, toolbarButtonProxy), Q_ARG(QVariant, buttonProxy->getProperties())); if (hasResult) { buttonProxy->setToolbarButtonProxy(toolbarButtonProxy); } else { qCWarning(scriptengine) << "ToolbarProxy addButton has no result"; } } // make the toolbar visible QMetaObject::invokeMethod(toolbarProxy, "writeProperty", Qt::AutoConnection, Q_ARG(QString, "visible"), Q_ARG(QVariant, QVariant(true))); } void TabletProxy::removeButtonsFromToolbar() { auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>(); QObject* toolbarProxy = tabletScriptingInterface->getSystemToolbarProxy(); for (auto& buttonProxy : _tabletButtonProxies) { // remove button from toolbarProxy QMetaObject::invokeMethod(toolbarProxy, "removeButton", Qt::AutoConnection, Q_ARG(QVariant, buttonProxy->getUuid().toString())); buttonProxy->setToolbarButtonProxy(nullptr); } } QQuickItem* TabletProxy::getQmlTablet() const { if (!_qmlTabletRoot) { return nullptr; } auto loader = _qmlTabletRoot->findChild<QQuickItem*>("loader"); if (!loader) { return nullptr; } auto tablet = loader->findChild<QQuickItem*>("tablet"); if (!tablet) { return nullptr; } return tablet; } QQuickItem* TabletProxy::getQmlMenu() const { if (!_qmlTabletRoot) { return nullptr; } auto loader = _qmlTabletRoot->findChild<QQuickItem*>("loader"); if (!loader) { return nullptr; } QQuickItem* VrMenu = loader->findChild<QQuickItem*>("tabletMenu"); if (!VrMenu) { return nullptr; } QQuickItem* menuList = VrMenu->findChild<QQuickItem*>("tabletMenuHandlerItem"); if (!menuList) { return nullptr; } return menuList; } // // TabletButtonProxy // const QString UUID_KEY = "uuid"; const QString OBJECT_NAME_KEY = "objectName"; const QString STABLE_ORDER_KEY = "stableOrder"; static int s_stableOrder = 1; TabletButtonProxy::TabletButtonProxy(const QVariantMap& properties) : _uuid(QUuid::createUuid()), _stableOrder(++s_stableOrder), _properties(properties) { // this is used to uniquely identify this button. _properties[UUID_KEY] = _uuid; _properties[OBJECT_NAME_KEY] = _uuid.toString(); _properties[STABLE_ORDER_KEY] = _stableOrder; } void TabletButtonProxy::setQmlButton(QQuickItem* qmlButton) { std::lock_guard<std::mutex> guard(_buttonMutex); _qmlButton = qmlButton; } void TabletButtonProxy::setToolbarButtonProxy(QObject* toolbarButtonProxy) { std::lock_guard<std::mutex> guard(_buttonMutex); _toolbarButtonProxy = toolbarButtonProxy; if (_toolbarButtonProxy) { QObject::connect(_toolbarButtonProxy, SIGNAL(clicked()), this, SLOT(clickedSlot())); } } QVariantMap TabletButtonProxy::getProperties() const { std::lock_guard<std::mutex> guard(_buttonMutex); return _properties; } void TabletButtonProxy::editProperties(QVariantMap properties) { std::lock_guard<std::mutex> guard(_buttonMutex); QVariantMap::const_iterator iter = properties.constBegin(); while (iter != properties.constEnd()) { _properties[iter.key()] = iter.value(); if (_qmlButton) { QMetaObject::invokeMethod(_qmlButton, "changeProperty", Qt::AutoConnection, Q_ARG(QVariant, QVariant(iter.key())), Q_ARG(QVariant, iter.value())); } ++iter; } if (_toolbarButtonProxy) { QMetaObject::invokeMethod(_toolbarButtonProxy, "editProperties", Qt::AutoConnection, Q_ARG(QVariantMap, properties)); } } #include "TabletScriptingInterface.moc"