From ec615caa80d66ec3e7f2544a904951ef85856522 Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Fri, 17 Jun 2016 10:56:35 -0700 Subject: [PATCH] Support toolbar API --- interface/resources/qml/AssetServer.qml | 2 +- interface/resources/qml/Browser.qml | 2 +- interface/resources/qml/InfoView.qml | 2 +- interface/resources/qml/LoginDialog.qml | 2 +- interface/resources/qml/QmlWebWindow.qml | 2 +- interface/resources/qml/ToolWindow.qml | 2 +- interface/resources/qml/UpdateDialog.qml | 2 +- .../qml/dialogs/PreferencesDialog.qml | 2 +- .../qml/dialogs/preferences/AvatarBrowser.qml | 15 +- interface/resources/qml/hifi/Desktop.qml | 46 +++-- .../resources/qml/hifi/ToggleHudButton.qml | 38 ----- .../qml/hifi/dialogs/AttachmentsDialog.qml | 2 +- .../qml/hifi/dialogs/ModelBrowserDialog.qml | 2 +- .../qml/hifi/dialogs/RunningScripts.qml | 2 +- .../qml/hifi/dialogs/SnapshotShareDialog.qml | 2 +- .../resources/qml/hifi/toolbars/Toolbar.qml | 117 +++++++++++++ .../qml/hifi/toolbars/ToolbarButton.qml | 39 +++++ interface/resources/qml/windows/Frame.qml | 2 +- .../resources/qml/windows/ModalWindow.qml | 2 +- .../resources/qml/windows/ScrollingWindow.qml | 157 ++++++++++++++++++ interface/resources/qml/windows/ToolFrame.qml | 49 ++++++ interface/resources/qml/windows/Window.qml | 146 ++-------------- interface/src/Application.cpp | 3 + .../scripting/ToolbarScriptingInterface.cpp | 124 ++++++++++++++ .../src/scripting/ToolbarScriptingInterface.h | 26 +++ scripts/defaultScripts.js | 3 +- scripts/developer/tests/toolbarTest.js | 118 +++++++++++++ .../system/assets/images/tools/microphone.svg | 13 ++ scripts/system/examples.js | 98 ++--------- scripts/system/goto.js | 42 ++--- scripts/system/hmd.js | 55 +++--- scripts/system/mute.js | 29 ++++ tests/ui/qml/Stubs.qml | 12 ++ tests/ui/qml/main.qml | 89 +++++++--- tests/ui/qmlscratch.pro | 1 + tests/ui/src/main.cpp | 3 + 36 files changed, 870 insertions(+), 381 deletions(-) delete mode 100644 interface/resources/qml/hifi/ToggleHudButton.qml create mode 100644 interface/resources/qml/hifi/toolbars/Toolbar.qml create mode 100644 interface/resources/qml/hifi/toolbars/ToolbarButton.qml create mode 100644 interface/resources/qml/windows/ScrollingWindow.qml create mode 100644 interface/resources/qml/windows/ToolFrame.qml create mode 100644 interface/src/scripting/ToolbarScriptingInterface.cpp create mode 100644 interface/src/scripting/ToolbarScriptingInterface.h create mode 100644 scripts/developer/tests/toolbarTest.js create mode 100644 scripts/system/assets/images/tools/microphone.svg create mode 100644 scripts/system/mute.js diff --git a/interface/resources/qml/AssetServer.qml b/interface/resources/qml/AssetServer.qml index 5b02020272..c9b6305258 100644 --- a/interface/resources/qml/AssetServer.qml +++ b/interface/resources/qml/AssetServer.qml @@ -18,7 +18,7 @@ import "controls-uit" as HifiControls import "windows" import "dialogs" -Window { +ScrollingWindow { id: root objectName: "AssetServer" title: "Asset Browser" diff --git a/interface/resources/qml/Browser.qml b/interface/resources/qml/Browser.qml index 01e1bb7680..8c8cf05444 100644 --- a/interface/resources/qml/Browser.qml +++ b/interface/resources/qml/Browser.qml @@ -6,7 +6,7 @@ import "controls-uit" import "styles-uit" import "windows" -Window { +ScrollingWindow { id: root HifiConstants { id: hifi } title: "Browser" diff --git a/interface/resources/qml/InfoView.qml b/interface/resources/qml/InfoView.qml index 0f17a88614..f18969fb2f 100644 --- a/interface/resources/qml/InfoView.qml +++ b/interface/resources/qml/InfoView.qml @@ -14,7 +14,7 @@ import Hifi 1.0 as Hifi import "controls-uit" import "windows" as Windows -Windows.Window { +Windows.ScrollingWindow { id: root width: 800 height: 800 diff --git a/interface/resources/qml/LoginDialog.qml b/interface/resources/qml/LoginDialog.qml index f5030cb88d..f75e83e36e 100644 --- a/interface/resources/qml/LoginDialog.qml +++ b/interface/resources/qml/LoginDialog.qml @@ -14,7 +14,7 @@ import "controls" import "styles" import "windows" -Window { +ScrollingWindow { id: root HifiConstants { id: hifi } objectName: "LoginDialog" diff --git a/interface/resources/qml/QmlWebWindow.qml b/interface/resources/qml/QmlWebWindow.qml index 09c3bd7f28..542b44b95e 100644 --- a/interface/resources/qml/QmlWebWindow.qml +++ b/interface/resources/qml/QmlWebWindow.qml @@ -17,7 +17,7 @@ import "windows" as Windows import "controls-uit" as Controls import "styles-uit" -Windows.Window { +Windows.ScrollingWindow { id: root HifiConstants { id: hifi } title: "WebWindow" diff --git a/interface/resources/qml/ToolWindow.qml b/interface/resources/qml/ToolWindow.qml index faa96fac5a..bbfc74493d 100644 --- a/interface/resources/qml/ToolWindow.qml +++ b/interface/resources/qml/ToolWindow.qml @@ -19,7 +19,7 @@ import "windows" import "controls-uit" import "styles-uit" -Window { +ScrollingWindow { id: toolWindow resizable: true objectName: "ToolWindow" diff --git a/interface/resources/qml/UpdateDialog.qml b/interface/resources/qml/UpdateDialog.qml index 52fdab25f9..91dc210eda 100644 --- a/interface/resources/qml/UpdateDialog.qml +++ b/interface/resources/qml/UpdateDialog.qml @@ -7,7 +7,7 @@ import "controls-uit" import "styles-uit" import "windows" -Window { +ScrollingWindow { id: root HifiConstants { id: hifi } objectName: "UpdateDialog" diff --git a/interface/resources/qml/dialogs/PreferencesDialog.qml b/interface/resources/qml/dialogs/PreferencesDialog.qml index 398e0abd8e..5278118a22 100644 --- a/interface/resources/qml/dialogs/PreferencesDialog.qml +++ b/interface/resources/qml/dialogs/PreferencesDialog.qml @@ -16,7 +16,7 @@ import "../styles-uit" import "../windows" import "preferences" -Window { +ScrollingWindow { id: root title: "Preferences" resizable: true diff --git a/interface/resources/qml/dialogs/preferences/AvatarBrowser.qml b/interface/resources/qml/dialogs/preferences/AvatarBrowser.qml index 90d2dc5284..16d25b3c4c 100644 --- a/interface/resources/qml/dialogs/preferences/AvatarBrowser.qml +++ b/interface/resources/qml/dialogs/preferences/AvatarBrowser.qml @@ -23,15 +23,10 @@ Windows.Window { resizable: true modality: Qt.ApplicationModal - Item { - width: pane.contentWidth - implicitHeight: pane.scrollHeight - - Controls.WebView { - id: webview - anchors.fill: parent - url: "https://metaverse.highfidelity.com/marketplace?category=avatars" - focus: true - } + Controls.WebView { + id: webview + anchors.fill: parent + url: "https://metaverse.highfidelity.com/marketplace?category=avatars" + focus: true } } diff --git a/interface/resources/qml/hifi/Desktop.qml b/interface/resources/qml/hifi/Desktop.qml index e127a235e6..c14d55cb00 100644 --- a/interface/resources/qml/hifi/Desktop.qml +++ b/interface/resources/qml/hifi/Desktop.qml @@ -1,10 +1,12 @@ import QtQuick 2.5 import QtQuick.Controls 1.4 import QtWebEngine 1.1; +import Qt.labs.settings 1.0 import "../desktop" import ".." import "." +import "./toolbars" Desktop { id: desktop @@ -20,13 +22,6 @@ Desktop { acceptedButtons: Qt.NoButton } - Component.onCompleted: { - WebEngine.settings.javascriptCanOpenWindows = true; - WebEngine.settings.javascriptCanAccessClipboard = false; - WebEngine.settings.spatialNavigationEnabled = false; - WebEngine.settings.localContentCanAccessRemoteUrls = true; - } - // The tool window, one instance property alias toolWindow: toolWindow ToolWindow { id: toolWindow } @@ -49,11 +44,40 @@ Desktop { } } + property var toolbars: ({}) + Component { id: toolbarBuilder; Toolbar { } } - ToggleHudButton { - anchors.bottom: parent.bottom - anchors.bottomMargin: 32 - anchors.horizontalCenter: parent.horizontalCenter + Component.onCompleted: { + WebEngine.settings.javascriptCanOpenWindows = true; + WebEngine.settings.javascriptCanAccessClipboard = false; + WebEngine.settings.spatialNavigationEnabled = false; + WebEngine.settings.localContentCanAccessRemoteUrls = true; + + var sysToolbar = desktop.getToolbar("com.highfidelity.interface.toolbar.system"); + //toolbars[sysToolbar.objectName] = sysToolbar + var toggleHudButton = sysToolbar.addButton({ + imageURL: "../../../icons/hud-01.svg", + visible: true, + + }); + toggleHudButton.yOffset = Qt.binding(function(){ + return desktop.pinned ? 50 : 0 + }); + toggleHudButton.clicked.connect(function(){ + console.log("Clicked on hud button") + var overlayMenuItem = "Overlays" + MenuInterface.setIsOptionChecked(overlayMenuItem, !MenuInterface.isOptionChecked(overlayMenuItem)); + }); + } + + // Create or fetch a toolbar with the given name + function getToolbar(name) { + var result = toolbars[name]; + if (!result) { + result = toolbars[name] = toolbarBuilder.createObject(desktop, {}); + result.objectName = name; + } + return result; } } diff --git a/interface/resources/qml/hifi/ToggleHudButton.qml b/interface/resources/qml/hifi/ToggleHudButton.qml deleted file mode 100644 index 63c056b352..0000000000 --- a/interface/resources/qml/hifi/ToggleHudButton.qml +++ /dev/null @@ -1,38 +0,0 @@ -import QtQuick 2.5 -import QtQuick.Controls 1.4 - -import "../windows" - -Window { - //frame: HiddenFrame {} - hideBackground: true - resizable: false - destroyOnCloseButton: false - destroyOnHidden: false - closable: false - shown: true - pinned: true - width: 50 - height: 50 - clip: true - visible: true - // Disable this window from being able to call 'desktop.raise() and desktop.showDesktop' - activator: Item {} - - Item { - width: 50 - height: 50 - Image { - y: desktop.pinned ? -50 : 0 - id: hudToggleImage - source: "../../icons/hud-01.svg" - } - MouseArea { - readonly property string overlayMenuItem: "Overlays" - anchors.fill: parent - onClicked: MenuInterface.setIsOptionChecked(overlayMenuItem, !MenuInterface.isOptionChecked(overlayMenuItem)); - } - } -} - - diff --git a/interface/resources/qml/hifi/dialogs/AttachmentsDialog.qml b/interface/resources/qml/hifi/dialogs/AttachmentsDialog.qml index 7b3a368bb0..15467f8021 100755 --- a/interface/resources/qml/hifi/dialogs/AttachmentsDialog.qml +++ b/interface/resources/qml/hifi/dialogs/AttachmentsDialog.qml @@ -9,7 +9,7 @@ import "../../controls-uit" as HifiControls import "../../windows" import "attachments" -Window { +ScrollingWindow { id: root title: "Attachments" objectName: "AttachmentsDialog" diff --git a/interface/resources/qml/hifi/dialogs/ModelBrowserDialog.qml b/interface/resources/qml/hifi/dialogs/ModelBrowserDialog.qml index 29f0498f59..aeffb8e4bf 100644 --- a/interface/resources/qml/hifi/dialogs/ModelBrowserDialog.qml +++ b/interface/resources/qml/hifi/dialogs/ModelBrowserDialog.qml @@ -11,7 +11,7 @@ import "../../styles-uit" import "../../controls-uit" as HifiControls import "../../windows" -Window { +ScrollingWindow { id: root resizable: true width: 600 diff --git a/interface/resources/qml/hifi/dialogs/RunningScripts.qml b/interface/resources/qml/hifi/dialogs/RunningScripts.qml index ccf2413421..5457caccf1 100644 --- a/interface/resources/qml/hifi/dialogs/RunningScripts.qml +++ b/interface/resources/qml/hifi/dialogs/RunningScripts.qml @@ -17,7 +17,7 @@ import "../../styles-uit" import "../../controls-uit" as HifiControls import "../../windows" -Window { +ScrollingWindow { id: root objectName: "RunningScripts" title: "Running Scripts" diff --git a/interface/resources/qml/hifi/dialogs/SnapshotShareDialog.qml b/interface/resources/qml/hifi/dialogs/SnapshotShareDialog.qml index f99b770a78..3dacb3b39c 100644 --- a/interface/resources/qml/hifi/dialogs/SnapshotShareDialog.qml +++ b/interface/resources/qml/hifi/dialogs/SnapshotShareDialog.qml @@ -7,7 +7,7 @@ import "../../windows" import "../../js/Utils.js" as Utils import "../models" -Window { +ScrollingWindow { id: root resizable: true width: 516 diff --git a/interface/resources/qml/hifi/toolbars/Toolbar.qml b/interface/resources/qml/hifi/toolbars/Toolbar.qml new file mode 100644 index 0000000000..35c816569b --- /dev/null +++ b/interface/resources/qml/hifi/toolbars/Toolbar.qml @@ -0,0 +1,117 @@ +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import Qt.labs.settings 1.0 + +import "../../windows" +import "." + +Window { + id: window + frame: ToolFrame { } + hideBackground: true + resizable: false + destroyOnCloseButton: false + destroyOnHidden: false + closable: false + shown: true + pinned: true + width: content.width + height: content.height + visible: true + // Disable this window from being able to call 'desktop.raise() and desktop.showDesktop' + activator: Item {} + property bool horizontal: true + property real buttonSize: 50; + property var buttons: [] + property var container: horizontal ? row : column + + Settings { + category: "toolbar/" + window.objectName + property alias x: window.x + property alias y: window.y + } + + onHorizontalChanged: { + var oldParent = horizontal ? column : row; + var newParent = horizontal ? row : column; + var move = []; + + var i; + for (i in oldParent.children) { + var child = oldParent.children[i]; + if (child.spacer) { + continue; + } + move.push(oldParent.children[i]); + } + for (i in move) { + move[i].parent = newParent; + if (horizontal) { + move[i].y = 0 + } else { + move[i].x = 0 + } + } + fixSpacers(); + } + + Item { + id: content + implicitHeight: horizontal ? row.height : column.height + implicitWidth: horizontal ? row.width : column.width + Row { + id: row + spacing: 6 + visible: window.horizontal + Rectangle{ readonly property bool spacer: true; id: rowSpacer1; width: 1; height: row.height } + Rectangle{ readonly property bool spacer: true; id: rowSpacer2; width: 1; height: row.height } + Rectangle{ readonly property bool spacer: true; id: rowSpacer3; width: 1; height: row.height } + Rectangle{ readonly property bool spacer: true; id: rowSpacer4; width: 1; height: row.height } + } + + Column { + id: column + spacing: 6 + visible: !window.horizontal + Rectangle{ readonly property bool spacer: true; id: colSpacer1; width: column.width; height: 1 } + Rectangle{ readonly property bool spacer: true; id: colSpacer2; width: column.width; height: 1 } + Rectangle{ readonly property bool spacer: true; id: colSpacer3; width: column.width; height: 1 } + Rectangle{ readonly property bool spacer: true; id: colSpacer4; width: column.width; height: 1 } + } + + Component { id: toolbarButtonBuilder; ToolbarButton { } } + } + + function addButton(properties) { + properties = properties || {} + + // If a name is specified, then check if there's an existing button with that name + // and return it if so. This will allow multiple clients to listen to a single button, + // and allow scripts to be idempotent so they don't duplicate buttons if they're reloaded + if (properties.objectName) { + for (var i in buttons) { + var child = buttons[i]; + if (child.objectName === properties.objectName) { + return child; + } + } + } + + properties.toolbar = this; + var result = toolbarButtonBuilder.createObject(container, properties); + buttons.push(result); + fixSpacers(); + return result; + } + + function fixSpacers() { + colSpacer3.parent = null + colSpacer4.parent = null + rowSpacer3.parent = null + rowSpacer4.parent = null + colSpacer3.parent = column + colSpacer4.parent = column + rowSpacer3.parent = row + rowSpacer4.parent = row + } +} diff --git a/interface/resources/qml/hifi/toolbars/ToolbarButton.qml b/interface/resources/qml/hifi/toolbars/ToolbarButton.qml new file mode 100644 index 0000000000..a8514689e8 --- /dev/null +++ b/interface/resources/qml/hifi/toolbars/ToolbarButton.qml @@ -0,0 +1,39 @@ +import QtQuick 2.5 +import QtQuick.Controls 1.4 + +Item { + id: button + property alias imageURL: image.source + property alias alpha: button.opacity + property var subImage; + property int yOffset: 0 + property var toolbar; + property real size: 50 // toolbar ? toolbar.buttonSize : 50 + width: size; height: size + clip: true + + Component.onCompleted: { + if (subImage) { + if (subImage.y) { + yOffset = subImage.y; + } + } + } + + signal clicked() + + Image { + id: image + y: -button.yOffset; + width: parent.width + } + + MouseArea { + anchors.fill: parent + onClicked: { + console.log("Clicked on button " + image.source + " named " + button.objectName) + button.clicked(); + } + } +} + diff --git a/interface/resources/qml/windows/Frame.qml b/interface/resources/qml/windows/Frame.qml index 9519a44cf0..bc8ecc35ec 100644 --- a/interface/resources/qml/windows/Frame.qml +++ b/interface/resources/qml/windows/Frame.qml @@ -80,7 +80,7 @@ Item { border.width: 3 border.color: hifi.colors.white50 radius: hifi.dimensions.borderRadius - visible: window ? !pane.visible : false + visible: window ? !window.content.visible : false } MouseArea { diff --git a/interface/resources/qml/windows/ModalWindow.qml b/interface/resources/qml/windows/ModalWindow.qml index f79dc9084f..2d56099051 100644 --- a/interface/resources/qml/windows/ModalWindow.qml +++ b/interface/resources/qml/windows/ModalWindow.qml @@ -12,7 +12,7 @@ import QtQuick 2.5 import "." -Window { +ScrollingWindow { id: window modality: Qt.ApplicationModal destroyOnCloseButton: true diff --git a/interface/resources/qml/windows/ScrollingWindow.qml b/interface/resources/qml/windows/ScrollingWindow.qml new file mode 100644 index 0000000000..f1dc744344 --- /dev/null +++ b/interface/resources/qml/windows/ScrollingWindow.qml @@ -0,0 +1,157 @@ +// +// Window.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.Controls.Styles 1.4 +import QtGraphicalEffects 1.0 + +import "." +import "../styles-uit" + +// FIXME how do I set the initial position of a window without +// overriding places where the a individual client of the window +// might be setting the position with a Settings{} element? + +// FIXME how to I enable dragging without allowing the window to lay outside +// of the desktop? How do I ensure when the desktop resizes all the windows +// are still at least partially visible? +Window { + id: window + HifiConstants { id: hifi } + children: [ swallower, frame, pane, activator ] + + property var footer: Item { } // Optional static footer at the bottom of the dialog. + + // Scrollable window content. + // FIXME this should not define any visual content in this type. The base window + // type should only consist of logic sized areas, with nothing drawn (although the + // default value for the frame property does include visual decorations) + property var pane: Item { + property bool isScrolling: scrollView.height < scrollView.contentItem.height + property int contentWidth: scrollView.width - (isScrolling ? 10 : 0) + property int scrollHeight: scrollView.height + + anchors.fill: parent + anchors.rightMargin: isScrolling ? 11 : 0 + + Rectangle { + id: contentBackground + anchors.fill: parent + anchors.rightMargin: parent.isScrolling ? 11 : 0 + color: hifi.colors.baseGray + visible: !window.hideBackground && modality != Qt.ApplicationModal + } + + + LinearGradient { + visible: !window.hideBackground && gradientsSupported && modality != Qt.ApplicationModal + anchors.top: contentBackground.bottom + anchors.left: contentBackground.left + width: contentBackground.width - 1 + height: 4 + start: Qt.point(0, 0) + end: Qt.point(0, 4) + gradient: Gradient { + GradientStop { position: 0.0; color: hifi.colors.darkGray } + GradientStop { position: 1.0; color: hifi.colors.darkGray0 } + } + cached: true + } + + ScrollView { + id: scrollView + contentItem: content + horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff + verticalScrollBarPolicy: Qt.ScrollBarAsNeeded + anchors.fill: parent + anchors.rightMargin: parent.isScrolling ? 1 : 0 + anchors.bottomMargin: footer.height > 0 ? footerPane.height : 0 + + style: ScrollViewStyle { + + padding.right: -7 // Move to right away from content. + + handle: Item { + implicitWidth: 8 + Rectangle { + radius: 4 + color: hifi.colors.white30 + anchors { + fill: parent + leftMargin: 2 // Finesse size and position. + topMargin: 1 + bottomMargin: 1 + } + } + } + + scrollBarBackground: Item { + implicitWidth: 10 + Rectangle { + color: hifi.colors.darkGray30 + radius: 4 + anchors { + fill: parent + topMargin: -1 // Finesse size + bottomMargin: -2 + } + } + } + + incrementControl: Item { + visible: false + } + + decrementControl: Item { + visible: false + } + } + } + + Rectangle { + // Optional non-scrolling footer. + id: footerPane + anchors { + left: parent.left + bottom: parent.bottom + } + width: parent.contentWidth + height: footer.height + 2 * hifi.dimensions.contentSpacing.y + 3 + color: hifi.colors.baseGray + visible: footer.height > 0 + + Item { + // Horizontal rule. + anchors.fill: parent + + Rectangle { + width: parent.width + height: 1 + y: 1 // Stop displaying content just above horizontal rule/=. + color: hifi.colors.baseGrayShadow + } + + Rectangle { + width: parent.width + height: 1 + y: 2 + color: hifi.colors.baseGrayHighlight + } + } + + Item { + anchors.fill: parent + anchors.topMargin: 3 // Horizontal rule. + children: [ footer ] + } + } + } +} diff --git a/interface/resources/qml/windows/ToolFrame.qml b/interface/resources/qml/windows/ToolFrame.qml new file mode 100644 index 0000000000..ac1093092e --- /dev/null +++ b/interface/resources/qml/windows/ToolFrame.qml @@ -0,0 +1,49 @@ +// +// DefaultFrame.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 QtGraphicalEffects 1.0 + +import "." +import "../styles-uit" + +Frame { + HifiConstants { id: hifi } + + Rectangle { + // Dialog frame + id: frameContent + readonly property int frameMargin: 6 + readonly property int frameMarginLeft: frameMargin + readonly property int frameMarginRight: frameMargin + readonly property int frameMarginTop: frameMargin + readonly property int frameMarginBottom: frameMargin + anchors { + topMargin: -frameMargin + leftMargin: -frameMargin + rightMargin: -frameMargin + bottomMargin: -frameMargin + } + anchors.fill: parent + color: hifi.colors.baseGrayHighlight40 + border { + width: hifi.dimensions.borderWidth + color: hifi.colors.faintGray50 + } + radius: hifi.dimensions.borderRadius / 2 + + // Enable dragging of the window + MouseArea { + anchors.fill: parent + drag.target: window + } + } +} + diff --git a/interface/resources/qml/windows/Window.qml b/interface/resources/qml/windows/Window.qml index ed1b820fc8..e3e70c1e74 100644 --- a/interface/resources/qml/windows/Window.qml +++ b/interface/resources/qml/windows/Window.qml @@ -41,7 +41,7 @@ Fadable { implicitHeight: content ? content.height : 0 implicitWidth: content ? content.width : 0 x: desktop.invalid_position; y: desktop.invalid_position; - children: [ swallower, frame, pane, activator ] + children: [ swallower, frame, content, activator ] // // Custom properties @@ -106,10 +106,10 @@ Fadable { // in the window and have a higher Z-order than the content, but follow // the position and size of frame decoration property var activator: MouseArea { - width: frame.decoration.width - height: frame.decoration.height - x: frame.decoration.anchors.leftMargin - y: frame.decoration.anchors.topMargin + width: frame.decoration ? frame.decoration.width : window.width + height: frame.decoration ? frame.decoration.height : window.height + x: frame.decoration ? frame.decoration.anchors.leftMargin : 0 + y: frame.decoration ? frame.decoration.anchors.topMargin : 0 propagateComposedEvents: true acceptedButtons: Qt.AllButtons enabled: window.visible @@ -124,10 +124,10 @@ Fadable { // to prevent things like mouse wheel events from reaching the application and changing // the camera if the user is scrolling through a list and gets to the end. property var swallower: MouseArea { - width: frame.decoration.width - height: frame.decoration.height - x: frame.decoration.anchors.leftMargin - y: frame.decoration.anchors.topMargin + width: frame.decoration ? frame.decoration.width : window.width + height: frame.decoration ? frame.decoration.height : window.height + x: frame.decoration ? frame.decoration.anchors.leftMargin : 0 + y: frame.decoration ? frame.decoration.anchors.topMargin : 0 hoverEnabled: true acceptedButtons: Qt.AllButtons enabled: window.visible @@ -140,133 +140,11 @@ Fadable { // Default to a standard frame. Can be overriden to provide custom // frame styles, like a full desktop frame to simulate a modal window - property var frame: DefaultFrame { } - - // Scrollable window content. - // FIXME this should not define any visual content in this type. The base window - // type should only consist of logic sized areas, with nothing drawn (although the - // default value for the frame property does include visual decorations) - property var pane: Item { - property bool isScrolling: scrollView.height < scrollView.contentItem.height - property int contentWidth: scrollView.width - (isScrolling ? 10 : 0) - property int scrollHeight: scrollView.height - - anchors.fill: parent - anchors.rightMargin: isScrolling ? 11 : 0 - - Rectangle { - id: contentBackground - anchors.fill: parent - anchors.rightMargin: parent.isScrolling ? 11 : 0 - color: hifi.colors.baseGray - visible: !window.hideBackground && modality != Qt.ApplicationModal - } - - - LinearGradient { - visible: !window.hideBackground && gradientsSupported && modality != Qt.ApplicationModal - anchors.top: contentBackground.bottom - anchors.left: contentBackground.left - width: contentBackground.width - 1 - height: 4 - start: Qt.point(0, 0) - end: Qt.point(0, 4) - gradient: Gradient { - GradientStop { position: 0.0; color: hifi.colors.darkGray } - GradientStop { position: 1.0; color: hifi.colors.darkGray0 } - } - cached: true - } - - ScrollView { - id: scrollView - contentItem: content - horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff - verticalScrollBarPolicy: Qt.ScrollBarAsNeeded - anchors.fill: parent - anchors.rightMargin: parent.isScrolling ? 1 : 0 - anchors.bottomMargin: footer.height > 0 ? footerPane.height : 0 - - style: ScrollViewStyle { - - padding.right: -7 // Move to right away from content. - - handle: Item { - implicitWidth: 8 - Rectangle { - radius: 4 - color: hifi.colors.white30 - anchors { - fill: parent - leftMargin: 2 // Finesse size and position. - topMargin: 1 - bottomMargin: 1 - } - } - } - - scrollBarBackground: Item { - implicitWidth: 10 - Rectangle { - color: hifi.colors.darkGray30 - radius: 4 - anchors { - fill: parent - topMargin: -1 // Finesse size - bottomMargin: -2 - } - } - } - - incrementControl: Item { - visible: false - } - - decrementControl: Item { - visible: false - } - } - } - - Rectangle { - // Optional non-scrolling footer. - id: footerPane - anchors { - left: parent.left - bottom: parent.bottom - } - width: parent.contentWidth - height: footer.height + 2 * hifi.dimensions.contentSpacing.y + 3 - color: hifi.colors.baseGray - visible: footer.height > 0 - - Item { - // Horizontal rule. - anchors.fill: parent - - Rectangle { - width: parent.width - height: 1 - y: 1 // Stop displaying content just above horizontal rule/=. - color: hifi.colors.baseGrayShadow - } - - Rectangle { - width: parent.width - height: 1 - y: 2 - color: hifi.colors.baseGrayHighlight - } - } - - Item { - anchors.fill: parent - anchors.topMargin: 3 // Horizontal rule. - children: [ footer ] - } - } + property var frame: DefaultFrame { + //window: window } + // // Handlers // diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ee365cd5a1..6dc575b572 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -133,6 +133,7 @@ #include "scripting/WebWindowClass.h" #include "scripting/WindowScriptingInterface.h" #include "scripting/ControllerScriptingInterface.h" +#include "scripting/ToolbarScriptingInterface.h" #include "scripting/RatesScriptingInterface.h" #if defined(Q_OS_MAC) || defined(Q_OS_WIN) #include "SpeechRecognizer.h" @@ -437,6 +438,7 @@ bool setupEssentials(int& argc, char** argv) { DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); + DependencyManager::set(); #if defined(Q_OS_MAC) || defined(Q_OS_WIN) @@ -4527,6 +4529,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri RayToOverlayIntersectionResultFromScriptValue); scriptEngine->registerGlobalObject("Desktop", DependencyManager::get().data()); + scriptEngine->registerGlobalObject("Toolbars", DependencyManager::get().data()); scriptEngine->registerGlobalObject("Window", DependencyManager::get().data()); scriptEngine->registerGetterSetter("location", LocationScriptingInterface::locationGetter, diff --git a/interface/src/scripting/ToolbarScriptingInterface.cpp b/interface/src/scripting/ToolbarScriptingInterface.cpp new file mode 100644 index 0000000000..fd96b6a809 --- /dev/null +++ b/interface/src/scripting/ToolbarScriptingInterface.cpp @@ -0,0 +1,124 @@ +// +// Created by Bradley Austin Davis on 2016-06-16 +// Copyright 2013-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 +// + +#include "ToolbarScriptingInterface.h" + +#include + +class QmlWrapper : public QObject { + Q_OBJECT +public: + QmlWrapper(QObject* qmlObject, QObject* parent = nullptr) + : QObject(parent), _qmlObject(qmlObject) { + + const QMetaObject *metaobject = qmlObject->metaObject(); + int count = metaobject->propertyCount(); + qDebug() << "Scanning properties for " << qmlObject; + for (int i = 0; i < count; ++i) { + QMetaProperty metaproperty = metaobject->property(i); + const char *name = metaproperty.name(); + qDebug() << "Property " << name; + } + } + + Q_INVOKABLE void writeProperty(QString propertyName, QVariant propertyValue) { + auto offscreenUi = DependencyManager::get(); + offscreenUi->executeOnUiThread([=] { + _qmlObject->setProperty(propertyName.toStdString().c_str(), propertyValue); + }); + } + + Q_INVOKABLE void writeProperties(QVariant propertyMap) { + auto offscreenUi = DependencyManager::get(); + offscreenUi->executeOnUiThread([=] { + QVariantMap map = propertyMap.toMap(); + for (const QString& key : map.keys()) { + _qmlObject->setProperty(key.toStdString().c_str(), map[key]); + } + }); + } + + Q_INVOKABLE QVariant readProperty(const QString& propertyName) { + auto offscreenUi = DependencyManager::get(); + return offscreenUi->returnFromUiThread([&]()->QVariant { + return _qmlObject->property(propertyName.toStdString().c_str()); + }); + } + + Q_INVOKABLE QVariant readProperties(const QVariant& propertyList) { + auto offscreenUi = DependencyManager::get(); + return offscreenUi->returnFromUiThread([&]()->QVariant { + QVariantMap result; + for (const QVariant& property : propertyList.toList()) { + QString propertyString = property.toString(); + result.insert(propertyString, _qmlObject->property(propertyString.toStdString().c_str())); + } + return result; + }); + } + + +protected: + QObject* _qmlObject{ nullptr }; +}; + + +class ToolbarButtonProxy : public QmlWrapper { + Q_OBJECT + +public: + ToolbarButtonProxy(QObject* qmlObject, QObject* parent = nullptr) : QmlWrapper(qmlObject, parent) { + connect(qmlObject, SIGNAL(clicked()), this, SIGNAL(clicked())); + } + +signals: + void clicked(); +}; + +class ToolbarProxy : public QmlWrapper { + Q_OBJECT + +public: + ToolbarProxy(QObject* qmlObject, QObject* parent = nullptr) : QmlWrapper(qmlObject, parent) { } + + Q_INVOKABLE QObject* addButton(const QVariant& properties) { + QVariant resultVar; + bool invokeResult = QMetaObject::invokeMethod(_qmlObject, "addButton", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QVariant, resultVar), Q_ARG(QVariant, properties)); + if (!invokeResult) { + return nullptr; + } + + QObject* rawButton = qvariant_cast(resultVar); + if (!rawButton) { + return nullptr; + } + + return new ToolbarButtonProxy(rawButton, this); + } +}; + + +QObject* ToolbarScriptingInterface::getToolbar(const QString& toolbarId) { + auto offscreenUi = DependencyManager::get(); + auto desktop = offscreenUi->getDesktop(); + QVariant resultVar; + bool invokeResult = QMetaObject::invokeMethod(desktop, "getToolbar", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QVariant, resultVar), Q_ARG(QVariant, toolbarId)); + if (!invokeResult) { + return nullptr; + } + + QObject* rawToolbar = qvariant_cast(resultVar); + if (!rawToolbar) { + return nullptr; + } + + return new ToolbarProxy(rawToolbar); +} + + +#include "ToolbarScriptingInterface.moc" \ No newline at end of file diff --git a/interface/src/scripting/ToolbarScriptingInterface.h b/interface/src/scripting/ToolbarScriptingInterface.h new file mode 100644 index 0000000000..d3706cb6e1 --- /dev/null +++ b/interface/src/scripting/ToolbarScriptingInterface.h @@ -0,0 +1,26 @@ +// +// Created by Bradley Austin Davis on 2016-06-16 +// Copyright 2013-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 +// + +#ifndef hifi_ToolbarScriptingInterface_h +#define hifi_ToolbarScriptingInterface_h + +#include + +#include + +#include + +class ToolbarProxy; + +class ToolbarScriptingInterface : public QObject, public Dependency { + Q_OBJECT +public: + Q_INVOKABLE QObject* getToolbar(const QString& toolbarId); +}; + +#endif // hifi_ToolbarScriptingInterface_h diff --git a/scripts/defaultScripts.js b/scripts/defaultScripts.js index 218cab8903..bbbe049f39 100644 --- a/scripts/defaultScripts.js +++ b/scripts/defaultScripts.js @@ -12,9 +12,10 @@ Script.load("system/progress.js"); Script.load("system/away.js"); Script.load("system/users.js"); -Script.load("system/examples.js"); +Script.load("system/mute.js"); Script.load("system/goto.js"); Script.load("system/hmd.js"); +Script.load("system/examples.js"); Script.load("system/edit.js"); Script.load("system/selectAudioDevice.js"); Script.load("system/notifications.js"); diff --git a/scripts/developer/tests/toolbarTest.js b/scripts/developer/tests/toolbarTest.js new file mode 100644 index 0000000000..20f349929f --- /dev/null +++ b/scripts/developer/tests/toolbarTest.js @@ -0,0 +1,118 @@ +var isActive = false; + +var toolBar = (function() { + var that = {}, + toolBar, + activeButton, + newModelButton, + newCubeButton, + newSphereButton, + newLightButton, + newTextButton, + newWebButton, + newZoneButton, + newParticleButton + + var toolIconUrl = Script.resolvePath("assets/images/tools/"); + + function initialize() { + print("Toolbars: " + Toolbars); + toolBar = Toolbars.getToolbar("highfidelity.edit.toolbar"); + print("Toolbar: " + toolBar); + activeButton = toolBar.addButton({ + objectName: "activeButton", + imageURL: toolIconUrl + "edit-01.svg", + visible: true, + alpha: 0.9, + }); + + print("Button " + activeButton); + print("Button signal " + activeButton.clicked); + activeButton.clicked.connect(function(){ + print("Clicked on button " + isActive); + that.setActive(!isActive); + }); + + newModelButton = toolBar.addButton({ + objectName: "newModelButton", + imageURL: toolIconUrl + "model-01.svg", + alpha: 0.9, + visible: false + }); + + newCubeButton = toolBar.addButton({ + objectName: "newCubeButton", + imageURL: toolIconUrl + "cube-01.svg", + alpha: 0.9, + visible: false + }); + + newSphereButton = toolBar.addButton({ + objectName: "newSphereButton", + imageURL: toolIconUrl + "sphere-01.svg", + alpha: 0.9, + visible: false + }); + + newLightButton = toolBar.addButton({ + objectName: "newLightButton", + imageURL: toolIconUrl + "light-01.svg", + alpha: 0.9, + visible: false + }); + + newTextButton = toolBar.addButton({ + objectName: "newTextButton", + imageURL: toolIconUrl + "text-01.svg", + alpha: 0.9, + visible: false + }); + + newWebButton = toolBar.addButton({ + objectName: "newWebButton", + imageURL: toolIconUrl + "web-01.svg", + alpha: 0.9, + visible: false + }); + + newZoneButton = toolBar.addButton({ + objectName: "newZoneButton", + imageURL: toolIconUrl + "zone-01.svg", + alpha: 0.9, + visible: false + }); + + newParticleButton = toolBar.addButton({ + objectName: "newParticleButton", + imageURL: toolIconUrl + "particle-01.svg", + alpha: 0.9, + visible: false + }); + + that.setActive(false); + newModelButton.clicked(); + } + + that.setActive = function(active) { + if (active != isActive) { + isActive = active; + that.showTools(isActive); + } + }; + + // Sets visibility of tool buttons, excluding the power button + that.showTools = function(doShow) { + newModelButton.writeProperty('visible', doShow); + newCubeButton.writeProperty('visible', doShow); + newSphereButton.writeProperty('visible', doShow); + newLightButton.writeProperty('visible', doShow); + newTextButton.writeProperty('visible', doShow); + newWebButton.writeProperty('visible', doShow); + newZoneButton.writeProperty('visible', doShow); + newModelButton.writeProperty('visible', doShow); + newParticleButton.writeProperty('visible', doShow); + }; + + initialize(); + return that; +}()); diff --git a/scripts/system/assets/images/tools/microphone.svg b/scripts/system/assets/images/tools/microphone.svg new file mode 100644 index 0000000000..bd5e8afac7 --- /dev/null +++ b/scripts/system/assets/images/tools/microphone.svg @@ -0,0 +1,13 @@ + + + image/svg+xml + + + Layer 1 + + + + Mute + + + \ No newline at end of file diff --git a/scripts/system/examples.js b/scripts/system/examples.js index 6f4268182c..f850a9789e 100644 --- a/scripts/system/examples.js +++ b/scripts/system/examples.js @@ -9,10 +9,6 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include([ - "libraries/toolBars.js", -]); - var toolIconUrl = Script.resolvePath("assets/images/tools/"); var EXAMPLES_URL = "https://metaverse.highfidelity.com/examples"; @@ -52,87 +48,21 @@ function toggleExamples() { } } -var toolBar = (function() { - var that = {}, - toolBar, - browseExamplesButton; +var toolBar = Toolbars.getToolbar("com.highfidelity.interface.toolbar.system"); - function initialize() { - toolBar = new ToolBar(0, 0, ToolBar.HORIZONTAL, "highfidelity.examples.toolbar", function(windowDimensions, toolbar) { - return { - x: (windowDimensions.x / 2) + (Tool.IMAGE_WIDTH * 2), - y: windowDimensions.y - }; - }, { - x: -toolWidth / 2, - y: -TOOLBAR_MARGIN_Y - toolHeight - }); - browseExamplesButton = toolBar.addTool({ - imageURL: toolIconUrl + "examples-01.svg", - subImage: { - x: 0, - y: Tool.IMAGE_WIDTH, - width: Tool.IMAGE_WIDTH, - height: Tool.IMAGE_HEIGHT - }, - width: toolWidth, - height: toolHeight, - alpha: 0.9, - visible: true, - showButtonDown: true - }); +var browseExamplesButton = toolBar.addButton({ + imageURL: toolIconUrl + "examples-01.svg", + objectName: "examples", + yOffset: 50, + alpha: 0.9, +}); - toolBar.showTool(browseExamplesButton, true); - } +var browseExamplesButtonDown = false; - var browseExamplesButtonDown = false; - that.mousePressEvent = function(event) { - var clickedOverlay, - url, - file; +browseExamplesButton.clicked.connect(function(){ + toggleExamples(); +}); - if (!event.isLeftButton) { - // if another mouse button than left is pressed ignore it - return false; - } - - clickedOverlay = Overlays.getOverlayAtPoint({ - x: event.x, - y: event.y - }); - - if (browseExamplesButton === toolBar.clicked(clickedOverlay)) { - toggleExamples(); - return true; - } - - return false; - }; - - that.mouseReleaseEvent = function(event) { - var handled = false; - - - if (browseExamplesButtonDown) { - var clickedOverlay = Overlays.getOverlayAtPoint({ - x: event.x, - y: event.y - }); - } - - newModelButtonDown = false; - browseExamplesButtonDown = false; - - return handled; - } - - that.cleanup = function() { - toolBar.cleanup(); - }; - - initialize(); - return that; -}()); - -Controller.mousePressEvent.connect(toolBar.mousePressEvent) -Script.scriptEnding.connect(toolBar.cleanup); +Script.scriptEnding.connect(function () { + browseExamplesButton.clicked.disconnect(); +}); diff --git a/scripts/system/goto.js b/scripts/system/goto.js index 00b5e912c0..a2ade02a78 100644 --- a/scripts/system/goto.js +++ b/scripts/system/goto.js @@ -9,39 +9,21 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("libraries/toolBars.js"); +var toolBar = Toolbars.getToolbar("com.highfidelity.interface.toolbar.system"); -function initialPosition(windowDimensions, toolbar) { - return { - x: (windowDimensions.x / 2) - (Tool.IMAGE_WIDTH * 1), - y: windowDimensions.y - }; -} -var toolBar = new ToolBar(0, 0, ToolBar.HORIZONTAL, "highfidelity.goto.toolbar", initialPosition, { - x: -Tool.IMAGE_WIDTH / 2, - y: -Tool.IMAGE_HEIGHT -}); -var button = toolBar.addTool({ + +var button = toolBar.addButton({ + objectName: "goto", imageURL: Script.resolvePath("assets/images/tools/directory-01.svg"), - subImage: { - x: 0, - y: Tool.IMAGE_WIDTH, - width: Tool.IMAGE_WIDTH, - height: Tool.IMAGE_HEIGHT - }, - width: Tool.IMAGE_WIDTH, - height: Tool.IMAGE_HEIGHT, - alpha: 0.9, visible: true, - showButtonDown: true + yOffset: 50, + alpha: 0.9, }); -function onMousePress (event) { - if (event.isLeftButton && button === toolBar.clicked(Overlays.getOverlayAtPoint(event))) { - DialogsManager.toggleAddressBar(); - } -}; -Controller.mousePressEvent.connect(onMousePress) + +button.clicked.connect(function(){ + DialogsManager.toggleAddressBar(); +}); + Script.scriptEnding.connect(function () { - Controller.mousePressEvent.disconnect(onMousePress) - toolBar.cleanup(); + button.clicked.disconnect(); }); diff --git a/scripts/system/hmd.js b/scripts/system/hmd.js index 8b91e45676..2965c0d254 100644 --- a/scripts/system/hmd.js +++ b/scripts/system/hmd.js @@ -9,8 +9,6 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("libraries/toolBars.js"); - var headset; // The preferred headset. Default to the first one found in the following list. var displayMenuName = "Display"; var desktopMenuItemName = "Desktop"; @@ -20,38 +18,25 @@ var desktopMenuItemName = "Desktop"; } }); -function initialPosition(windowDimensions, toolbar) { - return { - x: (windowDimensions.x / 2) - (Tool.IMAGE_WIDTH * 2.5), - y: windowDimensions.y - }; -} -var toolBar = new ToolBar(0, 0, ToolBar.HORIZONTAL, "highfidelity.hmd.toolbar", initialPosition, { - x: -Tool.IMAGE_WIDTH / 2, - y: -Tool.IMAGE_HEIGHT -}); -var button = toolBar.addTool({ - imageURL: Script.resolvePath("assets/images/tools/hmd-switch-01.svg"), - subImage: { - x: 0, - y: Tool.IMAGE_WIDTH, - width: Tool.IMAGE_WIDTH, - height: Tool.IMAGE_HEIGHT - }, - width: Tool.IMAGE_WIDTH, - height: Tool.IMAGE_HEIGHT, - alpha: 0.9, - visible: true, - showButtonDown: true -}); -function onMousePress (event) { - if (event.isLeftButton && button === toolBar.clicked(Overlays.getOverlayAtPoint(event))) { +var toolBar = Toolbars.getToolbar("com.highfidelity.interface.toolbar.system"); +var button; + +if (headset) { + button = toolBar.addButton({ + objectName: "hmdToggle", + imageURL: Script.resolvePath("assets/images/tools/hmd-switch-01.svg"), + visible: true, + yOffset: 50, + alpha: 0.9, + }); + + button.clicked.connect(function(){ var isDesktop = Menu.isOptionChecked(desktopMenuItemName); Menu.setIsOptionChecked(isDesktop ? headset : desktopMenuItemName, true); - } -}; -Controller.mousePressEvent.connect(onMousePress) -Script.scriptEnding.connect(function () { - Controller.mousePressEvent.disconnect(onMousePress) - toolBar.cleanup(); -}); + }); + + Script.scriptEnding.connect(function () { + button.clicked.disconnect(); + }); +} + diff --git a/scripts/system/mute.js b/scripts/system/mute.js new file mode 100644 index 0000000000..f66b6852ea --- /dev/null +++ b/scripts/system/mute.js @@ -0,0 +1,29 @@ +// +// goto.js +// scripts/system/ +// +// Created by Howard Stearns on 2 Jun 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 +// + +var toolBar = Toolbars.getToolbar("com.highfidelity.interface.toolbar.system"); + + +var button = toolBar.addButton({ + objectName: "mute", + imageURL: Script.resolvePath("assets/images/tools/microphone.svg"), + visible: true, + alpha: 0.9, +}); + +button.clicked.connect(function(){ + var menuItem = "Mute Microphone"; + Menu.setIsOptionChecked(menuItem, !Menu.isOptionChecked(menuItem)); +}); + +Script.scriptEnding.connect(function () { + button.clicked.disconnect(); +}); diff --git a/tests/ui/qml/Stubs.qml b/tests/ui/qml/Stubs.qml index 8f828a0186..8c1465d54c 100644 --- a/tests/ui/qml/Stubs.qml +++ b/tests/ui/qml/Stubs.qml @@ -23,11 +23,23 @@ Item { function getUsername() { return "Jherico"; } } + Item { + objectName: "GL" + property string vendor: "" + } + Item { objectName: "ApplicationCompositor" property bool reticleOverDesktop: true } + Item { + objectName: "Controller" + function getRecommendedOverlayRect() { + return Qt.rect(0, 0, 1920, 1080); + } + } + Item { objectName: "Preferences" // List of categories obtained by logging categories as they are added in Interface in Preferences::addPreference(). diff --git a/tests/ui/qml/main.qml b/tests/ui/qml/main.qml index 33408fb821..19f6a55bfd 100644 --- a/tests/ui/qml/main.qml +++ b/tests/ui/qml/main.qml @@ -25,35 +25,67 @@ ApplicationWindow { property var tabs: []; property var urls: []; + property var toolbar; + property var lastButton; // Window visibility - - Button { - text: "restore all" - onClicked: { - for (var i = 0; i < desktop.windows.length; ++i) { - desktop.windows[i].shown = true - } - } - } - Button { - text: "toggle blue visible" - onClicked: { - blue.shown = !blue.shown - } - } - Button { - text: "toggle blue enabled" - onClicked: { - blue.enabled = !blue.enabled - } - } - Button { text: "toggle desktop" onClicked: desktop.togglePinned() } + Button { + text: "Create Toolbar" + onClicked: testButtons.toolbar = desktop.getToolbar("com.highfidelity.interface.toolbar.system"); + } + + Button { + text: "Toggle Toolbar Direction" + onClicked: testButtons.toolbar.horizontal = !testButtons.toolbar.horizontal + } + + Button { + readonly property var icons: [ + "edit-01.svg", + "model-01.svg", + "cube-01.svg", + "sphere-01.svg", + "light-01.svg", + "text-01.svg", + "web-01.svg", + "zone-01.svg", + "particle-01.svg", + ] + property int iconIndex: 0 + readonly property string toolIconUrl: "file:///C:/Users/bdavi/git/hifi/scripts/system/assets/images/tools/" + text: "Create Button" + onClicked: { + var name = icons[iconIndex]; + var url = toolIconUrl + name; + iconIndex = (iconIndex + 1) % icons.length; + var button = testButtons.lastButton = testButtons.toolbar.addButton({ + imageURL: url, + objectName: name, + subImage: { + y: 50, + }, + alpha: 0.9 + }); + + button.clicked.connect(function(){ + console.log("Clicked on button " + button.imageURL + " alpha " + button.alpha) + }); + } + } + + Button { + text: "Toggle Button Visible" + onClicked: testButtons.lastButton.visible = !testButtons.lastButton.visible + } + + + + // Error alerts /* Button { @@ -106,7 +138,7 @@ ApplicationWindow { */ // Browser - + /* Button { text: "Open Browser" onClicked: builder.createObject(desktop); @@ -114,8 +146,11 @@ ApplicationWindow { Browser {} } } + */ + // file dialog + /* Button { text: "Open Directory" @@ -153,7 +188,6 @@ ApplicationWindow { }) } } - /* */ // tabs @@ -306,6 +340,7 @@ ApplicationWindow { } */ + /* Window { id: blue closable: true @@ -350,6 +385,8 @@ ApplicationWindow { height: green.height; } } + */ + /* Window { id: yellow @@ -379,3 +416,7 @@ ApplicationWindow { } } } + + + + diff --git a/tests/ui/qmlscratch.pro b/tests/ui/qmlscratch.pro index 95be6a480e..151893de2f 100644 --- a/tests/ui/qmlscratch.pro +++ b/tests/ui/qmlscratch.pro @@ -29,6 +29,7 @@ DISTFILES += \ ../../interface/resources/qml/styles-uit/*.qml \ ../../interface/resources/qml/windows/*.qml \ ../../interface/resources/qml/hifi/*.qml \ + ../../interface/resources/qml/hifi/toolbars/*.qml \ ../../interface/resources/qml/hifi/dialogs/*.qml \ ../../interface/resources/qml/hifi/dialogs/preferences/*.qml \ ../../interface/resources/qml/hifi/overlays/*.qml diff --git a/tests/ui/src/main.cpp b/tests/ui/src/main.cpp index 0cabfe28f5..e3cf37ba04 100644 --- a/tests/ui/src/main.cpp +++ b/tests/ui/src/main.cpp @@ -86,9 +86,11 @@ int main(int argc, char *argv[]) { setChild(engine, "offscreenFlags"); setChild(engine, "Account"); setChild(engine, "ApplicationCompositor"); + setChild(engine, "Controller"); setChild(engine, "Desktop"); setChild(engine, "ScriptDiscoveryService"); setChild(engine, "HMD"); + setChild(engine, "GL"); setChild(engine, "MenuHelper"); setChild(engine, "Preferences"); setChild(engine, "urlHandler"); @@ -101,3 +103,4 @@ int main(int argc, char *argv[]) { } #include "main.moc" +