mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 14:47:51 +02:00
Whitelist functionality for tablet apps
This commit is contained in:
parent
ff36cbf45f
commit
d162e1cff6
28 changed files with 284 additions and 218 deletions
18
interface/resources/qml/OverlayWindowTest.qml
Normal file
18
interface/resources/qml/OverlayWindowTest.qml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import QtQuick 2.5
|
||||||
|
import QtQuick.Controls 1.4
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 100
|
||||||
|
height: 100
|
||||||
|
color: "white"
|
||||||
|
Rectangle {
|
||||||
|
width: 10
|
||||||
|
height: 10
|
||||||
|
color: "red"
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: OverlayWindowTestString
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,7 +22,6 @@ Windows.Window {
|
||||||
// Don't destroy on close... otherwise the JS/C++ will have a dangling pointer
|
// Don't destroy on close... otherwise the JS/C++ will have a dangling pointer
|
||||||
destroyOnCloseButton: false
|
destroyOnCloseButton: false
|
||||||
property var source;
|
property var source;
|
||||||
property var component;
|
|
||||||
property var dynamicContent;
|
property var dynamicContent;
|
||||||
|
|
||||||
// Keyboard control properties in case needed by QML content.
|
// Keyboard control properties in case needed by QML content.
|
||||||
|
@ -35,28 +34,9 @@ Windows.Window {
|
||||||
dynamicContent.destroy();
|
dynamicContent.destroy();
|
||||||
dynamicContent = null;
|
dynamicContent = null;
|
||||||
}
|
}
|
||||||
component = Qt.createComponent(source);
|
QmlSurface.load(source, contentHolder, function(newObject) {
|
||||||
console.log("Created component " + component + " from source " + source);
|
dynamicContent = newObject;
|
||||||
}
|
});
|
||||||
|
|
||||||
onComponentChanged: {
|
|
||||||
console.log("Component changed to " + component)
|
|
||||||
populate();
|
|
||||||
}
|
|
||||||
|
|
||||||
function populate() {
|
|
||||||
console.log("Populate called: dynamicContent " + dynamicContent + " component " + component);
|
|
||||||
if (!dynamicContent && component) {
|
|
||||||
if (component.status == Component.Error) {
|
|
||||||
console.log("Error loading component:", component.errorString());
|
|
||||||
} else if (component.status == Component.Ready) {
|
|
||||||
console.log("Building dynamic content");
|
|
||||||
dynamicContent = component.createObject(contentHolder);
|
|
||||||
} else {
|
|
||||||
console.log("Component not yet ready, connecting to status change");
|
|
||||||
component.statusChanged.connect(populate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle message traffic from the script that launched us to the loaded QML
|
// Handle message traffic from the script that launched us to the loaded QML
|
||||||
|
|
|
@ -2,6 +2,7 @@ import QtQuick 2.5
|
||||||
import QtGraphicalEffects 1.0
|
import QtGraphicalEffects 1.0
|
||||||
import QtQuick.Layouts 1.3
|
import QtQuick.Layouts 1.3
|
||||||
|
|
||||||
|
import "."
|
||||||
import "../../styles-uit"
|
import "../../styles-uit"
|
||||||
import "../audio" as HifiAudio
|
import "../audio" as HifiAudio
|
||||||
|
|
||||||
|
@ -12,6 +13,31 @@ Item {
|
||||||
property int columnIndex: 0
|
property int columnIndex: 0
|
||||||
property int count: (flowMain.children.length - 1)
|
property int count: (flowMain.children.length - 1)
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: buttonComponent
|
||||||
|
TabletButton { }
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
tablet.populateButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
function createClickedHandler(proxy) {
|
||||||
|
return function() { proxy.clicked(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
function populateButtons() {
|
||||||
|
var tabletProxy = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||||
|
var buttons = tabletProxy.getButtons();
|
||||||
|
for (var i = 0; i < buttons.length; i++) {
|
||||||
|
var proxy = buttons[i];
|
||||||
|
var button = tablet.addButtonProxy(proxy.getProperties());
|
||||||
|
button.clicked.connect(createClickedHandler(proxy));
|
||||||
|
proxy.setQmlButton(button);
|
||||||
|
}
|
||||||
|
sortButtons();
|
||||||
|
}
|
||||||
|
|
||||||
// used to look up a button by its uuid
|
// used to look up a button by its uuid
|
||||||
function findButtonIndex(uuid) {
|
function findButtonIndex(uuid) {
|
||||||
if (!uuid) {
|
if (!uuid) {
|
||||||
|
@ -47,9 +73,7 @@ Item {
|
||||||
|
|
||||||
// called by C++ code when a button should be added to the tablet
|
// called by C++ code when a button should be added to the tablet
|
||||||
function addButtonProxy(properties) {
|
function addButtonProxy(properties) {
|
||||||
var component = Qt.createComponent("TabletButton.qml");
|
var button = buttonComponent.createObject(flowMain);
|
||||||
var button = component.createObject(flowMain);
|
|
||||||
|
|
||||||
// copy all properites to button
|
// copy all properites to button
|
||||||
var keys = Object.keys(properties).forEach(function (key) {
|
var keys = Object.keys(properties).forEach(function (key) {
|
||||||
button[key] = properties[key];
|
button[key] = properties[key];
|
||||||
|
@ -62,8 +86,6 @@ Item {
|
||||||
button.tabletRoot = parent.parent;
|
button.tabletRoot = parent.parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
sortButtons();
|
|
||||||
|
|
||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,11 +105,8 @@ Item {
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
top: parent.top
|
top: parent.top
|
||||||
topMargin: 0
|
|
||||||
left: parent.left
|
left: parent.left
|
||||||
leftMargin: 0
|
|
||||||
right: parent.right
|
right: parent.right
|
||||||
rightMargin: 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gradient: Gradient {
|
gradient: Gradient {
|
||||||
|
|
|
@ -68,18 +68,17 @@ Item {
|
||||||
|
|
||||||
function loadSource(url) {
|
function loadSource(url) {
|
||||||
tabletApps.clear();
|
tabletApps.clear();
|
||||||
loader.source = ""; // make sure we load the qml fresh each time.
|
loader.load(url)
|
||||||
loader.source = url;
|
tabletApps.append({"appUrl": url, "isWebUrl": false, "scriptUrl": "", "appWebUrl": ""});
|
||||||
tabletApps.append({"appUrl": url, "isWebUrl": false, "scriptUrl": "", "appWebUrl": ""});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadQMLOnTop(url) {
|
function loadQMLOnTop(url) {
|
||||||
tabletApps.append({"appUrl": url, "isWebUrl": false, "scriptUrl": "", "appWebUrl": ""});
|
tabletApps.append({"appUrl": url, "isWebUrl": false, "scriptUrl": "", "appWebUrl": ""});
|
||||||
loader.source = "";
|
loader.load(tabletApps.get(currentApp).appUrl, function(){
|
||||||
loader.source = tabletApps.get(currentApp).appUrl;
|
if (loader.item.hasOwnProperty("gotoPreviousApp")) {
|
||||||
if (loader.item.hasOwnProperty("gotoPreviousApp")) {
|
loader.item.gotoPreviousApp = true;
|
||||||
loader.item.gotoPreviousApp = true;
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadWebOnTop(url, injectJavaScriptUrl) {
|
function loadWebOnTop(url, injectJavaScriptUrl) {
|
||||||
|
@ -92,13 +91,11 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadWebBase() {
|
function loadWebBase() {
|
||||||
loader.source = "";
|
loader.load("hifi/tablet/TabletWebView.qml");
|
||||||
loader.source = "TabletWebView.qml";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadTabletWebBase() {
|
function loadTabletWebBase() {
|
||||||
loader.source = "";
|
loader.load("hifi/tablet/BlocksWebView.qml");
|
||||||
loader.source = "./BlocksWebView.qml";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function returnToPreviousApp() {
|
function returnToPreviousApp() {
|
||||||
|
@ -110,7 +107,7 @@ Item {
|
||||||
loadSource("TabletWebView.qml");
|
loadSource("TabletWebView.qml");
|
||||||
loadWebUrl(webUrl, scriptUrl);
|
loadWebUrl(webUrl, scriptUrl);
|
||||||
} else {
|
} else {
|
||||||
loader.source = tabletApps.get(currentApp).appUrl;
|
loader.load(tabletApps.get(currentApp).appUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,47 +170,72 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
// Hook up callback for clara.io download from the marketplace.
|
||||||
id: loader
|
Connections {
|
||||||
objectName: "loader"
|
id: eventBridgeConnection
|
||||||
asynchronous: false
|
target: eventBridge
|
||||||
|
onWebEventReceived: {
|
||||||
width: parent.width
|
if (message.slice(0, 17) === "CLARA.IO DOWNLOAD") {
|
||||||
height: parent.height
|
ApplicationInterface.addAssetToWorldFromURL(message.slice(18));
|
||||||
|
|
||||||
// Hook up callback for clara.io download from the marketplace.
|
|
||||||
Connections {
|
|
||||||
id: eventBridgeConnection
|
|
||||||
target: eventBridge
|
|
||||||
onWebEventReceived: {
|
|
||||||
if (message.slice(0, 17) === "CLARA.IO DOWNLOAD") {
|
|
||||||
ApplicationInterface.addAssetToWorldFromURL(message.slice(18));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onLoaded: {
|
|
||||||
if (loader.item.hasOwnProperty("sendToScript")) {
|
|
||||||
loader.item.sendToScript.connect(tabletRoot.sendToScript);
|
|
||||||
}
|
|
||||||
if (loader.item.hasOwnProperty("setRootMenu")) {
|
|
||||||
loader.item.setRootMenu(tabletRoot.rootMenu, tabletRoot.subMenu);
|
|
||||||
}
|
|
||||||
loader.item.forceActiveFocus();
|
|
||||||
|
|
||||||
if (openModal) {
|
|
||||||
openModal.canceled();
|
|
||||||
openModal.destroy();
|
|
||||||
openModal = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (openBrowser) {
|
|
||||||
openBrowser.destroy();
|
|
||||||
openBrowser = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: loader
|
||||||
|
objectName: "loader";
|
||||||
|
anchors.fill: parent;
|
||||||
|
property string source: "";
|
||||||
|
property var item: null;
|
||||||
|
signal loaded;
|
||||||
|
|
||||||
|
onWidthChanged: {
|
||||||
|
if (loader.item) {
|
||||||
|
loader.item.width = loader.width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onHeightChanged: {
|
||||||
|
if (loader.item) {
|
||||||
|
loader.item.height = loader.height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function load(newSource, callback) {
|
||||||
|
loader.source = newSource;
|
||||||
|
loader.item = null;
|
||||||
|
QmlSurface.load(newSource, loader, function(newItem) {
|
||||||
|
loader.item = newItem;
|
||||||
|
loader.item.width = loader.width;
|
||||||
|
loader.item.height = loader.height;
|
||||||
|
loader.loaded();
|
||||||
|
if (loader.item.hasOwnProperty("sendToScript")) {
|
||||||
|
loader.item.sendToScript.connect(tabletRoot.sendToScript);
|
||||||
|
}
|
||||||
|
if (loader.item.hasOwnProperty("setRootMenu")) {
|
||||||
|
loader.item.setRootMenu(tabletRoot.rootMenu, tabletRoot.subMenu);
|
||||||
|
}
|
||||||
|
loader.item.forceActiveFocus();
|
||||||
|
|
||||||
|
if (openModal) {
|
||||||
|
openModal.canceled();
|
||||||
|
openModal.destroy();
|
||||||
|
openModal = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (openBrowser) {
|
||||||
|
openBrowser.destroy();
|
||||||
|
openBrowser = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callback) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log("QQQ done calling QmlSurface.load")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
width: 480
|
width: 480
|
||||||
height: 706
|
height: 706
|
||||||
|
|
||||||
|
|
|
@ -2214,6 +2214,16 @@ extern void setupPreferences();
|
||||||
void Application::initializeUi() {
|
void Application::initializeUi() {
|
||||||
// Make sure all QML surfaces share the main thread GL context
|
// Make sure all QML surfaces share the main thread GL context
|
||||||
OffscreenQmlSurface::setSharedContext(_offscreenContext->getContext());
|
OffscreenQmlSurface::setSharedContext(_offscreenContext->getContext());
|
||||||
|
OffscreenQmlSurface::addWhitelistContextHandler(QUrl{ "qrc:///qml/OverlayWindowTest.qml" },
|
||||||
|
[](QQmlContext* context) {
|
||||||
|
qDebug() << "Whitelist OverlayWindow worked";
|
||||||
|
context->setContextProperty("OverlayWindowTestString", "TestWorked");
|
||||||
|
});
|
||||||
|
OffscreenQmlSurface::addWhitelistContextHandler(QUrl{ "qrc:///qml/hifi/audio/Audio.qml" },
|
||||||
|
[](QQmlContext* context) {
|
||||||
|
qDebug() << "QQQ" << __FUNCTION__ << "Whitelist Audio worked";
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
AddressBarDialog::registerType();
|
AddressBarDialog::registerType();
|
||||||
ErrorDialog::registerType();
|
ErrorDialog::registerType();
|
||||||
|
@ -2230,10 +2240,9 @@ void Application::initializeUi() {
|
||||||
auto surfaceContext = offscreenUi->getSurfaceContext();
|
auto surfaceContext = offscreenUi->getSurfaceContext();
|
||||||
|
|
||||||
offscreenUi->setProxyWindow(_window->windowHandle());
|
offscreenUi->setProxyWindow(_window->windowHandle());
|
||||||
offscreenUi->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/"));
|
|
||||||
// OffscreenUi is a subclass of OffscreenQmlSurface specifically designed to
|
// OffscreenUi is a subclass of OffscreenQmlSurface specifically designed to
|
||||||
// support the window management and scripting proxies for VR use
|
// support the window management and scripting proxies for VR use
|
||||||
offscreenUi->createDesktop(QString("qrc:///qml/hifi/Desktop.qml"));
|
offscreenUi->createDesktop(QString("hifi/Desktop.qml"));
|
||||||
|
|
||||||
// FIXME either expose so that dialogs can set this themselves or
|
// FIXME either expose so that dialogs can set this themselves or
|
||||||
// do better detection in the offscreen UI of what has focus
|
// do better detection in the offscreen UI of what has focus
|
||||||
|
@ -7194,13 +7203,17 @@ void Application::updateDisplayMode() {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
|
auto desktop = offscreenUi->getDesktop();
|
||||||
|
|
||||||
// Make the switch atomic from the perspective of other threads
|
// Make the switch atomic from the perspective of other threads
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(_displayPluginLock);
|
std::unique_lock<std::mutex> lock(_displayPluginLock);
|
||||||
// Tell the desktop to no reposition (which requires plugin info), until we have set the new plugin, below.
|
bool wasRepositionLocked = false;
|
||||||
bool wasRepositionLocked = offscreenUi->getDesktop()->property("repositionLocked").toBool();
|
if (desktop) {
|
||||||
offscreenUi->getDesktop()->setProperty("repositionLocked", true);
|
// Tell the desktop to no reposition (which requires plugin info), until we have set the new plugin, below.
|
||||||
|
wasRepositionLocked = offscreenUi->getDesktop()->property("repositionLocked").toBool();
|
||||||
|
offscreenUi->getDesktop()->setProperty("repositionLocked", true);
|
||||||
|
}
|
||||||
|
|
||||||
if (_displayPlugin) {
|
if (_displayPlugin) {
|
||||||
disconnect(_displayPlugin.get(), &DisplayPlugin::presented, this, &Application::onPresent);
|
disconnect(_displayPlugin.get(), &DisplayPlugin::presented, this, &Application::onPresent);
|
||||||
|
@ -7246,7 +7259,6 @@ void Application::updateDisplayMode() {
|
||||||
getApplicationCompositor().setDisplayPlugin(newDisplayPlugin);
|
getApplicationCompositor().setDisplayPlugin(newDisplayPlugin);
|
||||||
_displayPlugin = newDisplayPlugin;
|
_displayPlugin = newDisplayPlugin;
|
||||||
connect(_displayPlugin.get(), &DisplayPlugin::presented, this, &Application::onPresent, Qt::DirectConnection);
|
connect(_displayPlugin.get(), &DisplayPlugin::presented, this, &Application::onPresent, Qt::DirectConnection);
|
||||||
auto desktop = offscreenUi->getDesktop();
|
|
||||||
if (desktop) {
|
if (desktop) {
|
||||||
desktop->setProperty("repositionLocked", wasRepositionLocked);
|
desktop->setProperty("repositionLocked", wasRepositionLocked);
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,7 +101,7 @@ Menu::Menu() {
|
||||||
auto action = addActionToQMenuAndActionHash(editMenu, MenuOption::RunningScripts, Qt::CTRL | Qt::Key_J);
|
auto action = addActionToQMenuAndActionHash(editMenu, MenuOption::RunningScripts, Qt::CTRL | Qt::Key_J);
|
||||||
connect(action, &QAction::triggered, [] {
|
connect(action, &QAction::triggered, [] {
|
||||||
static const QUrl widgetUrl("hifi/dialogs/RunningScripts.qml");
|
static const QUrl widgetUrl("hifi/dialogs/RunningScripts.qml");
|
||||||
static const QUrl tabletUrl("../../hifi/dialogs/TabletRunningScripts.qml");
|
static const QUrl tabletUrl("hifi/dialogs/TabletRunningScripts.qml");
|
||||||
static const QString name("RunningScripts");
|
static const QString name("RunningScripts");
|
||||||
qApp->showDialog(widgetUrl, tabletUrl, name);
|
qApp->showDialog(widgetUrl, tabletUrl, name);
|
||||||
});
|
});
|
||||||
|
@ -338,7 +338,7 @@ Menu::Menu() {
|
||||||
connect(action, &QAction::triggered, [] {
|
connect(action, &QAction::triggered, [] {
|
||||||
auto tablet = DependencyManager::get<TabletScriptingInterface>()->getTablet("com.highfidelity.interface.tablet.system");
|
auto tablet = DependencyManager::get<TabletScriptingInterface>()->getTablet("com.highfidelity.interface.tablet.system");
|
||||||
auto hmd = DependencyManager::get<HMDScriptingInterface>();
|
auto hmd = DependencyManager::get<HMDScriptingInterface>();
|
||||||
tablet->loadQMLSource("ControllerSettings.qml");
|
tablet->loadQMLSource("hifi/tablet/ControllerSettings.qml");
|
||||||
|
|
||||||
if (!hmd->getShouldShowTablet()) {
|
if (!hmd->getShouldShowTablet()) {
|
||||||
hmd->toggleShouldShowTablet();
|
hmd->toggleShouldShowTablet();
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//
|
//
|
||||||
// WalletScriptingInterface.cpp
|
// WalletScriptingInterface.cpp
|
||||||
// interface/src/scripting
|
// interface/src/scripting
|
||||||
//
|
//
|
||||||
|
@ -23,7 +23,7 @@ void WalletScriptingInterface::refreshWalletStatus() {
|
||||||
wallet->getWalletStatus();
|
wallet->getWalletStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
static const QString CHECKOUT_QML_PATH = qApp->applicationDirPath() + "../../../qml/hifi/commerce/checkout/Checkout.qml";
|
static const QString CHECKOUT_QML_PATH = "hifi/commerce/checkout/Checkout.qml";
|
||||||
void WalletScriptingInterface::buy(const QString& name, const QString& id, const int& price, const QString& href) {
|
void WalletScriptingInterface::buy(const QString& name, const QString& id, const int& price, const QString& href) {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
QMetaObject::invokeMethod(this, "buy", Q_ARG(const QString&, name), Q_ARG(const QString&, id), Q_ARG(const int&, price), Q_ARG(const QString&, href));
|
QMetaObject::invokeMethod(this, "buy", Q_ARG(const QString&, name), Q_ARG(const QString&, id), Q_ARG(const int&, price), Q_ARG(const QString&, href));
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
|
|
||||||
#include "scripting/HMDScriptingInterface.h"
|
#include "scripting/HMDScriptingInterface.h"
|
||||||
|
|
||||||
static const QVariant TABLET_ADDRESS_DIALOG = "TabletAddressDialog.qml";
|
static const QVariant TABLET_ADDRESS_DIALOG = "hifi/tablet/TabletAddressDialog.qml";
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void DialogsManager::maybeCreateDialog(QPointer<T>& member) {
|
void DialogsManager::maybeCreateDialog(QPointer<T>& member) {
|
||||||
if (!member) {
|
if (!member) {
|
||||||
|
@ -91,7 +91,7 @@ void DialogsManager::setDomainConnectionFailureVisibility(bool visible) {
|
||||||
ConnectionFailureDialog::hide();
|
ConnectionFailureDialog::hide();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
static const QUrl url("../../dialogs/TabletConnectionFailureDialog.qml");
|
static const QUrl url("dialogs/TabletConnectionFailureDialog.qml");
|
||||||
auto hmd = DependencyManager::get<HMDScriptingInterface>();
|
auto hmd = DependencyManager::get<HMDScriptingInterface>();
|
||||||
if (visible) {
|
if (visible) {
|
||||||
tablet->initialScreen(url);
|
tablet->initialScreen(url);
|
||||||
|
|
|
@ -46,7 +46,7 @@ void LoginDialog::showWithSelection()
|
||||||
if (tablet->getToolbarMode()) {
|
if (tablet->getToolbarMode()) {
|
||||||
LoginDialog::show();
|
LoginDialog::show();
|
||||||
} else {
|
} else {
|
||||||
static const QUrl url("../../dialogs/TabletLoginDialog.qml");
|
static const QUrl url("dialogs/TabletLoginDialog.qml");
|
||||||
tablet->initialScreen(url);
|
tablet->initialScreen(url);
|
||||||
if (!hmd->getShouldShowTablet()) {
|
if (!hmd->getShouldShowTablet()) {
|
||||||
hmd->openTablet();
|
hmd->openTablet();
|
||||||
|
|
|
@ -264,7 +264,7 @@ void ContextOverlayInterface::contextOverlays_hoverLeaveEntity(const EntityItemI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const QString INSPECTION_CERTIFICATE_QML_PATH = qApp->applicationDirPath() + "../../../qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml";
|
static const QString INSPECTION_CERTIFICATE_QML_PATH = "hifi/commerce/inspectionCertificate/InspectionCertificate.qml";
|
||||||
void ContextOverlayInterface::openInspectionCertificate() {
|
void ContextOverlayInterface::openInspectionCertificate() {
|
||||||
// lets open the tablet to the inspection certificate QML
|
// lets open the tablet to the inspection certificate QML
|
||||||
if (!_currentEntityWithContextOverlay.isNull() && _entityMarketplaceID.length() > 0) {
|
if (!_currentEntityWithContextOverlay.isNull() && _entityMarketplaceID.length() > 0) {
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
using namespace render;
|
using namespace render;
|
||||||
using namespace render::entities;
|
using namespace render::entities;
|
||||||
|
|
||||||
|
static const QString WEB_ENTITY_QML = "controls/WebEntityView.qml";
|
||||||
|
|
||||||
const float METERS_TO_INCHES = 39.3701f;
|
const float METERS_TO_INCHES = 39.3701f;
|
||||||
static uint32_t _currentWebCount{ 0 };
|
static uint32_t _currentWebCount{ 0 };
|
||||||
// Don't allow more than 100 concurrent web views
|
// Don't allow more than 100 concurrent web views
|
||||||
|
@ -218,6 +220,7 @@ bool WebEntityRenderer::buildWebSurface(const TypedEntityPointer& entity) {
|
||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
|
// FIXME use the surface cache instead of explicit creation
|
||||||
_webSurface = QSharedPointer<OffscreenQmlSurface>(new OffscreenQmlSurface(), deleter);
|
_webSurface = QSharedPointer<OffscreenQmlSurface>(new OffscreenQmlSurface(), deleter);
|
||||||
_webSurface->create();
|
_webSurface->create();
|
||||||
}
|
}
|
||||||
|
@ -289,7 +292,6 @@ void WebEntityRenderer::loadSourceURL() {
|
||||||
if (sourceUrl.scheme() == "http" || sourceUrl.scheme() == "https" ||
|
if (sourceUrl.scheme() == "http" || sourceUrl.scheme() == "https" ||
|
||||||
_lastSourceUrl.toLower().endsWith(".htm") || _lastSourceUrl.toLower().endsWith(".html")) {
|
_lastSourceUrl.toLower().endsWith(".htm") || _lastSourceUrl.toLower().endsWith(".html")) {
|
||||||
_contentType = htmlContent;
|
_contentType = htmlContent;
|
||||||
_webSurface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "qml/controls/"));
|
|
||||||
|
|
||||||
// We special case YouTube URLs since we know they are videos that we should play with at least 30 FPS.
|
// We special case YouTube URLs since we know they are videos that we should play with at least 30 FPS.
|
||||||
if (sourceUrl.host().endsWith("youtube.com", Qt::CaseInsensitive)) {
|
if (sourceUrl.host().endsWith("youtube.com", Qt::CaseInsensitive)) {
|
||||||
|
@ -298,12 +300,11 @@ void WebEntityRenderer::loadSourceURL() {
|
||||||
_webSurface->setMaxFps(DEFAULT_MAX_FPS);
|
_webSurface->setMaxFps(DEFAULT_MAX_FPS);
|
||||||
}
|
}
|
||||||
|
|
||||||
_webSurface->load("WebEntityView.qml", [this](QQmlContext* context, QObject* item) {
|
_webSurface->load("controls/WebEntityView.qml", [this](QQmlContext* context, QObject* item) {
|
||||||
item->setProperty("url", _lastSourceUrl);
|
item->setProperty("url", _lastSourceUrl);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
_contentType = qmlContent;
|
_contentType = qmlContent;
|
||||||
_webSurface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath()));
|
|
||||||
_webSurface->load(_lastSourceUrl);
|
_webSurface->load(_lastSourceUrl);
|
||||||
if (_webSurface->getRootItem() && _webSurface->getRootItem()->objectName() == "tabletRoot") {
|
if (_webSurface->getRootItem() && _webSurface->getRootItem()->objectName() == "tabletRoot") {
|
||||||
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
|
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
|
||||||
|
|
|
@ -62,7 +62,7 @@ QVariantMap QmlWindowClass::parseArguments(QScriptContext* context) {
|
||||||
|
|
||||||
QUrl url { properties[SOURCE_PROPERTY].toString() };
|
QUrl url { properties[SOURCE_PROPERTY].toString() };
|
||||||
if (url.scheme() != "http" && url.scheme() != "https" && url.scheme() != "file" && url.scheme() != "about" &&
|
if (url.scheme() != "http" && url.scheme() != "https" && url.scheme() != "file" && url.scheme() != "about" &&
|
||||||
url.scheme() != "atp") {
|
url.scheme() != "atp" && url.scheme() != "qrc") {
|
||||||
properties[SOURCE_PROPERTY] = QUrl::fromLocalFile(url.toString()).toString();
|
properties[SOURCE_PROPERTY] = QUrl::fromLocalFile(url.toString()).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
#include "types/HFWebEngineProfile.h"
|
#include "types/HFWebEngineProfile.h"
|
||||||
#include "types/SoundEffect.h"
|
#include "types/SoundEffect.h"
|
||||||
|
|
||||||
|
#include "TabletScriptingInterface.h"
|
||||||
#include "Logging.h"
|
#include "Logging.h"
|
||||||
|
|
||||||
Q_LOGGING_CATEGORY(trace_render_qml, "trace.render.qml")
|
Q_LOGGING_CATEGORY(trace_render_qml, "trace.render.qml")
|
||||||
|
@ -98,7 +99,7 @@ void OffscreenQmlSurface::addWhitelistContextHandler(const std::initializer_list
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QmlContextCallback OffscreenQmlSurface::DEFAULT_CONTEXT_CALLBACK = [](QQmlContext*, QObject*) {};
|
QmlContextObjectCallback OffscreenQmlSurface::DEFAULT_CONTEXT_CALLBACK = [](QQmlContext*, QQuickItem*) {};
|
||||||
|
|
||||||
struct TextureSet {
|
struct TextureSet {
|
||||||
// The number of surfaces with this size
|
// The number of surfaces with this size
|
||||||
|
@ -586,10 +587,11 @@ void OffscreenQmlSurface::create() {
|
||||||
auto qmlEngine = acquireEngine(_quickWindow);
|
auto qmlEngine = acquireEngine(_quickWindow);
|
||||||
|
|
||||||
_qmlContext = new QQmlContext(qmlEngine->rootContext());
|
_qmlContext = new QQmlContext(qmlEngine->rootContext());
|
||||||
|
_qmlContext->setBaseUrl(QUrl{ "qrc:///qml/" });
|
||||||
_qmlContext->setContextProperty("offscreenWindow", QVariant::fromValue(getWindow()));
|
_qmlContext->setContextProperty("offscreenWindow", QVariant::fromValue(getWindow()));
|
||||||
_qmlContext->setContextProperty("eventBridge", this);
|
_qmlContext->setContextProperty("eventBridge", this);
|
||||||
_qmlContext->setContextProperty("webEntity", this);
|
_qmlContext->setContextProperty("webEntity", this);
|
||||||
|
_qmlContext->setContextProperty("QmlSurface", this);
|
||||||
|
|
||||||
// FIXME Compatibility mechanism for existing HTML and JS that uses eventBridgeWrapper
|
// FIXME Compatibility mechanism for existing HTML and JS that uses eventBridgeWrapper
|
||||||
// Find a way to flag older scripts using this mechanism and wanr that this is deprecated
|
// Find a way to flag older scripts using this mechanism and wanr that this is deprecated
|
||||||
|
@ -684,55 +686,69 @@ QQuickItem* OffscreenQmlSurface::getRootItem() {
|
||||||
return _rootItem;
|
return _rootItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffscreenQmlSurface::setBaseUrl(const QUrl& baseUrl) {
|
QQmlContext* OffscreenQmlSurface::contextForUrl(const QUrl& qmlSource, bool forceNewContext) {
|
||||||
_qmlContext->setBaseUrl(baseUrl);
|
// Get any whitelist functionality
|
||||||
|
QList<QmlContextCallback> callbacks = getQmlWhitelist()->getCallbacksForUrl(qmlSource);
|
||||||
|
// If we have whitelisted content, we must load a new context
|
||||||
|
forceNewContext |= !callbacks.empty();
|
||||||
|
|
||||||
|
QQmlContext* targetContext = _qmlContext;
|
||||||
|
if (_rootItem && forceNewContext) {
|
||||||
|
targetContext = new QQmlContext(targetContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& callback : callbacks) {
|
||||||
|
callback(targetContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
return targetContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffscreenQmlSurface::load(const QUrl& qmlSource, bool createNewContext, const QmlContextCallback& onQmlLoadedCallback) {
|
void OffscreenQmlSurface::load(const QUrl& qmlSource, QQuickItem* parent, const QJSValue& callback) {
|
||||||
|
loadInternal(qmlSource, false, parent, [callback](QQmlContext* context, QQuickItem* newItem) {
|
||||||
|
QJSValue(callback).call(QJSValueList() << context->engine()->newQObject(newItem));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffscreenQmlSurface::load(const QUrl& qmlSource, bool createNewContext, const QmlContextObjectCallback& onQmlLoadedCallback) {
|
||||||
|
loadInternal(qmlSource, createNewContext, nullptr, onQmlLoadedCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffscreenQmlSurface::loadInternal(const QUrl& qmlSource, bool createNewContext, QQuickItem* parent, const QmlContextObjectCallback& onQmlLoadedCallback) {
|
||||||
|
qCDebug(uiLogging) << "QQQ" << __FUNCTION__ << qmlSource;
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
qCWarning(uiLogging) << "Called load on a non-surface thread";
|
qCWarning(uiLogging) << "Called load on a non-surface thread";
|
||||||
}
|
}
|
||||||
// Synchronous loading may take a while; restart the deadlock timer
|
// Synchronous loading may take a while; restart the deadlock timer
|
||||||
QMetaObject::invokeMethod(qApp, "updateHeartbeat", Qt::DirectConnection);
|
QMetaObject::invokeMethod(qApp, "updateHeartbeat", Qt::DirectConnection);
|
||||||
|
|
||||||
// Get any whitelist functionality
|
|
||||||
QList<QmlContextCallback> callbacks = getQmlWhitelist()->getCallbacksForUrl(qmlSource);
|
|
||||||
// If we have whitelisted content, we must load a new context
|
|
||||||
createNewContext |= !callbacks.empty();
|
|
||||||
callbacks.push_back(onQmlLoadedCallback);
|
|
||||||
|
|
||||||
QQmlContext* targetContext = _qmlContext;
|
|
||||||
if (_rootItem && createNewContext) {
|
|
||||||
targetContext = new QQmlContext(targetContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// FIXME eliminate loading of relative file paths for QML
|
|
||||||
QUrl finalQmlSource = qmlSource;
|
QUrl finalQmlSource = qmlSource;
|
||||||
if ((qmlSource.isRelative() && !qmlSource.isEmpty()) || qmlSource.scheme() == QLatin1String("file")) {
|
if ((qmlSource.isRelative() && !qmlSource.isEmpty()) || qmlSource.scheme() == QLatin1String("file")) {
|
||||||
finalQmlSource = _qmlContext->resolvedUrl(qmlSource);
|
finalQmlSource = _qmlContext->resolvedUrl(qmlSource);
|
||||||
|
qCDebug(uiLogging) << "QQQ" << __FUNCTION__ << "resolved to " << finalQmlSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto targetContext = contextForUrl(finalQmlSource, createNewContext);
|
||||||
auto qmlComponent = new QQmlComponent(_qmlContext->engine(), finalQmlSource, QQmlComponent::PreferSynchronous);
|
auto qmlComponent = new QQmlComponent(_qmlContext->engine(), finalQmlSource, QQmlComponent::PreferSynchronous);
|
||||||
if (qmlComponent->isLoading()) {
|
if (qmlComponent->isLoading()) {
|
||||||
connect(qmlComponent, &QQmlComponent::statusChanged, this, [=](QQmlComponent::Status) {
|
connect(qmlComponent, &QQmlComponent::statusChanged, this, [=](QQmlComponent::Status) {
|
||||||
finishQmlLoad(qmlComponent, targetContext, callbacks);
|
finishQmlLoad(qmlComponent, targetContext, parent, onQmlLoadedCallback);
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
finishQmlLoad(qmlComponent, targetContext, callbacks);
|
finishQmlLoad(qmlComponent, targetContext, parent, onQmlLoadedCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffscreenQmlSurface::loadInNewContext(const QUrl& qmlSource, const QmlContextCallback& onQmlLoadedCallback) {
|
void OffscreenQmlSurface::loadInNewContext(const QUrl& qmlSource, const QmlContextObjectCallback& onQmlLoadedCallback) {
|
||||||
load(qmlSource, true, onQmlLoadedCallback);
|
load(qmlSource, true, onQmlLoadedCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffscreenQmlSurface::load(const QUrl& qmlSource, const QmlContextCallback& onQmlLoadedCallback) {
|
void OffscreenQmlSurface::load(const QUrl& qmlSource, const QmlContextObjectCallback& onQmlLoadedCallback) {
|
||||||
load(qmlSource, false, onQmlLoadedCallback);
|
load(qmlSource, false, onQmlLoadedCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffscreenQmlSurface::load(const QString& qmlSourceFile, const QmlContextCallback& onQmlLoadedCallback) {
|
void OffscreenQmlSurface::load(const QString& qmlSourceFile, const QmlContextObjectCallback& onQmlLoadedCallback) {
|
||||||
return load(QUrl(qmlSourceFile), onQmlLoadedCallback);
|
return load(QUrl(qmlSourceFile), onQmlLoadedCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -740,7 +756,8 @@ void OffscreenQmlSurface::clearCache() {
|
||||||
_qmlContext->engine()->clearComponentCache();
|
_qmlContext->engine()->clearComponentCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffscreenQmlSurface::finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext* qmlContext, const QList<QmlContextCallback>& callbacks) {
|
|
||||||
|
void OffscreenQmlSurface::finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext* qmlContext, QQuickItem* parent, const QmlContextObjectCallback& callback) {
|
||||||
disconnect(qmlComponent, &QQmlComponent::statusChanged, this, 0);
|
disconnect(qmlComponent, &QQmlComponent::statusChanged, this, 0);
|
||||||
if (qmlComponent->isError()) {
|
if (qmlComponent->isError()) {
|
||||||
for (const auto& error : qmlComponent->errors()) {
|
for (const auto& error : qmlComponent->errors()) {
|
||||||
|
@ -762,6 +779,22 @@ void OffscreenQmlSurface::finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!newObject) {
|
||||||
|
if (!_rootItem) {
|
||||||
|
qFatal("Could not load object as root item");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qCWarning(uiLogging) << "Unable to load QML item";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject* eventBridge = qmlContext->contextProperty("eventBridge").value<QObject*>();
|
||||||
|
if (qmlContext != _qmlContext && eventBridge && eventBridge != this) {
|
||||||
|
// FIXME Compatibility mechanism for existing HTML and JS that uses eventBridgeWrapper
|
||||||
|
// Find a way to flag older scripts using this mechanism and wanr that this is deprecated
|
||||||
|
qmlContext->setContextProperty("eventBridgeWrapper", new EventBridgeWrapper(eventBridge, qmlContext));
|
||||||
|
}
|
||||||
|
|
||||||
qmlContext->engine()->setObjectOwnership(this, QQmlEngine::CppOwnership);
|
qmlContext->engine()->setObjectOwnership(this, QQmlEngine::CppOwnership);
|
||||||
|
|
||||||
// All quick items should be focusable
|
// All quick items should be focusable
|
||||||
|
@ -772,37 +805,26 @@ void OffscreenQmlSurface::finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext
|
||||||
newItem->setFlag(QQuickItem::ItemIsFocusScope, true);
|
newItem->setFlag(QQuickItem::ItemIsFocusScope, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Make sure we will call callback for this codepath
|
// Make sure we will call callback for this codepath
|
||||||
// Call this before qmlComponent->completeCreate() otherwise ghost window appears
|
// Call this before qmlComponent->completeCreate() otherwise ghost window appears
|
||||||
if (newItem && _rootItem) {
|
// If we already have a root, just set a couple of flags and the ancestry
|
||||||
for (const auto& callback : callbacks) {
|
if (_rootItem) {
|
||||||
callback(qmlContext, newObject);
|
callback(qmlContext, newItem);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QObject* eventBridge = qmlContext->contextProperty("eventBridge").value<QObject*>();
|
if (!parent) {
|
||||||
if (qmlContext != _qmlContext && eventBridge && eventBridge != this) {
|
parent = _rootItem;
|
||||||
// FIXME Compatibility mechanism for existing HTML and JS that uses eventBridgeWrapper
|
}
|
||||||
// Find a way to flag older scripts using this mechanism and wanr that this is deprecated
|
// Allow child windows to be destroyed from JS
|
||||||
qmlContext->setContextProperty("eventBridgeWrapper", new EventBridgeWrapper(eventBridge, qmlContext));
|
QQmlEngine::setObjectOwnership(newObject, QQmlEngine::JavaScriptOwnership);
|
||||||
|
newObject->setParent(parent);
|
||||||
|
newItem->setParentItem(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
qmlComponent->completeCreate();
|
qmlComponent->completeCreate();
|
||||||
qmlComponent->deleteLater();
|
qmlComponent->deleteLater();
|
||||||
|
|
||||||
// If we already have a root, just set a couple of flags and the ancestry
|
if (_rootItem) {
|
||||||
if (newItem && _rootItem) {
|
|
||||||
// Allow child windows to be destroyed from JS
|
|
||||||
QQmlEngine::setObjectOwnership(newObject, QQmlEngine::JavaScriptOwnership);
|
|
||||||
newObject->setParent(_rootItem);
|
|
||||||
if (newItem) {
|
|
||||||
newItem->setParentItem(_rootItem);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!newItem) {
|
|
||||||
qFatal("Could not load object as root item");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -813,10 +835,16 @@ void OffscreenQmlSurface::finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext
|
||||||
_rootItem->setParentItem(_quickWindow->contentItem());
|
_rootItem->setParentItem(_quickWindow->contentItem());
|
||||||
_rootItem->setSize(_quickWindow->renderTargetSize());
|
_rootItem->setSize(_quickWindow->renderTargetSize());
|
||||||
|
|
||||||
// Call this callback after rootitem is set, otherwise VrMenu wont work
|
if (_rootItem->objectName() == "tabletRoot") {
|
||||||
for (const auto& callback : callbacks) {
|
_qmlContext->setContextProperty("tabletRoot", QVariant::fromValue(_rootItem));
|
||||||
callback(qmlContext, newObject);
|
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
|
||||||
|
tabletScriptingInterface->setQmlTabletRoot("com.highfidelity.interface.tablet.system", this);
|
||||||
|
QObject* tablet = tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system");
|
||||||
|
_qmlContext->engine()->setObjectOwnership(tablet, QQmlEngine::CppOwnership);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Call this callback after rootitem is set, otherwise VrMenu wont work
|
||||||
|
callback(qmlContext, newItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffscreenQmlSurface::updateQuick() {
|
void OffscreenQmlSurface::updateQuick() {
|
||||||
|
|
|
@ -30,12 +30,14 @@ class QQmlContext;
|
||||||
class QQmlComponent;
|
class QQmlComponent;
|
||||||
class QQuickWindow;
|
class QQuickWindow;
|
||||||
class QQuickItem;
|
class QQuickItem;
|
||||||
|
class QJSValue;
|
||||||
|
|
||||||
// GPU resources are typically buffered for one copy being used by the renderer,
|
// GPU resources are typically buffered for one copy being used by the renderer,
|
||||||
// one copy in flight, and one copy being used by the receiver
|
// one copy in flight, and one copy being used by the receiver
|
||||||
#define GPU_RESOURCE_BUFFER_SIZE 3
|
#define GPU_RESOURCE_BUFFER_SIZE 3
|
||||||
|
|
||||||
using QmlContextCallback = std::function<void(QQmlContext*, QObject*)>;
|
using QmlContextCallback = std::function<void(QQmlContext*)>;
|
||||||
|
using QmlContextObjectCallback = std::function<void(QQmlContext*, QQuickItem*)>;
|
||||||
|
|
||||||
class OffscreenQmlSurface : public QObject {
|
class OffscreenQmlSurface : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -43,7 +45,7 @@ class OffscreenQmlSurface : public QObject {
|
||||||
public:
|
public:
|
||||||
static void setSharedContext(QOpenGLContext* context);
|
static void setSharedContext(QOpenGLContext* context);
|
||||||
|
|
||||||
static QmlContextCallback DEFAULT_CONTEXT_CALLBACK;
|
static QmlContextObjectCallback DEFAULT_CONTEXT_CALLBACK;
|
||||||
static void addWhitelistContextHandler(const std::initializer_list<QUrl>& urls, const QmlContextCallback& callback);
|
static void addWhitelistContextHandler(const std::initializer_list<QUrl>& urls, const QmlContextCallback& callback);
|
||||||
static void addWhitelistContextHandler(const QUrl& url, const QmlContextCallback& callback) { addWhitelistContextHandler({ { url } }, callback); };
|
static void addWhitelistContextHandler(const QUrl& url, const QmlContextCallback& callback) { addWhitelistContextHandler({ { url } }, callback); };
|
||||||
|
|
||||||
|
@ -56,10 +58,15 @@ public:
|
||||||
void resize(const QSize& size, bool forceResize = false);
|
void resize(const QSize& size, bool forceResize = false);
|
||||||
QSize size() const;
|
QSize size() const;
|
||||||
|
|
||||||
Q_INVOKABLE void load(const QUrl& qmlSource, bool createNewContext, const QmlContextCallback& onQmlLoadedCallback = DEFAULT_CONTEXT_CALLBACK);
|
// Usable from QML code as QmlSurface.load(url, parent, function(newItem){ ... })
|
||||||
Q_INVOKABLE void loadInNewContext(const QUrl& qmlSource, const QmlContextCallback& onQmlLoadedCallback = DEFAULT_CONTEXT_CALLBACK);
|
Q_INVOKABLE void load(const QUrl& qmlSource, QQuickItem* parent, const QJSValue& callback);
|
||||||
Q_INVOKABLE void load(const QUrl& qmlSource, const QmlContextCallback& onQmlLoadedCallback = DEFAULT_CONTEXT_CALLBACK);
|
|
||||||
Q_INVOKABLE void load(const QString& qmlSourceFile, const QmlContextCallback& onQmlLoadedCallback = DEFAULT_CONTEXT_CALLBACK);
|
// For C++ use
|
||||||
|
Q_INVOKABLE void load(const QUrl& qmlSource, bool createNewContext, const QmlContextObjectCallback& onQmlLoadedCallback = DEFAULT_CONTEXT_CALLBACK);
|
||||||
|
Q_INVOKABLE void loadInNewContext(const QUrl& qmlSource, const QmlContextObjectCallback& onQmlLoadedCallback = DEFAULT_CONTEXT_CALLBACK);
|
||||||
|
Q_INVOKABLE void load(const QUrl& qmlSource, const QmlContextObjectCallback& onQmlLoadedCallback = DEFAULT_CONTEXT_CALLBACK);
|
||||||
|
Q_INVOKABLE void load(const QString& qmlSourceFile, const QmlContextObjectCallback& onQmlLoadedCallback = DEFAULT_CONTEXT_CALLBACK);
|
||||||
|
|
||||||
void clearCache();
|
void clearCache();
|
||||||
void setMaxFps(uint8_t maxFps) { _maxFps = maxFps; }
|
void setMaxFps(uint8_t maxFps) { _maxFps = maxFps; }
|
||||||
// Optional values for event handling
|
// Optional values for event handling
|
||||||
|
@ -73,7 +80,6 @@ public:
|
||||||
void resume();
|
void resume();
|
||||||
bool isPaused() const;
|
bool isPaused() const;
|
||||||
|
|
||||||
void setBaseUrl(const QUrl& baseUrl);
|
|
||||||
QQuickItem* getRootItem();
|
QQuickItem* getRootItem();
|
||||||
QQuickWindow* getWindow();
|
QQuickWindow* getWindow();
|
||||||
QObject* getEventHandler();
|
QObject* getEventHandler();
|
||||||
|
@ -124,13 +130,13 @@ protected:
|
||||||
private:
|
private:
|
||||||
static QOpenGLContext* getSharedContext();
|
static QOpenGLContext* getSharedContext();
|
||||||
|
|
||||||
void finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext* qmlContext, const QList<QmlContextCallback>& callbacks);
|
QQmlContext* contextForUrl(const QUrl& url, bool forceNewContext = false);
|
||||||
|
void loadInternal(const QUrl& qmlSource, bool createNewContext, QQuickItem* parent, const QmlContextObjectCallback& onQmlLoadedCallback);
|
||||||
|
void finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext* qmlContext, QQuickItem* parent, const QmlContextObjectCallback& onQmlLoadedCallback);
|
||||||
QPointF mapWindowToUi(const QPointF& sourcePosition, QObject* sourceObject);
|
QPointF mapWindowToUi(const QPointF& sourcePosition, QObject* sourceObject);
|
||||||
void setupFbo();
|
|
||||||
bool allowNewFrame(uint8_t fps);
|
bool allowNewFrame(uint8_t fps);
|
||||||
void render();
|
void render();
|
||||||
void cleanup();
|
void cleanup();
|
||||||
QJsonObject getGLContextData();
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void updateQuick();
|
void updateQuick();
|
||||||
|
|
|
@ -45,7 +45,6 @@ void OffscreenQmlSurfaceCache::release(const QString& rootSource, const QSharedP
|
||||||
QSharedPointer<OffscreenQmlSurface> OffscreenQmlSurfaceCache::buildSurface(const QString& rootSource) {
|
QSharedPointer<OffscreenQmlSurface> OffscreenQmlSurfaceCache::buildSurface(const QString& rootSource) {
|
||||||
auto surface = QSharedPointer<OffscreenQmlSurface>(new OffscreenQmlSurface());
|
auto surface = QSharedPointer<OffscreenQmlSurface>(new OffscreenQmlSurface());
|
||||||
surface->create();
|
surface->create();
|
||||||
surface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/"));
|
|
||||||
surface->load(rootSource);
|
surface->load(rootSource);
|
||||||
surface->resize(QSize(100, 100));
|
surface->resize(QSize(100, 100));
|
||||||
return surface;
|
return surface;
|
||||||
|
|
|
@ -210,9 +210,9 @@ QObject* TabletScriptingInterface::getFlags() {
|
||||||
// TabletProxy
|
// TabletProxy
|
||||||
//
|
//
|
||||||
|
|
||||||
static const char* TABLET_SOURCE_URL = "Tablet.qml";
|
static const char* TABLET_SOURCE_URL = "hifi/tablet/Tablet.qml";
|
||||||
static const char* WEB_VIEW_SOURCE_URL = "TabletWebView.qml";
|
static const char* WEB_VIEW_SOURCE_URL = "hifi/tablet/TabletWebView.qml";
|
||||||
static const char* VRMENU_SOURCE_URL = "TabletMenu.qml";
|
static const char* VRMENU_SOURCE_URL = "hifi/tablet/TabletMenu.qml";
|
||||||
|
|
||||||
class TabletRootWindow : public QmlWindowClass {
|
class TabletRootWindow : public QmlWindowClass {
|
||||||
virtual QString qmlSource() const override { return "hifi/tablet/WindowRoot.qml"; }
|
virtual QString qmlSource() const override { return "hifi/tablet/WindowRoot.qml"; }
|
||||||
|
@ -232,6 +232,15 @@ TabletProxy::~TabletProxy() {
|
||||||
disconnect(this, &TabletProxy::tabletShownChanged, this, &TabletProxy::onTabletShown);
|
disconnect(this, &TabletProxy::tabletShownChanged, this, &TabletProxy::onTabletShown);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVariant TabletProxy::getButtons() {
|
||||||
|
Q_ASSERT(QThread::currentThread() == qApp->thread());
|
||||||
|
QVariantList result;
|
||||||
|
for (const auto& button : _tabletButtonProxies) {
|
||||||
|
result.push_back(QVariant::fromValue(button.data()));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void TabletProxy::setToolbarMode(bool toolbarMode) {
|
void TabletProxy::setToolbarMode(bool toolbarMode) {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
QMetaObject::invokeMethod(this, "setToolbarMode", Q_ARG(bool, toolbarMode));
|
QMetaObject::invokeMethod(this, "setToolbarMode", Q_ARG(bool, toolbarMode));
|
||||||
|
@ -247,7 +256,6 @@ void TabletProxy::setToolbarMode(bool toolbarMode) {
|
||||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
|
|
||||||
if (toolbarMode) {
|
if (toolbarMode) {
|
||||||
removeButtonsFromHomeScreen();
|
|
||||||
addButtonsToToolbar();
|
addButtonsToToolbar();
|
||||||
|
|
||||||
// create new desktop window
|
// create new desktop window
|
||||||
|
@ -267,7 +275,7 @@ void TabletProxy::setToolbarMode(bool toolbarMode) {
|
||||||
removeButtonsFromToolbar();
|
removeButtonsFromToolbar();
|
||||||
|
|
||||||
if (_currentPathLoaded == TABLET_SOURCE_URL) {
|
if (_currentPathLoaded == TABLET_SOURCE_URL) {
|
||||||
addButtonsToHomeScreen();
|
// Tablet QML now pulls buttons from Tablet proxy
|
||||||
} else {
|
} else {
|
||||||
loadHomeScreen(true);
|
loadHomeScreen(true);
|
||||||
}
|
}
|
||||||
|
@ -284,18 +292,20 @@ void TabletProxy::setToolbarMode(bool toolbarMode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static void addButtonProxyToQmlTablet(QQuickItem* qmlTablet, TabletButtonProxy* buttonProxy) {
|
static void addButtonProxyToQmlTablet(QQuickItem* qmlTablet, TabletButtonProxy* buttonProxy) {
|
||||||
Q_ASSERT(QThread::currentThread() == qApp->thread());
|
Q_ASSERT(QThread::currentThread() == qApp->thread());
|
||||||
if (buttonProxy == NULL){
|
if (buttonProxy == NULL){
|
||||||
qCCritical(uiLogging) << "TabletScriptingInterface addButtonProxyToQmlTablet buttonProxy is NULL";
|
qCCritical(uiLogging) << __FUNCTION__ << "buttonProxy is NULL";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant resultVar;
|
QVariant resultVar;
|
||||||
|
qCDebug(uiLogging) << "QQQ" << __FUNCTION__ << "adding button " << buttonProxy;
|
||||||
bool hasResult = QMetaObject::invokeMethod(qmlTablet, "addButtonProxy", Qt::DirectConnection,
|
bool hasResult = QMetaObject::invokeMethod(qmlTablet, "addButtonProxy", Qt::DirectConnection,
|
||||||
Q_RETURN_ARG(QVariant, resultVar), Q_ARG(QVariant, buttonProxy->getProperties()));
|
Q_RETURN_ARG(QVariant, resultVar), Q_ARG(QVariant, buttonProxy->getProperties()));
|
||||||
if (!hasResult) {
|
if (!hasResult) {
|
||||||
qCWarning(uiLogging) << "TabletScriptingInterface addButtonProxyToQmlTablet has no result";
|
qCWarning(uiLogging) << __FUNCTION__ << " has no result";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,6 +317,8 @@ static void addButtonProxyToQmlTablet(QQuickItem* qmlTablet, TabletButtonProxy*
|
||||||
QObject::connect(qmlButton, SIGNAL(clicked()), buttonProxy, SLOT(clickedSlot()));
|
QObject::connect(qmlButton, SIGNAL(clicked()), buttonProxy, SLOT(clickedSlot()));
|
||||||
buttonProxy->setQmlButton(qobject_cast<QQuickItem*>(qmlButton));
|
buttonProxy->setQmlButton(qobject_cast<QQuickItem*>(qmlButton));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static QString getUsername() {
|
static QString getUsername() {
|
||||||
QString username = "Unknown user";
|
QString username = "Unknown user";
|
||||||
|
@ -362,7 +374,7 @@ void TabletProxy::onTabletShown() {
|
||||||
static_cast<TabletScriptingInterface*>(parent())->playSound(TabletScriptingInterface::TabletOpen);
|
static_cast<TabletScriptingInterface*>(parent())->playSound(TabletScriptingInterface::TabletOpen);
|
||||||
if (_showRunningScripts) {
|
if (_showRunningScripts) {
|
||||||
_showRunningScripts = false;
|
_showRunningScripts = false;
|
||||||
pushOntoStack("../../hifi/dialogs/TabletRunningScripts.qml");
|
pushOntoStack("hifi/dialogs/TabletRunningScripts.qml");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -396,9 +408,6 @@ void TabletProxy::setQmlTabletRoot(OffscreenQmlSurface* qmlOffscreenSurface) {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (_toolbarMode) {
|
if (_toolbarMode) {
|
||||||
// if someone creates the tablet in toolbar mode, make sure to display the home screen on the tablet.
|
|
||||||
auto loader = _qmlTabletRoot->findChild<QQuickItem*>("loader");
|
|
||||||
QObject::connect(loader, SIGNAL(loaded()), this, SLOT(addButtonsToHomeScreen()));
|
|
||||||
QMetaObject::invokeMethod(_qmlTabletRoot, "loadSource", Q_ARG(const QVariant&, QVariant(TABLET_SOURCE_URL)));
|
QMetaObject::invokeMethod(_qmlTabletRoot, "loadSource", Q_ARG(const QVariant&, QVariant(TABLET_SOURCE_URL)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,7 +436,6 @@ void TabletProxy::setQmlTabletRoot(OffscreenQmlSurface* qmlOffscreenSurface) {
|
||||||
QMetaObject::invokeMethod(_qmlTabletRoot, "setShown", Q_ARG(const QVariant&, QVariant(true)));
|
QMetaObject::invokeMethod(_qmlTabletRoot, "setShown", Q_ARG(const QVariant&, QVariant(true)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
removeButtonsFromHomeScreen();
|
|
||||||
_state = State::Uninitialized;
|
_state = State::Uninitialized;
|
||||||
emit screenChanged(QVariant("Closed"), QVariant(""));
|
emit screenChanged(QVariant("Closed"), QVariant(""));
|
||||||
_currentPathLoaded = "";
|
_currentPathLoaded = "";
|
||||||
|
@ -456,7 +464,6 @@ void TabletProxy::gotoMenuScreen(const QString& submenu) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (root) {
|
if (root) {
|
||||||
removeButtonsFromHomeScreen();
|
|
||||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
QObject* menu = offscreenUi->getRootMenu();
|
QObject* menu = offscreenUi->getRootMenu();
|
||||||
QMetaObject::invokeMethod(root, "setMenuProperties", Q_ARG(QVariant, QVariant::fromValue(menu)), Q_ARG(const QVariant&, QVariant(submenu)));
|
QMetaObject::invokeMethod(root, "setMenuProperties", Q_ARG(QVariant, QVariant::fromValue(menu)), Q_ARG(const QVariant&, QVariant(submenu)));
|
||||||
|
@ -530,7 +537,6 @@ void TabletProxy::loadQMLSource(const QVariant& path, bool resizable) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (root) {
|
if (root) {
|
||||||
removeButtonsFromHomeScreen(); //works only in Tablet
|
|
||||||
QMetaObject::invokeMethod(root, "loadSource", Q_ARG(const QVariant&, path));
|
QMetaObject::invokeMethod(root, "loadSource", Q_ARG(const QVariant&, path));
|
||||||
_state = State::QML;
|
_state = State::QML;
|
||||||
if (path != _currentPathLoaded) {
|
if (path != _currentPathLoaded) {
|
||||||
|
@ -612,8 +618,6 @@ void TabletProxy::loadHomeScreen(bool forceOntoHomeScreen) {
|
||||||
|
|
||||||
if ((_state != State::Home && _state != State::Uninitialized) || forceOntoHomeScreen) {
|
if ((_state != State::Home && _state != State::Uninitialized) || forceOntoHomeScreen) {
|
||||||
if (!_toolbarMode && _qmlTabletRoot) {
|
if (!_toolbarMode && _qmlTabletRoot) {
|
||||||
auto loader = _qmlTabletRoot->findChild<QQuickItem*>("loader");
|
|
||||||
QObject::connect(loader, SIGNAL(loaded()), this, SLOT(addButtonsToHomeScreen()));
|
|
||||||
QMetaObject::invokeMethod(_qmlTabletRoot, "loadSource", Q_ARG(const QVariant&, QVariant(TABLET_SOURCE_URL)));
|
QMetaObject::invokeMethod(_qmlTabletRoot, "loadSource", Q_ARG(const QVariant&, QVariant(TABLET_SOURCE_URL)));
|
||||||
QMetaObject::invokeMethod(_qmlTabletRoot, "playButtonClickSound");
|
QMetaObject::invokeMethod(_qmlTabletRoot, "playButtonClickSound");
|
||||||
} else if (_toolbarMode && _desktopWindow) {
|
} else if (_toolbarMode && _desktopWindow) {
|
||||||
|
@ -674,7 +678,6 @@ void TabletProxy::gotoWebScreen(const QString& url, const QString& injectedJavaS
|
||||||
}
|
}
|
||||||
|
|
||||||
if (root) {
|
if (root) {
|
||||||
removeButtonsFromHomeScreen();
|
|
||||||
if (loadOtherBase) {
|
if (loadOtherBase) {
|
||||||
QMetaObject::invokeMethod(root, "loadTabletWebBase");
|
QMetaObject::invokeMethod(root, "loadTabletWebBase");
|
||||||
} else {
|
} else {
|
||||||
|
@ -701,12 +704,8 @@ TabletButtonProxy* TabletProxy::addButton(const QVariant& properties) {
|
||||||
auto tabletButtonProxy = QSharedPointer<TabletButtonProxy>(new TabletButtonProxy(properties.toMap()));
|
auto tabletButtonProxy = QSharedPointer<TabletButtonProxy>(new TabletButtonProxy(properties.toMap()));
|
||||||
_tabletButtonProxies.push_back(tabletButtonProxy);
|
_tabletButtonProxies.push_back(tabletButtonProxy);
|
||||||
if (!_toolbarMode && _qmlTabletRoot) {
|
if (!_toolbarMode && _qmlTabletRoot) {
|
||||||
auto tablet = getQmlTablet();
|
// Tablet now pulls buttons from the tablet proxy
|
||||||
if (tablet) {
|
// FIXME emit a signal so that the tablet can refresh buttons if they change
|
||||||
addButtonProxyToQmlTablet(tablet, tabletButtonProxy.data());
|
|
||||||
} else {
|
|
||||||
qCCritical(uiLogging) << "Could not find tablet in TabletRoot.qml";
|
|
||||||
}
|
|
||||||
} else if (_toolbarMode) {
|
} else if (_toolbarMode) {
|
||||||
auto toolbarProxy = DependencyManager::get<TabletScriptingInterface>()->getSystemToolbarProxy();
|
auto toolbarProxy = DependencyManager::get<TabletScriptingInterface>()->getSystemToolbarProxy();
|
||||||
if (toolbarProxy) {
|
if (toolbarProxy) {
|
||||||
|
@ -791,31 +790,11 @@ void TabletProxy::sendToQml(const QVariant& msg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabletProxy::addButtonsToHomeScreen() {
|
|
||||||
auto tablet = getQmlTablet();
|
|
||||||
if (!tablet || _toolbarMode) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (auto& buttonProxy : _tabletButtonProxies) {
|
|
||||||
addButtonProxyToQmlTablet(tablet, buttonProxy.data());
|
|
||||||
}
|
|
||||||
auto loader = _qmlTabletRoot->findChild<QQuickItem*>("loader");
|
|
||||||
QObject::disconnect(loader, SIGNAL(loaded()), this, SLOT(addButtonsToHomeScreen()));
|
|
||||||
}
|
|
||||||
|
|
||||||
OffscreenQmlSurface* TabletProxy::getTabletSurface() {
|
OffscreenQmlSurface* TabletProxy::getTabletSurface() {
|
||||||
return _qmlOffscreenSurface;
|
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() {
|
void TabletProxy::desktopWindowClosed() {
|
||||||
gotoHomeScreen();
|
gotoHomeScreen();
|
||||||
|
|
|
@ -196,6 +196,8 @@ public:
|
||||||
|
|
||||||
Q_INVOKABLE bool isPathLoaded(const QVariant& path);
|
Q_INVOKABLE bool isPathLoaded(const QVariant& path);
|
||||||
|
|
||||||
|
Q_INVOKABLE QVariant getButtons();
|
||||||
|
|
||||||
QQuickItem* getTabletRoot() const { return _qmlTabletRoot; }
|
QQuickItem* getTabletRoot() const { return _qmlTabletRoot; }
|
||||||
|
|
||||||
OffscreenQmlSurface* getTabletSurface();
|
OffscreenQmlSurface* getTabletSurface();
|
||||||
|
@ -237,12 +239,10 @@ signals:
|
||||||
void tabletShownChanged();
|
void tabletShownChanged();
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void addButtonsToHomeScreen();
|
|
||||||
void desktopWindowClosed();
|
void desktopWindowClosed();
|
||||||
void emitWebEvent(const QVariant& msg);
|
void emitWebEvent(const QVariant& msg);
|
||||||
void onTabletShown();
|
void onTabletShown();
|
||||||
protected:
|
protected:
|
||||||
void removeButtonsFromHomeScreen();
|
|
||||||
void loadHomeScreen(bool forceOntoHomeScreen);
|
void loadHomeScreen(bool forceOntoHomeScreen);
|
||||||
void addButtonsToToolbar();
|
void addButtonsToToolbar();
|
||||||
void removeButtonsFromToolbar();
|
void removeButtonsFromToolbar();
|
||||||
|
@ -277,7 +277,9 @@ public:
|
||||||
TabletButtonProxy(const QVariantMap& properties);
|
TabletButtonProxy(const QVariantMap& properties);
|
||||||
~TabletButtonProxy();
|
~TabletButtonProxy();
|
||||||
|
|
||||||
void setQmlButton(QQuickItem* qmlButton);
|
|
||||||
|
Q_INVOKABLE void setQmlButton(QQuickItem* qmlButton);
|
||||||
|
|
||||||
void setToolbarButtonProxy(QObject* toolbarButtonProxy);
|
void setToolbarButtonProxy(QObject* toolbarButtonProxy);
|
||||||
|
|
||||||
QUuid getUuid() const { return _uuid; }
|
QUuid getUuid() const { return _uuid; }
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
tablet.gotoHomeScreen();
|
tablet.gotoHomeScreen();
|
||||||
onRecordingScreen = false;
|
onRecordingScreen = false;
|
||||||
} else {
|
} else {
|
||||||
tablet.loadQMLSource("InputRecorder.qml");
|
tablet.loadQMLSource("hifi/tablet/InputRecorder.qml");
|
||||||
onRecordingScreen = true;
|
onRecordingScreen = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
print("Launching web window");
|
print("Launching web window");
|
||||||
qmlWindow = new OverlayWindow({
|
qmlWindow = new OverlayWindow({
|
||||||
title: 'Test Qml',
|
title: 'Test Qml',
|
||||||
source: "https://s3.amazonaws.com/DreamingContent/qml/content.qml",
|
source: "qrc:///qml/OverlayWindowTest.qml",
|
||||||
height: 240,
|
height: 240,
|
||||||
width: 320,
|
width: 320,
|
||||||
toolWindow: false,
|
toolWindow: false,
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
var TABLET_BUTTON_NAME = "AUDIO";
|
var TABLET_BUTTON_NAME = "AUDIO";
|
||||||
var HOME_BUTTON_TEXTURE = "http://hifi-content.s3.amazonaws.com/alan/dev/tablet-with-home-button.fbx/tablet-with-home-button.fbm/button-root.png";
|
var HOME_BUTTON_TEXTURE = "http://hifi-content.s3.amazonaws.com/alan/dev/tablet-with-home-button.fbx/tablet-with-home-button.fbm/button-root.png";
|
||||||
var AUDIO_QML_SOURCE = "../audio/Audio.qml";
|
var AUDIO_QML_SOURCE = "hifi/audio/Audio.qml";
|
||||||
|
|
||||||
var MUTE_ICONS = {
|
var MUTE_ICONS = {
|
||||||
icon: "icons/tablet-icons/mic-mute-i.svg",
|
icon: "icons/tablet-icons/mic-mute-i.svg",
|
||||||
|
|
|
@ -26,8 +26,8 @@
|
||||||
// Relevant Variables:
|
// Relevant Variables:
|
||||||
// -WALLET_QML_SOURCE: The path to the Wallet QML
|
// -WALLET_QML_SOURCE: The path to the Wallet QML
|
||||||
// -onWalletScreen: true/false depending on whether we're looking at the app.
|
// -onWalletScreen: true/false depending on whether we're looking at the app.
|
||||||
var WALLET_QML_SOURCE = Script.resourcesPath() + "qml/hifi/commerce/wallet/Wallet.qml";
|
var WALLET_QML_SOURCE = "hifi/commerce/wallet/Wallet.qml";
|
||||||
var MARKETPLACE_PURCHASES_QML_PATH = Script.resourcesPath() + "qml/hifi/commerce/purchases/Purchases.qml";
|
var MARKETPLACE_PURCHASES_QML_PATH = "hifi/commerce/purchases/Purchases.qml";
|
||||||
var onWalletScreen = false;
|
var onWalletScreen = false;
|
||||||
function onButtonClicked() {
|
function onButtonClicked() {
|
||||||
if (!tablet) {
|
if (!tablet) {
|
||||||
|
|
|
@ -656,7 +656,7 @@ var toolBar = (function () {
|
||||||
selectionDisplay.triggerMapping.disable();
|
selectionDisplay.triggerMapping.disable();
|
||||||
tablet.landscape = false;
|
tablet.landscape = false;
|
||||||
} else {
|
} else {
|
||||||
tablet.loadQMLSource("Edit.qml", true);
|
tablet.loadQMLSource("hifi/tablet/Edit.qml", true);
|
||||||
UserActivityLogger.enabledEdit();
|
UserActivityLogger.enabledEdit();
|
||||||
entityListTool.setVisible(true);
|
entityListTool.setVisible(true);
|
||||||
gridTool.setVisible(true);
|
gridTool.setVisible(true);
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
var buttonName = "Settings";
|
var buttonName = "Settings";
|
||||||
var toolBar = null;
|
var toolBar = null;
|
||||||
var tablet = null;
|
var tablet = null;
|
||||||
var settings = "TabletGeneralPreferences.qml"
|
var settings = "hifi/tablet/TabletGeneralPreferences.qml"
|
||||||
function onClicked(){
|
function onClicked(){
|
||||||
if (tablet) {
|
if (tablet) {
|
||||||
tablet.loadQMLSource(settings);
|
tablet.loadQMLSource(settings);
|
||||||
|
|
|
@ -346,7 +346,7 @@
|
||||||
Menu.setIsOptionChecked("Disable Preview", isHmdPreviewDisabled);
|
Menu.setIsOptionChecked("Disable Preview", isHmdPreviewDisabled);
|
||||||
break;
|
break;
|
||||||
case 'purchases_openGoTo':
|
case 'purchases_openGoTo':
|
||||||
tablet.loadQMLSource("TabletAddressDialog.qml");
|
tablet.loadQMLSource("hifi/tablet/TabletAddressDialog.qml");
|
||||||
break;
|
break;
|
||||||
case 'purchases_itemCertificateClicked':
|
case 'purchases_itemCertificateClicked':
|
||||||
setCertificateInfo("", message.itemCertificateId);
|
setCertificateInfo("", message.itemCertificateId);
|
||||||
|
|
|
@ -40,7 +40,7 @@ var HOVER_TEXTURES = {
|
||||||
var UNSELECTED_COLOR = { red: 0x1F, green: 0xC6, blue: 0xA6};
|
var UNSELECTED_COLOR = { red: 0x1F, green: 0xC6, blue: 0xA6};
|
||||||
var SELECTED_COLOR = {red: 0xF3, green: 0x91, blue: 0x29};
|
var SELECTED_COLOR = {red: 0xF3, green: 0x91, blue: 0x29};
|
||||||
var HOVER_COLOR = {red: 0xD0, green: 0xD0, blue: 0xD0}; // almost white for now
|
var HOVER_COLOR = {red: 0xD0, green: 0xD0, blue: 0xD0}; // almost white for now
|
||||||
var PAL_QML_SOURCE = "../Pal.qml";
|
var PAL_QML_SOURCE = "hifi/Pal.qml";
|
||||||
var conserveResources = true;
|
var conserveResources = true;
|
||||||
|
|
||||||
Script.include("/~/system/libraries/controllers.js");
|
Script.include("/~/system/libraries/controllers.js");
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
print('tablet-goto.js:', [].map.call(arguments, JSON.stringify));
|
print('tablet-goto.js:', [].map.call(arguments, JSON.stringify));
|
||||||
}
|
}
|
||||||
|
|
||||||
var gotoQmlSource = "TabletAddressDialog.qml";
|
var gotoQmlSource = "hifi/tablet/TabletAddressDialog.qml";
|
||||||
var buttonName = "GOTO";
|
var buttonName = "GOTO";
|
||||||
var onGotoScreen = false;
|
var onGotoScreen = false;
|
||||||
var shouldActivateButton = false;
|
var shouldActivateButton = false;
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
if (onSkyboxChangerScreen) {
|
if (onSkyboxChangerScreen) {
|
||||||
tablet.gotoHomeScreen();
|
tablet.gotoHomeScreen();
|
||||||
} else {
|
} else {
|
||||||
tablet.loadQMLSource("../SkyboxChanger.qml");
|
tablet.loadQMLSource("hifi/SkyboxChanger.qml");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -390,7 +390,7 @@
|
||||||
// Relevant Variables:
|
// Relevant Variables:
|
||||||
// -SPECTATOR_CAMERA_QML_SOURCE: The path to the SpectatorCamera QML
|
// -SPECTATOR_CAMERA_QML_SOURCE: The path to the SpectatorCamera QML
|
||||||
// -onSpectatorCameraScreen: true/false depending on whether we're looking at the spectator camera app.
|
// -onSpectatorCameraScreen: true/false depending on whether we're looking at the spectator camera app.
|
||||||
var SPECTATOR_CAMERA_QML_SOURCE = Script.resourcesPath() + "qml/hifi/SpectatorCamera.qml";
|
var SPECTATOR_CAMERA_QML_SOURCE = "hifi/SpectatorCamera.qml";
|
||||||
var onSpectatorCameraScreen = false;
|
var onSpectatorCameraScreen = false;
|
||||||
function onTabletButtonClicked() {
|
function onTabletButtonClicked() {
|
||||||
if (!tablet) {
|
if (!tablet) {
|
||||||
|
|
Loading…
Reference in a new issue