Support toolbar API

This commit is contained in:
Bradley Austin Davis 2016-06-17 10:56:35 -07:00
parent 5bc8b53d1b
commit ec615caa80
36 changed files with 870 additions and 381 deletions

View file

@ -18,7 +18,7 @@ import "controls-uit" as HifiControls
import "windows"
import "dialogs"
Window {
ScrollingWindow {
id: root
objectName: "AssetServer"
title: "Asset Browser"

View file

@ -6,7 +6,7 @@ import "controls-uit"
import "styles-uit"
import "windows"
Window {
ScrollingWindow {
id: root
HifiConstants { id: hifi }
title: "Browser"

View file

@ -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

View file

@ -14,7 +14,7 @@ import "controls"
import "styles"
import "windows"
Window {
ScrollingWindow {
id: root
HifiConstants { id: hifi }
objectName: "LoginDialog"

View file

@ -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"

View file

@ -19,7 +19,7 @@ import "windows"
import "controls-uit"
import "styles-uit"
Window {
ScrollingWindow {
id: toolWindow
resizable: true
objectName: "ToolWindow"

View file

@ -7,7 +7,7 @@ import "controls-uit"
import "styles-uit"
import "windows"
Window {
ScrollingWindow {
id: root
HifiConstants { id: hifi }
objectName: "UpdateDialog"

View file

@ -16,7 +16,7 @@ import "../styles-uit"
import "../windows"
import "preferences"
Window {
ScrollingWindow {
id: root
title: "Preferences"
resizable: true

View file

@ -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
}
}

View file

@ -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;
}
}

View file

@ -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));
}
}
}

View file

@ -9,7 +9,7 @@ import "../../controls-uit" as HifiControls
import "../../windows"
import "attachments"
Window {
ScrollingWindow {
id: root
title: "Attachments"
objectName: "AttachmentsDialog"

View file

@ -11,7 +11,7 @@ import "../../styles-uit"
import "../../controls-uit" as HifiControls
import "../../windows"
Window {
ScrollingWindow {
id: root
resizable: true
width: 600

View file

@ -17,7 +17,7 @@ import "../../styles-uit"
import "../../controls-uit" as HifiControls
import "../../windows"
Window {
ScrollingWindow {
id: root
objectName: "RunningScripts"
title: "Running Scripts"

View file

@ -7,7 +7,7 @@ import "../../windows"
import "../../js/Utils.js" as Utils
import "../models"
Window {
ScrollingWindow {
id: root
resizable: true
width: 516

View file

@ -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
}
}

View file

@ -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();
}
}
}

View file

@ -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 {

View file

@ -12,7 +12,7 @@ import QtQuick 2.5
import "."
Window {
ScrollingWindow {
id: window
modality: Qt.ApplicationModal
destroyOnCloseButton: true

View file

@ -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 ]
}
}
}
}

View file

@ -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
}
}
}

View file

@ -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
//

View file

@ -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<WindowScriptingInterface>();
DependencyManager::set<HMDScriptingInterface>();
DependencyManager::set<ResourceScriptingInterface>();
DependencyManager::set<ToolbarScriptingInterface>();
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
@ -4527,6 +4529,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri
RayToOverlayIntersectionResultFromScriptValue);
scriptEngine->registerGlobalObject("Desktop", DependencyManager::get<DesktopScriptingInterface>().data());
scriptEngine->registerGlobalObject("Toolbars", DependencyManager::get<ToolbarScriptingInterface>().data());
scriptEngine->registerGlobalObject("Window", DependencyManager::get<WindowScriptingInterface>().data());
scriptEngine->registerGetterSetter("location", LocationScriptingInterface::locationGetter,

View file

@ -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 <OffscreenUi.h>
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>();
offscreenUi->executeOnUiThread([=] {
_qmlObject->setProperty(propertyName.toStdString().c_str(), propertyValue);
});
}
Q_INVOKABLE void writeProperties(QVariant propertyMap) {
auto offscreenUi = DependencyManager::get<OffscreenUi>();
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<OffscreenUi>();
return offscreenUi->returnFromUiThread([&]()->QVariant {
return _qmlObject->property(propertyName.toStdString().c_str());
});
}
Q_INVOKABLE QVariant readProperties(const QVariant& propertyList) {
auto offscreenUi = DependencyManager::get<OffscreenUi>();
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<QObject *>(resultVar);
if (!rawButton) {
return nullptr;
}
return new ToolbarButtonProxy(rawButton, this);
}
};
QObject* ToolbarScriptingInterface::getToolbar(const QString& toolbarId) {
auto offscreenUi = DependencyManager::get<OffscreenUi>();
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<QObject *>(resultVar);
if (!rawToolbar) {
return nullptr;
}
return new ToolbarProxy(rawToolbar);
}
#include "ToolbarScriptingInterface.moc"

View file

@ -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 <mutex>
#include <QtCore/QObject>
#include <DependencyManager.h>
class ToolbarProxy;
class ToolbarScriptingInterface : public QObject, public Dependency {
Q_OBJECT
public:
Q_INVOKABLE QObject* getToolbar(const QString& toolbarId);
};
#endif // hifi_ToolbarScriptingInterface_h

View file

@ -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");

View file

@ -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;
}());

View file

@ -0,0 +1,13 @@
<?xml version="1.0"?>
<svg width="50" height="50.1" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<metadata id="metadata27">image/svg+xml</metadata>
<g>
<title>Layer 1</title>
<g id="g3" opacity="0.9">
<path id="path5" d="m50,46c0,2.2 -1.8,4 -4,4l-42,0c-2.2,0 -4,-1.8 -4,-4l0,-42c0,-2.2 1.8,-4 4,-4l42,0c2.2,0 4,1.8 4,4l0,42z" fill="#1E1E1E"/>
</g>
<text xml:space="preserve" text-anchor="middle" font-family="Sans" font-size="11px" id="svg_5" y="42.610549" x="25.949214" stroke="#cbcbcb" fill="#cbcbcb">Mute</text>
<ellipse ry="6.644531" rx="0.632813" id="svg_6" cy="15.716017" cx="25.316401" stroke-width="5" stroke="#cbcbcb" fill="#1E1E1E"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 702 B

View file

@ -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();
});

View file

@ -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();
});

View file

@ -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();
});
}

29
scripts/system/mute.js Normal file
View file

@ -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();
});

View file

@ -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().

View file

@ -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 {
}
}
}

View file

@ -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

View file

@ -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"