From 22baab13592c6de7622db085cf64bcee7f0b5918 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 15 Feb 2017 15:24:08 +0000 Subject: [PATCH 01/18] updating branch with master --- .../resources/qml/hifi/tablet/TabletMenu.qml | 13 +++++-- ...etMouseHandler.qml => TabletMenuStack.qml} | 37 +++++++++++-------- interface/src/Application.cpp | 11 +++++- 3 files changed, 42 insertions(+), 19 deletions(-) rename interface/resources/qml/hifi/tablet/{TabletMouseHandler.qml => TabletMenuStack.qml} (88%) diff --git a/interface/resources/qml/hifi/tablet/TabletMenu.qml b/interface/resources/qml/hifi/tablet/TabletMenu.qml index cd3a9cacae..618aa30fb4 100644 --- a/interface/resources/qml/hifi/tablet/TabletMenu.qml +++ b/interface/resources/qml/hifi/tablet/TabletMenu.qml @@ -2,8 +2,14 @@ import QtQuick 2.5 import QtGraphicalEffects 1.0 import QtQuick.Controls 1.4 import QtQml 2.2 +import QtWebChannel 1.0 +import QtWebEngine 1.1 +import HFWebEngineProfile 1.0 + + import "." import "../../styles-uit" +import "../../controls" FocusScope { id: tabletMenu @@ -14,8 +20,9 @@ FocusScope { property var rootMenu: Menu { objectName:"rootMenu" } property var point: Qt.point(50, 50) - - TabletMouseHandler { id: menuPopperUpper } + property var eventBridge; + signal sendToScript(var message); + TabletMenuStack { id: menuPopperUpper } Rectangle { id: bgNavBar @@ -101,6 +108,6 @@ FocusScope { buildMenu() } function buildMenu() { - menuPopperUpper.popup(tabletMenu, rootMenu.items) + menuPopperUpper.popup(rootMenu.items); } } diff --git a/interface/resources/qml/hifi/tablet/TabletMouseHandler.qml b/interface/resources/qml/hifi/tablet/TabletMenuStack.qml similarity index 88% rename from interface/resources/qml/hifi/tablet/TabletMouseHandler.qml rename to interface/resources/qml/hifi/tablet/TabletMenuStack.qml index f2fa5f8d75..f84f90fbb3 100644 --- a/interface/resources/qml/hifi/tablet/TabletMouseHandler.qml +++ b/interface/resources/qml/hifi/tablet/TabletMenuStack.qml @@ -1,7 +1,7 @@ // // MessageDialog.qml // -// Created by Bradley Austin Davis on 18 Jan 2016 +// Created by Dante Ruiz on 13 Feb 2017 // Copyright 2016 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. @@ -28,8 +28,11 @@ Item { } } - QtObject { + StackView { + anchors.fill: parent id: d + objectName: "stack" + initialItem: topMenu property var menuStack: [] property var topMenu: null; property var modelMaker: Component { ListModel { } } @@ -53,6 +56,12 @@ Item { } } + function pushSource(path) { + } + + function popSource() { + } + function toModel(items) { var result = modelMaker.createObject(tabletMenu); for (var i = 0; i < items.length; ++i) { @@ -76,15 +85,15 @@ Item { } function popMenu() { - if (menuStack.length) { - menuStack.pop().destroy(); + if (d.depth) { + d.pop(); } - if (menuStack.length) { - topMenu = menuStack[menuStack.length - 1]; + if (d.depth) { + topMenu = d.currentItem; topMenu.focus = true; topMenu.forceActiveFocus(); // show current menu level on nav bar - if (topMenu.objectName === "" || menuStack.length === 1) { + if (topMenu.objectName === "" || d.depth === 1) { breadcrumbText.text = "Menu"; } else { breadcrumbText.text = topMenu.objectName; @@ -96,16 +105,14 @@ Item { } function pushMenu(newMenu) { - menuStack.push(newMenu); + d.push({ item:newMenu, destroyOnPop: true}); topMenu = newMenu; topMenu.focus = true; topMenu.forceActiveFocus(); } function clearMenus() { - while (menuStack.length) { - popMenu() - } + d.clear() } function clampMenuPosition(menu) { @@ -123,7 +130,7 @@ Item { } } - function buildMenu(items, targetPosition) { + function buildMenu(items) { var model = toModel(items); // Menus must be childed to desktop for Z-ordering var newMenu = menuViewMaker.createObject(tabletMenu, { model: model, isSubMenu: topMenu !== null }); @@ -154,13 +161,13 @@ Item { } - function popup(parent, items) { + function popup(items) { d.clearMenus(); - d.buildMenu(items, point); + d.buildMenu(items); } function closeLastMenu() { - if (d.menuStack.length > 1) { + if (d.depth > 1) { d.popMenu(); return true; } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b7aecfa597..663c1f81fb 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5743,8 +5743,17 @@ bool Application::displayAvatarAttachmentConfirmationDialog(const QString& name) } void Application::toggleRunningScriptsWidget() const { + auto tabletScriptingInterface = DependencyManager::get(); + auto tabletWindow = tabletScriptingInterface->getTabletWindow(); static const QUrl url("hifi/dialogs/RunningScripts.qml"); - DependencyManager::get()->show(url, "RunningScripts"); + if (tabletWindow) { + auto tablet = dynamic_cast(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system")); + if (tablet) { + tablet->pushOntoStack("../..//hifi/dialogs/RunningScripts.qml"); + } + } else { + DependencyManager::get()->show(url, "RunningScripts"); + } //if (_runningScriptsWidget->isVisible()) { // if (_runningScriptsWidget->hasFocus()) { // _runningScriptsWidget->hide(); From e6853a925549e148648349e7351d8a073e9c3278 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 15 Feb 2017 18:57:06 +0000 Subject: [PATCH 02/18] updated menu stack --- interface/resources/qml/hifi/tablet/TabletMenu.qml | 13 +++++-------- .../resources/qml/hifi/tablet/TabletMenuStack.qml | 7 ++++++- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/TabletMenu.qml b/interface/resources/qml/hifi/tablet/TabletMenu.qml index 10ee247b2d..e4895740e6 100644 --- a/interface/resources/qml/hifi/tablet/TabletMenu.qml +++ b/interface/resources/qml/hifi/tablet/TabletMenu.qml @@ -19,7 +19,7 @@ FocusScope { height: 720 property var rootMenu: Menu { objectName:"rootMenu" } - property var point: Qt.point(50, 50) + property var point: Qt.point(50, 50); property var eventBridge; signal sendToScript(var message); TabletMenuStack { id: menuPopperUpper } @@ -64,6 +64,7 @@ FocusScope { // navigate back to root level menu onClicked: { buildMenu(); + breadcrumbText.text = "Menu"; tabletRoot.playButtonClickSound(); } } @@ -106,12 +107,9 @@ FocusScope { function setRootMenu(menu) { tabletMenu.rootMenu = menu - buildMenu() + buildMenu(); } function buildMenu() { -<<<<<<< HEAD - menuPopperUpper.popup(rootMenu.items); -======= // Build submenu if specified. if (subMenu !== "") { var index = 0; @@ -124,13 +122,12 @@ FocusScope { } subMenu = ""; // Continue with full menu after initially displaying submenu. if (found) { - menuPopperUpper.popup(tabletMenu, rootMenu.items[index].items); + menuPopperUpper.popup(rootMenu.items[index].items); return; } } // Otherwise build whole menu. - menuPopperUpper.popup(tabletMenu, rootMenu.items); ->>>>>>> 01bdac49d04ec897a3da7a264a1a26748a4e1938 + menuPopperUpper.popup(rootMenu.items); } } diff --git a/interface/resources/qml/hifi/tablet/TabletMenuStack.qml b/interface/resources/qml/hifi/tablet/TabletMenuStack.qml index f84f90fbb3..c33f4e648b 100644 --- a/interface/resources/qml/hifi/tablet/TabletMenuStack.qml +++ b/interface/resources/qml/hifi/tablet/TabletMenuStack.qml @@ -27,12 +27,13 @@ Item { d.clearMenus(); } } - + StackView { anchors.fill: parent id: d objectName: "stack" initialItem: topMenu + property var menuStack: [] property var topMenu: null; property var modelMaker: Component { ListModel { } } @@ -57,9 +58,13 @@ Item { } function pushSource(path) { + d.push(Qt.resolvedUrl(path)); + d.currentItem.eventBridge = tabletMenu.eventBridge + d.currentItem.sendToScript.connect(tabletMenu.sendToScript); } function popSource() { + d.pop(); } function toModel(items) { From 896f9d7181f92e77746a1e4cd41eca9897ffc3de Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Thu, 16 Feb 2017 15:58:26 +0000 Subject: [PATCH 03/18] refreshing with master --- interface/src/Application.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4011eafb6a..78b81f2075 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5744,13 +5744,10 @@ bool Application::displayAvatarAttachmentConfirmationDialog(const QString& name) void Application::toggleRunningScriptsWidget() const { auto tabletScriptingInterface = DependencyManager::get(); - auto tabletWindow = tabletScriptingInterface->getTabletWindow(); static const QUrl url("hifi/dialogs/RunningScripts.qml"); - if (tabletWindow) { + if (true) { auto tablet = dynamic_cast(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system")); - if (tablet) { - tablet->pushOntoStack("../..//hifi/dialogs/RunningScripts.qml"); - } + tablet->pushOntoStack("../..//hifi/dialogs/RunningScripts.qml"); } else { DependencyManager::get()->show(url, "RunningScripts"); } From 2a97ebb076254f9f92aa64f0b33ab0af66311028 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 15 Feb 2017 15:24:08 +0000 Subject: [PATCH 04/18] updating branch with master --- .../resources/qml/hifi/tablet/TabletMenu.qml | 15 +++++++- ...etMouseHandler.qml => TabletMenuStack.qml} | 37 +++++++++++-------- interface/src/Application.cpp | 11 +++++- .../system/libraries/entitySelectionTool.js | 2 +- 4 files changed, 46 insertions(+), 19 deletions(-) rename interface/resources/qml/hifi/tablet/{TabletMouseHandler.qml => TabletMenuStack.qml} (88%) diff --git a/interface/resources/qml/hifi/tablet/TabletMenu.qml b/interface/resources/qml/hifi/tablet/TabletMenu.qml index c154ac0f49..1903a700d6 100644 --- a/interface/resources/qml/hifi/tablet/TabletMenu.qml +++ b/interface/resources/qml/hifi/tablet/TabletMenu.qml @@ -2,8 +2,14 @@ import QtQuick 2.5 import QtGraphicalEffects 1.0 import QtQuick.Controls 1.4 import QtQml 2.2 +import QtWebChannel 1.0 +import QtWebEngine 1.1 +import HFWebEngineProfile 1.0 + + import "." import "../../styles-uit" +import "../../controls" FocusScope { id: tabletMenu @@ -15,8 +21,9 @@ FocusScope { property var rootMenu: Menu { objectName:"rootMenu" } property var point: Qt.point(50, 50) property string subMenu: "" - - TabletMouseHandler { id: menuPopperUpper } + property var eventBridge; + signal sendToScript(var message); + TabletMenuStack { id: menuPopperUpper } Rectangle { id: bgNavBar @@ -102,6 +109,7 @@ FocusScope { buildMenu() } function buildMenu() { +<<<<<<< HEAD // Build submenu if specified. if (subMenu !== "") { var index = 0; @@ -121,5 +129,8 @@ FocusScope { // Otherwise build whole menu. menuPopperUpper.popup(tabletMenu, rootMenu.items); +======= + menuPopperUpper.popup(rootMenu.items); +>>>>>>> updating branch with master } } diff --git a/interface/resources/qml/hifi/tablet/TabletMouseHandler.qml b/interface/resources/qml/hifi/tablet/TabletMenuStack.qml similarity index 88% rename from interface/resources/qml/hifi/tablet/TabletMouseHandler.qml rename to interface/resources/qml/hifi/tablet/TabletMenuStack.qml index f2fa5f8d75..f84f90fbb3 100644 --- a/interface/resources/qml/hifi/tablet/TabletMouseHandler.qml +++ b/interface/resources/qml/hifi/tablet/TabletMenuStack.qml @@ -1,7 +1,7 @@ // // MessageDialog.qml // -// Created by Bradley Austin Davis on 18 Jan 2016 +// Created by Dante Ruiz on 13 Feb 2017 // Copyright 2016 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. @@ -28,8 +28,11 @@ Item { } } - QtObject { + StackView { + anchors.fill: parent id: d + objectName: "stack" + initialItem: topMenu property var menuStack: [] property var topMenu: null; property var modelMaker: Component { ListModel { } } @@ -53,6 +56,12 @@ Item { } } + function pushSource(path) { + } + + function popSource() { + } + function toModel(items) { var result = modelMaker.createObject(tabletMenu); for (var i = 0; i < items.length; ++i) { @@ -76,15 +85,15 @@ Item { } function popMenu() { - if (menuStack.length) { - menuStack.pop().destroy(); + if (d.depth) { + d.pop(); } - if (menuStack.length) { - topMenu = menuStack[menuStack.length - 1]; + if (d.depth) { + topMenu = d.currentItem; topMenu.focus = true; topMenu.forceActiveFocus(); // show current menu level on nav bar - if (topMenu.objectName === "" || menuStack.length === 1) { + if (topMenu.objectName === "" || d.depth === 1) { breadcrumbText.text = "Menu"; } else { breadcrumbText.text = topMenu.objectName; @@ -96,16 +105,14 @@ Item { } function pushMenu(newMenu) { - menuStack.push(newMenu); + d.push({ item:newMenu, destroyOnPop: true}); topMenu = newMenu; topMenu.focus = true; topMenu.forceActiveFocus(); } function clearMenus() { - while (menuStack.length) { - popMenu() - } + d.clear() } function clampMenuPosition(menu) { @@ -123,7 +130,7 @@ Item { } } - function buildMenu(items, targetPosition) { + function buildMenu(items) { var model = toModel(items); // Menus must be childed to desktop for Z-ordering var newMenu = menuViewMaker.createObject(tabletMenu, { model: model, isSubMenu: topMenu !== null }); @@ -154,13 +161,13 @@ Item { } - function popup(parent, items) { + function popup(items) { d.clearMenus(); - d.buildMenu(items, point); + d.buildMenu(items); } function closeLastMenu() { - if (d.menuStack.length > 1) { + if (d.depth > 1) { d.popMenu(); return true; } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 488e97b5e6..4011eafb6a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5743,8 +5743,17 @@ bool Application::displayAvatarAttachmentConfirmationDialog(const QString& name) } void Application::toggleRunningScriptsWidget() const { + auto tabletScriptingInterface = DependencyManager::get(); + auto tabletWindow = tabletScriptingInterface->getTabletWindow(); static const QUrl url("hifi/dialogs/RunningScripts.qml"); - DependencyManager::get()->show(url, "RunningScripts"); + if (tabletWindow) { + auto tablet = dynamic_cast(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system")); + if (tablet) { + tablet->pushOntoStack("../..//hifi/dialogs/RunningScripts.qml"); + } + } else { + DependencyManager::get()->show(url, "RunningScripts"); + } //if (_runningScriptsWidget->isVisible()) { // if (_runningScriptsWidget->hasFocus()) { // _runningScriptsWidget->hide(); diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 596620b59a..0fd0b01d25 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -2048,7 +2048,7 @@ SelectionDisplay = (function() { Overlays.editOverlay(grabberPointLightL, { visible: false }); - Overlays.editOverlay(grabberPointLightR, { + Overlays.editOverlay(grabberPointLightR, { visible: false }); Overlays.editOverlay(grabberPointLightF, { From b50bc99cbdccb8d74bc4ff3b93dfcfd63de16338 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 15 Feb 2017 18:57:06 +0000 Subject: [PATCH 05/18] updated menu stack --- interface/resources/qml/hifi/tablet/TabletMenu.qml | 12 ++++++++++-- .../resources/qml/hifi/tablet/TabletMenuStack.qml | 7 ++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/TabletMenu.qml b/interface/resources/qml/hifi/tablet/TabletMenu.qml index 1903a700d6..ec916a60f9 100644 --- a/interface/resources/qml/hifi/tablet/TabletMenu.qml +++ b/interface/resources/qml/hifi/tablet/TabletMenu.qml @@ -64,6 +64,7 @@ FocusScope { // navigate back to root level menu onClicked: { buildMenu(); + breadcrumbText.text = "Menu"; tabletRoot.playButtonClickSound(); } } @@ -106,10 +107,13 @@ FocusScope { function setRootMenu(menu) { tabletMenu.rootMenu = menu - buildMenu() + buildMenu(); } function buildMenu() { <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> updated menu stack // Build submenu if specified. if (subMenu !== "") { var index = 0; @@ -122,15 +126,19 @@ FocusScope { } subMenu = ""; // Continue with full menu after initially displaying submenu. if (found) { - menuPopperUpper.popup(tabletMenu, rootMenu.items[index].items); + menuPopperUpper.popup(rootMenu.items[index].items); return; } } // Otherwise build whole menu. +<<<<<<< HEAD menuPopperUpper.popup(tabletMenu, rootMenu.items); ======= menuPopperUpper.popup(rootMenu.items); >>>>>>> updating branch with master +======= + menuPopperUpper.popup(rootMenu.items); +>>>>>>> updated menu stack } } diff --git a/interface/resources/qml/hifi/tablet/TabletMenuStack.qml b/interface/resources/qml/hifi/tablet/TabletMenuStack.qml index f84f90fbb3..c33f4e648b 100644 --- a/interface/resources/qml/hifi/tablet/TabletMenuStack.qml +++ b/interface/resources/qml/hifi/tablet/TabletMenuStack.qml @@ -27,12 +27,13 @@ Item { d.clearMenus(); } } - + StackView { anchors.fill: parent id: d objectName: "stack" initialItem: topMenu + property var menuStack: [] property var topMenu: null; property var modelMaker: Component { ListModel { } } @@ -57,9 +58,13 @@ Item { } function pushSource(path) { + d.push(Qt.resolvedUrl(path)); + d.currentItem.eventBridge = tabletMenu.eventBridge + d.currentItem.sendToScript.connect(tabletMenu.sendToScript); } function popSource() { + d.pop(); } function toModel(items) { From 7ad8a389f62eb743f40d31fb37ed2ab47cfc3c1b Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Thu, 16 Feb 2017 15:58:26 +0000 Subject: [PATCH 06/18] refreshing with master --- interface/src/Application.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4011eafb6a..78b81f2075 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5744,13 +5744,10 @@ bool Application::displayAvatarAttachmentConfirmationDialog(const QString& name) void Application::toggleRunningScriptsWidget() const { auto tabletScriptingInterface = DependencyManager::get(); - auto tabletWindow = tabletScriptingInterface->getTabletWindow(); static const QUrl url("hifi/dialogs/RunningScripts.qml"); - if (tabletWindow) { + if (true) { auto tablet = dynamic_cast(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system")); - if (tablet) { - tablet->pushOntoStack("../..//hifi/dialogs/RunningScripts.qml"); - } + tablet->pushOntoStack("../..//hifi/dialogs/RunningScripts.qml"); } else { DependencyManager::get()->show(url, "RunningScripts"); } From afd56bbbbe0db2b8c46a1c5d2cdfb5f9eaf0a8a8 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 17 Feb 2017 00:01:12 +0000 Subject: [PATCH 07/18] fixed qml font path issue for desktop and tablet --- .../qml/hifi/dialogs/TabletRunningScripts.qml | 342 ++++++++++++++++++ .../resources/qml/hifi/tablet/TabletMenu.qml | 11 - .../qml/hifi/tablet/TabletMenuStack.qml | 14 +- .../qml/styles-uit/FiraSansSemiBold.qml | 2 +- .../resources/qml/styles-uit/HiFiGlyphs.qml | 2 +- .../resources/qml/styles-uit/RalewayBold.qml | 2 +- .../qml/styles-uit/RalewayRegular.qml | 2 +- .../qml/styles-uit/RalewaySemiBold.qml | 2 +- interface/src/Application.cpp | 11 +- interface/src/ui/overlays/Web3DOverlay.cpp | 4 + 10 files changed, 358 insertions(+), 34 deletions(-) create mode 100644 interface/resources/qml/hifi/dialogs/TabletRunningScripts.qml diff --git a/interface/resources/qml/hifi/dialogs/TabletRunningScripts.qml b/interface/resources/qml/hifi/dialogs/TabletRunningScripts.qml new file mode 100644 index 0000000000..235f7103ff --- /dev/null +++ b/interface/resources/qml/hifi/dialogs/TabletRunningScripts.qml @@ -0,0 +1,342 @@ +// +// RunningScripts.qml +// +// Created by Bradley Austin Davis on 12 Jan 2016 +// 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 +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Dialogs 1.2 as OriginalDialogs +import Qt.labs.settings 1.0 + +import "../../styles-uit" +import "../../controls-uit" as HifiControls +import "../../windows" + +Item { + id: root + objectName: "RunningScripts" + HifiConstants { id: hifi } + signal sendToScript(var message); + property var eventBridge; + property var scripts: ScriptDiscoveryService; + property var scriptsModel: scripts.scriptsModelFilter + property var runningScriptsModel: ListModel { } + property bool isHMD: false + + Connections { + target: ScriptDiscoveryService + onScriptCountChanged: updateRunningScripts(); + } + + Component.onCompleted: { + isHMD = HMD.active; + updateRunningScripts(); + } + + function updateRunningScripts() { + var runningScripts = ScriptDiscoveryService.getRunning(); + runningScriptsModel.clear() + for (var i = 0; i < runningScripts.length; ++i) { + runningScriptsModel.append(runningScripts[i]); + } + } + + function loadScript(script) { + console.log("Load script " + script); + scripts.loadOneScript(script); + } + + function reloadScript(script) { + console.log("Reload script " + script); + scripts.stopScript(script, true); + } + + function stopScript(script) { + console.log("Stop script " + script); + scripts.stopScript(script); + } + + function reloadAll() { + console.log("Reload all scripts"); + scripts.reloadAllScripts(); + } + + function loadDefaults() { + console.log("Load default scripts"); + scripts.loadOneScript(scripts.defaultScriptsPath + "/defaultScripts.js"); + } + + function stopAll() { + console.log("Stop all scripts"); + scripts.stopAllScripts(); + } + + Column { + width: parent.width + HifiControls.TabletContentSection { + name: "Currently Running" + isFirst: true + + HifiControls.VerticalSpacer {} + + Row { + spacing: hifi.dimensions.contentSpacing.x + + HifiControls.Button { + text: "Reload All" + color: hifi.buttons.black + onClicked: reloadAll() + } + + HifiControls.Button { + text: "Remove All" + color: hifi.buttons.red + onClicked: stopAll() + } + } + + HifiControls.VerticalSpacer { + height: hifi.dimensions.controlInterlineHeight + 2 // Add space for border + } + + HifiControls.Table { + model: runningScriptsModel + id: table + height: 185 + colorScheme: hifi.colorSchemes.dark + anchors.left: parent.left + anchors.right: parent.right + expandSelectedRow: true + + itemDelegate: Item { + anchors { + left: parent ? parent.left : undefined + leftMargin: hifi.dimensions.tablePadding + right: parent ? parent.right : undefined + rightMargin: hifi.dimensions.tablePadding + } + + FiraSansSemiBold { + id: textItem + text: styleData.value + size: hifi.fontSizes.tableText + color: table.colorScheme == hifi.colorSchemes.light + ? (styleData.selected ? hifi.colors.black : hifi.colors.baseGrayHighlight) + : (styleData.selected ? hifi.colors.black : hifi.colors.lightGrayText) + anchors { + left: parent.left + right: parent.right + top: parent.top + topMargin: 3 + } + + HiFiGlyphs { + id: reloadButton + text: hifi.glyphs.reloadSmall + color: reloadButtonArea.pressed ? hifi.colors.white : parent.color + anchors { + top: parent.top + right: stopButton.left + verticalCenter: parent.verticalCenter + } + MouseArea { + id: reloadButtonArea + anchors { fill: parent; margins: -2 } + onClicked: reloadScript(model.url) + } + } + + HiFiGlyphs { + id: stopButton + text: hifi.glyphs.closeSmall + color: stopButtonArea.pressed ? hifi.colors.white : parent.color + anchors { + top: parent.top + right: parent.right + verticalCenter: parent.verticalCenter + } + MouseArea { + id: stopButtonArea + anchors { fill: parent; margins: -2 } + onClicked: stopScript(model.url) + } + } + + } + + FiraSansSemiBold { + text: runningScriptsModel.get(styleData.row) ? runningScriptsModel.get(styleData.row).url : "" + elide: Text.ElideMiddle + size: hifi.fontSizes.tableText + color: table.colorScheme == hifi.colorSchemes.light + ? (styleData.selected ? hifi.colors.black : hifi.colors.lightGray) + : (styleData.selected ? hifi.colors.black : hifi.colors.lightGrayText) + anchors { + top: textItem.bottom + left: parent.left + right: parent.right + } + visible: styleData.selected + } + } + + TableViewColumn { + role: "name" + } + } + + HifiControls.VerticalSpacer { + height: hifi.dimensions.controlInterlineHeight + 2 // Add space for border + } + } + + HifiControls.TabletContentSection { + name: "Load Scripts" + + HifiControls.VerticalSpacer {} + + Row { + spacing: hifi.dimensions.contentSpacing.x + + HifiControls.Button { + text: "from URL" + color: hifi.buttons.black + height: 26 + onClicked: fromUrlTimer.running = true + + // For some reason trigginer an API that enters + // an internal event loop directly from the button clicked + // trigger below causes the appliction to behave oddly. + // Most likely because the button onClicked handling is never + // completed until the function returns. + // FIXME find a better way of handling the input dialogs that + // doesn't trigger this. + Timer { + id: fromUrlTimer + interval: 5 + repeat: false + running: false + onTriggered: ApplicationInterface.loadScriptURLDialog(); + } + } + + HifiControls.Button { + text: "from Disk" + color: hifi.buttons.black + height: 26 + onClicked: fromDiskTimer.running = true + + Timer { + id: fromDiskTimer + interval: 5 + repeat: false + running: false + onTriggered: ApplicationInterface.loadDialog(); + } + } + + HifiControls.Button { + text: "Load Defaults" + color: hifi.buttons.black + height: 26 + onClicked: loadDefaults() + } + } + + HifiControls.VerticalSpacer {} + + HifiControls.TextField { + id: filterEdit + isSearchField: true + anchors.left: parent.left + anchors.right: parent.right + colorScheme: hifi.colorSchemes.dark + placeholderText: "Filter" + onTextChanged: scriptsModel.filterRegExp = new RegExp("^.*" + text + ".*$", "i") + Component.onCompleted: scriptsModel.filterRegExp = new RegExp("^.*$", "i") + } + + HifiControls.VerticalSpacer { + height: hifi.dimensions.controlInterlineHeight + 2 // Add space for border + } + + HifiControls.Tree { + id: treeView + height: 155 + treeModel: scriptsModel + colorScheme: hifi.colorSchemes.dark + anchors.left: parent.left + anchors.right: parent.right + } + + HifiControls.VerticalSpacer { + height: hifi.dimensions.controlInterlineHeight + 2 // Add space for border + } + + HifiControls.TextField { + id: selectedScript + anchors.left: parent.left + anchors.right: parent.right + anchors.rightMargin: loadButton.width + hifi.dimensions.contentSpacing.x + + colorScheme: hifi.colorSchemes.dark + readOnly: true + + Connections { + target: treeView + onCurrentIndexChanged: { + var path = scriptsModel.data(treeView.currentIndex, 0x100) + if (path) { + selectedScript.text = path + } else { + selectedScript.text = "" + } + } + } + } + + Item { + // Take the loadButton out of the column flow. + id: loadButtonContainer + anchors.top: selectedScript.top + anchors.right: parent.right + + HifiControls.Button { + id: loadButton + anchors.right: parent.right + + text: "Load" + color: hifi.buttons.blue + enabled: selectedScript.text != "" + onClicked: root.loadScript(selectedScript.text) + } + } + + HifiControls.VerticalSpacer { + height: hifi.dimensions.controlInterlineHeight - (!isHMD ? 3 : 0) + } + + HifiControls.TextAction { + id: directoryButton + icon: hifi.glyphs.script + iconSize: 24 + text: "Reveal Scripts Folder" + onClicked: fileDialogHelper.openDirectory(scripts.defaultScriptsPath) + colorScheme: hifi.colorSchemes.dark + anchors.left: parent.left + visible: !isHMD + } + + HifiControls.VerticalSpacer { + height: hifi.dimensions.controlInterlineHeight - 3 + visible: !isHMD + } + } + } +} + diff --git a/interface/resources/qml/hifi/tablet/TabletMenu.qml b/interface/resources/qml/hifi/tablet/TabletMenu.qml index ec916a60f9..46a62ace82 100644 --- a/interface/resources/qml/hifi/tablet/TabletMenu.qml +++ b/interface/resources/qml/hifi/tablet/TabletMenu.qml @@ -110,10 +110,6 @@ FocusScope { buildMenu(); } function buildMenu() { -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> updated menu stack // Build submenu if specified. if (subMenu !== "") { var index = 0; @@ -132,13 +128,6 @@ FocusScope { } // Otherwise build whole menu. -<<<<<<< HEAD - menuPopperUpper.popup(tabletMenu, rootMenu.items); -======= menuPopperUpper.popup(rootMenu.items); ->>>>>>> updating branch with master -======= - menuPopperUpper.popup(rootMenu.items); ->>>>>>> updated menu stack } } diff --git a/interface/resources/qml/hifi/tablet/TabletMenuStack.qml b/interface/resources/qml/hifi/tablet/TabletMenuStack.qml index c33f4e648b..ca4c657242 100644 --- a/interface/resources/qml/hifi/tablet/TabletMenuStack.qml +++ b/interface/resources/qml/hifi/tablet/TabletMenuStack.qml @@ -17,16 +17,6 @@ Item { id: root anchors.fill: parent objectName: "tabletMenuHandlerItem" - - MouseArea { - id: menuRoot; - objectName: "tabletMenuHandlerMouseArea" - anchors.fill: parent - enabled: d.topMenu !== null - onClicked: { - d.clearMenus(); - } - } StackView { anchors.fill: parent @@ -61,9 +51,11 @@ Item { d.push(Qt.resolvedUrl(path)); d.currentItem.eventBridge = tabletMenu.eventBridge d.currentItem.sendToScript.connect(tabletMenu.sendToScript); + breadcrumbText.text = d.currentItem.objectName; } function popSource() { + console.log("trying to pop page"); d.pop(); } @@ -90,7 +82,9 @@ Item { } function popMenu() { + console.log("the depth of the stack " + d.depth); if (d.depth) { + console.log("trying to pop page from stack"); d.pop(); } if (d.depth) { diff --git a/interface/resources/qml/styles-uit/FiraSansSemiBold.qml b/interface/resources/qml/styles-uit/FiraSansSemiBold.qml index ddbeff7d90..b3f3324090 100644 --- a/interface/resources/qml/styles-uit/FiraSansSemiBold.qml +++ b/interface/resources/qml/styles-uit/FiraSansSemiBold.qml @@ -14,7 +14,7 @@ import QtQuick.Controls.Styles 1.4 Text { id: root - FontLoader { id: firaSansSemiBold; source: "../../fonts/FiraSans-SemiBold.ttf"; } + FontLoader { id: firaSansSemiBold; source: pathToFonts + "fonts/FiraSans-SemiBold.ttf"; } property real size: 32 font.pixelSize: size verticalAlignment: Text.AlignVCenter diff --git a/interface/resources/qml/styles-uit/HiFiGlyphs.qml b/interface/resources/qml/styles-uit/HiFiGlyphs.qml index d0dae746be..cbd6fa1d68 100644 --- a/interface/resources/qml/styles-uit/HiFiGlyphs.qml +++ b/interface/resources/qml/styles-uit/HiFiGlyphs.qml @@ -14,7 +14,7 @@ import QtQuick.Controls.Styles 1.4 Text { id: root - FontLoader { id: hiFiGlyphs; source: "../../fonts/hifi-glyphs.ttf"; } + FontLoader { id: hiFiGlyphs; source: pathToFonts + "fonts/hifi-glyphs.ttf"; } property int size: 32 font.pixelSize: size width: size diff --git a/interface/resources/qml/styles-uit/RalewayBold.qml b/interface/resources/qml/styles-uit/RalewayBold.qml index 97a6a4c208..433fdb7ae6 100644 --- a/interface/resources/qml/styles-uit/RalewayBold.qml +++ b/interface/resources/qml/styles-uit/RalewayBold.qml @@ -14,7 +14,7 @@ import QtQuick.Controls.Styles 1.4 Text { id: root - FontLoader { id: ralewayBold; source: "../../fonts/Raleway-Bold.ttf"; } + FontLoader { id: ralewayBold; source: pathToFonts + "fonts/Raleway-Bold.ttf"; } property real size: 32 font.pixelSize: size verticalAlignment: Text.AlignVCenter diff --git a/interface/resources/qml/styles-uit/RalewayRegular.qml b/interface/resources/qml/styles-uit/RalewayRegular.qml index 1ed5f122dc..2cffeeb59d 100644 --- a/interface/resources/qml/styles-uit/RalewayRegular.qml +++ b/interface/resources/qml/styles-uit/RalewayRegular.qml @@ -14,7 +14,7 @@ import QtQuick.Controls.Styles 1.4 Text { id: root - FontLoader { id: ralewayRegular; source: "../../fonts/Raleway-Regular.ttf"; } + FontLoader { id: ralewayRegular; source: pathToFonts + "fonts/Raleway-Regular.ttf"; } property real size: 32 font.pixelSize: size verticalAlignment: Text.AlignVCenter diff --git a/interface/resources/qml/styles-uit/RalewaySemiBold.qml b/interface/resources/qml/styles-uit/RalewaySemiBold.qml index 3c36a872a4..b6c79e02a4 100644 --- a/interface/resources/qml/styles-uit/RalewaySemiBold.qml +++ b/interface/resources/qml/styles-uit/RalewaySemiBold.qml @@ -14,7 +14,7 @@ import QtQuick.Controls.Styles 1.4 Text { id: root - FontLoader { id: ralewaySemiBold; source: "../../fonts/Raleway-SemiBold.ttf"; } + FontLoader { id: ralewaySemiBold; source: pathToFonts + "fonts/Raleway-SemiBold.ttf"; } property real size: 32 font.pixelSize: size verticalAlignment: Text.AlignVCenter diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 78b81f2075..d6c69f005d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1940,6 +1940,7 @@ void Application::initializeUi() { rootContext->setContextProperty("AddressManager", DependencyManager::get().data()); rootContext->setContextProperty("FrameTimings", &_frameTimingsScriptingInterface); rootContext->setContextProperty("Rates", new RatesScriptingInterface(this)); + rootContext->setContextProperty("pathToFonts", "../../"); rootContext->setContextProperty("TREE_SCALE", TREE_SCALE); rootContext->setContextProperty("Quat", new Quat()); @@ -5743,14 +5744,8 @@ bool Application::displayAvatarAttachmentConfirmationDialog(const QString& name) } void Application::toggleRunningScriptsWidget() const { - auto tabletScriptingInterface = DependencyManager::get(); - static const QUrl url("hifi/dialogs/RunningScripts.qml"); - if (true) { - auto tablet = dynamic_cast(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system")); - tablet->pushOntoStack("../..//hifi/dialogs/RunningScripts.qml"); - } else { - DependencyManager::get()->show(url, "RunningScripts"); - } + DependencyManager::get()->show(url, "RunningScripts"); + //if (_runningScriptsWidget->isVisible()) { // if (_runningScriptsWidget->hasFocus()) { // _runningScriptsWidget->hide(); diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 72bd0228f3..bfd58b9cff 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -38,8 +38,10 @@ #include "scripting/AccountScriptingInterface.h" #include "scripting/HMDScriptingInterface.h" #include +#include #include "FileDialogHelper.h" + static const float DPI = 30.47f; static const float INCHES_TO_METERS = 1.0f / 39.3701f; static const float METERS_TO_INCHES = 39.3701f; @@ -170,6 +172,8 @@ void Web3DOverlay::loadSourceURL() { _webSurface->getRootContext()->setContextProperty("Account", AccountScriptingInterface::getInstance()); _webSurface->getRootContext()->setContextProperty("HMD", DependencyManager::get().data()); _webSurface->getRootContext()->setContextProperty("fileDialogHelper", new FileDialogHelper()); + _webSurface->getRootContext()->setContextProperty("ScriptDiscoveryService", DependencyManager::get().data()); + _webSurface->getRootContext()->setContextProperty("pathToFonts", "../../../"); tabletScriptingInterface->setQmlTabletRoot("com.highfidelity.interface.tablet.system", _webSurface->getRootItem(), _webSurface.data()); // Override min fps for tablet UI, for silky smooth scrolling From 3189b44612edb006ccc23920ae10e79bead59a3c Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 17 Feb 2017 15:50:08 +0000 Subject: [PATCH 08/18] refreshing with master --- interface/resources/qml/hifi/tablet/TabletMenu.qml | 3 --- interface/src/Application.cpp | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/TabletMenu.qml b/interface/resources/qml/hifi/tablet/TabletMenu.qml index 8c277fef04..4c687131ca 100644 --- a/interface/resources/qml/hifi/tablet/TabletMenu.qml +++ b/interface/resources/qml/hifi/tablet/TabletMenu.qml @@ -20,13 +20,10 @@ FocusScope { property var rootMenu: Menu { objectName:"rootMenu" } property var point: Qt.point(50, 50); - property var eventBridge; - signal sendToScript(var message); TabletMenuStack { id: menuPopperUpper } property string subMenu: "" property var eventBridge; signal sendToScript(var message); - TabletMenuStack { id: menuPopperUpper } Rectangle { id: bgNavBar diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2d049dbec7..ffd5c53d47 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5744,7 +5744,9 @@ bool Application::displayAvatarAttachmentConfirmationDialog(const QString& name) } void Application::toggleRunningScriptsWidget() const { + static const QUrl url("hifi/dialogs/RunningScripts.qml"); DependencyManager::get()->show(url, "RunningScripts"); + //if (_runningScriptsWidget->isVisible()) { // if (_runningScriptsWidget->hasFocus()) { // _runningScriptsWidget->hide(); From dedd85d29696445ae3a04237fd1028e9a5714002 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 17 Feb 2017 18:47:59 +0000 Subject: [PATCH 09/18] saving work --- interface/resources/qml/hifi/tablet/TabletRoot.qml | 1 + interface/src/Application.cpp | 10 +++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/TabletRoot.qml b/interface/resources/qml/hifi/tablet/TabletRoot.qml index 481c7846a9..fcefd1af24 100644 --- a/interface/resources/qml/hifi/tablet/TabletRoot.qml +++ b/interface/resources/qml/hifi/tablet/TabletRoot.qml @@ -81,6 +81,7 @@ Item { loader.item.subMenu = option; } loader.item.forceActiveFocus(); + tabletRoot.findStackableChild(); } } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4e0cf46634..95620b1ddf 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5747,9 +5747,13 @@ bool Application::displayAvatarAttachmentConfirmationDialog(const QString& name) } void Application::toggleRunningScriptsWidget() const { - static const QUrl url("hifi/dialogs/RunningScripts.qml"); - DependencyManager::get()->show(url, "RunningScripts"); - + static const QUrl url("../../hifi/dialogs/TabletRunningScripts.qml"); + auto tabletScriptingInterface = DependencyManager::get(); + auto tablet = dynamic_cast(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system")); + if (tablet) { + tablet->pushOntoStack(url); + } + //DependencyManager::get()->show(url, "RunningScripts"); //if (_runningScriptsWidget->isVisible()) { // if (_runningScriptsWidget->hasFocus()) { // _runningScriptsWidget->hide(); From 3ba605bf23cd53e4962de78a15a647c93ef48c23 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Thu, 23 Feb 2017 00:28:30 +0000 Subject: [PATCH 10/18] saving work --- cmake/macros/LinkHifiLibraries.cmake | 2 +- .../qml/dialogs/TabletQueryDialog.qml | 205 ++++++++++++++++++ .../resources/qml/hifi/tablet/TabletRoot.qml | 20 +- .../qml/windows/TabletModalFrame.qml | 85 ++++++++ .../qml/windows/TabletModalWindow.qml | 22 ++ interface/src/Application.cpp | 8 +- .../src/TabletScriptingInterface.h | 2 + libraries/ui/CMakeLists.txt | 2 +- libraries/ui/src/OffscreenUi.cpp | 20 +- 9 files changed, 355 insertions(+), 11 deletions(-) create mode 100644 interface/resources/qml/dialogs/TabletQueryDialog.qml create mode 100644 interface/resources/qml/windows/TabletModalFrame.qml create mode 100644 interface/resources/qml/windows/TabletModalWindow.qml diff --git a/cmake/macros/LinkHifiLibraries.cmake b/cmake/macros/LinkHifiLibraries.cmake index 3767dc7131..de4ff23863 100644 --- a/cmake/macros/LinkHifiLibraries.cmake +++ b/cmake/macros/LinkHifiLibraries.cmake @@ -21,7 +21,7 @@ macro(LINK_HIFI_LIBRARIES) include_directories("${HIFI_LIBRARY_DIR}/${HIFI_LIBRARY}/src") include_directories("${CMAKE_BINARY_DIR}/libraries/${HIFI_LIBRARY}/shaders") - add_dependencies(${TARGET_NAME} ${HIFI_LIBRARY}) + #add_dependencies(${TARGET_NAME} ${HIFI_LIBRARY}) # link the actual library - it is static so don't bubble it up target_link_libraries(${TARGET_NAME} ${HIFI_LIBRARY}) diff --git a/interface/resources/qml/dialogs/TabletQueryDialog.qml b/interface/resources/qml/dialogs/TabletQueryDialog.qml new file mode 100644 index 0000000000..0ae18d1c2d --- /dev/null +++ b/interface/resources/qml/dialogs/TabletQueryDialog.qml @@ -0,0 +1,205 @@ +// +// QueryDialog.qml +// +// Created by Bradley Austin Davis on 22 Jan 2016 +// Copyright 2015 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 +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Dialogs 1.2 as OriginalDialogs + +import "../controls-uit" +import "../styles-uit" +import "../windows" + +TabletModalWindow { + id: root + HifiConstants { id: hifi } + signal selected(var result); + signal canceled(); + layer.enabled: true + property int icon: hifi.icons.none + property string iconText: "" + property int iconSize: 35 + + MouseArea { + width: parent.width + height: parent.height + } + + property bool keyboardOverride: true + onIconChanged: updateIcon(); + + property var items; + property string label: "" + property var result; + property alias current: textResult.text + + // For text boxes + property alias placeholderText: textResult.placeholderText + + // For combo boxes + property bool editable: true; + + property int titleWidth: 0 + onTitleWidthChanged: d.resize(); + + property bool keyboardEnabled: false + property bool keyboardRaised: false + property bool punctuationMode: false + + onKeyboardRaisedChanged: d.resize(); + + function updateIcon() { + if (!root) { + return; + } + iconText = hifi.glyphForIcon(root.icon); + } + + Rectangle { + id: modalWindowItem + width: parent.width + height: 480 + anchors.margins: 0 + anchors { + verticalCenter: parent.verticalCenter + horizontalCenter: parent.horizontalCenter + } + + QtObject { + id: d + readonly property int minWidth: 480 + readonly property int maxWdith: 480 + readonly property int minHeight: 120 + readonly property int maxHeight: 720 + + function resize() { + var targetWidth = Math.max(titleWidth, 480) + var targetHeight = (items ? comboBox.controlHeight : textResult.controlHeight) + 5 * hifi.dimensions.contentSpacing.y + buttons.height + modalWindowItem.width = (targetWidth < d.minWidth) ? d.minWidth : ((targetWidth > d.maxWdith) ? d.maxWidth : targetWidth); + modalWindowItem.height = ((targetHeight < d.minHeight) ? d.minHeight : ((targetHeight > d.maxHeight) ? d.maxHeight : targetHeight)) + ((keyboardEnabled && keyboardRaised) ? (keyboard.raisedHeight + 2 * hifi.dimensions.contentSpacing.y) : 0) + } + } + + Item { + anchors { + top: frameTitle.bottom + bottom: keyboard.top; + left: parent.left; + right: parent.right; + margins: 0 + bottomMargin: 2 * hifi.dimensions.contentSpacing.y + } + + // FIXME make a text field type that can be bound to a history for autocompletion + TextField { + id: textResult + label: root.label + focus: items ? false : true + visible: items ? false : true + anchors { + left: parent.left; + right: parent.right; + bottom: parent.bottom + } + } + + TabletComboBox { + id: comboBox + label: root.label + focus: true + visible: items ? true : false + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + } + model: items ? items : [] + } + } + + property alias keyboardOverride: root.keyboardOverride + property alias keyboardRaised: root.keyboardRaised + property alias punctuationMode: root.punctuationMode + + Keyboard { + id: keyboard + raised: keyboardEnabled && keyboardRaised + numeric: punctuationMode + anchors { + left: parent.left + right: parent.right + bottom: buttons.top + bottomMargin: raised ? 2 * hifi.dimensions.contentSpacing.y : 0 + } + } + + Flow { + id: buttons + focus: true + spacing: hifi.dimensions.contentSpacing.x + onHeightChanged: d.resize(); onWidthChanged: d.resize(); + layoutDirection: Qt.RightToLeft + anchors { + bottom: parent.bottom + right: parent.right + margins: 0 + bottomMargin: hifi.dimensions.contentSpacing.y + } + Button { action: cancelAction } + Button { action: acceptAction } + } + + Action { + id: cancelAction + text: qsTr("Cancel") + shortcut: Qt.Key_Escape + onTriggered: { + root.canceled(); + root.destroy(); + } + } + Action { + id: acceptAction + text: qsTr("OK") + shortcut: Qt.Key_Return + onTriggered: { + root.result = items ? comboBox.currentText : textResult.text + root.selected(root.result); + root.destroy(); + } + } + } + + Keys.onPressed: { + if (!visible) { + return + } + + switch (event.key) { + case Qt.Key_Escape: + case Qt.Key_Back: + cancelAction.trigger() + event.accepted = true; + break; + + case Qt.Key_Return: + case Qt.Key_Enter: + acceptAction.trigger() + event.accepted = true; + break; + } + } + + Component.onCompleted: { + keyboardEnabled = HMD.active; + updateIcon(); + d.resize(); + textResult.forceActiveFocus(); + } +} diff --git a/interface/resources/qml/hifi/tablet/TabletRoot.qml b/interface/resources/qml/hifi/tablet/TabletRoot.qml index 22efe63064..79b127098b 100644 --- a/interface/resources/qml/hifi/tablet/TabletRoot.qml +++ b/interface/resources/qml/hifi/tablet/TabletRoot.qml @@ -1,6 +1,7 @@ import QtQuick 2.0 import Hifi 1.0 - +import QtQuick.Controls 1.4 +import "../../dialogs" Item { id: tabletRoot objectName: "tabletRoot" @@ -9,13 +10,26 @@ Item { property var rootMenu; property string subMenu: "" - signal showDesktop(); function setOption(value) { option = value; } + Component { id: inputDialogBuilder; TabletQueryDialog { } } + function inputDialog(properties) { + return inputDialogBuilder.createObject(tabletRoot, properties); + } + + function messageBox(properties) { + } + + function customInputDialog(properties) { + } + + function fileDialog(properties) { + } + function setMenuProperties(rootMenu, subMenu) { tabletRoot.rootMenu = rootMenu; tabletRoot.subMenu = subMenu; @@ -68,6 +82,7 @@ Item { objectName: "loader" asynchronous: false + width: parent.width height: parent.height @@ -89,7 +104,6 @@ Item { loader.item.setRootMenu(tabletRoot.rootMenu, tabletRoot.subMenu); } loader.item.forceActiveFocus(); - tabletRoot.findStackableChild(); } } diff --git a/interface/resources/qml/windows/TabletModalFrame.qml b/interface/resources/qml/windows/TabletModalFrame.qml new file mode 100644 index 0000000000..41775f6b3e --- /dev/null +++ b/interface/resources/qml/windows/TabletModalFrame.qml @@ -0,0 +1,85 @@ +// +// ModalFrame.qml +// +// Created by Bradley Austin Davis on 15 Jan 2016 +// Copyright 2015 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 +// + +import QtQuick 2.5 + +import "." +import "../controls-uit" +import "../styles-uit" + + +Rectangle { + HifiConstants { id: hifi } + + + Rectangle { + id: frameContent + + //readonly property bool hasTitle: window.title != "" + + readonly property int frameMarginLeft: hifi.dimensions.modalDialogMargin.x + readonly property int frameMarginRight: hifi.dimensions.modalDialogMargin.x + readonly property int frameMarginTop: hifi.dimensions.modalDialogMargin.y + (frameContent.hasTitle ? hifi.dimensions.modalDialogTitleHeight + 10 : 0) + readonly property int frameMarginBottom: hifi.dimensions.modalDialogMargin.y + + border { + width: hifi.dimensions.borderWidth + color: hifi.colors.lightGrayText80 + } + radius: hifi.dimensions.borderRadius + color: hifi.colors.faintGray + Item { + id: frameTitle + visible: true//frameContent.hasTitle + //anchors.fill: parent + + anchors { + fill: parent + topMargin: -frameMarginTop + leftMargin: -frameMarginLeft + rightMargin: -frameMarginRight + bottomMargin: -frameMarginBottom + } + + Item { + width: title.width + (icon.text !== "" ? icon.width + hifi.dimensions.contentSpacing.x : 20) + + onWidthChanged: root.titleWidth = width + + HiFiGlyphs { + id: icon + text: root.iconText ? root.iconText : "hello" + size: root.iconSize ? root.iconSize : 30 + color: hifi.colors.lightGray + visible: true + anchors.verticalCenter: title.verticalCenter + anchors.left: parent.left + } + RalewayRegular { + id: title + text: root.title + elide: Text.ElideRight + color: hifi.colors.baseGrayHighlight + size: hifi.fontSizes.overlayTitle + y: -hifi.dimensions.modalDialogTitleHeight + anchors.right: parent.right + } + } + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + height: 1 + color: hifi.colors.lightGray + } + } + } + +} diff --git a/interface/resources/qml/windows/TabletModalWindow.qml b/interface/resources/qml/windows/TabletModalWindow.qml new file mode 100644 index 0000000000..05f192f7a7 --- /dev/null +++ b/interface/resources/qml/windows/TabletModalWindow.qml @@ -0,0 +1,22 @@ +// +// ModalWindow.qml +// +// Created by Bradley Austin Davis on 22 Jan 2016 +// Copyright 2015 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 +// +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Dialogs 1.2 as OriginalDialogs +import "." + +Rectangle { + id: modalWindow + layer.enabled: true + property var title: "Modal" + width: tabletRoot.width + height: tabletRoot.height + color: "#80000000" +} diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index cf677a1c95..c016b31a14 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5769,10 +5769,14 @@ bool Application::displayAvatarAttachmentConfirmationDialog(const QString& name) } void Application::toggleRunningScriptsWidget() const { - static const QUrl url("../../hifi/dialogs/TabletRunningScripts.qml"); + auto tabletScriptingInterface = DependencyManager::get(); auto tablet = dynamic_cast(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system")); - if (tablet) { + if (tablet->getToolbarMode()) { + static const QUrl url("hifi/dialogs/RunningScripts.qml"); + DependencyManager::get()->show(url, "RunningScripts"); + } else { + static const QUrl url("../../hifi/dialogs/TabletRunningScripts.qml"); tablet->pushOntoStack(url); } //DependencyManager::get()->show(url, "RunningScripts"); diff --git a/libraries/script-engine/src/TabletScriptingInterface.h b/libraries/script-engine/src/TabletScriptingInterface.h index a30b4459e3..8b9bec4013 100644 --- a/libraries/script-engine/src/TabletScriptingInterface.h +++ b/libraries/script-engine/src/TabletScriptingInterface.h @@ -154,6 +154,8 @@ public: Q_INVOKABLE bool onHomeScreen(); + QQuickItem* getTabletRoot() const { return _qmlTabletRoot; } + QObject* getTabletSurface(); QQuickItem* getQmlTablet() const; diff --git a/libraries/ui/CMakeLists.txt b/libraries/ui/CMakeLists.txt index cc2382926f..f2b48446fe 100644 --- a/libraries/ui/CMakeLists.txt +++ b/libraries/ui/CMakeLists.txt @@ -1,3 +1,3 @@ set(TARGET_NAME ui) setup_hifi_library(OpenGL Network Qml Quick Script WebChannel WebSockets XmlPatterns) -link_hifi_libraries(shared networking gl) +link_hifi_libraries(shared networking gl script-engine) diff --git a/libraries/ui/src/OffscreenUi.cpp b/libraries/ui/src/OffscreenUi.cpp index 7724a409f0..f3cb28b8ce 100644 --- a/libraries/ui/src/OffscreenUi.cpp +++ b/libraries/ui/src/OffscreenUi.cpp @@ -19,7 +19,8 @@ #include #include - +#include +#include #include "FileDialogHelper.h" #include "VrMenu.h" @@ -405,10 +406,21 @@ QQuickItem* OffscreenUi::createInputDialog(const Icon icon, const QString& title map.insert("label", label); map.insert("current", current); QVariant result; - bool invokeResult = QMetaObject::invokeMethod(_desktop, "inputDialog", - Q_RETURN_ARG(QVariant, result), - Q_ARG(QVariant, QVariant::fromValue(map))); + auto tabletScriptingInterface = DependencyManager::get(); + TabletProxy* tablet = dynamic_cast(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system")); + + bool invokeResult; + if (tablet->getToolbarMode()) { + invokeResult = QMetaObject::invokeMethod(_desktop, "inputDialog", + Q_RETURN_ARG(QVariant, result), + Q_ARG(QVariant, QVariant::fromValue(map))); + } else { + QQuickItem* tabletRoot = tablet->getTabletRoot(); + invokeResult = QMetaObject::invokeMethod(tabletRoot, "inputDialog", + Q_RETURN_ARG(QVariant, result), + Q_ARG(QVariant, QVariant::fromValue(map))); + } if (!invokeResult) { qWarning() << "Failed to create message box"; return nullptr; From 4a5be4238e4c5ba44851a1924af3f35ec1db9172 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 24 Feb 2017 00:19:32 +0000 Subject: [PATCH 11/18] messages and file dialogs in tablet --- .../qml/dialogs/TabletFileDialog.qml | 776 ++++++++++++++++++ .../qml/dialogs/TabletMessageBox.qml | 248 ++++++ .../qml/dialogs/TabletQueryDialog.qml | 8 +- .../qml/hifi/dialogs/TabletRunningScripts.qml | 4 +- .../resources/qml/hifi/tablet/TabletRoot.qml | 17 +- .../qml/windows/TabletModalFrame.qml | 101 +-- libraries/ui/src/OffscreenUi.cpp | 49 +- 7 files changed, 1137 insertions(+), 66 deletions(-) create mode 100644 interface/resources/qml/dialogs/TabletFileDialog.qml create mode 100644 interface/resources/qml/dialogs/TabletMessageBox.qml diff --git a/interface/resources/qml/dialogs/TabletFileDialog.qml b/interface/resources/qml/dialogs/TabletFileDialog.qml new file mode 100644 index 0000000000..1b0e6d694d --- /dev/null +++ b/interface/resources/qml/dialogs/TabletFileDialog.qml @@ -0,0 +1,776 @@ +// +// FileDialog.qml +// +// Created by Dante Ruiz on 23 Feb 2017 +// Copyright 2015 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 +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import Qt.labs.folderlistmodel 2.1 +import Qt.labs.settings 1.0 +import QtQuick.Controls.Styles 1.4 +import QtQuick.Dialogs 1.2 as OriginalDialogs + +import ".." +import "../controls-uit" +import "../styles-uit" +import "../windows" + +import "fileDialog" + +//FIXME implement shortcuts for favorite location +TabletModalWindow { + id: root + anchors.fill: parent + width: parent.width + height: parent.height + HifiConstants { id: hifi } + + Settings { + category: "FileDialog" + property alias width: root.width + property alias height: root.height + property alias x: root.x + property alias y: root.y + } + + + // Set from OffscreenUi::getOpenFile() + property alias caption: root.title; + // Set from OffscreenUi::getOpenFile() + property alias dir: fileTableModel.folder; + // Set from OffscreenUi::getOpenFile() + property alias filter: selectionType.filtersString; + // Set from OffscreenUi::getOpenFile() + property int options; // <-- FIXME unused + + property string iconText: root.title !== "" ? hifi.glyphs.scriptUpload : "" + property int iconSize: 40 + + property bool selectDirectory: false; + property bool showHidden: false; + // FIXME implement + property bool multiSelect: false; + property bool saveDialog: false; + property var helper: fileDialogHelper + property alias model: fileTableView.model + property var drives: helper.drives() + + property int titleWidth: 0 + + signal selectedFile(var file); + signal canceled(); + + Component.onCompleted: { + console.log("Helper " + helper + " drives " + drives); + + fileDialogItem.keyboardEnabled = HMD.active; + + // HACK: The following lines force the model to initialize properly such that the go-up button + // works properly from the initial screen. + var initialFolder = folderListModel.folder; + fileTableModel.folder = helper.pathToUrl(drives[0]); + fileTableModel.folder = initialFolder; + + iconText = root.title !== "" ? hifi.glyphs.scriptUpload : ""; + + // Clear selection when click on external frame. + //frameClicked.connect(function() { d.clearSelection(); }); + + if (selectDirectory) { + currentSelection.text = d.capitalizeDrive(helper.urlToPath(initialFolder)); + d.currentSelectionIsFolder = true; + d.currentSelectionUrl = initialFolder; + } + + helper.contentsChanged.connect(function() { + if (folderListModel) { + // Make folderListModel refresh. + var save = folderListModel.folder; + folderListModel.folder = ""; + folderListModel.folder = save; + } + }); + + fileTableView.forceActiveFocus(); + } + + TabletModalFrame { + id: fileDialogItem + width: parent.width + height: parent.height + anchors.margins: 0 + + property bool keyboardEnabled: false + property bool keyboardRaised: false + property bool punctuationMode: false + + MouseArea { + // Clear selection when click on internal unused area. + anchors.fill: parent + onClicked: { + d.clearSelection(); + } + } + + Row { + id: navControls + anchors { + top: parent.top + topMargin: (fileDialogItem.hasTitle ? (fileDialogItem.frameMarginTop + hifi.dimensions.modalDialogMargin.y) : hifi.dimension.modalDialogMargin.y) + left: parent.left + } + spacing: hifi.dimensions.contentSpacing.x + + GlyphButton { + id: upButton + glyph: hifi.glyphs.levelUp + width: height + size: 30 + enabled: fileTableModel.parentFolder && fileTableModel.parentFolder !== "" + onClicked: d.navigateUp(); + } + + GlyphButton { + id: homeButton + property var destination: helper.home(); + glyph: hifi.glyphs.home + size: 28 + width: height + enabled: d.homeDestination ? true : false + onClicked: d.navigateHome(); + } + } + + /*TabletComboBox { + id: pathSelector + anchors { + top: parent.top + topMargin: hifi.dimensions.contentMargin.y + left: navControls.right + leftMargin: hifi.dimensions.contentSpacing.x + right: parent.right + } + + property var lastValidFolder: helper.urlToPath(fileTableModel.folder) + + function calculatePathChoices(folder) { + var folders = folder.split("/"), + choices = [], + i, length; + + if (folders[folders.length - 1] === "") { + folders.pop(); + } + + choices.push(folders[0]); + + for (i = 1, length = folders.length; i < length; i++) { + choices.push(choices[i - 1] + "/" + folders[i]); + } + + if (folders[0] === "") { + // Special handling for OSX root dir. + choices[0] = "/"; + } + + choices.reverse(); + + if (drives && drives.length > 1) { + choices.push("This PC"); + } + + if (choices.length > 0) { + pathSelector.model = choices; + } + } + + onLastValidFolderChanged: { + var folder = d.capitalizeDrive(lastValidFolder); + calculatePathChoices(folder); + } + + onCurrentTextChanged: { + var folder = currentText; + + if (/^[a-zA-z]:$/.test(folder)) { + folder = "file:///" + folder + "/"; + } else if (folder === "This PC") { + folder = "file:///"; + } else { + folder = helper.pathToUrl(folder); + } + + if (helper.urlToPath(folder).toLowerCase() !== helper.urlToPath(fileTableModel.folder).toLowerCase()) { + if (root.selectDirectory) { + currentSelection.text = currentText !== "This PC" ? currentText : ""; + d.currentSelectionUrl = helper.pathToUrl(currentText); + } + fileTableModel.folder = folder; + fileTableView.forceActiveFocus(); + } + } + }*/ + + QtObject { + id: d + property var currentSelectionUrl; + readonly property string currentSelectionPath: helper.urlToPath(currentSelectionUrl); + property bool currentSelectionIsFolder; + property var backStack: [] + property var tableViewConnection: Connections { target: fileTableView; onCurrentRowChanged: d.update(); } + property var modelConnection: Connections { target: fileTableModel; onFolderChanged: d.update(); } + property var homeDestination: helper.home(); + + function capitalizeDrive(path) { + // Consistently capitalize drive letter for Windows. + if (/[a-zA-Z]:/.test(path)) { + return path.charAt(0).toUpperCase() + path.slice(1); + } + return path; + } + + function update() { + var row = fileTableView.currentRow; + + if (row === -1) { + if (!root.selectDirectory) { + currentSelection.text = ""; + currentSelectionIsFolder = false; + } + return; + } + + currentSelectionUrl = helper.pathToUrl(fileTableView.model.get(row).filePath); + currentSelectionIsFolder = fileTableView.model.isFolder(row); + if (root.selectDirectory || !currentSelectionIsFolder) { + currentSelection.text = capitalizeDrive(helper.urlToPath(currentSelectionUrl)); + } else { + currentSelection.text = ""; + } + } + + function navigateUp() { + if (fileTableModel.parentFolder && fileTableModel.parentFolder !== "") { + fileTableModel.folder = fileTableModel.parentFolder; + return true; + } + } + + function navigateHome() { + fileTableModel.folder = homeDestination; + return true; + } + + function clearSelection() { + fileTableView.selection.clear(); + fileTableView.currentRow = -1; + update(); + } + } + + FolderListModel { + id: folderListModel + nameFilters: selectionType.currentFilter + showDirsFirst: true + showDotAndDotDot: false + showFiles: !root.selectDirectory + Component.onCompleted: { + showFiles = !root.selectDirectory + } + + onFolderChanged: { + fileTableModel.update(); // Update once the data from the folder change is available. + } + + function getItem(index, field) { + return get(index, field); + } + } + + ListModel { + // Emulates FolderListModel but contains drive data. + id: driveListModel + + property int count: 1 + + Component.onCompleted: initialize(); + + function initialize() { + var drive, + i; + + count = drives.length; + + for (i = 0; i < count; i++) { + drive = drives[i].slice(0, -1); // Remove trailing "/". + append({ + fileName: drive, + fileModified: new Date(0), + fileSize: 0, + filePath: drive + "/", + fileIsDir: true, + fileNameSort: drive.toLowerCase() + }); + } + } + + function getItem(index, field) { + return get(index)[field]; + } + } + + ListModel { + id: fileTableModel + + // FolderListModel has a couple of problems: + // 1) Files and directories sort case-sensitively: https://bugreports.qt.io/browse/QTBUG-48757 + // 2) Cannot browse up to the "computer" level to view Windows drives: https://bugreports.qt.io/browse/QTBUG-42901 + // + // To solve these problems an intermediary ListModel is used that implements proper sorting and can be populated with + // drive information when viewing at the computer level. + + property var folder + property int sortOrder: Qt.AscendingOrder + property int sortColumn: 0 + property var model: folderListModel + property string parentFolder: calculateParentFolder(); + + readonly property string rootFolder: "file:///" + + function calculateParentFolder() { + if (model === folderListModel) { + if (folderListModel.parentFolder.toString() === "" && driveListModel.count > 1) { + return rootFolder; + } else { + return folderListModel.parentFolder; + } + } else { + return ""; + } + } + + onFolderChanged: { + if (folder === rootFolder) { + model = driveListModel; + helper.monitorDirectory(""); + update(); + } else { + var needsUpdate = model === driveListModel && folder === folderListModel.folder; + + model = folderListModel; + folderListModel.folder = folder; + helper.monitorDirectory(helper.urlToPath(folder)); + + if (needsUpdate) { + update(); + } + } + } + + function isFolder(row) { + if (row === -1) { + return false; + } + return get(row).fileIsDir; + } + + function update() { + var dataFields = ["fileName", "fileModified", "fileSize"], + sortFields = ["fileNameSort", "fileModified", "fileSize"], + dataField = dataFields[sortColumn], + sortField = sortFields[sortColumn], + sortValue, + fileName, + fileIsDir, + comparisonFunction, + lower, + middle, + upper, + rows = 0, + i; + + clear(); + + comparisonFunction = sortOrder === Qt.AscendingOrder + ? function(a, b) { return a < b; } + : function(a, b) { return a > b; } + + for (i = 0; i < model.count; i++) { + fileName = model.getItem(i, "fileName"); + fileIsDir = model.getItem(i, "fileIsDir"); + + sortValue = model.getItem(i, dataField); + if (dataField === "fileName") { + // Directories first by prefixing a "*". + // Case-insensitive. + sortValue = (fileIsDir ? "*" : "") + sortValue.toLowerCase(); + } + + lower = 0; + upper = rows; + while (lower < upper) { + middle = Math.floor((lower + upper) / 2); + var lessThan; + if (comparisonFunction(sortValue, get(middle)[sortField])) { + lessThan = true; + upper = middle; + } else { + lessThan = false; + lower = middle + 1; + } + } + + insert(lower, { + fileName: fileName, + fileModified: (fileIsDir ? new Date(0) : model.getItem(i, "fileModified")), + fileSize: model.getItem(i, "fileSize"), + filePath: model.getItem(i, "filePath"), + fileIsDir: fileIsDir, + fileNameSort: (fileIsDir ? "*" : "") + fileName.toLowerCase() + }); + + rows++; + } + + d.clearSelection(); + } + } + + Table { + id: fileTableView + colorScheme: hifi.colorSchemes.light + anchors { + top: navControls.bottom + topMargin: hifi.dimensions.contentSpacing.y + left: parent.left + right: parent.right + bottom: currentSelection.top + bottomMargin: hifi.dimensions.contentSpacing.y + currentSelection.controlHeight - currentSelection.height + } + headerVisible: !selectDirectory + onDoubleClicked: navigateToRow(row); + focus: true + Keys.onReturnPressed: navigateToCurrentRow(); + Keys.onEnterPressed: navigateToCurrentRow(); + + sortIndicatorColumn: 0 + sortIndicatorOrder: Qt.AscendingOrder + sortIndicatorVisible: true + + model: fileTableModel + + function updateSort() { + model.sortOrder = sortIndicatorOrder; + model.sortColumn = sortIndicatorColumn; + model.update(); + } + + onSortIndicatorColumnChanged: { updateSort(); } + + onSortIndicatorOrderChanged: { updateSort(); } + + itemDelegate: Item { + clip: true + + //FontLoader { id: firaSansSemiBold; source: "../../fonts/FiraSans-SemiBold.ttf"; } + //FontLoader { id: firaSansRegular; source: "../../fonts/FiraSans-Regular.ttf"; } + + FiraSansSemiBold { + text: getText(); + elide: styleData.elideMode + anchors { + left: parent.left + leftMargin: hifi.dimensions.tablePadding + right: parent.right + rightMargin: hifi.dimensions.tablePadding + verticalCenter: parent.verticalCenter + } + size: hifi.fontSizes.tableText + color: hifi.colors.baseGrayHighlight + //font.family: (styleData.row !== -1 && fileTableView.model.get(styleData.row).fileIsDir) + //? firaSansSemiBold.name : firaSansRegular.name + + function getText() { + if (styleData.row === -1) { + return styleData.value; + } + + switch (styleData.column) { + case 1: return fileTableView.model.get(styleData.row).fileIsDir ? "" : styleData.value; + case 2: return fileTableView.model.get(styleData.row).fileIsDir ? "" : formatSize(styleData.value); + default: return styleData.value; + } + } + function formatSize(size) { + var suffixes = [ "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" ]; + var suffixIndex = 0 + while ((size / 1024.0) > 1.1) { + size /= 1024.0; + ++suffixIndex; + } + + size = Math.round(size*1000)/1000; + size = size.toLocaleString() + + return size + " " + suffixes[suffixIndex]; + } + } + } + + TableViewColumn { + id: fileNameColumn + role: "fileName" + title: "Name" + width: (selectDirectory ? 1.0 : 0.5) * fileTableView.width + movable: false + resizable: true + } + TableViewColumn { + id: fileMofifiedColumn + role: "fileModified" + title: "Date" + width: 0.3 * fileTableView.width + movable: false + resizable: true + visible: !selectDirectory + } + TableViewColumn { + role: "fileSize" + title: "Size" + width: fileTableView.width - fileNameColumn.width - fileMofifiedColumn.width + movable: false + resizable: true + visible: !selectDirectory + } + + function navigateToRow(row) { + currentRow = row; + navigateToCurrentRow(); + } + + function navigateToCurrentRow() { + var row = fileTableView.currentRow + var isFolder = model.isFolder(row); + var file = model.get(row).filePath; + if (isFolder) { + fileTableView.model.folder = helper.pathToUrl(file); + } else { + okAction.trigger(); + } + } + + property string prefix: "" + + function addToPrefix(event) { + if (!event.text || event.text === "") { + return false; + } + var newPrefix = prefix + event.text.toLowerCase(); + var matchedIndex = -1; + for (var i = 0; i < model.count; ++i) { + var name = model.get(i).fileName.toLowerCase(); + if (0 === name.indexOf(newPrefix)) { + matchedIndex = i; + break; + } + } + + if (matchedIndex !== -1) { + fileTableView.selection.clear(); + fileTableView.selection.select(matchedIndex); + fileTableView.currentRow = matchedIndex; + fileTableView.prefix = newPrefix; + } + prefixClearTimer.restart(); + return true; + } + + Timer { + id: prefixClearTimer + interval: 1000 + repeat: false + running: false + onTriggered: fileTableView.prefix = ""; + } + + Keys.onPressed: { + switch (event.key) { + case Qt.Key_Backspace: + case Qt.Key_Tab: + case Qt.Key_Backtab: + event.accepted = false; + break; + + default: + if (addToPrefix(event)) { + event.accepted = true + } else { + event.accepted = false; + } + break; + } + } + } + + TextField { + id: currentSelection + label: selectDirectory ? "Directory:" : "File name:" + anchors { + left: parent.left + right: selectionType.visible ? selectionType.left: parent.right + rightMargin: selectionType.visible ? hifi.dimensions.contentSpacing.x : 0 + bottom: keyboard.top + bottomMargin: hifi.dimensions.contentSpacing.y + } + readOnly: !root.saveDialog + activeFocusOnTab: !readOnly + onActiveFocusChanged: if (activeFocus) { selectAll(); } + onAccepted: okAction.trigger(); + } + + FileTypeSelection { + id: selectionType + anchors { + top: currentSelection.top + left: buttonRow.left + right: parent.right + } + visible: !selectDirectory && filtersCount > 1 + KeyNavigation.left: fileTableView + KeyNavigation.right: openButton + } + + Keyboard { + id: keyboard + raised: parent.keyboardEnabled && parent.keyboardRaised + numeric: parent.punctuationMode + anchors { + left: parent.left + right: parent.right + bottom: buttonRow.top + bottomMargin: visible ? hifi.dimensions.contentSpacing.y : 0 + } + } + + Row { + id: buttonRow + anchors { + right: parent.right + bottom: parent.bottom + } + spacing: hifi.dimensions.contentSpacing.y + + Button { + id: openButton + color: hifi.buttons.blue + action: okAction + Keys.onReturnPressed: okAction.trigger() + KeyNavigation.up: selectionType + KeyNavigation.left: selectionType + KeyNavigation.right: cancelButton + } + + Button { + id: cancelButton + action: cancelAction + KeyNavigation.up: selectionType + KeyNavigation.left: openButton + KeyNavigation.right: fileTableView.contentItem + Keys.onReturnPressed: { canceled(); root.enabled = false } + } + } + + Action { + id: okAction + text: currentSelection.text ? (root.selectDirectory && fileTableView.currentRow === -1 ? "Choose" : (root.saveDialog ? "Save" : "Open")) : "Open" + enabled: currentSelection.text || !root.selectDirectory && d.currentSelectionIsFolder ? true : false + onTriggered: { + if (!root.selectDirectory && !d.currentSelectionIsFolder + || root.selectDirectory && fileTableView.currentRow === -1) { + okActionTimer.start(); + } else { + fileTableView.navigateToCurrentRow(); + } + } + } + + Timer { + id: okActionTimer + interval: 50 + running: false + repeat: false + onTriggered: { + if (!root.saveDialog) { + selectedFile(d.currentSelectionUrl); + root.destroy(); + return; + } + + // Handle the ambiguity between different cases + // * typed name (with or without extension) + // * full path vs relative vs filename only + var selection = helper.saveHelper(currentSelection.text, root.dir, selectionType.currentFilter); + + if (!selection) { + desktop.messageBox({ icon: OriginalDialogs.StandardIcon.Warning, text: "Unable to parse selection" }) + return; + } + + if (helper.urlIsDir(selection)) { + root.dir = selection; + currentSelection.text = ""; + return; + } + + // Check if the file is a valid target + if (!helper.urlIsWritable(selection)) { + desktop.messageBox({ + icon: OriginalDialogs.StandardIcon.Warning, + text: "Unable to write to location " + selection + }) + return; + } + + if (helper.urlExists(selection)) { + var messageBox = desktop.messageBox({ + icon: OriginalDialogs.StandardIcon.Question, + buttons: OriginalDialogs.StandardButton.Yes | OriginalDialogs.StandardButton.No, + text: "Do you wish to overwrite " + selection + "?", + }); + var result = messageBox.exec(); + if (OriginalDialogs.StandardButton.Yes !== result) { + return; + } + } + + console.log("Selecting " + selection) + selectedFile(selection); + root.destroy(); + } + } + + Action { + id: cancelAction + text: "Cancel" + onTriggered: { canceled();root.destroy(); } + } + } + + Keys.onPressed: { + switch (event.key) { + case Qt.Key_Backspace: + event.accepted = d.navigateUp(); + break; + + case Qt.Key_Home: + event.accepted = d.navigateHome(); + break; + + } + } +} diff --git a/interface/resources/qml/dialogs/TabletMessageBox.qml b/interface/resources/qml/dialogs/TabletMessageBox.qml new file mode 100644 index 0000000000..2102874ffd --- /dev/null +++ b/interface/resources/qml/dialogs/TabletMessageBox.qml @@ -0,0 +1,248 @@ +// +// MessageDialog.qml +// +// Created by Bradley Austin Davis on 15 Jan 2016 +// 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 +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Dialogs 1.2 as OriginalDialogs + +import "../controls-uit" +import "../styles-uit" +import "../windows" + +import "messageDialog" + +TabletModalWindow { + id: root + HifiConstants { id: hifi } + visible: true + + signal selected(int button); + + MouseArea { + id: mouse; + anchors.fill: parent + } + + function click(button) { + clickedButton = button; + selected(button); + destroy(); + } + + function exec() { + return OffscreenUi.waitForMessageBoxResult(root); + } + + property alias detailedText: detailedText.text + property alias text: mainTextContainer.text + property alias informativeText: informativeTextContainer.text + property int buttons: OriginalDialogs.StandardButton.Ok + property int icon: OriginalDialogs.StandardIcon.NoIcon + property string iconText: "" + property int iconSize: 50 + // onIconChanged: updateIcon(); + property int defaultButton: OriginalDialogs.StandardButton.NoButton; + property int clickedButton: OriginalDialogs.StandardButton.NoButton; + //focus: defaultButton === OriginalDialogs.StandardButton.NoButton + + property int titleWidth: 0 + onTitleWidthChanged: d.resize(); + + function updateIcon() { + if (!root) { + return; + } + iconText = hifi.glyphForIcon(root.icon); + } + + TabletModalFrame { + id: messageBox + clip: true + anchors.verticalCenter: parent.verticalCenter + width: parent.width + height: 300 + + QtObject { + id: d + readonly property int minWidth: 200 + readonly property int maxWidth: 1280 + readonly property int minHeight: 120 + readonly property int maxHeight: 720 + + function resize() { + console.log("[DR]-> setting the target height"); + var targetWidth = Math.max(titleWidth, mainTextContainer.contentWidth) + var targetHeight = mainTextContainer.height + 3 * hifi.dimensions.contentSpacing.y + + (informativeTextContainer.text != "" ? informativeTextContainer.contentHeight + 3 * hifi.dimensions.contentSpacing.y : 0) + + buttons.height + + (details.implicitHeight + hifi.dimensions.contentSpacing.y) + messageBox.frameMarginTop + //messageBox.width = (targetWidth < d.minWidth) ? d.minWidth : ((targetWidth > d.maxWidth) ? d.maxWidth : targetWidth) + + console.log("[DR} -> about to set the height"); + messageBox.height = (targetHeight < d.minHeight) ? d.minHeight: ((targetHeight > d.maxHeight) ? d.maxHeight : targetHeight) + } + } + + RalewaySemiBold { + id: mainTextContainer + onTextChanged: d.resize(); + wrapMode: Text.WrapAnywhere + size: hifi.fontSizes.sectionName + color: hifi.colors.baseGrayHighlight + anchors { + top: parent.top + horizontalCenter: parent.horizontalCenter + margins: 0 + topMargin: hifi.dimensions.contentSpacing.y + messageBox.frameMarginTop + } + lineHeight: 2 + lineHeightMode: Text.ProportionalHeight + horizontalAlignment: Text.AlignHCenter + } + + RalewaySemiBold { + id: informativeTextContainer + onTextChanged: d.resize(); + wrapMode: Text.WrapAnywhere + size: hifi.fontSizes.sectionName + color: hifi.colors.baseGrayHighlight + anchors { + top: mainTextContainer.bottom + left: parent.left + right: parent.right + margins: 0 + topMargin: text != "" ? hifi.dimensions.contentSpacing.y : 0 + } + } + + Flow { + id: buttons + focus: true + spacing: hifi.dimensions.contentSpacing.x + onHeightChanged: d.resize(); onWidthChanged: d.resize(); + layoutDirection: Qt.RightToLeft + anchors { + top: informativeTextContainer.text == "" ? mainTextContainer.bottom : informativeTextContainer.bottom + horizontalCenter: parent.horizontalCenter + margins: 0 + topMargin: 2 * hifi.dimensions.contentSpacing.y + } + MessageDialogButton { dialog: root; text: qsTr("Close"); button: OriginalDialogs.StandardButton.Close; } + MessageDialogButton { dialog: root; text: qsTr("Abort"); button: OriginalDialogs.StandardButton.Abort; } + MessageDialogButton { dialog: root; text: qsTr("Cancel"); button: OriginalDialogs.StandardButton.Cancel; } + MessageDialogButton { dialog: root; text: qsTr("Restore Defaults"); button: OriginalDialogs.StandardButton.RestoreDefaults; } + MessageDialogButton { dialog: root; text: qsTr("Reset"); button: OriginalDialogs.StandardButton.Reset; } + MessageDialogButton { dialog: root; text: qsTr("Discard"); button: OriginalDialogs.StandardButton.Discard; } + MessageDialogButton { dialog: root; text: qsTr("No to All"); button: OriginalDialogs.StandardButton.NoToAll; } + MessageDialogButton { dialog: root; text: qsTr("No"); button: OriginalDialogs.StandardButton.No; } + MessageDialogButton { dialog: root; text: qsTr("Yes to All"); button: OriginalDialogs.StandardButton.YesToAll; } + MessageDialogButton { dialog: root; text: qsTr("Yes"); button: OriginalDialogs.StandardButton.Yes; } + MessageDialogButton { dialog: root; text: qsTr("Apply"); button: OriginalDialogs.StandardButton.Apply; } + MessageDialogButton { dialog: root; text: qsTr("Ignore"); button: OriginalDialogs.StandardButton.Ignore; } + MessageDialogButton { dialog: root; text: qsTr("Retry"); button: OriginalDialogs.StandardButton.Retry; } + MessageDialogButton { dialog: root; text: qsTr("Save All"); button: OriginalDialogs.StandardButton.SaveAll; } + MessageDialogButton { dialog: root; text: qsTr("Save"); button: OriginalDialogs.StandardButton.Save; } + MessageDialogButton { dialog: root; text: qsTr("Open"); button: OriginalDialogs.StandardButton.Open; } + MessageDialogButton { dialog: root; text: qsTr("OK"); button: OriginalDialogs.StandardButton.Ok; } + + Button { + id: moreButton + text: qsTr("Show Details...") + width: 160 + onClicked: { content.state = (content.state === "" ? "expanded" : "") } + visible: detailedText && detailedText.length > 0 + } + MessageDialogButton { dialog: root; text: qsTr("Help"); button: OriginalDialogs.StandardButton.Help; } + } + + Item { + id: details + width: parent.width + implicitHeight: detailedText.implicitHeight + height: 0 + clip: true + anchors { + top: buttons.bottom + left: parent.left; + right: parent.right; + margins: 0 + topMargin: hifi.dimensions.contentSpacing.y + } + Flickable { + id: flickable + contentHeight: detailedText.height + anchors.fill: parent + anchors.topMargin: hifi.dimensions.contentSpacing.x + anchors.bottomMargin: hifi.dimensions.contentSpacing.y + TextEdit { + id: detailedText + size: hifi.fontSizes.menuItem + color: hifi.colors.baseGrayHighlight + width: details.width + wrapMode: Text.WordWrap + readOnly: true + selectByMouse: true + anchors.margins: 0 + } + } + } + + states: [ + State { + name: "expanded" + PropertyChanges { target: root; anchors.fill: undefined } + PropertyChanges { target: details; height: 120 } + PropertyChanges { target: moreButton; text: qsTr("Hide Details") } + } + ] + + Component.onCompleted: { + updateIcon(); + d.resize(); + } + onStateChanged: d.resize() + } + + Keys.onPressed: { + if (!visible) { + return + } + + if (event.modifiers === Qt.ControlModifier) + switch (event.key) { + case Qt.Key_A: + event.accepted = true + detailedText.selectAll() + break + case Qt.Key_C: + event.accepted = true + detailedText.copy() + break + case Qt.Key_Period: + if (Qt.platform.os === "osx") { + event.accepted = true + content.reject() + } + break + } else switch (event.key) { + case Qt.Key_Escape: + case Qt.Key_Back: + event.accepted = true + root.click(OriginalDialogs.StandardButton.Cancel) + break + + case Qt.Key_Enter: + case Qt.Key_Return: + event.accepted = true + root.click(root.defaultButton) + break + } + } +} diff --git a/interface/resources/qml/dialogs/TabletQueryDialog.qml b/interface/resources/qml/dialogs/TabletQueryDialog.qml index 0ae18d1c2d..a920971031 100644 --- a/interface/resources/qml/dialogs/TabletQueryDialog.qml +++ b/interface/resources/qml/dialogs/TabletQueryDialog.qml @@ -61,10 +61,10 @@ TabletModalWindow { iconText = hifi.glyphForIcon(root.icon); } - Rectangle { + TabletModalFrame { id: modalWindowItem width: parent.width - height: 480 + height: 240 anchors.margins: 0 anchors { verticalCenter: parent.verticalCenter @@ -82,13 +82,13 @@ TabletModalWindow { var targetWidth = Math.max(titleWidth, 480) var targetHeight = (items ? comboBox.controlHeight : textResult.controlHeight) + 5 * hifi.dimensions.contentSpacing.y + buttons.height modalWindowItem.width = (targetWidth < d.minWidth) ? d.minWidth : ((targetWidth > d.maxWdith) ? d.maxWidth : targetWidth); - modalWindowItem.height = ((targetHeight < d.minHeight) ? d.minHeight : ((targetHeight > d.maxHeight) ? d.maxHeight : targetHeight)) + ((keyboardEnabled && keyboardRaised) ? (keyboard.raisedHeight + 2 * hifi.dimensions.contentSpacing.y) : 0) + modalWindowItem.height = ((targetHeight < d.minHeight) ? d.minHeight : ((targetHeight > d.maxHeight) ? d.maxHeight : targetHeight)) + ((keyboardEnabled && keyboardRaised) ? (keyboard.raisedHeight + 2 * hifi.dimensions.contentSpacing.y) : 0) + modalWindowItem.frameMarginTop } } Item { anchors { - top: frameTitle.bottom + top: parent.top bottom: keyboard.top; left: parent.left; right: parent.right; diff --git a/interface/resources/qml/hifi/dialogs/TabletRunningScripts.qml b/interface/resources/qml/hifi/dialogs/TabletRunningScripts.qml index 235f7103ff..e217a6e38e 100644 --- a/interface/resources/qml/hifi/dialogs/TabletRunningScripts.qml +++ b/interface/resources/qml/hifi/dialogs/TabletRunningScripts.qml @@ -17,7 +17,7 @@ import "../../styles-uit" import "../../controls-uit" as HifiControls import "../../windows" -Item { +Rectangle { id: root objectName: "RunningScripts" HifiConstants { id: hifi } @@ -28,6 +28,8 @@ Item { property var runningScriptsModel: ListModel { } property bool isHMD: false + color: hifi.colors.baseGray + Connections { target: ScriptDiscoveryService onScriptCountChanged: updateRunningScripts(); diff --git a/interface/resources/qml/hifi/tablet/TabletRoot.qml b/interface/resources/qml/hifi/tablet/TabletRoot.qml index 79b127098b..348d8167b1 100644 --- a/interface/resources/qml/hifi/tablet/TabletRoot.qml +++ b/interface/resources/qml/hifi/tablet/TabletRoot.qml @@ -9,6 +9,7 @@ Item { property var eventBridge; property var rootMenu; + property var openModal: null; property string subMenu: "" signal showDesktop(); @@ -18,16 +19,22 @@ Item { Component { id: inputDialogBuilder; TabletQueryDialog { } } function inputDialog(properties) { - return inputDialogBuilder.createObject(tabletRoot, properties); + openModal = inputDialogBuilder.createObject(tabletRoot, properties); + return openModal; } - + Component { id: messageBoxBuilder; TabletMessageBox { } } function messageBox(properties) { + openModal = messageBoxBuilder.createObject(tabletRoot, properties); + return openModal; } function customInputDialog(properties) { } + Component { id: fileDialogBuilder; TabletFileDialog { } } function fileDialog(properties) { + openModal = fileDialogBuilder.createObject(tabletRoot, properties); + return openModal; } function setMenuProperties(rootMenu, subMenu) { @@ -104,6 +111,12 @@ Item { loader.item.setRootMenu(tabletRoot.rootMenu, tabletRoot.subMenu); } loader.item.forceActiveFocus(); + + if (openModal) { + openModal.canceled(); + openModal.destroy(); + openModal = null; + } } } diff --git a/interface/resources/qml/windows/TabletModalFrame.qml b/interface/resources/qml/windows/TabletModalFrame.qml index 41775f6b3e..6d357a091a 100644 --- a/interface/resources/qml/windows/TabletModalFrame.qml +++ b/interface/resources/qml/windows/TabletModalFrame.qml @@ -18,68 +18,69 @@ import "../styles-uit" Rectangle { HifiConstants { id: hifi } + id: frameContent - Rectangle { - id: frameContent + readonly property bool hasTitle: root.title != "" - //readonly property bool hasTitle: window.title != "" + readonly property int frameMarginLeft: hifi.dimensions.modalDialogMargin.x + readonly property int frameMarginRight: hifi.dimensions.modalDialogMargin.x + readonly property int frameMarginTop: hifi.dimensions.modalDialogMargin.y + (frameContent.hasTitle ? hifi.dimensions.modalDialogTitleHeight + 10 : 0) + readonly property int frameMarginBottom: hifi.dimensions.modalDialogMargin.y - readonly property int frameMarginLeft: hifi.dimensions.modalDialogMargin.x - readonly property int frameMarginRight: hifi.dimensions.modalDialogMargin.x - readonly property int frameMarginTop: hifi.dimensions.modalDialogMargin.y + (frameContent.hasTitle ? hifi.dimensions.modalDialogTitleHeight + 10 : 0) - readonly property int frameMarginBottom: hifi.dimensions.modalDialogMargin.y - - border { - width: hifi.dimensions.borderWidth - color: hifi.colors.lightGrayText80 + border { + width: hifi.dimensions.borderWidth + color: hifi.colors.lightGrayText80 } + radius: hifi.dimensions.borderRadius color: hifi.colors.faintGray + Item { + id: frameTitle + visible: frameContent.hasTitle + + anchors { + fill: parent + topMargin: frameMarginTop + leftMargin: frameMarginLeft + rightMargin: frameMarginRight + //bottomMargin: frameMarginBottom + } + Item { - id: frameTitle - visible: true//frameContent.hasTitle - //anchors.fill: parent - - anchors { - fill: parent - topMargin: -frameMarginTop - leftMargin: -frameMarginLeft - rightMargin: -frameMarginRight - bottomMargin: -frameMarginBottom - } + width: title.width + (icon.text !== "" ? icon.width + hifi.dimensions.contentSpacing.x : 20) - Item { - width: title.width + (icon.text !== "" ? icon.width + hifi.dimensions.contentSpacing.x : 20) - - onWidthChanged: root.titleWidth = width - - HiFiGlyphs { - id: icon - text: root.iconText ? root.iconText : "hello" - size: root.iconSize ? root.iconSize : 30 - color: hifi.colors.lightGray - visible: true - anchors.verticalCenter: title.verticalCenter - anchors.left: parent.left - } - RalewayRegular { - id: title - text: root.title - elide: Text.ElideRight - color: hifi.colors.baseGrayHighlight - size: hifi.fontSizes.overlayTitle - y: -hifi.dimensions.modalDialogTitleHeight - anchors.right: parent.right - } + onWidthChanged: root.titleWidth = width + + HiFiGlyphs { + id: icon + text: root.iconText ? root.iconText : "" + size: root.iconSize ? root.iconSize : 30 + color: hifi.colors.lightGray + visible: true + anchors.verticalCenter: title.verticalCenter + anchors.leftMargin: 50 + anchors.left: parent.left } - Rectangle { - anchors.left: parent.left + RalewayRegular { + id: title + text: root.title + elide: Text.ElideRight + color: hifi.colors.baseGrayHighlight + size: hifi.fontSizes.overlayTitle + y: -hifi.dimensions.modalDialogTitleHeight + anchors.rightMargin: -50 anchors.right: parent.right - height: 1 - color: hifi.colors.lightGray } } + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + height: 1 + color: hifi.colors.lightGray + } + } - + } diff --git a/libraries/ui/src/OffscreenUi.cpp b/libraries/ui/src/OffscreenUi.cpp index f3cb28b8ce..982d58464f 100644 --- a/libraries/ui/src/OffscreenUi.cpp +++ b/libraries/ui/src/OffscreenUi.cpp @@ -211,9 +211,19 @@ QQuickItem* OffscreenUi::createMessageBox(Icon icon, const QString& title, const map.insert("buttons", buttons.operator int()); map.insert("defaultButton", defaultButton); QVariant result; - bool invokeResult = QMetaObject::invokeMethod(_desktop, "messageBox", - Q_RETURN_ARG(QVariant, result), - Q_ARG(QVariant, QVariant::fromValue(map))); + bool invokeResult; + auto tabletScriptingInterface = DependencyManager::get(); + TabletProxy* tablet = dynamic_cast(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system")); + if (tablet->getToolbarMode()) { + invokeResult = QMetaObject::invokeMethod(_desktop, "messageBox", + Q_RETURN_ARG(QVariant, result), + Q_ARG(QVariant, QVariant::fromValue(map))); + } else { + QQuickItem* tabletRoot = tablet->getTabletRoot(); + invokeResult = QMetaObject::invokeMethod(tabletRoot, "messageBox", + Q_RETURN_ARG(QVariant, result), + Q_ARG(QVariant, QVariant::fromValue(map))); + } if (!invokeResult) { qWarning() << "Failed to create message box"; @@ -434,10 +444,21 @@ QQuickItem* OffscreenUi::createCustomInputDialog(const Icon icon, const QString& map.insert("title", title); map.insert("icon", icon); QVariant result; - bool invokeResult = QMetaObject::invokeMethod(_desktop, "customInputDialog", - Q_RETURN_ARG(QVariant, result), - Q_ARG(QVariant, QVariant::fromValue(map))); + auto tabletScriptingInterface = DependencyManager::get(); + TabletProxy* tablet = dynamic_cast(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system")); + bool invokeResult; + if (tablet->getToolbarMode()) { + invokeResult = QMetaObject::invokeMethod(_desktop, "inputDialog", + Q_RETURN_ARG(QVariant, result), + Q_ARG(QVariant, QVariant::fromValue(map))); + } else { + QQuickItem* tabletRoot = tablet->getTabletRoot(); + invokeResult = QMetaObject::invokeMethod(tabletRoot, "inputDialog", + Q_RETURN_ARG(QVariant, result), + Q_ARG(QVariant, QVariant::fromValue(map))); + } + if (!invokeResult) { qWarning() << "Failed to create custom message box"; return nullptr; @@ -581,9 +602,19 @@ private slots: QString OffscreenUi::fileDialog(const QVariantMap& properties) { QVariant buildDialogResult; - bool invokeResult = QMetaObject::invokeMethod(_desktop, "fileDialog", - Q_RETURN_ARG(QVariant, buildDialogResult), - Q_ARG(QVariant, QVariant::fromValue(properties))); + bool invokeResult; + auto tabletScriptingInterface = DependencyManager::get(); + TabletProxy* tablet = dynamic_cast(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system")); + if (tablet->getToolbarMode()) { + invokeResult = QMetaObject::invokeMethod(_desktop, "fileDialog", + Q_RETURN_ARG(QVariant, buildDialogResult), + Q_ARG(QVariant, QVariant::fromValue(properties))); + } else { + QQuickItem* tabletRoot = tablet->getTabletRoot(); + invokeResult = QMetaObject::invokeMethod(tabletRoot, "fileDialog", + Q_RETURN_ARG(QVariant, buildDialogResult), + Q_ARG(QVariant, QVariant::fromValue(properties))); + } if (!invokeResult) { qWarning() << "Failed to create file open dialog"; From 835b23832fc309df61bbb56988729bc6d7a8791b Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Sat, 25 Feb 2017 00:40:38 +0000 Subject: [PATCH 12/18] some modal clean up --- .../qml/dialogs/TabletFileDialog.qml | 14 +++++++---- .../qml/dialogs/TabletMessageBox.qml | 15 ++++++------ .../qml/dialogs/TabletQueryDialog.qml | 11 +++++---- .../resources/qml/hifi/tablet/TabletRoot.qml | 11 ++++++++- .../qml/windows/TabletModalFrame.qml | 3 +++ interface/src/Application.cpp | 20 ++++++++++++---- .../src/TabletScriptingInterface.cpp | 12 ++++++++++ .../src/TabletScriptingInterface.h | 10 ++++++++ scripts/system/libraries/WebTablet.js | 23 ++++++++++++++----- 9 files changed, 91 insertions(+), 28 deletions(-) diff --git a/interface/resources/qml/dialogs/TabletFileDialog.qml b/interface/resources/qml/dialogs/TabletFileDialog.qml index 1b0e6d694d..0aef9179e8 100644 --- a/interface/resources/qml/dialogs/TabletFileDialog.qml +++ b/interface/resources/qml/dialogs/TabletFileDialog.qml @@ -101,9 +101,13 @@ TabletModalWindow { TabletModalFrame { id: fileDialogItem - width: parent.width - height: parent.height - anchors.margins: 0 + width: parent.width - 6 + height: parent.height - 6 + + anchors { + horizontalCenter: root.horizontalCenter + verticalCenter: root.verticalCenter + } property bool keyboardEnabled: false property bool keyboardRaised: false @@ -123,6 +127,7 @@ TabletModalWindow { top: parent.top topMargin: (fileDialogItem.hasTitle ? (fileDialogItem.frameMarginTop + hifi.dimensions.modalDialogMargin.y) : hifi.dimension.modalDialogMargin.y) left: parent.left + leftMargin: hifi.dimensions.contentSpacing.x } spacing: hifi.dimensions.contentSpacing.x @@ -623,7 +628,8 @@ TabletModalWindow { anchors { left: parent.left right: selectionType.visible ? selectionType.left: parent.right - rightMargin: selectionType.visible ? hifi.dimensions.contentSpacing.x : 0 + rightMargin: hifi.dimensions.contentSpacing.x + leftMargin: hifi.dimensions.contentSpacing.x bottom: keyboard.top bottomMargin: hifi.dimensions.contentSpacing.y } diff --git a/interface/resources/qml/dialogs/TabletMessageBox.qml b/interface/resources/qml/dialogs/TabletMessageBox.qml index 2102874ffd..e9b5f45e7f 100644 --- a/interface/resources/qml/dialogs/TabletMessageBox.qml +++ b/interface/resources/qml/dialogs/TabletMessageBox.qml @@ -66,7 +66,8 @@ TabletModalWindow { id: messageBox clip: true anchors.verticalCenter: parent.verticalCenter - width: parent.width + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width - 6 height: 300 QtObject { @@ -77,15 +78,11 @@ TabletModalWindow { readonly property int maxHeight: 720 function resize() { - console.log("[DR]-> setting the target height"); var targetWidth = Math.max(titleWidth, mainTextContainer.contentWidth) var targetHeight = mainTextContainer.height + 3 * hifi.dimensions.contentSpacing.y + (informativeTextContainer.text != "" ? informativeTextContainer.contentHeight + 3 * hifi.dimensions.contentSpacing.y : 0) + buttons.height + (details.implicitHeight + hifi.dimensions.contentSpacing.y) + messageBox.frameMarginTop - //messageBox.width = (targetWidth < d.minWidth) ? d.minWidth : ((targetWidth > d.maxWidth) ? d.maxWidth : targetWidth) - - console.log("[DR} -> about to set the height"); messageBox.height = (targetHeight < d.minHeight) ? d.minHeight: ((targetHeight > d.maxHeight) ? d.maxHeight : targetHeight) } } @@ -93,24 +90,28 @@ TabletModalWindow { RalewaySemiBold { id: mainTextContainer onTextChanged: d.resize(); - wrapMode: Text.WrapAnywhere + wrapMode: Text.WordWrap size: hifi.fontSizes.sectionName color: hifi.colors.baseGrayHighlight + width: parent.width - 6 anchors { top: parent.top horizontalCenter: parent.horizontalCenter margins: 0 topMargin: hifi.dimensions.contentSpacing.y + messageBox.frameMarginTop } + maximumLineCount: 30 + elide: Text.ElideLeft lineHeight: 2 lineHeightMode: Text.ProportionalHeight horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter } RalewaySemiBold { id: informativeTextContainer onTextChanged: d.resize(); - wrapMode: Text.WrapAnywhere + wrapMode: Text.WordWrap size: hifi.fontSizes.sectionName color: hifi.colors.baseGrayHighlight anchors { diff --git a/interface/resources/qml/dialogs/TabletQueryDialog.qml b/interface/resources/qml/dialogs/TabletQueryDialog.qml index a920971031..3ff3347ebc 100644 --- a/interface/resources/qml/dialogs/TabletQueryDialog.qml +++ b/interface/resources/qml/dialogs/TabletQueryDialog.qml @@ -63,9 +63,8 @@ TabletModalWindow { TabletModalFrame { id: modalWindowItem - width: parent.width + width: parent.width - 12 height: 240 - anchors.margins: 0 anchors { verticalCenter: parent.verticalCenter horizontalCenter: parent.horizontalCenter @@ -73,13 +72,13 @@ TabletModalWindow { QtObject { id: d - readonly property int minWidth: 480 - readonly property int maxWdith: 480 + readonly property int minWidth: 470 + readonly property int maxWidth: 470 readonly property int minHeight: 120 readonly property int maxHeight: 720 function resize() { - var targetWidth = Math.max(titleWidth, 480) + var targetWidth = Math.max(titleWidth, 470) var targetHeight = (items ? comboBox.controlHeight : textResult.controlHeight) + 5 * hifi.dimensions.contentSpacing.y + buttons.height modalWindowItem.width = (targetWidth < d.minWidth) ? d.minWidth : ((targetWidth > d.maxWdith) ? d.maxWidth : targetWidth); modalWindowItem.height = ((targetHeight < d.minHeight) ? d.minHeight : ((targetHeight > d.maxHeight) ? d.maxHeight : targetHeight)) + ((keyboardEnabled && keyboardRaised) ? (keyboard.raisedHeight + 2 * hifi.dimensions.contentSpacing.y) : 0) + modalWindowItem.frameMarginTop @@ -106,6 +105,7 @@ TabletModalWindow { left: parent.left; right: parent.right; bottom: parent.bottom + leftMargin: 5 } } @@ -118,6 +118,7 @@ TabletModalWindow { left: parent.left right: parent.right bottom: parent.bottom + rightMargin: 5 } model: items ? items : [] } diff --git a/interface/resources/qml/hifi/tablet/TabletRoot.qml b/interface/resources/qml/hifi/tablet/TabletRoot.qml index 348d8167b1..102094ae1a 100644 --- a/interface/resources/qml/hifi/tablet/TabletRoot.qml +++ b/interface/resources/qml/hifi/tablet/TabletRoot.qml @@ -10,6 +10,7 @@ Item { property var rootMenu; property var openModal: null; + property var openMessage: null; property string subMenu: "" signal showDesktop(); @@ -24,7 +25,7 @@ Item { } Component { id: messageBoxBuilder; TabletMessageBox { } } function messageBox(properties) { - openModal = messageBoxBuilder.createObject(tabletRoot, properties); + openMessage = messageBoxBuilder.createObject(tabletRoot, properties); return openModal; } @@ -42,6 +43,14 @@ Item { tabletRoot.subMenu = subMenu; } + function isDialogOpen() { + if (openMessage !== null || openModal !== null) { + return true; + } + + return false; + } + function loadSource(url) { loader.source = ""; // make sure we load the qml fresh each time. loader.source = url; diff --git a/interface/resources/qml/windows/TabletModalFrame.qml b/interface/resources/qml/windows/TabletModalFrame.qml index 6d357a091a..550eec8357 100644 --- a/interface/resources/qml/windows/TabletModalFrame.qml +++ b/interface/resources/qml/windows/TabletModalFrame.qml @@ -39,6 +39,8 @@ Rectangle { visible: frameContent.hasTitle anchors { + horizontalCenter: parent.horizontalCenter + verticalCenter: parent.verticalCenter fill: parent topMargin: frameMarginTop leftMargin: frameMarginLeft @@ -71,6 +73,7 @@ Rectangle { y: -hifi.dimensions.modalDialogTitleHeight anchors.rightMargin: -50 anchors.right: parent.right + //anchors.horizontalCenter: parent.horizontalCenter } } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d8b974def2..c0c5a1d748 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1617,9 +1617,13 @@ void Application::toggleTabletUI() const { return; } lastTabletUIToggle = now; - - auto HMD = DependencyManager::get(); - HMD->toggleShouldShowTablet(); + auto tabletScriptingInterface = DependencyManager::get(); + TabletProxy* tablet = dynamic_cast(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system")); + bool messageOpen = tablet->isMessageDialogOpen(); + if (!messageOpen) { + auto HMD = DependencyManager::get(); + HMD->toggleShouldShowTablet(); + } } void Application::checkChangeCursor() { @@ -5776,8 +5780,14 @@ void Application::toggleRunningScriptsWidget() const { static const QUrl url("hifi/dialogs/RunningScripts.qml"); DependencyManager::get()->show(url, "RunningScripts"); } else { - static const QUrl url("../../hifi/dialogs/TabletRunningScripts.qml"); - tablet->pushOntoStack(url); + QQuickItem* tabletRoot = tablet->getTabletRoot(); + if (!tabletRoot && !isHMDMode()) { + static const QUrl url("hifi/dialogs/RunningScripts.qml"); + DependencyManager::get()->show(url, "RunningScripts"); + } else { + static const QUrl url("../../hifi/dialogs/TabletRunningScripts.qml"); + tablet->pushOntoStack(url); + } } //DependencyManager::get()->show(url, "RunningScripts"); //if (_runningScriptsWidget->isVisible()) { diff --git a/libraries/script-engine/src/TabletScriptingInterface.cpp b/libraries/script-engine/src/TabletScriptingInterface.cpp index 04e170a8d7..3e0babd086 100644 --- a/libraries/script-engine/src/TabletScriptingInterface.cpp +++ b/libraries/script-engine/src/TabletScriptingInterface.cpp @@ -250,6 +250,18 @@ static QString getUsername() { } } +bool TabletProxy::isMessageDialogOpen() { + if (_qmlTabletRoot) { + QVariant result; + QMetaObject::invokeMethod(_qmlTabletRoot, "isDialogOpen",Qt::DirectConnection, + Q_RETURN_ARG(QVariant, result)); + + return result.toBool(); + } + + return false; +} + void TabletProxy::setQmlTabletRoot(QQuickItem* qmlTabletRoot, QObject* qmlOffscreenSurface) { std::lock_guard guard(_mutex); _qmlOffscreenSurface = qmlOffscreenSurface; diff --git a/libraries/script-engine/src/TabletScriptingInterface.h b/libraries/script-engine/src/TabletScriptingInterface.h index 8b9bec4013..f17d441023 100644 --- a/libraries/script-engine/src/TabletScriptingInterface.h +++ b/libraries/script-engine/src/TabletScriptingInterface.h @@ -109,6 +109,12 @@ public: Q_INVOKABLE void pushOntoStack(const QVariant& path); Q_INVOKABLE void popFromStack(); + /** jsdoc + * Check if the tablet has a message dialog open + * @function TabletProxy#isMessageDialogOpen + */ + Q_INVOKABLE bool isMessageDialogOpen(); + /**jsdoc * Creates a new button, adds it to this and returns it. * @function TabletProxy#addButton @@ -152,6 +158,10 @@ public: */ Q_INVOKABLE void sendToQml(QVariant msg); + /**jsdoc + * Check if the tablet is on the homescreen + * @function TabletProxy#onHomeScreen() + */ Q_INVOKABLE bool onHomeScreen(); QQuickItem* getTabletRoot() const { return _qmlTabletRoot; } diff --git a/scripts/system/libraries/WebTablet.js b/scripts/system/libraries/WebTablet.js index 367ef05aea..dbda42e407 100644 --- a/scripts/system/libraries/WebTablet.js +++ b/scripts/system/libraries/WebTablet.js @@ -169,10 +169,16 @@ WebTablet = function (url, width, dpi, hand, clientOnly) { var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); var onHomeScreen = tablet.onHomeScreen(); if (onHomeScreen) { - HMD.closeTablet(); + var isMessageOpen = tablet.isMessageDialogOpen(); + if (isMessageOpen === false) { + HMD.closeTablet(); + } } else { - tablet.gotoHomeScreen(); - _this.setHomeButtonTexture(); + var isMessageOpen = tablet.isMessageDialogOpen(); + if (isMessageOpen === false) { + tablet.gotoHomeScreen(); + _this.setHomeButtonTexture(); + } } } }; @@ -432,11 +438,16 @@ WebTablet.prototype.mousePressEvent = function (event) { if (overlayPickResults.intersects && overlayPickResults.overlayID === HMD.homeButtonID) { var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); var onHomeScreen = tablet.onHomeScreen(); + var isMessageOpen = tablet.isMessageDialogOpen(); if (onHomeScreen) { - HMD.closeTablet(); + if (isMessageOpen === false) { + HMD.closeTablet(); + } } else { - tablet.gotoHomeScreen(); - this.setHomeButtonTexture(); + if (isMessageOpen === false) { + tablet.gotoHomeScreen(); + this.setHomeButtonTexture(); + } } } else if (!HMD.active && (!overlayPickResults.intersects || !overlayPickResults.overlayID === this.webOverlayID)) { this.dragging = true; From 5ba89e67afdac2dfabba6a3e3df4f5d4d5fae29b Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Thu, 2 Mar 2017 16:50:42 +0000 Subject: [PATCH 13/18] fixed message dialog bug --- interface/resources/qml/dialogs/TabletMessageBox.qml | 4 ++-- interface/resources/qml/hifi/tablet/TabletRoot.qml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/resources/qml/dialogs/TabletMessageBox.qml b/interface/resources/qml/dialogs/TabletMessageBox.qml index e9b5f45e7f..f8876b1ec8 100644 --- a/interface/resources/qml/dialogs/TabletMessageBox.qml +++ b/interface/resources/qml/dialogs/TabletMessageBox.qml @@ -47,10 +47,10 @@ TabletModalWindow { property int icon: OriginalDialogs.StandardIcon.NoIcon property string iconText: "" property int iconSize: 50 - // onIconChanged: updateIcon(); + onIconChanged: updateIcon(); property int defaultButton: OriginalDialogs.StandardButton.NoButton; property int clickedButton: OriginalDialogs.StandardButton.NoButton; - //focus: defaultButton === OriginalDialogs.StandardButton.NoButton + focus: defaultButton === OriginalDialogs.StandardButton.NoButton property int titleWidth: 0 onTitleWidthChanged: d.resize(); diff --git a/interface/resources/qml/hifi/tablet/TabletRoot.qml b/interface/resources/qml/hifi/tablet/TabletRoot.qml index 102094ae1a..8eaddfb601 100644 --- a/interface/resources/qml/hifi/tablet/TabletRoot.qml +++ b/interface/resources/qml/hifi/tablet/TabletRoot.qml @@ -26,7 +26,7 @@ Item { Component { id: messageBoxBuilder; TabletMessageBox { } } function messageBox(properties) { openMessage = messageBoxBuilder.createObject(tabletRoot, properties); - return openModal; + return openMessage; } function customInputDialog(properties) { From 2b53cb4722c60f41c8a91bb969b622ab99641ca2 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 3 Mar 2017 11:31:41 +1300 Subject: [PATCH 14/18] Display audio stats in tablet --- scripts/developer/utilities/audio/stats.js | 28 +++++++++++++--------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/scripts/developer/utilities/audio/stats.js b/scripts/developer/utilities/audio/stats.js index 493271ac99..064fd72fe5 100644 --- a/scripts/developer/utilities/audio/stats.js +++ b/scripts/developer/utilities/audio/stats.js @@ -9,17 +9,23 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var INITIAL_WIDTH = 400; -var INITIAL_OFFSET = 50; +if (HMD.active && !Settings.getValue("HUDUIEnabled")) { + var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); + var qml = Script.resolvePath("stats.qml"); + tablet.loadQMLSource(qml); + Script.stop(); -// Set up the qml ui -var qml = Script.resolvePath('stats.qml'); -var window = new OverlayWindow({ - title: 'Audio Interface Statistics', - source: qml, - width: 500, height: 520 // stats.qml may be too large for some screens -}); -window.setPosition(INITIAL_OFFSET, INITIAL_OFFSET); +} else { + var INITIAL_WIDTH = 400; + var INITIAL_OFFSET = 50; -window.closed.connect(function() { Script.stop(); }); + var qml = Script.resolvePath("stats.qml"); + var window = new OverlayWindow({ + title: "Audio Interface Statistics", + source: qml, + width: 500, height: 520 // stats.qml may be too large for some screens + }); + window.setPosition(INITIAL_OFFSET, INITIAL_OFFSET); + window.closed.connect(function () { Script.stop(); }); +} From 02a2bb6fc3461bbf20db4a90f6667e7866a8bd1c Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 3 Mar 2017 16:25:15 +1300 Subject: [PATCH 15/18] Rename QML file --- scripts/developer/utilities/audio/{stats.qml => DesktopStats.qml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename scripts/developer/utilities/audio/{stats.qml => DesktopStats.qml} (100%) diff --git a/scripts/developer/utilities/audio/stats.qml b/scripts/developer/utilities/audio/DesktopStats.qml similarity index 100% rename from scripts/developer/utilities/audio/stats.qml rename to scripts/developer/utilities/audio/DesktopStats.qml From 3285816fca60d813bdc97aea6e4b16993dea2855 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 3 Mar 2017 16:45:35 +1300 Subject: [PATCH 16/18] Fix up audio stats displayed in tablet --- interface/src/ui/overlays/Web3DOverlay.cpp | 2 + .../audio/{DesktopStats.qml => Stats.qml} | 7 +- .../developer/utilities/audio/TabletStats.qml | 89 +++++++++++++++++++ scripts/developer/utilities/audio/stats.js | 4 +- 4 files changed, 94 insertions(+), 8 deletions(-) rename scripts/developer/utilities/audio/{DesktopStats.qml => Stats.qml} (96%) create mode 100644 scripts/developer/utilities/audio/TabletStats.qml diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 8d72f877b6..508ac00c5f 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -40,6 +40,7 @@ #include #include #include "FileDialogHelper.h" +#include "AudioClient.h" static const float DPI = 30.47f; @@ -170,6 +171,7 @@ void Web3DOverlay::loadSourceURL() { _webSurface->getRootContext()->setContextProperty("offscreenFlags", flags); _webSurface->getRootContext()->setContextProperty("AddressManager", DependencyManager::get().data()); _webSurface->getRootContext()->setContextProperty("Account", AccountScriptingInterface::getInstance()); + _webSurface->getRootContext()->setContextProperty("AudioStats", DependencyManager::get()->getStats().data()); _webSurface->getRootContext()->setContextProperty("HMD", DependencyManager::get().data()); _webSurface->getRootContext()->setContextProperty("fileDialogHelper", new FileDialogHelper()); _webSurface->getRootContext()->setContextProperty("ScriptDiscoveryService", DependencyManager::get().data()); diff --git a/scripts/developer/utilities/audio/DesktopStats.qml b/scripts/developer/utilities/audio/Stats.qml similarity index 96% rename from scripts/developer/utilities/audio/DesktopStats.qml rename to scripts/developer/utilities/audio/Stats.qml index 346e5e3544..614c682f98 100644 --- a/scripts/developer/utilities/audio/DesktopStats.qml +++ b/scripts/developer/utilities/audio/Stats.qml @@ -1,5 +1,5 @@ // -// stats.qml +// Stats.qml // scripts/developer/utilities/audio // // Created by Zach Pomerantz on 9/22/2016 @@ -15,7 +15,6 @@ import QtQuick.Layouts 1.3 Column { id: stats width: parent.width - height: parent.height property bool showGraphs: toggleGraphs.checked RowLayout { @@ -35,11 +34,9 @@ Column { Grid { width: parent.width - height: parent.height - 30 Column { width: parent.width / 2 - height: parent.height Section { label: "Latency" @@ -76,7 +73,6 @@ Column { Column { width: parent.width / 2 - height: parent.height Section { label: "Mixer (upstream)" @@ -92,4 +88,3 @@ Column { } } } - diff --git a/scripts/developer/utilities/audio/TabletStats.qml b/scripts/developer/utilities/audio/TabletStats.qml new file mode 100644 index 0000000000..130b90f032 --- /dev/null +++ b/scripts/developer/utilities/audio/TabletStats.qml @@ -0,0 +1,89 @@ +// +// TabletStats.qml +// scripts/developer/utilities/audio +// +// Created by David Rowe on 3 Mar 2017. +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html +// +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Layouts 1.3 + +import "../../../../resources/qml/styles-uit" + +Item { + id: dialog + width: 480 + height: 720 + + HifiConstants { id: hifi } + + Rectangle { + id: header + height: 90 + anchors { + top: parent.top + left: parent.left + right: parent.right + } + z: 100 + + gradient: Gradient { + GradientStop { + position: 0 + color: "#2b2b2b" + } + + GradientStop { + position: 1 + color: "#1e1e1e" + } + } + + RalewayBold { + text: "Audio Interface Statistics" + size: 26 + color: "#34a2c7" + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: hifi.dimensions.contentMargin.x // ####### hifi is not defined + } + } + + Rectangle { + id: main + anchors { + top: header.bottom + bottom: parent.bottom + left: parent.left + right: parent.right + } + + gradient: Gradient { + GradientStop { + position: 0 + color: "#2b2b2b" + } + + GradientStop { + position: 1 + color: "#0f212e" + } + } + + Flickable { + id: scrollView + width: parent.width + height: parent.height + contentWidth: parent.width + contentHeight: stats.height + + Stats { + id: stats + } + } + } +} diff --git a/scripts/developer/utilities/audio/stats.js b/scripts/developer/utilities/audio/stats.js index 064fd72fe5..382e14df5f 100644 --- a/scripts/developer/utilities/audio/stats.js +++ b/scripts/developer/utilities/audio/stats.js @@ -11,7 +11,7 @@ if (HMD.active && !Settings.getValue("HUDUIEnabled")) { var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); - var qml = Script.resolvePath("stats.qml"); + var qml = Script.resolvePath("TabletStats.qml"); tablet.loadQMLSource(qml); Script.stop(); @@ -19,7 +19,7 @@ if (HMD.active && !Settings.getValue("HUDUIEnabled")) { var INITIAL_WIDTH = 400; var INITIAL_OFFSET = 50; - var qml = Script.resolvePath("stats.qml"); + var qml = Script.resolvePath("Stats.qml"); var window = new OverlayWindow({ title: "Audio Interface Statistics", source: qml, From b31cf23c8d57253d604f5a703657ec20d4db31eb Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 3 Mar 2017 17:45:23 +1300 Subject: [PATCH 17/18] Fix tablet QML fonts path This is the path for running scripts from build/install directory rather than from source directory. --- interface/src/ui/overlays/Web3DOverlay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 508ac00c5f..e2001d7766 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -175,7 +175,7 @@ void Web3DOverlay::loadSourceURL() { _webSurface->getRootContext()->setContextProperty("HMD", DependencyManager::get().data()); _webSurface->getRootContext()->setContextProperty("fileDialogHelper", new FileDialogHelper()); _webSurface->getRootContext()->setContextProperty("ScriptDiscoveryService", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("pathToFonts", "../../../"); + _webSurface->getRootContext()->setContextProperty("pathToFonts", "../../"); tabletScriptingInterface->setQmlTabletRoot("com.highfidelity.interface.tablet.system", _webSurface->getRootItem(), _webSurface.data()); // Override min fps for tablet UI, for silky smooth scrolling From 55963c4418f79731cba27e2bfa5699beb3d78621 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 3 Mar 2017 17:46:12 +1300 Subject: [PATCH 18/18] Style audio stats dialog button --- scripts/developer/utilities/audio/Stats.qml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/developer/utilities/audio/Stats.qml b/scripts/developer/utilities/audio/Stats.qml index 614c682f98..7f559ea664 100644 --- a/scripts/developer/utilities/audio/Stats.qml +++ b/scripts/developer/utilities/audio/Stats.qml @@ -12,21 +12,21 @@ import QtQuick 2.5 import QtQuick.Controls 1.4 import QtQuick.Layouts 1.3 +import "../../../../resources/qml/controls-uit" as HifiControls + Column { id: stats width: parent.width property bool showGraphs: toggleGraphs.checked - RowLayout { + Item { width: parent.width height: 30 - Button { + HifiControls.Button { id: toggleGraphs property bool checked: false - - Layout.alignment: Qt.AlignCenter - + anchors.horizontalCenter: parent.horizontalCenter text: checked ? "Hide graphs" : "Show graphs" onClicked: function() { checked = !checked; } }