mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 04:44:11 +02:00
Merge pull request #9295 from hyperlogic/tablet-ui
Make eventBridge work for web pages on tablet.
This commit is contained in:
commit
0c2d08db4a
7 changed files with 141 additions and 22 deletions
|
@ -3,6 +3,7 @@ import QtQuick 2.0
|
|||
Item {
|
||||
id: tabletRoot
|
||||
objectName: "tabletRoot"
|
||||
property var eventBridge;
|
||||
|
||||
function loadSource(url) {
|
||||
loader.source = url;
|
||||
|
@ -19,6 +20,13 @@ Item {
|
|||
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
onLoaded: {
|
||||
// propogate eventBridge to WebEngineView
|
||||
if (loader.item.hasOwnProperty("eventBridge")) {
|
||||
loader.item.eventBridge = eventBridge;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
width: 480
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import QtQuick 2.0
|
||||
import QtWebEngine 1.2
|
||||
|
||||
WebEngineView {
|
||||
id: webEngineView
|
||||
height: parent.height
|
||||
width: parent.width
|
||||
import "../../controls" as Controls
|
||||
|
||||
Controls.WebView {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ Web3DOverlay::~Web3DOverlay() {
|
|||
|
||||
if (rootItem && rootItem->objectName() == "tabletRoot") {
|
||||
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
|
||||
tabletScriptingInterface->setQmlTabletRoot("com.highfidelity.interface.tablet.system", nullptr);
|
||||
tabletScriptingInterface->setQmlTabletRoot("com.highfidelity.interface.tablet.system", nullptr, nullptr);
|
||||
}
|
||||
|
||||
// Fix for crash in QtWebEngineCore when rapidly switching domains
|
||||
|
@ -138,7 +138,7 @@ void Web3DOverlay::loadSourceURL() {
|
|||
|
||||
if (_webSurface->getRootItem() && _webSurface->getRootItem()->objectName() == "tabletRoot") {
|
||||
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
|
||||
tabletScriptingInterface->setQmlTabletRoot("com.highfidelity.interface.tablet.system", _webSurface->getRootItem());
|
||||
tabletScriptingInterface->setQmlTabletRoot("com.highfidelity.interface.tablet.system", _webSurface->getRootItem(), _webSurface.data());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -268,7 +268,7 @@ void RenderableWebEntityItem::loadSourceURL() {
|
|||
|
||||
if (_webSurface->getRootItem() && _webSurface->getRootItem()->objectName() == "tabletRoot") {
|
||||
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
|
||||
tabletScriptingInterface->setQmlTabletRoot("com.highfidelity.interface.tablet.system", _webSurface->getRootItem());
|
||||
tabletScriptingInterface->setQmlTabletRoot("com.highfidelity.interface.tablet.system", _webSurface->getRootItem(), _webSurface.data());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -372,7 +372,7 @@ void RenderableWebEntityItem::destroyWebSurface() {
|
|||
|
||||
if (rootItem && rootItem->objectName() == "tabletRoot") {
|
||||
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
|
||||
tabletScriptingInterface->setQmlTabletRoot("com.highfidelity.interface.tablet.system", nullptr);
|
||||
tabletScriptingInterface->setQmlTabletRoot("com.highfidelity.interface.tablet.system", nullptr, nullptr);
|
||||
}
|
||||
|
||||
// Fix for crash in QtWebEngineCore when rapidly switching domains
|
||||
|
|
|
@ -29,10 +29,10 @@ QObject* TabletScriptingInterface::getTablet(const QString& tabletId) {
|
|||
}
|
||||
}
|
||||
|
||||
void TabletScriptingInterface::setQmlTabletRoot(QString tabletId, QQuickItem* qmlTabletRoot) {
|
||||
void TabletScriptingInterface::setQmlTabletRoot(QString tabletId, QQuickItem* qmlTabletRoot, QObject* qmlOffscreenSurface) {
|
||||
TabletProxy* tablet = qobject_cast<TabletProxy*>(getTablet(tabletId));
|
||||
if (tablet) {
|
||||
tablet->setQmlTabletRoot(qmlTabletRoot);
|
||||
if (tablet && qmlOffscreenSurface) {
|
||||
tablet->setQmlTabletRoot(qmlTabletRoot, qmlOffscreenSurface);
|
||||
} else {
|
||||
qCWarning(scriptengine) << "TabletScriptingInterface::setupTablet() bad tablet object";
|
||||
}
|
||||
|
@ -72,10 +72,12 @@ static void addButtonProxyToQmlTablet(QQuickItem* qmlTablet, TabletButtonProxy*
|
|||
buttonProxy->setQmlButton(qobject_cast<QQuickItem*>(qmlButton));
|
||||
}
|
||||
|
||||
void TabletProxy::setQmlTabletRoot(QQuickItem* qmlTabletRoot) {
|
||||
void TabletProxy::setQmlTabletRoot(QQuickItem* qmlTabletRoot, QObject* qmlOffscreenSurface) {
|
||||
std::lock_guard<std::mutex> guard(_mutex);
|
||||
_qmlOffscreenSurface = qmlOffscreenSurface;
|
||||
_qmlTabletRoot = qmlTabletRoot;
|
||||
if (_qmlTabletRoot) {
|
||||
if (_qmlTabletRoot && _qmlOffscreenSurface) {
|
||||
QObject::connect(_qmlOffscreenSurface, SIGNAL(webEventReceived(QVariant)), this, SIGNAL(webEventReceived(QVariant)));
|
||||
gotoHomeScreen();
|
||||
} else {
|
||||
removeButtonsFromHomeScreen();
|
||||
|
@ -150,6 +152,12 @@ void TabletProxy::updateAudioBar(const double micLevel) {
|
|||
}
|
||||
}
|
||||
|
||||
void TabletProxy::emitScriptEvent(QVariant msg) {
|
||||
if (_qmlOffscreenSurface) {
|
||||
QMetaObject::invokeMethod(_qmlOffscreenSurface, "emitScriptEvent", Qt::AutoConnection, Q_ARG(QVariant, msg));
|
||||
}
|
||||
}
|
||||
|
||||
void TabletProxy::addButtonsToHomeScreen() {
|
||||
auto tablet = getQmlTablet();
|
||||
if (!tablet) {
|
||||
|
|
|
@ -37,7 +37,7 @@ public:
|
|||
*/
|
||||
Q_INVOKABLE QObject* getTablet(const QString& tabletId);
|
||||
|
||||
void setQmlTabletRoot(QString tabletId, QQuickItem* qmlTabletRoot);
|
||||
void setQmlTabletRoot(QString tabletId, QQuickItem* qmlTabletRoot, QObject* qmlOffscreenSurface);
|
||||
|
||||
protected:
|
||||
std::mutex _mutex;
|
||||
|
@ -46,7 +46,7 @@ protected:
|
|||
|
||||
/**jsdoc
|
||||
* @class TabletProxy
|
||||
* @property name {string} name of this tablet
|
||||
* @property name {string} READ_ONLY: name of this tablet
|
||||
*/
|
||||
class TabletProxy : public QObject {
|
||||
Q_OBJECT
|
||||
|
@ -54,32 +54,32 @@ class TabletProxy : public QObject {
|
|||
public:
|
||||
TabletProxy(QString name);
|
||||
|
||||
void setQmlTabletRoot(QQuickItem* qmlTabletRoot);
|
||||
void setQmlTabletRoot(QQuickItem* qmlTabletRoot, QObject* qmlOffscreenSurface);
|
||||
|
||||
/**jsdoc
|
||||
* @function TabletProxy#gotoHomeScreen
|
||||
* transition to the home screen
|
||||
* @function TabletProxy#gotoHomeScreen
|
||||
*/
|
||||
Q_INVOKABLE void gotoHomeScreen();
|
||||
|
||||
/**jsdoc
|
||||
* @function TabletProxy#gotoWebScreen
|
||||
* show the specified web url on the tablet.
|
||||
* @function TabletProxy#gotoWebScreen
|
||||
* @param url {string}
|
||||
*/
|
||||
Q_INVOKABLE void gotoWebScreen(const QString& url);
|
||||
|
||||
/**jsdoc
|
||||
* @function TabletProxy#addButton
|
||||
* Creates a new button, adds it to this and returns it.
|
||||
* @function TabletProxy#addButton
|
||||
* @param properties {Object} button properties UI_TABLET_HACK: enumerate these when we figure out what they should be!
|
||||
* @returns {TabletButtonProxy}
|
||||
*/
|
||||
Q_INVOKABLE QObject* addButton(const QVariant& properties);
|
||||
|
||||
/**jsdoc
|
||||
* @function TabletProxy#removeButton
|
||||
* removes button from the tablet
|
||||
* @function TabletProxy.removeButton
|
||||
* @param tabletButtonProxy {TabletButtonProxy} button to be removed
|
||||
*/
|
||||
Q_INVOKABLE void removeButton(QObject* tabletButtonProxy);
|
||||
|
@ -90,8 +90,25 @@ public:
|
|||
* @param micLevel {double} mic level value between 0 and 1
|
||||
*/
|
||||
Q_INVOKABLE void updateAudioBar(const double micLevel);
|
||||
|
||||
|
||||
QString getName() const { return _name; }
|
||||
|
||||
/**jsdoc
|
||||
* Used to send an event to the html/js embedded in the tablet
|
||||
* @function TabletProxy#emitScriptEvent
|
||||
* @param msg {object|string}
|
||||
*/
|
||||
Q_INVOKABLE void emitScriptEvent(QVariant msg);
|
||||
|
||||
signals:
|
||||
/**jsdoc
|
||||
* Signaled when this tablet receives an event from the html/js embedded in the tablet
|
||||
* @function TabletProxy#webEventReceived
|
||||
* @param msg {object|string}
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void webEventReceived(QVariant msg);
|
||||
|
||||
protected:
|
||||
|
||||
void addButtonsToHomeScreen();
|
||||
|
@ -102,19 +119,23 @@ protected:
|
|||
std::mutex _mutex;
|
||||
std::vector<QSharedPointer<TabletButtonProxy>> _tabletButtonProxies;
|
||||
QQuickItem* _qmlTabletRoot { nullptr };
|
||||
QObject* _qmlOffscreenSurface { nullptr };
|
||||
};
|
||||
|
||||
/**jsdoc
|
||||
* @class TabletButtonProxy
|
||||
* @property imageUrl {string}
|
||||
* @property uuid {QUuid} READ_ONLY: uniquely identifies this button
|
||||
*/
|
||||
class TabletButtonProxy : public QObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QUuid uuid READ getUuid)
|
||||
public:
|
||||
TabletButtonProxy(const QVariantMap& properties);
|
||||
|
||||
void setQmlButton(QQuickItem* qmlButton);
|
||||
|
||||
QUuid getUuid() const { return _uuid; }
|
||||
|
||||
/**jsdoc
|
||||
* Returns the current value of this button's properties
|
||||
* @function TabletButtonProxy#getProperties
|
||||
|
|
81
scripts/developer/tests/tabletEventBridgeTest.js
Normal file
81
scripts/developer/tests/tabletEventBridgeTest.js
Normal file
|
@ -0,0 +1,81 @@
|
|||
//
|
||||
// tabletEventBridgeTest.js
|
||||
//
|
||||
// Created by Anthony J. Thibault on 2016-12-15
|
||||
// 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
|
||||
//
|
||||
|
||||
// Adds a button to the tablet that will switch to a web page.
|
||||
// This web page contains buttons that will use the event bridge to trigger sounds.
|
||||
|
||||
/* globals Tablet */
|
||||
|
||||
|
||||
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||
var tabletButton = tablet.addButton({
|
||||
text: "SOUNDS"
|
||||
});
|
||||
|
||||
var WEB_BRIDGE_TEST_HTML = "https://s3.amazonaws.com/hifi-public/tony/webBridgeTest.html?2";
|
||||
|
||||
var TROMBONE_URL = "https://s3.amazonaws.com/hifi-public/tony/audio/sad-trombone.wav";
|
||||
var tromboneSound = SoundCache.getSound(TROMBONE_URL);
|
||||
var tromboneInjector;
|
||||
|
||||
var SCREAM_URL = "https://s3.amazonaws.com/hifi-public/tony/audio/wilhelm-scream.wav";
|
||||
var screamSound = SoundCache.getSound(SCREAM_URL);
|
||||
var screamInjector;
|
||||
|
||||
tabletButton.clicked.connect(function () {
|
||||
tablet.gotoWebScreen(WEB_BRIDGE_TEST_HTML);
|
||||
});
|
||||
|
||||
// hook up to the event bridge
|
||||
tablet.webEventReceived.connect(function (msg) {
|
||||
Script.print("HIFI: recv web event = " + JSON.stringify(msg));
|
||||
if (msg === "button-1-play") {
|
||||
|
||||
// play sad trombone
|
||||
if (tromboneSound.downloaded) {
|
||||
if (tromboneInjector) {
|
||||
tromboneInjector.restart();
|
||||
} else {
|
||||
tromboneInjector = Audio.playSound(tromboneSound, { position: MyAvatar.position,
|
||||
volume: 1.0,
|
||||
loop: false });
|
||||
}
|
||||
}
|
||||
|
||||
// wait until sound is finished then send a done event
|
||||
Script.setTimeout(function () {
|
||||
tablet.emitScriptEvent("button-1-done");
|
||||
}, 3500);
|
||||
}
|
||||
|
||||
if (msg === "button-2-play") {
|
||||
|
||||
// play scream
|
||||
if (screamSound.downloaded) {
|
||||
if (screamInjector) {
|
||||
screamInjector.restart();
|
||||
} else {
|
||||
screamInjector = Audio.playSound(screamSound, { position: MyAvatar.position,
|
||||
volume: 1.0,
|
||||
loop: false });
|
||||
}
|
||||
}
|
||||
|
||||
// wait until sound is finished then send a done event
|
||||
Script.setTimeout(function () {
|
||||
tablet.emitScriptEvent("button-2-done");
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
|
||||
Script.scriptEnding.connect(function () {
|
||||
tablet.removeButton(tabletButton);
|
||||
});
|
||||
|
Loading…
Reference in a new issue