From 314c04ab9623cf4dd977a50a7ab3e4ad024a903e Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 10 May 2019 10:49:25 -0700 Subject: [PATCH] Simplified UI v1 --- interface/resources/fonts/Graphik-Medium.ttf | Bin 0 -> 147368 bytes interface/resources/fonts/Graphik-Regular.ttf | Bin 0 -> 144968 bytes .../resources/fonts/Graphik-Semibold.ttf | Bin 0 -> 52264 bytes .../hifi/simplifiedUI/avatarApp/AvatarApp.qml | 227 ++++++ .../components/AvatarAppListDelegate.qml | 108 +++ .../components/DisplayNameHeader.qml | 133 ++++ .../qml/hifi/simplifiedUI/images/accent.svg | 4 + .../qml/hifi/simplifiedUI/images/loading.gif | Bin 0 -> 71043 bytes .../inputDeviceButton/InputDeviceButton.qml | 193 +++++ .../inputDeviceButton/images/mic-clip-i.svg | 10 + .../inputDeviceButton/images/mic-gate-i.svg | 3 + .../inputDeviceButton/images/mic-mute-a.svg | 3 + .../inputDeviceButton/images/mic-mute-i.svg | 3 + .../inputDeviceButton/images/mic-ptt-a.svg | 1 + .../inputDeviceButton/images/mic-ptt-i.svg | 24 + .../inputDeviceButton/images/mic-unmute-a.svg | 3 + .../inputDeviceButton/images/mic-unmute-i.svg | 3 + .../simplifiedUI/settingsApp/SettingsApp.qml | 147 ++++ .../simplifiedUI/settingsApp/audio/Audio.qml | 405 +++++++++++ .../settingsApp/general/General.qml | 236 ++++++ .../hifi/simplifiedUI/settingsApp/vr/VR.qml | 418 +++++++++++ .../SimplifiedConstants.qml | 169 +++++ .../simplifiedControls/Button.qml | 106 +++ .../simplifiedControls/InputPeak.qml | 101 +++ .../simplifiedControls/RadioButton.qml | 119 +++ .../simplifiedControls/Slider.qml | 120 +++ .../simplifiedControls/Switch.qml | 204 ++++++ .../simplifiedUI/topBar/SimplifiedTopBar.qml | 238 ++++++ .../topBar/images/defaultAvatar.jpg | Bin 0 -> 36764 bytes .../resources/qml/stylesUit/GraphikMedium.qml | 21 + .../qml/stylesUit/GraphikRegular.qml | 20 + .../qml/stylesUit/GraphikSemiBold.qml | 21 + interface/resources/qml/stylesUit/qmldir | 6 +- interface/src/Application.cpp | 5 + interface/src/avatar/MyAvatar.h | 2 + .../modules/defaultLocalEntityProps.js | 26 + .../resources/modules/entityMaker.js | 154 ++++ .../resources/modules/nameTagListManager.js | 687 ++++++++++++++++++ .../resources/modules/objectAssign.js | 32 + .../resources/modules/pickRayController.js | 305 ++++++++ .../resources/modules/textHelper.js | 224 ++++++ .../simplifiedNametag/simplifiedNametag.js | 96 +++ .../simplifiedUI/images/inputDeviceMuted.svg | 12 + .../simplifiedUI/images/outputDeviceMuted.svg | 4 + scripts/system/simplifiedUI/simplifiedUI.js | 502 +++++++++++++ 45 files changed, 5094 insertions(+), 1 deletion(-) create mode 100644 interface/resources/fonts/Graphik-Medium.ttf create mode 100644 interface/resources/fonts/Graphik-Regular.ttf create mode 100644 interface/resources/fonts/Graphik-Semibold.ttf create mode 100644 interface/resources/qml/hifi/simplifiedUI/avatarApp/AvatarApp.qml create mode 100644 interface/resources/qml/hifi/simplifiedUI/avatarApp/components/AvatarAppListDelegate.qml create mode 100644 interface/resources/qml/hifi/simplifiedUI/avatarApp/components/DisplayNameHeader.qml create mode 100644 interface/resources/qml/hifi/simplifiedUI/images/accent.svg create mode 100644 interface/resources/qml/hifi/simplifiedUI/images/loading.gif create mode 100644 interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/InputDeviceButton.qml create mode 100644 interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-clip-i.svg create mode 100644 interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-gate-i.svg create mode 100644 interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-mute-a.svg create mode 100644 interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-mute-i.svg create mode 100644 interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-ptt-a.svg create mode 100644 interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-ptt-i.svg create mode 100644 interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-unmute-a.svg create mode 100644 interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-unmute-i.svg create mode 100644 interface/resources/qml/hifi/simplifiedUI/settingsApp/SettingsApp.qml create mode 100644 interface/resources/qml/hifi/simplifiedUI/settingsApp/audio/Audio.qml create mode 100644 interface/resources/qml/hifi/simplifiedUI/settingsApp/general/General.qml create mode 100644 interface/resources/qml/hifi/simplifiedUI/settingsApp/vr/VR.qml create mode 100644 interface/resources/qml/hifi/simplifiedUI/simplifiedConstants/SimplifiedConstants.qml create mode 100644 interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Button.qml create mode 100644 interface/resources/qml/hifi/simplifiedUI/simplifiedControls/InputPeak.qml create mode 100644 interface/resources/qml/hifi/simplifiedUI/simplifiedControls/RadioButton.qml create mode 100644 interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Slider.qml create mode 100644 interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Switch.qml create mode 100644 interface/resources/qml/hifi/simplifiedUI/topBar/SimplifiedTopBar.qml create mode 100644 interface/resources/qml/hifi/simplifiedUI/topBar/images/defaultAvatar.jpg create mode 100644 interface/resources/qml/stylesUit/GraphikMedium.qml create mode 100644 interface/resources/qml/stylesUit/GraphikRegular.qml create mode 100644 interface/resources/qml/stylesUit/GraphikSemiBold.qml create mode 100644 scripts/system/simplifiedNametag/resources/modules/defaultLocalEntityProps.js create mode 100644 scripts/system/simplifiedNametag/resources/modules/entityMaker.js create mode 100644 scripts/system/simplifiedNametag/resources/modules/nameTagListManager.js create mode 100644 scripts/system/simplifiedNametag/resources/modules/objectAssign.js create mode 100644 scripts/system/simplifiedNametag/resources/modules/pickRayController.js create mode 100644 scripts/system/simplifiedNametag/resources/modules/textHelper.js create mode 100644 scripts/system/simplifiedNametag/simplifiedNametag.js create mode 100644 scripts/system/simplifiedUI/images/inputDeviceMuted.svg create mode 100644 scripts/system/simplifiedUI/images/outputDeviceMuted.svg create mode 100644 scripts/system/simplifiedUI/simplifiedUI.js diff --git a/interface/resources/fonts/Graphik-Medium.ttf b/interface/resources/fonts/Graphik-Medium.ttf new file mode 100644 index 0000000000000000000000000000000000000000..9d766a1d761532beceac5968ca4d0186dd1d48ce GIT binary patch literal 147368 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 literal 0 HcmV?d00001 diff --git a/interface/resources/fonts/Graphik-Semibold.ttf b/interface/resources/fonts/Graphik-Semibold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..b0ee02248d4f672b646884c768921992b72563ab GIT binary patch literal 52264 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 literal 0 HcmV?d00001 diff --git a/interface/resources/qml/hifi/simplifiedUI/avatarApp/AvatarApp.qml b/interface/resources/qml/hifi/simplifiedUI/avatarApp/AvatarApp.qml new file mode 100644 index 0000000000..eff6eae5ce --- /dev/null +++ b/interface/resources/qml/hifi/simplifiedUI/avatarApp/AvatarApp.qml @@ -0,0 +1,227 @@ +// +// AvatarApp.qml +// +// Created by Zach Fox on 2019-05-02 +// Copyright 2019 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.10 +import "../simplifiedConstants" as SimplifiedConstants +import "./components" as AvatarAppComponents +import stylesUit 1.0 as HifiStylesUit +import "qrc:////qml//hifi//models" as HifiModels // Absolute path so the same code works everywhere. + +Rectangle { + id: root + + property bool inventoryReceived: false + property bool isDebuggingFirstUseTutorial: false + property bool keyboardRaised: false + property int numUpdatesAvailable: 0 + property string avatarPreviewUrl: "" + + onAvatarPreviewUrlChanged: { + sendToScript({ + "source": "AvatarApp.qml", + "method": "updateAvatarThumbnailURL", + "data": { + "avatarThumbnailURL": root.avatarPreviewUrl + } + }); + } + + SimplifiedConstants.SimplifiedConstants { + id: simplifiedUI + } + + color: simplifiedUI.colors.darkBackground + + Component.onCompleted: { + Commerce.getLoginStatus(); + } + + Connections { + target: MyAvatar + + onSkeletonModelURLChanged: { + root.updatePreviewUrl(); + } + } + + Connections { + target: Commerce + + onLoginStatusResult: { + if (isLoggedIn) { + Commerce.getWalletStatus(); + } else { + // Show some error to the user + } + } + + onWalletStatusResult: { + if (walletStatus === 5) { + getInventory(); + } else { + // Show some error to the user + } + } + + onInventoryResult: { + inventoryModel.handlePage(result.status !== "success" && result.message, result); + root.updatePreviewUrl(); + } + } + + Image { + id: accent + source: "../images/accent.svg" + anchors.top: parent.top + anchors.right: parent.right + width: 60 + height: 103 + transform: Scale { + yScale: -1 + origin.x: accent.width / 2 + origin.y: accent.height / 2 + } + } + + AvatarAppComponents.DisplayNameHeader { + id: displayNameHeader + previewUrl: avatarPreviewUrl + loading: !inventoryContentsList.visible + anchors.top: parent.top + anchors.topMargin: 30 + anchors.left: parent.left + anchors.leftMargin: 24 + anchors.right: parent.right + anchors.rightMargin: 24 + } + + Item { + id: avatarInfoTextContainer + width: parent.implicitWidth + height: childrenRect.height + anchors.top: displayNameHeader.bottom + anchors.topMargin: 30 + anchors.left: parent.left + anchors.leftMargin: 24 + anchors.right: parent.right + anchors.rightMargin: 24 + + HifiStylesUit.GraphikRegular { + id: yourAvatarsTitle + text: "Your Avatars" + anchors.top: parent.top + verticalAlignment: TextInput.AlignVCenter + horizontalAlignment: TextInput.AlignLeft + color: simplifiedUI.colors.text.white + size: 22 + } + HifiStylesUit.GraphikRegular { + id: yourAvatarsSubtitle + text: "These are the avatars that you've created and uploaded via the Avatar Creator." + width: parent.width + wrapMode: Text.WordWrap + anchors.top: yourAvatarsTitle.bottom + anchors.topMargin: 6 + verticalAlignment: TextInput.AlignVCenter + horizontalAlignment: TextInput.AlignLeft + color: simplifiedUI.colors.text.darkGrey + size: 14 + } + } + + HifiModels.PSFListModel { + id: inventoryModel + itemsPerPage: 4 + listModelName: 'inventory' + listView: inventoryContentsList + getPage: function () { + var editionFilter = ""; + var primaryFilter = "avatar"; + var titleFilter = ""; + + Commerce.inventory( + editionFilter, + primaryFilter, + titleFilter, + inventoryModel.currentPageToRetrieve, + inventoryModel.itemsPerPage + ); + } + processPage: function(data) { + inventoryReceived = true; + data.assets.forEach(function (item) { + if (item.status.length > 1) { console.warn("Unrecognized inventory status", item); } + item.status = item.status[0]; + }); + return data.assets; + } + } + + Item { + anchors.top: avatarInfoTextContainer.bottom + anchors.topMargin: 16 + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + + AnimatedImage { + visible: !inventoryContentsList.visible + anchors.centerIn: parent + width: 72 + height: width + source: "../images/loading.gif" + } + + ListView { + id: inventoryContentsList + visible: inventoryModel.count !== 0 + interactive: contentItem.height > height + clip: true + model: inventoryModel + anchors.fill: parent + width: parent.width + delegate: AvatarAppComponents.AvatarAppListDelegate { + id: avatarAppListDelegate + itemName: title + itemPreviewImageUrl: preview + itemHref: download_url + standaloneOptimized: model.standalone_optimized + standaloneIncompatible: model.standalone_incompatible + } + } + } + + + function getInventory() { + inventoryModel.getFirstPage(); + } + + function updatePreviewUrl() { + var previewUrl = ""; + var downloadUrl = ""; + for (var i = 0; i < inventoryModel.count; ++i) { + downloadUrl = inventoryModel.get(i).download_url; + previewUrl = inventoryModel.get(i).preview; + if (MyAvatar.skeletonModelURL === downloadUrl) { + avatarPreviewUrl = previewUrl; + return; + } + } + } + + function fromScript(message) { + switch (message.method) { + default: + console.log('AvatarApp.qml: Unrecognized message from JS'); + break; + } + } + signal sendToScript(var message); +} diff --git a/interface/resources/qml/hifi/simplifiedUI/avatarApp/components/AvatarAppListDelegate.qml b/interface/resources/qml/hifi/simplifiedUI/avatarApp/components/AvatarAppListDelegate.qml new file mode 100644 index 0000000000..a34a39cda4 --- /dev/null +++ b/interface/resources/qml/hifi/simplifiedUI/avatarApp/components/AvatarAppListDelegate.qml @@ -0,0 +1,108 @@ +// +// AvatarAppListDelegate.qml +// +// Created by Zach Fox on 2019-05-09 +// Copyright 2019 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.10 +import "../../simplifiedConstants" as SimplifiedConstants +import "../../simplifiedControls" as SimplifiedControls +import stylesUit 1.0 as HifiStylesUit +import QtGraphicalEffects 1.0 + +Rectangle { + id: root; + + SimplifiedConstants.SimplifiedConstants { + id: simplifiedUI + } + + property string itemName; + property string itemPreviewImageUrl; + property string itemHref; + property bool standaloneOptimized; + property bool standaloneIncompatible; + property bool isCurrentItem; + + property bool isHovering: mouseArea.containsMouse || wearButton.hovered || wearButton.down + + height: 102; + width: parent.width; + color: root.isHovering ? simplifiedUI.colors.darkBackgroundHighlight : "transparent" + + + Rectangle { + id: borderMask + visible: root.isHovering + width: itemPreviewImage.width + 4 + height: width + radius: width + anchors.centerIn: itemPreviewImage + color: "#FFFFFF" + } + + Image { + id: itemPreviewImage + source: root.itemPreviewImageUrl + anchors.left: parent.left + anchors.leftMargin: 20 + anchors.verticalCenter: parent.verticalCenter + height: 60 + width: height + fillMode: Image.PreserveAspectCrop + mipmap: true + layer.enabled: true + layer.effect: OpacityMask { + maskSource: mask + } + + Rectangle { + id: mask + width: itemPreviewImage.width + height: itemPreviewImage.height + radius: itemPreviewImage.width / 2 + visible: false + } + } + + HifiStylesUit.GraphikRegular { + id: avatarName + text: root.itemName + anchors.left: itemPreviewImage.right + anchors.leftMargin: 20 + anchors.right: root.isHovering ? wearButton.left : parent.right + anchors.rightMargin: 20 + anchors.verticalCenter: parent.verticalCenter + elide: Text.ElideRight + height: parent.height + size: 20 + color: simplifiedUI.colors.text.almostWhite + } + + SimplifiedControls.Button { + id: wearButton; + visible: MyAvatar.skeletonModelURL !== root.itemHref && root.isHovering; + + anchors.right: parent.right; + anchors.rightMargin: 24; + anchors.verticalCenter: parent.verticalCenter + width: 165; + height: 32; + text: "WEAR" + + onClicked: { + MyAvatar.useFullAvatarURL(root.itemHref); + } + } + + MouseArea { + z: -1 + id: mouseArea + anchors.fill: parent + hoverEnabled: true + } +} diff --git a/interface/resources/qml/hifi/simplifiedUI/avatarApp/components/DisplayNameHeader.qml b/interface/resources/qml/hifi/simplifiedUI/avatarApp/components/DisplayNameHeader.qml new file mode 100644 index 0000000000..8386e3cddc --- /dev/null +++ b/interface/resources/qml/hifi/simplifiedUI/avatarApp/components/DisplayNameHeader.qml @@ -0,0 +1,133 @@ +// +// DisplayNameHeader.qml +// +// Created by Wayne Chen on 2019-05-03 +// Copyright 2019 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.10 +import "../../simplifiedConstants" as SimplifiedConstants +import stylesUit 1.0 as HifiStylesUit +import controlsUit 1.0 as HifiControlsUit +import QtGraphicalEffects 1.0 + +Item { + id: root + + SimplifiedConstants.SimplifiedConstants { + id: simplifiedUI + } + + height: itemPreviewImage.height + property string previewUrl: "" + property bool loading: true + + AnimatedImage { + visible: root.loading + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + height: 72 + width: height + source: "../../images/loading.gif" + } + + Image { + id: itemPreviewImage + visible: !root.loading + source: root.previewUrl + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + height: 100 + width: height + fillMode: Image.PreserveAspectCrop + layer.enabled: true + layer.effect: OpacityMask { + maskSource: mask + } + mipmap: true + + Rectangle { + id: mask + width: itemPreviewImage.width + height: width + radius: width + visible: false + } + } + + Item { + id: displayNameContainer + height: itemPreviewImage.height + anchors.right: parent.right + anchors.left: itemPreviewImage.right + anchors.leftMargin: 21 + anchors.verticalCenter: parent.verticalCenter + + HifiStylesUit.GraphikRegular { + id: displayNameLabel + text: "Display Name" + color: simplifiedUI.colors.text.lightGrey + size: 16 + anchors.top: parent.top + anchors.right: parent.right + anchors.bottom: parent.verticalCenter + anchors.left: parent.left + verticalAlignment: Text.AlignBottom + } + + Item { + id: myDisplayNameContainer + // Size + width: parent.width + height: 40 + anchors.top: parent.verticalCenter + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.left: parent.left + + MouseArea { + anchors.fill: parent + hoverEnabled: true + onClicked: { + myDisplayNameText.focus = true; + myDisplayNameText.cursorPosition = myDisplayNameText.positionAt(mouseX - myDisplayNameText.anchors.leftMargin, mouseY, TextInput.CursorOnCharacter); + } + onDoubleClicked: { + myDisplayNameText.selectAll(); + myDisplayNameText.focus = true; + } + } + + TextInput { + id: myDisplayNameText + text: MyAvatar.displayName + maximumLength: 256 + clip: true + anchors.fill: parent + color: simplifiedUI.colors.text.white + font.family: "Graphik Medium" + font.pixelSize: 22 + selectionColor: simplifiedUI.colors.text.white + selectedTextColor: simplifiedUI.colors.text.darkGrey + verticalAlignment: TextInput.AlignVCenter + horizontalAlignment: TextInput.AlignLeft + autoScroll: false + onEditingFinished: { + if (MyAvatar.displayName !== text) { + MyAvatar.displayName = text; + } + myDisplayNameText.focus = false; + } + onFocusChanged: { + if (!focus) { + cursorPosition = 0; + } + myDisplayNameText.autoScroll = focus; + } + } + } + } +} diff --git a/interface/resources/qml/hifi/simplifiedUI/images/accent.svg b/interface/resources/qml/hifi/simplifiedUI/images/accent.svg new file mode 100644 index 0000000000..d0a8ff258d --- /dev/null +++ b/interface/resources/qml/hifi/simplifiedUI/images/accent.svg @@ -0,0 +1,4 @@ + + + + diff --git a/interface/resources/qml/hifi/simplifiedUI/images/loading.gif b/interface/resources/qml/hifi/simplifiedUI/images/loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..365e9ddba6836eb42c4a1a2d43f2b991435f504b GIT binary patch literal 71043 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

miPaH)dKKI<$@= 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 userSpeakingLevel)) ? 1.0 : 0.7; + if (pushToTalk && !pushingToTalk) { + rectOpacity = (mouseArea.containsMouse) ? 1.0 : 0.7; + } else if (mouseArea.containsMouse && rectOpacity != 1.0) { + rectOpacity = 1.0; + } + micBar.opacity = rectOpacity; + } + + color: "#00000000"; + + MouseArea { + id: mouseArea; + + anchors { + left: icon.left; + right: bar.right; + top: icon.top; + bottom: icon.bottom; + } + + hoverEnabled: true; + scrollGestureEnabled: false; + onClicked: { + if (pushToTalk) { + return; + } + AudioScriptingInterface.muted = !muted; + Tablet.playSound(TabletEnums.ButtonClick); + muted = Qt.binding(function() { return AudioScriptingInterface.muted; }); // restore binding + } + onContainsMouseChanged: { + if (containsMouse) { + Tablet.playSound(TabletEnums.ButtonHover); + } + } + } + + QtObject { + id: colors; + + readonly property string unmutedColor: simplifiedUI.colors.controls.inputVolumeButton.text.noisy; + readonly property string gatedColor: "#00BDFF"; + readonly property string mutedColor: simplifiedUI.colors.controls.inputVolumeButton.text.muted; + readonly property string gutter: "#575757"; + readonly property string greenStart: "#39A38F"; + readonly property string greenEnd: "#1FC6A6"; + readonly property string yellow: "#C0C000"; + readonly property string fill: "#55000000"; + readonly property string icon: (muted || clipping) ? mutedColor : gated ? gatedColor : unmutedColor; + } + + Item { + id: icon; + width: parent.width - bar.width - bar.anchors.leftMargin; + height: parent.height - 4; + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + + Item { + anchors.fill: parent + opacity: mouseArea.containsMouse ? 1.0 : 0.7 + Image { + id: image; + source: (pushToTalk) ? pushToTalkIcon : muted ? mutedIcon : + clipping ? clippingIcon : gated ? gatedIcon : unmutedIcon; + anchors.fill: parent + fillMode: Image.PreserveAspectFit + } + + ColorOverlay { + id: imageOverlay + anchors { fill: image } + source: image; + color: pushToTalk ? (pushingToTalk ? colors.unmutedColor : colors.mutedColor) : colors.icon; + } + } + } + + Item { + id: bar; + + anchors { + left: icon.right; + leftMargin: 0; + verticalCenter: icon.verticalCenter; + } + + width: 6; + height: parent.height - 12; + + Rectangle { // base + id: baseBar + radius: 4; + anchors { fill: parent } + color: colors.gutter; + } + + Rectangle { // mask + id: mask; + height: micBar.muted ? parent.height : parent.height * level; + color: micBar.muted ? colors.mutedColor : "white" + width: parent.width; + radius: 5; + anchors { + bottom: parent.bottom; + bottomMargin: 0; + left: parent.left; + leftMargin: 0; + } + } + + LinearGradient { + anchors { fill: mask } + visible: mask.visible && !micBar.muted + source: mask + start: Qt.point(0, 0); + end: Qt.point(0, bar.height); + rotation: 180 + gradient: Gradient { + GradientStop { + position: 0.0; + color: colors.greenStart; + } + GradientStop { + position: 0.5; + color: colors.greenEnd; + } + GradientStop { + position: 1.0; + color: colors.yellow; + } + } + } + } +} diff --git a/interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-clip-i.svg b/interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-clip-i.svg new file mode 100644 index 0000000000..f912c1e744 --- /dev/null +++ b/interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-clip-i.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-gate-i.svg b/interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-gate-i.svg new file mode 100644 index 0000000000..8255174532 --- /dev/null +++ b/interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-gate-i.svg @@ -0,0 +1,3 @@ + + + diff --git a/interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-mute-a.svg b/interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-mute-a.svg new file mode 100644 index 0000000000..67eafc27c8 --- /dev/null +++ b/interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-mute-a.svg @@ -0,0 +1,3 @@ + + + diff --git a/interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-mute-i.svg b/interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-mute-i.svg new file mode 100644 index 0000000000..63af1b0da8 --- /dev/null +++ b/interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-mute-i.svg @@ -0,0 +1,3 @@ + + + diff --git a/interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-ptt-a.svg b/interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-ptt-a.svg new file mode 100644 index 0000000000..e6df3c69d7 --- /dev/null +++ b/interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-ptt-a.svg @@ -0,0 +1 @@ +mic-ptt-a \ No newline at end of file diff --git a/interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-ptt-i.svg b/interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-ptt-i.svg new file mode 100644 index 0000000000..2141ea5229 --- /dev/null +++ b/interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-ptt-i.svg @@ -0,0 +1,24 @@ + + + + + + diff --git a/interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-unmute-a.svg b/interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-unmute-a.svg new file mode 100644 index 0000000000..0bf7677017 --- /dev/null +++ b/interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-unmute-a.svg @@ -0,0 +1,3 @@ + + + diff --git a/interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-unmute-i.svg b/interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-unmute-i.svg new file mode 100644 index 0000000000..0bf7677017 --- /dev/null +++ b/interface/resources/qml/hifi/simplifiedUI/inputDeviceButton/images/mic-unmute-i.svg @@ -0,0 +1,3 @@ + + + diff --git a/interface/resources/qml/hifi/simplifiedUI/settingsApp/SettingsApp.qml b/interface/resources/qml/hifi/simplifiedUI/settingsApp/SettingsApp.qml new file mode 100644 index 0000000000..ec4f1b3bd5 --- /dev/null +++ b/interface/resources/qml/hifi/simplifiedUI/settingsApp/SettingsApp.qml @@ -0,0 +1,147 @@ +// +// SettingsApp.qml +// +// Created by Zach Fox on 2019-05-02 +// Copyright 2019 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.10 +import "../simplifiedConstants" as SimplifiedConstants +import stylesUit 1.0 as HifiStylesUit +import "./audio" as AudioSettings +import "./general" as GeneralSettings +import "./vr" as VrSettings + +Rectangle { + property string activeTabView: "generalTabView" + id: root + color: simplifiedUI.colors.darkBackground + anchors.fill: parent + + SimplifiedConstants.SimplifiedConstants { + id: simplifiedUI + } + + + Rectangle { + id: tabContainer + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + height: 64 + color: simplifiedUI.colors.highlightOnDark + + ListModel { + id: tabListModel + + ListElement { + tabTitle: "General" + tabViewName: "generalTabView" + } + ListElement { + tabTitle: "Audio" + tabViewName: "audioTabView" + } + ListElement { + tabTitle: "VR" + tabViewName: "vrTabView" + } + } + + + Component { + id: highlightBar + Rectangle { + color: simplifiedUI.colors.darkBackground + } + } + + + ListView { + id: tabListView + anchors.fill: parent + contentHeight: parent.height + contentWidth: childrenRect.width + orientation: ListView.Horizontal + model: tabListModel + highlight: highlightBar + interactive: contentItem.width > width + delegate: Item { + width: tabTitleText.paintedWidth + 64 + height: parent.height + + HifiStylesUit.GraphikRegular { + id: tabTitleText + color: simplifiedUI.colors.text.white + anchors.fill: parent + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + text: model.tabTitle + size: 24 + } + + MouseArea { + anchors.fill: parent + onClicked: { + tabListView.currentIndex = index; + root.activeTabView = model.tabViewName; + } + } + } + } + } + + Item { + id: tabViewContainers + anchors.top: tabContainer.bottom + anchors.left: parent.left + anchors.leftMargin: 26 + anchors.right: parent.right + anchors.rightMargin: 26 + anchors.bottom: parent.bottom + + + GeneralSettings.General { + id: generalTabViewContainer + visible: activeTabView === "generalTabView" + anchors.fill: parent + onSendNameTagInfo: { + sendToScript(message); + } + } + + + AudioSettings.Audio { + id: audioTabViewContainer + visible: activeTabView === "audioTabView" + anchors.fill: parent + } + + VrSettings.VR { + id: vrTabViewContainer + visible: activeTabView === "vrTabView" + anchors.fill: parent + } + } + + Image { + source: "../images/accent.svg" + anchors.right: parent.right + anchors.bottom: parent.bottom + width: 94 + height: 175 + } + + + function fromScript(message) { + switch (message.method) { + default: + console.log('SettingsApp.qml: Unrecognized message from JS'); + break; + } + } + signal sendToScript(var message); +} diff --git a/interface/resources/qml/hifi/simplifiedUI/settingsApp/audio/Audio.qml b/interface/resources/qml/hifi/simplifiedUI/settingsApp/audio/Audio.qml new file mode 100644 index 0000000000..a5c884c6ac --- /dev/null +++ b/interface/resources/qml/hifi/simplifiedUI/settingsApp/audio/Audio.qml @@ -0,0 +1,405 @@ +// +// Audio.qml +// +// Created by Zach Fox on 2019-05-06 +// Copyright 2019 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.10 +import QtQuick.Controls 2.3 +import "../../simplifiedConstants" as SimplifiedConstants +import "../../simplifiedControls" as SimplifiedControls +import stylesUit 1.0 as HifiStylesUit +import QtQuick.Layouts 1.3 + +Flickable { + id: root; + contentWidth: parent.width; + contentHeight: audioColumnLayout.height; + topMargin: 16 + bottomMargin: 16 + clip: true; + + function changePeakValuesEnabled(enabled) { + if (!enabled) { + AudioScriptingInterface.devices.input.peakValuesEnabled = true; + } + } + + onVisibleChanged: { + AudioScriptingInterface.devices.input.peakValuesEnabled = visible; + if (visible) { + AudioScriptingInterface.devices.input.peakValuesEnabledChanged.connect(changePeakValuesEnabled); + } else { + AudioScriptingInterface.devices.input.peakValuesEnabledChanged.disconnect(changePeakValuesEnabled); + } + } + + + SimplifiedConstants.SimplifiedConstants { + id: simplifiedUI + } + + ColumnLayout { + id: audioColumnLayout + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + spacing: simplifiedUI.margins.settings.spacingBetweenSettings + + ColumnLayout { + id: volumeControlsContainer + Layout.preferredWidth: parent.width + spacing: 0 + + HifiStylesUit.GraphikRegular { + id: volumeControlsTitle + text: "Volume Controls" + Layout.maximumWidth: parent.width + height: paintedHeight + size: 22 + color: simplifiedUI.colors.text.white + } + + HifiStylesUit.GraphikRegular { + id: volumeControlsSubtitle + Layout.topMargin: simplifiedUI.margins.settings.subtitleTopMargin + text: "Set your HQ's audio output levels. Change \"People Volume\" to control how loud others sound to you." + wrapMode: Text.Wrap + Layout.maximumWidth: parent.width + height: paintedHeight + size: 14 + color: simplifiedUI.colors.text.darkGrey + } + + SimplifiedControls.Slider { + id: peopleVolume + anchors.left: parent.left + anchors.right: parent.right + Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin + height: 30 + labelText: "People Volume" + from: -60 + to: 10 + defaultValue: 0.0 + value: AudioScriptingInterface.getAvatarGain() + live: true + onValueChanged: { + if (AudioScriptingInterface.getAvatarGain() != peopleVolume.value) { + AudioScriptingInterface.setAvatarGain(peopleVolume.value); + } + } + } + + SimplifiedControls.Slider { + id: environmentVolume + anchors.left: parent.left + anchors.right: parent.right + Layout.topMargin: 2 + height: 30 + labelText: "Environment Volume" + from: -60 + to: 10 + defaultValue: 0.0 + value: AudioScriptingInterface.getInjectorGain() + live: true + onValueChanged: { + if (AudioScriptingInterface.getInjectorGain() != environmentVolume.value) { + AudioScriptingInterface.setInjectorGain(environmentVolume.value); + } + } + } + + SimplifiedControls.Slider { + id: systemSoundVolume + anchors.left: parent.left + anchors.right: parent.right + Layout.topMargin: 2 + height: 30 + labelText: "System Sound Volume" + from: -60 + to: 10 + defaultValue: 0.0 + value: AudioScriptingInterface.getSystemInjectorGain() + live: true + onValueChanged: { + if (AudioScriptingInterface.getSystemInjectorGain() != systemSoundVolume.value) { + AudioScriptingInterface.setSystemInjectorGain(systemSoundVolume.value); + } + } + } + } + + ColumnLayout { + id: micControlsContainer + Layout.preferredWidth: parent.width + spacing: 0 + + HifiStylesUit.GraphikRegular { + id: micControlsTitle + text: "Default Mute Controls" + Layout.maximumWidth: parent.width + height: paintedHeight + size: 22 + color: simplifiedUI.colors.text.white + } + + HifiStylesUit.GraphikRegular { + id: micControlsSubtitle + Layout.topMargin: simplifiedUI.margins.settings.subtitleTopMargin + text: "These settings let you configure how you communicate with others in your HQ while in Desktop mode. Push to Talk works like a walkie-talkie!" + wrapMode: Text.Wrap + Layout.maximumWidth: parent.width + height: paintedHeight + size: 14 + color: simplifiedUI.colors.text.darkGrey + } + + ColumnLayout { + id: micControlsSwitchGroup + Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin + + SimplifiedControls.Switch { + id: muteMicrophoneSwitch + width: parent.width + height: simplifiedUI.sizes.controls.simplifiedSwitch.switchBackgroundHeight + labelTextOn: "Mute Microphone" + checked: AudioScriptingInterface.mutedDesktop + onClicked: { + AudioScriptingInterface.mutedDesktop = !AudioScriptingInterface.mutedDesktop; + } + } + + SimplifiedControls.Switch { + id: pushToTalkSwitch + width: parent.width + height: simplifiedUI.sizes.controls.simplifiedSwitch.switchBackgroundHeight + labelTextOn: "Push to Talk - Press and Hold \"T\" to Talk" + checked: AudioScriptingInterface.pushToTalkDesktop + onClicked: { + AudioScriptingInterface.pushToTalkDesktop = !AudioScriptingInterface.pushToTalkDesktop; + } + } + } + } + + ColumnLayout { + id: inputDeviceContainer + Layout.preferredWidth: parent.width + spacing: 0 + + HifiStylesUit.GraphikRegular { + id: inputDeviceTitle + text: "Which input device?" + Layout.maximumWidth: parent.width + height: paintedHeight + size: 22 + color: simplifiedUI.colors.text.white + } + + HifiStylesUit.GraphikRegular { + id: inputDeviceSubtitle + Layout.topMargin: simplifiedUI.margins.settings.subtitleTopMargin + text: "Here are all of the input devices and microphones that we found. Select the one you'd like to use in your HQ while in Desktop mode." + wrapMode: Text.Wrap + Layout.maximumWidth: parent.width + height: paintedHeight + size: 14 + color: simplifiedUI.colors.text.darkGrey + } + + ButtonGroup { id: inputDeviceButtonGroup } + + ListView { + id: inputDeviceListView; + anchors.left: parent.left + anchors.right: parent.right + Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin + interactive: false; + height: contentItem.height; + spacing: 4; + clip: true; + model: AudioScriptingInterface.devices.input; + delegate: Item { + width: parent.width + height: inputDeviceCheckbox.height + + SimplifiedControls.RadioButton { + id: inputDeviceCheckbox + anchors.left: parent.left + width: parent.width - inputLevel.width + checked: selectedDesktop; + text: model.devicename + ButtonGroup.group: inputDeviceButtonGroup + onClicked: { + AudioScriptingInterface.setStereoInput(false); // the next selected audio device might not support stereo + AudioScriptingInterface.setInputDevice(model.info, false); // `false` argument for Desktop mode setting + } + } + + SimplifiedControls.InputPeak { + id: inputLevel + showMuted: AudioScriptingInterface.mutedDesktop + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + peak: model.peak; + visible: AudioScriptingInterface.devices.input.peakValuesAvailable; + } + } + } + + SimplifiedControls.Button { + property bool audioLoopedBack: AudioScriptingInterface.getLocalEcho() + + function startAudioLoopback() { + if (!audioLoopedBack) { + audioLoopedBack = true; + AudioScriptingInterface.setLocalEcho(true); + } + } + function stopAudioLoopback() { + if (audioLoopedBack) { + audioLoopedBack = false; + AudioScriptingInterface.setLocalEcho(false); + } + } + + Timer { + id: loopbackTimer + interval: 8000; + running: false; + repeat: false; + onTriggered: { + stopAudioLoopback(); + } + } + + id: testYourMicButton + enabled: !HMD.active + anchors.left: parent.left + Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin + width: 160 + height: 32 + text: audioLoopedBack ? "STOP TESTING" : "TEST YOUR MIC" + onClicked: { + if (audioLoopedBack) { + loopbackTimer.stop(); + stopAudioLoopback(); + } else { + loopbackTimer.restart(); + startAudioLoopback(); + } + } + } + } + + ColumnLayout { + id: outputDeviceContainer + Layout.preferredWidth: parent.width + spacing: 0 + + HifiStylesUit.GraphikRegular { + id: outputDeviceTitle + text: "Which output device?" + Layout.maximumWidth: parent.width + height: paintedHeight + size: 22 + color: simplifiedUI.colors.text.white + } + + HifiStylesUit.GraphikRegular { + id: outputDeviceSubtitle + Layout.topMargin: simplifiedUI.margins.settings.subtitleTopMargin + text: "Here are all of the output devices that we found. Select the one you'd like to use in your HQ while in Desktop mode." + wrapMode: Text.Wrap + Layout.maximumWidth: parent.width + height: paintedHeight + size: 14 + color: simplifiedUI.colors.text.darkGrey + } + + ButtonGroup { id: outputDeviceButtonGroup } + + ListView { + id: outputDeviceListView; + anchors.left: parent.left + anchors.right: parent.right + Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin + interactive: false; + height: contentItem.height; + spacing: 4; + clip: true; + model: AudioScriptingInterface.devices.output; + delegate: Item { + width: parent.width + height: outputDeviceCheckbox.height + + SimplifiedControls.RadioButton { + id: outputDeviceCheckbox + anchors.left: parent.left + width: parent.width + checked: selectedDesktop; + text: model.devicename + ButtonGroup.group: outputDeviceButtonGroup + onClicked: { + AudioScriptingInterface.setOutputDevice(model.info, false); // `false` argument for Desktop mode setting + } + } + } + } + + SimplifiedControls.Button { + property var sound: null; + property var sample: null; + property bool isPlaying: false; + function createSampleSound() { + sound = ApplicationInterface.getSampleSound(); + sample = null; + } + function playSound() { + // FIXME: MyAvatar is not properly exposed to QML; MyAvatar.qmlPosition is a stopgap + // FIXME: AudioScriptingInterface.playSystemSound should not require position + if (sample === null && !isPlaying) { + sample = AudioScriptingInterface.playSystemSound(sound, MyAvatar.qmlPosition); + isPlaying = true; + sample.finished.connect(reset); + } + } + function stopSound() { + if (sample && isPlaying) { + sample.stop(); + } + } + + function reset() { + sample.finished.disconnect(reset); + isPlaying = false; + sample = null; + } + + Component.onCompleted: createSampleSound(); + Component.onDestruction: stopSound(); + + onVisibleChanged: { + if (!visible) { + stopSound(); + } + } + + id: testYourSoundButton + enabled: !HMD.active + anchors.left: parent.left + Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin + width: 160 + height: 32 + text: isPlaying ? "STOP TESTING" : "TEST YOUR SOUND" + onClicked: { + isPlaying ? stopSound() : playSound(); + } + } + } + } +} diff --git a/interface/resources/qml/hifi/simplifiedUI/settingsApp/general/General.qml b/interface/resources/qml/hifi/simplifiedUI/settingsApp/general/General.qml new file mode 100644 index 0000000000..15e526fd19 --- /dev/null +++ b/interface/resources/qml/hifi/simplifiedUI/settingsApp/general/General.qml @@ -0,0 +1,236 @@ +// +// General.qml +// +// Created by Zach Fox on 2019-05-06 +// Copyright 2019 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.10 +import "../../simplifiedConstants" as SimplifiedConstants +import "../../simplifiedControls" as SimplifiedControls +import stylesUit 1.0 as HifiStylesUit +import QtQuick.Layouts 1.3 + +Flickable { + property string avatarNametagMode: Settings.getValue("simplifiedNametag/avatarNametagMode", "on"); + id: root; + contentWidth: parent.width; + contentHeight: generalColumnLayout.height; + topMargin: 16 + bottomMargin: 16 + clip: true; + + onAvatarNametagModeChanged: { + sendNameTagInfo({method: 'handleAvatarNametagMode', avatarNametagMode: root.avatarNametagMode, source: "SettingsApp.qml"}); + } + + SimplifiedConstants.SimplifiedConstants { + id: simplifiedUI + } + + ColumnLayout { + id: generalColumnLayout + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + spacing: simplifiedUI.margins.settings.spacingBetweenSettings + + ColumnLayout { + id: avatarNameTagsContainer + Layout.preferredWidth: parent.width + spacing: 0 + + HifiStylesUit.GraphikRegular { + id: avatarNameTagsTitle + text: "Avatar Name Tags" + Layout.maximumWidth: parent.width + height: paintedHeight + size: 22 + color: simplifiedUI.colors.text.white + } + + HifiStylesUit.GraphikRegular { + id: avatarNameTagsSubtitle + Layout.topMargin: simplifiedUI.margins.settings.subtitleTopMargin + text: "Control how nametags appear over other peoples' heads in your HQ. \"Click to View\" allows you to click anyone to see their name." + wrapMode: Text.Wrap + Layout.maximumWidth: parent.width + height: paintedHeight + size: 14 + color: simplifiedUI.colors.text.darkGrey + } + + ColumnLayout { + id: avatarNameTagsRadioButtonGroup + Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin + + SimplifiedControls.RadioButton { + id: avatarNameTagsOff + text: "Off" + checked: root.avatarNametagMode === "off" + onClicked: { + root.avatarNametagMode = "off" + } + } + + SimplifiedControls.RadioButton { + id: avatarNameTagsAlwaysOn + text: "Always On" + checked: root.avatarNametagMode === "alwaysOn" + onClicked: { + root.avatarNametagMode = "alwaysOn" + } + } + + SimplifiedControls.RadioButton { + id: avatarNameTagsClickToView + text: "Click to View" + checked: root.avatarNametagMode === "on" + onClicked: { + root.avatarNametagMode = "on" + } + } + } + } + + ColumnLayout { + id: performanceContainer + Layout.preferredWidth: parent.width + spacing: 0 + + HifiStylesUit.GraphikRegular { + id: performanceTitle + text: "Performance" + Layout.maximumWidth: parent.width + height: paintedHeight + size: 22 + color: simplifiedUI.colors.text.white + } + + HifiStylesUit.GraphikRegular { + id: performanceSubtitle + Layout.topMargin: simplifiedUI.margins.settings.subtitleTopMargin + text: "Modify how this application uses system resources and impacts battery life." + wrapMode: Text.Wrap + Layout.maximumWidth: parent.width + height: paintedHeight + size: 14 + color: simplifiedUI.colors.text.darkGrey + } + + ColumnLayout { + id: performanceRadioButtonGroup + Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin + + SimplifiedControls.RadioButton { + id: performanceLow + text: "Eco" + } + + SimplifiedControls.RadioButton { + id: performanceMedium + text: "Interactive" + } + + SimplifiedControls.RadioButton { + id: performanceHigh + text: "Realtime" + } + } + } + + ColumnLayout { + id: cameraContainer + Layout.preferredWidth: parent.width + spacing: 0 + + HifiStylesUit.GraphikRegular { + id: cameraTitle + text: "Camera View" + Layout.maximumWidth: parent.width + height: paintedHeight + size: 22 + color: simplifiedUI.colors.text.white + } + + HifiStylesUit.GraphikRegular { + id: cameraSubtitle + Layout.topMargin: simplifiedUI.margins.settings.subtitleTopMargin + text: "Change your point of view by selecting either first or third person view. Try scrolling your mouse wheel." + wrapMode: Text.Wrap + Layout.maximumWidth: parent.width + height: paintedHeight + size: 14 + color: simplifiedUI.colors.text.darkGrey + } + + ColumnLayout { + id: cameraRadioButtonGroup + Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin + + SimplifiedControls.RadioButton { + id: firstPerson + text: "First Person View" + checked: Camera.mode === "first person" + onClicked: { + Camera.mode = "first person" + } + } + + SimplifiedControls.RadioButton { + id: thirdPerson + text: "Third Person View" + checked: Camera.mode === "third person" + onClicked: { + Camera.mode = "third person" + } + } + + Connections { + target: Camera; + + onModeUpdated: { + if (Camera.mode === "first person") { + firstPerson.checked = true + } else if (Camera.mode === "third person") { + thirdPerson.checked = true + } + } + } + } + } + + HifiStylesUit.GraphikRegular { + id: logoutText + text: (AccountServices.username === "Unknown user" ? "Log In" : "Logout " + AccountServices.username) + wrapMode: Text.Wrap + width: paintedWidth + height: paintedHeight + size: 22 + color: simplifiedUI.colors.text.lightBlue + + MouseArea { + anchors.fill: parent + hoverEnabled: true + onEntered: { + parent.color = simplifiedUI.colors.text.lightBlueHover; + } + onExited: { + parent.color = simplifiedUI.colors.text.lightBlue; + } + onClicked: { + if (Account.loggedIn) { + AccountServices.logOut(); + } else { + DialogsManager.showLoginDialog(); + } + } + } + } + } + + signal sendNameTagInfo(var message); +} diff --git a/interface/resources/qml/hifi/simplifiedUI/settingsApp/vr/VR.qml b/interface/resources/qml/hifi/simplifiedUI/settingsApp/vr/VR.qml new file mode 100644 index 0000000000..96323f7cae --- /dev/null +++ b/interface/resources/qml/hifi/simplifiedUI/settingsApp/vr/VR.qml @@ -0,0 +1,418 @@ +// +// VR.qml +// +// Created by Zach Fox on 2019-05-08 +// Copyright 2019 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.10 +import QtQuick.Controls 2.3 +import "../../simplifiedConstants" as SimplifiedConstants +import "../../simplifiedControls" as SimplifiedControls +import stylesUit 1.0 as HifiStylesUit +import QtQuick.Layouts 1.3 + +Flickable { + id: root; + contentWidth: parent.width; + contentHeight: vrColumnLayout.height; + topMargin: 16 + bottomMargin: 16 + clip: true; + + function changePeakValuesEnabled(enabled) { + if (!enabled) { + AudioScriptingInterface.devices.input.peakValuesEnabled = true; + } + } + + onVisibleChanged: { + AudioScriptingInterface.devices.input.peakValuesEnabled = visible; + if (visible) { + AudioScriptingInterface.devices.input.peakValuesEnabledChanged.connect(changePeakValuesEnabled); + } else { + AudioScriptingInterface.devices.input.peakValuesEnabledChanged.disconnect(changePeakValuesEnabled); + } + } + + + SimplifiedConstants.SimplifiedConstants { + id: simplifiedUI + } + + ColumnLayout { + id: vrColumnLayout + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + spacing: simplifiedUI.margins.settings.spacingBetweenSettings + + ColumnLayout { + id: controlsContainer + Layout.preferredWidth: parent.width + spacing: 0 + + HifiStylesUit.GraphikRegular { + id: controlsTitle + text: "VR Movement Controls" + Layout.maximumWidth: parent.width + height: paintedHeight + size: 22 + color: simplifiedUI.colors.text.white + } + + HifiStylesUit.GraphikRegular { + id: controlsSubtitle + Layout.topMargin: simplifiedUI.margins.settings.subtitleTopMargin + text: "Everyone responds to VR movement differently. Choose the setting that is most comfortable for you. Try using \"Default\" first." + wrapMode: Text.Wrap + Layout.maximumWidth: parent.width + height: paintedHeight + size: 14 + color: simplifiedUI.colors.text.darkGrey + } + + ColumnLayout { + id: controlsRadioButtonGroup + width: parent.width + Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin + + ButtonGroup { id: controlsButtonGroup } + + SimplifiedControls.RadioButton { + id: controlsDefault + text: "Default" + ButtonGroup.group: controlsButtonGroup + checked: MyAvatar.getControlScheme() === 0 + onClicked: { + MyAvatar.setControlScheme(0); + } + } + + SimplifiedControls.RadioButton { + id: controlsAnalog + text: "Analog" + ButtonGroup.group: controlsButtonGroup + checked: MyAvatar.getControlScheme() === 1 + onClicked: { + MyAvatar.setControlScheme(1); + } + } + + Item { + id: controlsAdvancedContainer + Layout.minimumWidth: parent.width + Layout.minimumHeight: 14 + + SimplifiedControls.RadioButton { + id: controlsAdvanced + text: "Advanced" + ButtonGroup.group: controlsButtonGroup + checked: MyAvatar.getControlScheme() === 2 + onClicked: { + MyAvatar.setControlScheme(2); + } + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: parent.left + height: 14 + } + + SimplifiedControls.Slider { + id: controlsAdvancedMovementSpeed + anchors.top: parent.top + anchors.topMargin: 4 // For perfect alignment + anchors.bottom: parent.bottom + anchors.right: parent.right + width: 300 + height: 14 + labelText: "Movement Speed" + labelTextColor: simplifiedUI.colors.text.darkGrey + from: 3 + to: 30 + defaultValue: 6 + value: MyAvatar.analogPlusWalkSpeed + live: true + onValueChanged: { + if (MyAvatar.analogPlusWalkSpeed != controlsAdvancedMovementSpeed.value) { + MyAvatar.analogPlusWalkSpeed = controlsAdvancedMovementSpeed.value; + } + } + } + } + } + } + + ColumnLayout { + id: micControlsContainer + Layout.preferredWidth: parent.width + spacing: 0 + + HifiStylesUit.GraphikRegular { + id: micControlsTitle + text: "Default Mute Controls" + Layout.maximumWidth: parent.width + height: paintedHeight + size: 22 + color: simplifiedUI.colors.text.white + } + + HifiStylesUit.GraphikRegular { + id: micControlsSubtitle + Layout.topMargin: simplifiedUI.margins.settings.subtitleTopMargin + text: "These settings let you configure how you communicate with others in your HQ while in VR mode. Push to Talk works like a walkie-talkie!" + wrapMode: Text.Wrap + Layout.maximumWidth: parent.width + height: paintedHeight + size: 14 + color: simplifiedUI.colors.text.darkGrey + } + + ColumnLayout { + id: micControlsSwitchGroup + Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin + + SimplifiedControls.Switch { + id: muteMicrophoneSwitch + width: parent.width + height: simplifiedUI.sizes.controls.simplifiedSwitch.switchBackgroundHeight + labelTextOn: "Mute Microphone" + checked: AudioScriptingInterface.mutedHMD + onClicked: { + AudioScriptingInterface.mutedHMD = !AudioScriptingInterface.mutedHMD; + } + } + + SimplifiedControls.Switch { + id: pushToTalkSwitch + width: parent.width + height: simplifiedUI.sizes.controls.simplifiedSwitch.switchBackgroundHeight + labelTextOn: "Push to Talk - Press and Hold Grip Triggers to Talk" + checked: AudioScriptingInterface.pushToTalkHMD + onClicked: { + AudioScriptingInterface.pushToTalkHMD = !AudioScriptingInterface.pushToTalkHMD; + } + } + } + } + + ColumnLayout { + id: inputDeviceContainer + Layout.preferredWidth: parent.width + spacing: 0 + + HifiStylesUit.GraphikRegular { + id: inputDeviceTitle + text: "Which input device?" + Layout.maximumWidth: parent.width + height: paintedHeight + size: 22 + color: simplifiedUI.colors.text.white + } + + HifiStylesUit.GraphikRegular { + id: inputDeviceSubtitle + Layout.topMargin: simplifiedUI.margins.settings.subtitleTopMargin + text: "Here are all of the input devices and microphones that we found. Select the one you'd like to use in your HQ while in VR mode." + wrapMode: Text.Wrap + Layout.maximumWidth: parent.width + height: paintedHeight + size: 14 + color: simplifiedUI.colors.text.darkGrey + } + + ButtonGroup { id: inputDeviceButtonGroup } + + ListView { + id: inputDeviceListView; + anchors.left: parent.left + anchors.right: parent.right + Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin + interactive: false; + height: contentItem.height; + spacing: 4; + clip: true; + model: AudioScriptingInterface.devices.input; + delegate: Item { + width: parent.width + height: inputDeviceCheckbox.height + + SimplifiedControls.RadioButton { + id: inputDeviceCheckbox + anchors.left: parent.left + width: parent.width - inputLevel.width + checked: selectedHMD; + text: model.devicename + ButtonGroup.group: inputDeviceButtonGroup + onClicked: { + AudioScriptingInterface.setStereoInput(false); // the next selected audio device might not support stereo + AudioScriptingInterface.setInputDevice(model.info, true); // `true` argument for HMD mode setting + } + } + + SimplifiedControls.InputPeak { + id: inputLevel + showMuted: AudioScriptingInterface.mutedHMD + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + peak: model.peak; + visible: AudioScriptingInterface.devices.input.peakValuesAvailable; + } + } + } + + SimplifiedControls.Button { + property bool audioLoopedBack: AudioScriptingInterface.getLocalEcho() + + function startAudioLoopback() { + if (!audioLoopedBack) { + audioLoopedBack = true; + AudioScriptingInterface.setLocalEcho(true); + } + } + function stopAudioLoopback() { + if (audioLoopedBack) { + audioLoopedBack = false; + AudioScriptingInterface.setLocalEcho(false); + } + } + + Timer { + id: loopbackTimer + interval: 8000; + running: false; + repeat: false; + onTriggered: { + stopAudioLoopback(); + } + } + + id: testYourMicButton + enabled: HMD.active + anchors.left: parent.left + Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin + width: 160 + height: 32 + text: audioLoopedBack ? "STOP TESTING" : "TEST YOUR MIC" + onClicked: { + if (audioLoopedBack) { + loopbackTimer.stop(); + stopAudioLoopback(); + } else { + loopbackTimer.restart(); + startAudioLoopback(); + } + } + } + } + + ColumnLayout { + id: outputDeviceContainer + Layout.preferredWidth: parent.width + spacing: 0 + + HifiStylesUit.GraphikRegular { + id: outputDeviceTitle + text: "Which output device?" + Layout.maximumWidth: parent.width + height: paintedHeight + size: 22 + color: simplifiedUI.colors.text.white + } + + HifiStylesUit.GraphikRegular { + id: outputDeviceSubtitle + Layout.topMargin: simplifiedUI.margins.settings.subtitleTopMargin + text: "Here are all of the output devices that we found. Select the one you'd like to use in your HQ while in VR mode." + wrapMode: Text.Wrap + Layout.maximumWidth: parent.width + height: paintedHeight + size: 14 + color: simplifiedUI.colors.text.darkGrey + } + + ButtonGroup { id: outputDeviceButtonGroup } + + ListView { + id: outputDeviceListView; + anchors.left: parent.left + anchors.right: parent.right + Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin + interactive: false; + height: contentItem.height; + spacing: 4; + clip: true; + model: AudioScriptingInterface.devices.output; + delegate: Item { + width: parent.width + height: outputDeviceCheckbox.height + + SimplifiedControls.RadioButton { + id: outputDeviceCheckbox + anchors.left: parent.left + width: parent.width + checked: selectedDesktop; + text: model.devicename + ButtonGroup.group: outputDeviceButtonGroup + onClicked: { + AudioScriptingInterface.setOutputDevice(model.info, true); // `false` argument for Desktop mode setting + } + } + } + } + + SimplifiedControls.Button { + property var sound: null; + property var sample: null; + property bool isPlaying: false; + function createSampleSound() { + sound = ApplicationInterface.getSampleSound(); + sample = null; + } + function playSound() { + // FIXME: MyAvatar is not properly exposed to QML; MyAvatar.qmlPosition is a stopgap + // FIXME: AudioScriptingInterface.playSystemSound should not require position + if (sample === null && !isPlaying) { + sample = AudioScriptingInterface.playSystemSound(sound, MyAvatar.qmlPosition); + isPlaying = true; + sample.finished.connect(reset); + } + } + function stopSound() { + if (sample && isPlaying) { + sample.stop(); + } + } + + function reset() { + sample.finished.disconnect(reset); + isPlaying = false; + sample = null; + } + + Component.onCompleted: createSampleSound(); + Component.onDestruction: stopSound(); + + onVisibleChanged: { + if (!visible) { + stopSound(); + } + } + + id: testYourSoundButton + enabled: HMD.active + anchors.left: parent.left + Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin + width: 160 + height: 32 + text: isPlaying ? "STOP TESTING" : "TEST YOUR SOUND" + onClicked: { + isPlaying ? stopSound() : playSound(); + } + } + } + } +} diff --git a/interface/resources/qml/hifi/simplifiedUI/simplifiedConstants/SimplifiedConstants.qml b/interface/resources/qml/hifi/simplifiedUI/simplifiedConstants/SimplifiedConstants.qml new file mode 100644 index 0000000000..c2b9d1d6c6 --- /dev/null +++ b/interface/resources/qml/hifi/simplifiedUI/simplifiedConstants/SimplifiedConstants.qml @@ -0,0 +1,169 @@ +// +// SimplifiedConstants.qml +// +// Created by Zach Fox on 2019-05-02 +// Copyright 2019 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.10 +QtObject { + readonly property QtObject colors: QtObject { + readonly property QtObject text: QtObject { + readonly property color almostWhite: "#FAFAFA" + readonly property color lightGrey: "#CCCCCC" + readonly property color darkGrey: "#8F8F8F" + readonly property color white: "#FFFFFF" + readonly property color lightBlue: "#00B4EF" + readonly property color lightBlueHover: "#3dcfff" + } + + readonly property QtObject controls: QtObject { + readonly property QtObject radioButton: QtObject { + readonly property QtObject checked: QtObject { + readonly property color startColor: "#7d7d7d" + readonly property color checkboxFinish: "#6b6a6b" + } + readonly property QtObject unchecked: QtObject { + readonly property color startColor: "#7d7d7d" + readonly property color checkboxFinish: "#6b6a6b" + } + } + readonly property QtObject slider: QtObject { + readonly property QtObject background: QtObject { + readonly property color empty: "#252525" + readonly property QtObject filled: QtObject { + readonly property color start: "#0093C5" + readonly property color finish: "#00B4EF" + } + } + readonly property QtObject handle: QtObject { + readonly property color border: "#000000" + readonly property QtObject normal: QtObject { + readonly property color start: "#828282" + readonly property color finish: "#6A6A6A" + } + readonly property QtObject pressed: QtObject { + readonly property color start: "#6A6A6A" + readonly property color finish: "#828282" + } + } + } + readonly property QtObject simplifiedSwitch: QtObject { + readonly property QtObject background: QtObject { + readonly property color off: "#252525" + readonly property color hover: "#00b4ef" + readonly property color pressed: "#ffffff" + readonly property color on: "#ffffff" + } + readonly property QtObject handle: QtObject { + readonly property color off: "#6A6A6A" + readonly property color hover: "#00b4ef" + readonly property color pressed: "#0093C5" + readonly property color on: "#0093C5" + } + readonly property QtObject text: QtObject { + readonly property color off: "#8F8F8F" + readonly property color on: "#ffffff" + } + } + readonly property QtObject button: QtObject { + readonly property QtObject background: QtObject { + readonly property color disabled: "#191919" + readonly property color enabled: "#191919" + readonly property color hover: "#00B4EF" + readonly property color active: "#00B4EF" + } + readonly property QtObject border: QtObject { + readonly property color disabled: "#8F8F8F" + readonly property color enabled: "#FFFFFF" + readonly property color hover: "#FFFFFF" + readonly property color active: "#FFFFFF" + } + readonly property QtObject text: QtObject { + readonly property color disabled: "#8F8F8F" + readonly property color enabled: "#FFFFFF" + } + } + readonly property QtObject outputVolumeButton: QtObject { + readonly property QtObject text: QtObject { + readonly property color muted: "#b20012" + readonly property color noisy: "#FFFFFF" + } + } + readonly property QtObject inputVolumeButton: QtObject { + readonly property QtObject text: QtObject { + readonly property color muted: "#b20012" + readonly property color noisy: "#FFFFFF" + } + } + } + + readonly property color darkSeparator: "#595959" + readonly property color darkBackground: "#1A1A1A" + readonly property color darkBackgroundHighlight: "#575757" + readonly property color highlightOnDark: Qt.rgba(1, 1, 1, 0.2) + readonly property color white: "#FFFFFF" + } + + readonly property QtObject glyphs: QtObject { + readonly property string gear: "@" + readonly property string editPencil: "\ue00d" + readonly property string playback_play: "\ue01d" + readonly property string stop_square: "\ue01e" + readonly property string hmd: "b" + readonly property string screen: "c" + readonly property string vol_0: "\ue00e" + readonly property string vol_1: "\ue00f" + readonly property string vol_2: "\ue010" + readonly property string vol_3: "\ue011" + readonly property string vol_4: "\ue012" + readonly property string vol_x_0: "\ue013" + readonly property string vol_x_1: "\ue014" + readonly property string vol_x_2: "\ue015" + readonly property string vol_x_3: "\ue016" + readonly property string vol_x_4: "\ue017" + } + + readonly property QtObject margins: QtObject { + readonly property QtObject controls: QtObject { + readonly property QtObject radioButton: QtObject { + readonly property int labelLeftMargin: 6 + } + readonly property QtObject simplifiedSwitch: QtObject { + readonly property int handleMargins: 2 + } + } + + readonly property QtObject settings: QtObject { + property real subtitleTopMargin: 2 + property real settingsGroupTopMargin: 10 + property real spacingBetweenSettings: 24 + } + } + + readonly property QtObject sizes: QtObject { + readonly property QtObject controls: QtObject { + readonly property QtObject slider: QtObject { + readonly property int height: 14 + readonly property int labelTextSize: 14 + readonly property int backgroundHeight: 8 + } + readonly property QtObject simplifiedSwitch: QtObject { + readonly property int switchBackgroundHeight: 18 + readonly property int switchBackgroundWidth: 47 + readonly property int labelTextSize: 14 + readonly property int labelGlyphSize: 32 + } + readonly property QtObject button: QtObject { + readonly property int borderWidth: 1 + readonly property int textPadding: 16 + readonly property int width: 160 + readonly property int height: 32 + readonly property int textSize: 14 + } + } + } +} diff --git a/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Button.qml b/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Button.qml new file mode 100644 index 0000000000..d719c20178 --- /dev/null +++ b/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Button.qml @@ -0,0 +1,106 @@ +// +// Button.qml +// +// Created by Zach Fox on 2019-05-08 +// Copyright 2019 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.10 +import QtQuick.Controls 2.3 as Original +import stylesUit 1.0 as HifiStylesUit +import "../simplifiedConstants" as SimplifiedConstants +import TabletScriptingInterface 1.0 + +Original.Button { + id: root + + SimplifiedConstants.SimplifiedConstants { + id: simplifiedUI + } + + hoverEnabled: true + width: simplifiedUI.sizes.controls.button.width + height: simplifiedUI.sizes.controls.button.height + + onHoveredChanged: { + if (hovered && enabled) { + Tablet.playSound(TabletEnums.ButtonHover); + } + } + + onFocusChanged: { + if (focus && enabled) { + Tablet.playSound(TabletEnums.ButtonHover); + } + } + + onClicked: { + if (enabled) { + Tablet.playSound(TabletEnums.ButtonClick); + } + } + + background: Rectangle { + implicitWidth: root.width + implicitHeight: root.height + color: { + if (root.enabled) { + if (root.hovered) { + simplifiedUI.colors.controls.button.background.enabled + } else if (root.down) { + simplifiedUI.colors.controls.button.background.active + } else { + simplifiedUI.colors.controls.button.background.enabled + } + } else { + simplifiedUI.colors.controls.button.background.disabled + } + } + + border.width: simplifiedUI.sizes.controls.button.borderWidth + border.color: root.enabled ? simplifiedUI.colors.controls.button.border.enabled : simplifiedUI.colors.controls.button.border.disabled + + Item { + clip: true; + visible: root.enabled + anchors.centerIn: parent + width: parent.width - parent.border.width * 2 + height: parent.height - parent.border.width * 2 + + Rectangle { + z: -1 + clip: true + width: root.down ? parent.width * 1.5 : (root.hovered ? parent.width * 9 / 10 : 0) + height: parent.height + anchors.horizontalCenter: parent.horizontalCenter + anchors.horizontalCenterOffset: -14 + color: simplifiedUI.colors.controls.button.background.active + Behavior on width { + enabled: true + SmoothedAnimation { velocity: 400 } + } + transform: Matrix4x4 { + property real a: Math.PI / 4 + matrix: Qt.matrix4x4(1, Math.tan(a), 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1) + } + } + } + } + + contentItem: HifiStylesUit.GraphikMedium { + id: buttonText + topPadding: -2 // Necessary for proper alignment using Graphik Medium + wrapMode: Text.Wrap + color: enabled ? simplifiedUI.colors.controls.button.text.enabled : simplifiedUI.colors.controls.button.text.disabled + size: simplifiedUI.sizes.controls.button.textSize + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + text: root.text + } +} diff --git a/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/InputPeak.qml b/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/InputPeak.qml new file mode 100644 index 0000000000..6ad82895df --- /dev/null +++ b/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/InputPeak.qml @@ -0,0 +1,101 @@ +// +// InputPeak.qml +// +// Created by Zach Pomerantz on 6/20/2017 +// Copyright 2017 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.10 +import QtGraphicalEffects 1.0 + +Item { + property var peak; + property alias showMuted: status.visible + + width: 70; + height: 8; + + QtObject { + id: colors; + + readonly property string unmuted: "#FFF"; + readonly property string muted: "#E2334D"; + readonly property string gutter: "#575757"; + readonly property string greenStart: "#39A38F"; + readonly property string greenEnd: "#1FC6A6"; + readonly property string yellow: "#C0C000"; + readonly property string red: colors.muted; + readonly property string fill: "#55000000"; + } + + + Text { + id: status; + + anchors { + horizontalCenter: parent.horizontalCenter; + verticalCenter: parent.verticalCenter; + } + + visible: false; + color: colors.muted; + + text: "MUTED"; + font.pointSize: 10; + } + + Item { + id: bar; + + width: parent.width; + height: parent.height; + + anchors { fill: parent } + + visible: !status.visible; + + Rectangle { // base + radius: 4; + anchors { fill: parent } + color: colors.gutter; + } + + Rectangle { // mask + id: mask; + width: parent.width * peak; + radius: 5; + anchors { + bottom: parent.bottom; + bottomMargin: 0; + top: parent.top; + topMargin: 0; + left: parent.left; + leftMargin: 0; + } + } + + LinearGradient { + anchors { fill: mask } + source: mask + start: Qt.point(0, 0); + end: Qt.point(bar.width, 0); + gradient: Gradient { + GradientStop { + position: 0; + color: colors.greenStart; + } + GradientStop { + position: 0.5; + color: colors.greenEnd; + } + GradientStop { + position: 1; + color: colors.yellow; + } + } + } + } +} diff --git a/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/RadioButton.qml b/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/RadioButton.qml new file mode 100644 index 0000000000..14508e219f --- /dev/null +++ b/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/RadioButton.qml @@ -0,0 +1,119 @@ +// +// RadioButton.qml +// +// Created by Zach Fox on 2019-05-06 +// Copyright 2019 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.10 +import QtQuick.Controls 2.3 +import TabletScriptingInterface 1.0 +import "../simplifiedConstants" as SimplifiedConstants + +RadioButton { + id: root + + SimplifiedConstants.SimplifiedConstants { + id: simplifiedUI + } + + padding: 0 + property alias labelTextColor: radioButtonLabel.color + property alias labelFontSize: radioButtonLabel.font.pixelSize + property int radioButtonRadius: 14 + property int labelLeftMargin: simplifiedUI.margins.controls.radioButton.labelLeftMargin + property bool wrapLabel: true; + readonly property int checkSize: Math.max(root.radioButtonRadius - 8, 10) + focusPolicy: Qt.ClickFocus + hoverEnabled: true + + onClicked: { + Tablet.playSound(TabletEnums.ButtonClick); + } + + onHoveredChanged: { + if (hovered) { + Tablet.playSound(TabletEnums.ButtonHover); + } + } + + indicator: Rectangle { + id: radioButtonIndicator + implicitWidth: root.radioButtonRadius + implicitHeight: root.radioButtonRadius + radius: root.radioButtonRadius + y: parent.height / 2 - height / 2 + border.width: 1 + border.color: pressed || hovered + ? hifi.colors.checkboxCheckedBorder + : hifi.colors.checkboxDarkFinish + + gradient: Gradient { + GradientStop { + position: 0.2 + color: pressed || hovered + ? hifi.colors.checkboxLightStart + : hifi.colors.checkboxDarkStart + } + GradientStop { + position: 1.0 + color: pressed || hovered + ? hifi.colors.checkboxLightFinish + : hifi.colors.checkboxDarkFinish + } + } + + Rectangle { + id: innerBox + visible: pressed || hovered + anchors.centerIn: parent + width: checkSize - 4 + height: width + radius: checkSize / 2 + color: hifi.colors.checkboxCheckedBorder + } + + Rectangle { + id: check + width: checkSize + height: checkSize + radius: checkSize / 2 + anchors.centerIn: parent + color: hifi.colors.checkboxChecked + border.width: 2 + border.color: hifi.colors.checkboxCheckedBorder + visible: checked && !pressed || !checked && pressed + } + + Rectangle { + id: disabledOverlay + visible: !enabled + width: root.radioButtonRadius + height: root.radioButtonRadius + radius: root.radioButtonRadius / 2 + border.width: 1 + border.color: hifi.colors.baseGrayHighlight + color: hifi.colors.baseGrayHighlight + opacity: 0.5 + } + } + + contentItem: Text { + id: radioButtonLabel + height: root.radioButtonRadius + font.pixelSize: 14 + font.family: "Graphik" + font.weight: Font.Normal + text: root.text + color: simplifiedUI.colors.text.white + x: 2 + wrapMode: root.wrapLabel ? Text.Wrap : Text.NoWrap + elide: root.wrapLabel ? Text.ElideNone : Text.ElideRight + enabled: root.enabled + verticalAlignment: Text.AlignVCenter + leftPadding: radioButtonIndicator.width + root.labelLeftMargin + } +} diff --git a/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Slider.qml b/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Slider.qml new file mode 100644 index 0000000000..20e150340e --- /dev/null +++ b/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Slider.qml @@ -0,0 +1,120 @@ +// +// Slider.qml +// +// Created by Zach Fox on 2019-05-06 +// Copyright 2019 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.10 +import QtQuick.Controls 2.3 +import stylesUit 1.0 as HifiStylesUit +import TabletScriptingInterface 1.0 +import "../simplifiedConstants" as SimplifiedConstants + +Item { + id: root + + SimplifiedConstants.SimplifiedConstants { + id: simplifiedUI + } + + property alias labelText: sliderText.text + property alias labelTextSize: sliderText.size + property alias labelTextColor: sliderText.color + property alias value: sliderControl.value + property alias from: sliderControl.from + property alias to: sliderControl.to + property alias live: sliderControl.live + property alias stepSize: sliderControl.stepSize + property alias snapMode: sliderControl.snapMode + property real defaultValue: 0.0 + + HifiStylesUit.GraphikRegular { + id: sliderText + text: "" + anchors.right: sliderControl.left + anchors.rightMargin: 8 + anchors.left: parent.left + anchors.top: parent.top + anchors.topMargin: -4 // Necessary for vertical alignment + anchors.bottom: parent.bottom + horizontalAlignment: Text.AlignRight + visible: sliderText.text != "" + color: simplifiedUI.colors.text.white + size: simplifiedUI.sizes.controls.slider.labelTextSize + } + + Slider { + id: sliderControl + height: simplifiedUI.sizes.controls.slider.height + width: root.width * 0.6 + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + + onPressedChanged: { + if (pressed) { + Tablet.playSound(TabletEnums.ButtonClick); + } + } + + onHoveredChanged: { + if (hovered) { + Tablet.playSound(TabletEnums.ButtonHover); + } + } + + background: Rectangle { + id: sliderBackground + width: sliderControl.width + height: simplifiedUI.sizes.controls.slider.backgroundHeight + y: sliderControl.height / 2 - height / 2 + radius: height / 2 + color: simplifiedUI.colors.controls.slider.background.empty + + Rectangle { + width: sliderControl.visualPosition * sliderControl.width + height: parent.height + radius: height / 2 + gradient: Gradient { + GradientStop { position: 0.0; color: simplifiedUI.colors.controls.slider.background.filled.start } + GradientStop { position: 1.0; color: simplifiedUI.colors.controls.slider.background.filled.finish } + } + } + } + + handle: Rectangle { + width: sliderControl.height + height: sliderControl.height + x: sliderControl.visualPosition * (sliderControl.width - width) + y: sliderControl.height / 2 - height / 2 + radius: height / 2 + gradient: Gradient { + GradientStop { + position: 0.0 + color: sliderControl.pressed + ? (simplifiedUI.colors.controls.slider.handle.pressed.start) + : (simplifiedUI.colors.controls.slider.handle.normal.start) + } + GradientStop { + position: 1.0 + color: sliderControl.pressed + ? (simplifiedUI.colors.controls.slider.handle.pressed.finish) + : (simplifiedUI.colors.controls.slider.handle.normal.finish) + } + } + + Rectangle { + height: parent.height - 2 + width: height + radius: height / 2 + anchors.centerIn: parent + color: "transparent" + border.width: 1 + border.color: simplifiedUI.colors.controls.slider.handle.border + } + } + } +} diff --git a/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Switch.qml b/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Switch.qml new file mode 100644 index 0000000000..9002218230 --- /dev/null +++ b/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Switch.qml @@ -0,0 +1,204 @@ +// +// Switch.qml +// +// Created by Zach Fox on 2019-05-08 +// Copyright 2019 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.10 +import QtQuick.Controls 2.3 as Original +import stylesUit 1.0 as HifiStylesUit +import TabletScriptingInterface 1.0 +import "../simplifiedConstants" as SimplifiedConstants + +Item { + id: root + + SimplifiedConstants.SimplifiedConstants { + id: simplifiedUI + } + + property alias switchWidth: switchBackground.width + property alias labelTextOff: labelOff.text + property alias labelTextOffSize: labelOff.size + property alias labelGlyphOffText: labelGlyphOff.text + property alias labelGlyphOffSize: labelGlyphOff.size + property alias labelTextOn: labelOn.text + property alias labelTextOnSize: labelOn.size + property alias labelGlyphOnText: labelGlyphOn.text + property alias labelGlyphOnSize: labelGlyphOn.size + property alias checked: originalSwitch.checked + property string backgroundOnColor: "#252525" + signal clicked + + function changeColor() { + if (originalSwitch.checked) { + if (originalSwitch.hovered) { + switchHandle.color = simplifiedUI.colors.controls.simplifiedSwitch.handle.hover; + } else { + switchHandle.color = simplifiedUI.colors.controls.simplifiedSwitch.handle.on; + } + } else { + if (originalSwitch.hovered) { + switchHandle.color = simplifiedUI.colors.controls.simplifiedSwitch.handle.hover; + } else { + switchHandle.color = simplifiedUI.colors.controls.simplifiedSwitch.handle.off; + } + } + } + + onClicked: { + Tablet.playSound(TabletEnums.ButtonClick); + } + + Original.Switch { + id: originalSwitch + focusPolicy: Qt.ClickFocus + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: labelOff.text === "" ? undefined : parent.horizontalCenter + anchors.left: labelOff.text === "" ? parent.left : undefined + width: simplifiedUI.sizes.controls.simplifiedSwitch.switchBackgroundWidth + hoverEnabled: true + + onCheckedChanged: { + root.checkedChanged(); + Tablet.playSound(TabletEnums.ButtonClick); + root.changeColor(); + } + + onClicked: { + root.clicked(); + root.changeColor(); + } + + onHoveredChanged: { + if (hovered) { + Tablet.playSound(TabletEnums.ButtonHover); + } + root.changeColor(); + } + + background: Rectangle { + id: switchBackground + anchors.verticalCenter: parent.verticalCenter + color: originalSwitch.checked ? simplifiedUI.colors.controls.simplifiedSwitch.background.on : simplifiedUI.colors.controls.simplifiedSwitch.background.off + width: originalSwitch.width + height: root.height + radius: height/2 + } + + indicator: Rectangle { + id: switchHandle + anchors.verticalCenter: parent.verticalCenter + width: switchBackground.height - (2 * simplifiedUI.margins.controls.simplifiedSwitch.handleMargins) + height: switchHandle.width + radius: switchHandle.width/2 + color: originalSwitch.checked ? simplifiedUI.colors.controls.simplifiedSwitch.handle.on : simplifiedUI.colors.controls.simplifiedSwitch.handle.off + x: originalSwitch.visualPosition * switchBackground.width - (switchHandle.width / 2) + (originalSwitch.checked ? -5 * simplifiedUI.margins.controls.simplifiedSwitch.handleMargins : 5 * simplifiedUI.margins.controls.simplifiedSwitch.handleMargins) + y: simplifiedUI.margins.controls.simplifiedSwitch.handleMargins + Behavior on x { + enabled: !originalSwitch.down + SmoothedAnimation { velocity: 200 } + } + } + } + + // OFF Label + Item { + anchors.right: originalSwitch.left + anchors.rightMargin: 10 + anchors.top: parent.top + anchors.bottom: parent.bottom + + HifiStylesUit.GraphikRegular { + id: labelOff + text: "" + size: simplifiedUI.sizes.controls.simplifiedSwitch.labelTextSize + color: originalSwitch.checked ? simplifiedUI.colors.controls.simplifiedSwitch.text.off : simplifiedUI.colors.controls.simplifiedSwitch.text.on + anchors.top: parent.top + anchors.topMargin: -2 // Necessary for text alignment + anchors.bottom: parent.bottom + anchors.right: parent.right + width: paintedWidth + verticalAlignment: Text.AlignVCenter + } + + HifiStylesUit.HiFiGlyphs { + id: labelGlyphOff + text: "" + size: simplifiedUI.sizes.controls.simplifiedSwitch.labelGlyphSize + color: labelOff.color + anchors.top: parent.top + anchors.topMargin: 2 + anchors.right: labelOff.left + anchors.rightMargin: 4 + } + + MouseArea { + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: labelGlyphOff.left + anchors.right: labelOff.right + onClicked: { + if (labelOn.text === "" && labelGlyphOn.text === "") { + originalSwitch.checked = !originalSwitch.checked; + } else { + originalSwitch.checked = false; + } + + root.clicked(); + } + } + } + + // ON Label + Item { + anchors.left: originalSwitch.right + anchors.leftMargin: 10 + anchors.top: parent.top + anchors.bottom: parent.bottom + + HifiStylesUit.GraphikRegular { + id: labelOn + text: "" + size: simplifiedUI.sizes.controls.simplifiedSwitch.labelTextSize + color: originalSwitch.checked ? simplifiedUI.colors.controls.simplifiedSwitch.text.on : simplifiedUI.colors.controls.simplifiedSwitch.text.off + anchors.top: parent.top + anchors.topMargin: -2 // Necessary for text alignment + anchors.left: parent.left + width: paintedWidth + height: parent.height + verticalAlignment: Text.AlignVCenter + } + + HifiStylesUit.HiFiGlyphs { + id: labelGlyphOn + text: "" + size: simplifiedUI.sizes.controls.simplifiedSwitch.labelGlyphSize + color: labelOn.color + anchors.top: parent.top + anchors.topMargin: 2 + anchors.left: labelOn.right + anchors.leftMargin: 4 + } + + MouseArea { + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: labelOn.left + anchors.right: labelGlyphOn.right + onClicked: { + if (labelOff.text === "" && labelGlyphOff.text === "") { + originalSwitch.checked = !originalSwitch.checked; + } else { + originalSwitch.checked = true; + } + + root.clicked(); + } + } + } +} diff --git a/interface/resources/qml/hifi/simplifiedUI/topBar/SimplifiedTopBar.qml b/interface/resources/qml/hifi/simplifiedUI/topBar/SimplifiedTopBar.qml new file mode 100644 index 0000000000..156cd3038d --- /dev/null +++ b/interface/resources/qml/hifi/simplifiedUI/topBar/SimplifiedTopBar.qml @@ -0,0 +1,238 @@ +// +// SimplifiedTopBar.qml +// +// Created by Zach Fox on 2019-05-02 +// Copyright 2019 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.10 +import "../simplifiedConstants" as SimplifiedConstants +import "../inputDeviceButton" as InputDeviceButton +import stylesUit 1.0 as HifiStylesUit +import TabletScriptingInterface 1.0 +import QtGraphicalEffects 1.0 + +Rectangle { + id: root + + SimplifiedConstants.SimplifiedConstants { + id: simplifiedUI + } + + color: simplifiedUI.colors.darkBackground + anchors.fill: parent; + + + Item { + id: avatarButtonContainer + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.leftMargin: 16 + width: height + + Image { + id: avatarButtonImage + source: "images/defaultAvatar.jpg" + anchors.centerIn: parent + width: parent.width - 10 + height: width + mipmap: true + fillMode: Image.PreserveAspectCrop + layer.enabled: true + layer.effect: OpacityMask { + maskSource: mask + } + + MouseArea { + id: avatarButtonImageMouseArea + anchors.fill: parent + hoverEnabled: enabled + onEntered: { + Tablet.playSound(TabletEnums.ButtonHover); + } + onClicked: { + Tablet.playSound(TabletEnums.ButtonClick); + + if (Account.loggedIn) { + sendToScript({ + "source": "SimplifiedTopBar.qml", + "method": "toggleAvatarApp" + }); + } else { + DialogsManager.showLoginDialog(); + } + } + } + } + + Rectangle { + z: -1 + id: borderMask + visible: avatarButtonImageMouseArea.containsMouse + width: avatarButtonImage.width + 4 + height: width + radius: width + anchors.centerIn: avatarButtonImage + color: "#FFFFFF" + } + + Rectangle { + id: mask + anchors.fill: avatarButtonImage + radius: avatarButtonImage.width + visible: false + } + } + + + InputDeviceButton.InputDeviceButton { + id: inputDeviceButton + anchors.left: avatarButtonContainer.right + anchors.leftMargin: 8 + anchors.top: parent.top + anchors.bottom: parent.bottom + } + + + Item { + id: outputDeviceButtonContainer + anchors.left: inputDeviceButton.right + anchors.leftMargin: 8 + anchors.top: parent.top + anchors.bottom: parent.bottom + width: 40 + + HifiStylesUit.HiFiGlyphs { + property bool outputMuted: false + id: outputDeviceButton + text: (outputDeviceButton.outputMuted ? simplifiedUI.glyphs.vol_0 : simplifiedUI.glyphs.vol_3) + color: (outputDeviceButton.outputMuted ? simplifiedUI.colors.controls.outputVolumeButton.text.muted : simplifiedUI.colors.controls.outputVolumeButton.text.noisy) + opacity: outputDeviceButtonMouseArea.containsMouse ? 1.0 : 0.7 + size: 40 + anchors.centerIn: parent + width: 35 + height: parent.height + horizontalAlignment: Text.AlignHCenter + MouseArea { + id: outputDeviceButtonMouseArea + anchors.fill: parent + hoverEnabled: true + onEntered: { + Tablet.playSound(TabletEnums.ButtonHover); + } + onClicked: { + Tablet.playSound(TabletEnums.ButtonClick); + outputDeviceButton.outputMuted = !outputDeviceButton.outputMuted; + + sendToScript({ + "source": "SimplifiedTopBar.qml", + "method": "setOutputMuted", + "data": { + "outputMuted": outputDeviceButton.outputMuted + } + }); + } + } + } + } + + + + Item { + id: hmdButtonContainer + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.right: settingsButtonContainer.left + anchors.rightMargin: 8 + width: height + + HifiStylesUit.HiFiGlyphs { + id: hmdGlyph + text: HMD.active ? simplifiedUI.glyphs.hmd : simplifiedUI.glyphs.screen + color: simplifiedUI.colors.text.white + opacity: hmdGlyphMouseArea.containsMouse ? 1.0 : 0.7 + size: 40 + anchors.centerIn: parent + width: 35 + height: parent.height + horizontalAlignment: Text.AlignHCenter + MouseArea { + id: hmdGlyphMouseArea + anchors.fill: parent + hoverEnabled: true + onEntered: { + Tablet.playSound(TabletEnums.ButtonHover); + } + onClicked: { + Tablet.playSound(TabletEnums.ButtonClick); + // TODO: actually do this right and change the display plugin + HMD.active = !HMD.active; + } + } + } + } + + + + Item { + id: settingsButtonContainer + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.right: parent.right + anchors.rightMargin: 16 + width: height + + HifiStylesUit.HiFiGlyphs { + id: settingsGlyph + text: simplifiedUI.glyphs.gear + color: simplifiedUI.colors.text.white + opacity: settingsGlyphMouseArea.containsMouse ? 1.0 : 0.7 + size: 40 + anchors.centerIn: parent + width: 35 + height: parent.height + horizontalAlignment: Text.AlignHCenter + MouseArea { + id: settingsGlyphMouseArea + anchors.fill: parent + hoverEnabled: true + onEntered: { + Tablet.playSound(TabletEnums.ButtonHover); + } + onClicked: { + Tablet.playSound(TabletEnums.ButtonClick); + sendToScript({ + "source": "SimplifiedTopBar.qml", + "method": "toggleSettingsApp" + }); + } + } + } + } + + + function fromScript(message) { + if (message.source !== "simplifiedUI.js") { + return; + } + + switch (message.method) { + case "updateAvatarThumbnailURL": + avatarButtonImage.source = message.data.avatarThumbnailURL; + break; + + case "updateOutputMuted": + outputDeviceButton.outputMuted = message.data.outputMuted; + break; + + default: + console.log('SimplifiedTopBar.qml: Unrecognized message from JS'); + break; + } + } + signal sendToScript(var message); +} diff --git a/interface/resources/qml/hifi/simplifiedUI/topBar/images/defaultAvatar.jpg b/interface/resources/qml/hifi/simplifiedUI/topBar/images/defaultAvatar.jpg new file mode 100644 index 0000000000000000000000000000000000000000..821be6c584d86455df30a882481ae210048bb294 GIT binary patch literal 36764 zcmeFZcT|(xvoQS7ixeqQqzfnzYUsW9UJ`CB1LH`^;-c1^_=s&_uOy2_xzW5q0|0f(M!yjhn$7lO)Br%Y*?xu^02op>bf5zOfNAr2CjbD0z(0FazQy{@C8 zDgdPX^vrg3L;fXd0ASyI&ZP!`omV$xQgo#%*m$M@^-s?sU`GQ0)SJ(Rq8mN_h}IvU zYkxP|`T;|Lo|cZDj+UODj-G*mo{@PcGcywtGdCMM%g){0JUqL(ckSX8*eArxC(6HT zm$0<3=zeiYu;d;g8F?8A`F#?S5)>g+3=9m+jLclj%v=(@yLcu3HLN`VI2eIapp=G6 z1fb@iqT!%gYXSrSfSQJi0za%sM^8h`K+Q-6Fs(HK8an}MDjFJUT3R}4IvPsQQc=?Y zv>bGtd+8xuBKr0W3W#8CQG?@o$(4*CMTd5=hwpGFsy=^NYXZ2pW&Qw4E5}w(KVYp7 zV4;r8%}+|PbVW%$WzMd+2rSMwpUp52&snz2}e17=HhhaWl=Fday5#GZ9Ab#f^P zxzp#zEdND)DkiOnBx07Ae4L@nE{5qK?e){4$@-6*+GO~hf520 z2%+u$sI{Em!XxM*Q*J^1Pm>zZJ7E%sGwg1qSRP0_knv=Uj zbS>}1`{@X2-8$u1@l36rupyjU{eX~5ob?gOvDV8JmRvV`(ssV@>dN=W(v zI!Wh=TPKf9aI<|cnyR6FZ$+WlJNuo%#3UnitCA z4y*wjyExneI&Zzc7H=y%!m?8OvahGK*gqT_QtWoGqw?kDn=1^3Y!PN2F6?1PbjGh> zZhZVut!XU5pVV@=guAt-^5y5-LUC=J>MsPtroSpzO>@(<(|52Vr5@{o?%)p6km=@l z_Dl9R8&2`$EREF@OPoEvU21c7>Ge;Nb>IJaWGU+C&`H|ZCXVlyX?kCM%90LvI%|E= z$9Dg~*$s8`og)f8gP&iKC+ABDFTOuN7F=C# z+SU_z^jbvZQ;A#$QIn;s`@|g6NDOszvNtAG)qvBXEc*~8^zCn2C_lbQzp*~; zkD+r9=W{zp?wp~y{a|JMR;+qlT54jwXS#qs{wrgORj!XXL;bFr?rUHc&O?HYO1vz0 zaAqMS6Qxrx5tchYsWNhfWUb~a%e-=E^~*bWOg4y>hUR0k#B88Y6ntD8Yt?RlOyt0^ zckpaq!OCtN_z9o+#p#D-me&^xN7E+DyxvHy0VTrkh4l5q$qY@dcc1LLc{3f2;VF5i zlN0qqW@03(R!EU6#eCYSEWpL-*}1076m-5#`@S^&c!}M}&PO@V0nbmcYGktUnRJGl z;8qPc-&%WlN1pc=^bsBX_T%-cwotKW;1Z#FhT>HYbfe)18HHE0n!?GmtHVQ?YXHYQ zF|6h)pKreXF(N(KkRw;Vvg1C9m3{f^)oMN^nkL9a+dA$+!k7_TLV1fQx1i9+%HllV zlt~1mMN%`5$fdq}N9kKj!SLHmY?pvm)J4#D#V(vA_`0l&l{fWqE5^Hw}LU-rf%?7VS*%HR#nj4ll?M&waaR{P{0hJiLG0#8EnJLelyLz(T3 zTrQ$XZ-n12ls@C$xqm*MnLmlWkbeB^$YBuVNOPRMzNOQ-VFiL~dO1!L@S5U_mj=GTWn@ zD|_8C2e^3IUZ7)##v)S9_|G&KYuPFIrH7Z&d=n2Ac+6%x;hXconsq+=W?i>z>`2vw z*^22Ja5Zf@bgr(FLv``?gW#bW_Rp{U!5{k4n)=OBj?fF#l2$f2|FGh*aONUaKQ~SG=Rt*1R-z`mp9E$|!r*aX61$CGW|XUuVFSj?1XEr*?%loQy4EA!*A?}pbm*Kejym4XbBQG;m1v%par4hskFFSXp95l~ z{FuVQ`ju{Sc>~_>THR@P{R#?UE)ES|xCsEHyNqFAkd3g=| zv_zscxOz2ByY%fe`pDi7jIE&|;cN!d$FHmmrE+~_F6AnS@V&B^9P&iSBBf(YLR`Lt zM_f3^etxm-l6Zu-dLzBMnig-F_tD4C-}AFk<*FZ6^Zk-k#%6H-{ZL-#dk&icFSS)) ztJ+KH5l_^gI6Att-hSf=FmSW#5`qK5xh}qyyRQAgDKCuojW~drbZeD7FJ1cm!Q`}o zGJRGpPM+Sj@7O|G1g#ApQ1^hyWyxP_&C=W$?{?F3KBth5upHZ0kPrnmSTHQ67Y&}) zdl^-+uh^%bpEgo-zPWSN*Qg_P$2(FLq?gTH8F_%UiTM0G%^u}okeCx3WtFY?MhWPH z3oD#3tu43o;SXo88+HBU;O2UdE0FJit!K91{4EoOli<5I%$xma1Qe1QOY{}@i=8{p zA6{YO>yjD1hyCR5)M1%eV&Ex>{YlMlHJ8yl5!ur*k-1zbU_f| zMCwZ(I?4L#PR)S=)VUkrX6vCRDmh`x>CI8kPd~F%(VTUWGZkLuCq}fqkYE^3QLAOd zJs*5oEjeJQ7RhkNNo9V%DB4e#?#UVu)bgb8aO|Pp$002w>iVGz%Fm7qG}XOeW0Sg` z*-jnGbkYGWR=eZn{>yV8-*K`xC9>Y^oi%xGQ5)>1fe-{IXykNh7lU-fKK6wj2bKDg zKe`o-MYN`ge>?`U>MEKxmsP1{A4`7!?)8RSvcZ5#G(j%lpN<_-I-+c z1k_jgx^^!gCOVFL&*0^=$7FM8gl3K$JyPhzcmdkDq~CV3;oN>4F#e$u1v zX#E-+@!mRrL~=?SUjHl zR7qK5vb(yzEQQH=S5nvxhtU0TCFs6Xl}FyP!$C#YFKOu7+A2QM1>xR5;}#9mjpiC}#nXWjV3NU@sWq4ewTylKLN`?jec)rty*XBbWj4rl=j;`wRR}rpT!=mDQR>mhks@fISa#V<)%w%TH z(uTxF=E0w17|M6w>wK58Pr9*5JV~1l?DG8LtD6#s41(CNOH8nb?8~=c>lWX$XcsP< zg%#s!N;wfcDmb@`hc0uX?4f)z@a3-OMZplqQMK6hM&d04XBT(I|H!OL8V0L+b?Uev`QT_!xYZ{rfxr7Gp;Rx~j zeraW+Ybrur;R<3d>)!ExE#}s<9qEvZP%!CGFgv@AdWxBPiuJ_d zP9t9BCKc;omf%L(V~EPxXi3aWYu+8abZ+I#w7T3fTyF8~ivha+1b9D_Y<{Xz{7r#} zE*JTn6!IR14IYEnU1Rkg%nTwlv(66p~K61_<7-rw31aYO*t{roJEBEta@Sv(#QLc}dim-~Mq^q@~vy zAe`Y9$V&T&?v&vNEyG$}FE^ScLN+Gh0`@G|v%09fopRH)v~Avtqo>AS%(y;%o0DZm zV(Ls88Zx+QiVitfrpCPn5b=YPjS9x1StlDhifspP>sId{INEkA`CvaM>~@l*qn@hk z`7xf;FS2{<&WevVPntiwK6E9{{A>Pdpso+sDmkH*$U)nvR13l6BW zX)2kGmQaLuGx6nquN(uSdX9fCx*FHx_~Zm%dN}`$Md(qs2JUg*>;ex*ksW3Q zjl*|6JL=5~8qr10B>#Y2YWa3V27bG}%a)yQD?gr*mYHyVoXG^c!8PvBN)HJ-$`QJY zD?vzg+3EWiWO*r*-5@Y%Wj$aXUWpj9lF`pu;Brkt3#i780x84FXRsNqaR7WKj4;VZ+CF6YiHlHeUD_xilgLPhs%}usp%nl^RM4k z*M=r5=*{QO#yNjj!0l$*3x7$~yz)t{u6^`CmcaUS75hF;t}x^@AlOS3`-e@p0il(+kd{V z<;KJJI=65GDl@x}fxBMvNxn z@_x~tSZ$W!mp3CpeO%nFeJXSzu{qleLDR~+*e=6R7*Ga{up=(MAIeB+L_Yyxq}-zH zSkKzVB|h7;1nVt-#6kzaNC|QX2gc@dI_UAk$quIlPh9JhdiVB=zEkKvGX_vr=tL}! z&{5F=r?X*iC0~NB9MP*eP%eg$9f%q`$^ObKtu{?FUFR0@!9{WIH>Fhk0b-&bOv|Np z2AeZjJ*>L&PE2Txdm;V(K3j^lc%Z#!7!@>bDn+8H_AcK3S-;$?^A z4r4n?2kOq5i&I}W?@OP5EpR9R!f)r;E!XvEOvOpGQ#pSArJbc%1(m}kop~V-zwnyy zHDK@uCJm;W)v&umH7Q`rq}chCq^CIcYM-#Dqh7PJj!`yH&nSOSbuSTJ z9cHZvjflXYKolM!91$3R3DJnq7FidrfeF!|G|Pzyuan^YwM90Lw>ewe2^(T@C}Cw; zWf@O-c?DsJEJR67UO_=xSV115ASbUX2T_)RsA3+f_@zG z`+L4E^g8p;T}1>2SzG@-(+^(;2L8ekf;SGs|7VU6Xk-vd&H)vI4aIq)jKfeEyy(xJ zhTt7g+qV8&bNnj80p#%hZw%gaH8*MG^&$y0uQq0tuk z?P%aHSaTz75e4;Mnttnh3$}>N0}(!`E#0=7O#%=hzJ}PqAQUD9K^a=wBJy&OZ8RDe z7>>Z9v_&AY5Lw0b_N_42pcrPu8D78p?RQUDTWc6$JwqvhL(x7WFi6%5?WF-xR#*2@ zL8;29sw%3;sHiHb%BXuIkuu8a-bh6?Wd${5HLvwf*GG_sEe`F2#vlTI7NugSZfK%l zBCl^?V4w&w(l=C7H&9hmfheo%8yTr88UMs?jtRjdFrKI%8leA;240>T-dJ290F9_wcF5D9rqTz(Xg{)goO?Jb2ltw!o))N&HvV~KT-H1#I4(^M_qYMxM6n(Ts z3`0Zk*uX7mP*h+L3WvalQY^2ish_;A|!d9zQ zXdoIxk?k0W#o~R@7$0qs4X;zA7-9pkI2$ZF1m%G83iaIZyMpo-w-ee2gTmuc`hnO` zN`Kp&j=l&lZ1{#2+pP{LFSAh8&vXtbFGq_0KVoW2v?&gS!u&?O-uCz81_7a{->4}~ ze@|?RLquAmBTzU8NIV8bcMZBuM}pz%;F z295FA@WXGG`3wH<&GZwQ8QRA;fO25{pCxUP{FlPEqIvsu><~CaAPSE|du}Kk@^g%A zBaIL^|9?QOAE*BZ+?HzpfZynI{dKi}4)5)bt; zD5JO?Lch~kqrHN#>zU!_SNKhk2?~MtrOZtKfyMzFit*Y=CO_HYH$jg0NJ`jl51`)( zwoGP-#o%#>kY6&0DGq_g{57%sO-lM%%65RtT#FUWsE@}DQax%NkLj8FrkP5 zBXkHJi=(8qzjkDY!i5B(Jn`r-loJYvM|&ayeirf*+6;?BM`1Dee2*QSh;!u=2 zd_4%2wu9-112%Cg+tbFDk3u$Z+i$QrQa4$C61F~N{b>Jb1~Ldhc=~U)%WO|Uh5-m1 z8XvhS2eLgh46&Fn6b=u?QZix4hLNDSP}Ejlg<>%%!%$op$_5d*`C3+J3<`nUqA*;q zC^sYFM`h=TM_{}VxQ&8=V(p)z#Sw)M4f@MG`x61Bs~>_S*1!KFY-}R@%hxkDD#PCd zo1gZ>WLC_t2z^$iUajr8@mUG@v_kI?^{@cW6*&=-ddMBve$`bZRRW19ZY44e6g zGWYy7t~cX#tI~leDk(rzRezc*Hz^EJ7(5DRjrICv_42=rc7BN8tgltFSX6H~G0uw^101bby ziOdioj+@IG?Oy|#lEPuBr<8jZq)tL&-TZ3bGJYCHd_cgTiNs#f0D~*%yk1BXAV0 zwt~+L5kjH(O?~|U917tTsUH*+fTmPb>w}cC9v9ZysK?FLgDrBsX=9P@hzj2LYva!V z^!n;tSa^LstAW@oHN8+cbQo%5pl%_9HfjYFWfkeUks?rD!rnM+pzub)9UOXA&4-P7o`z{3KtH*dajq9B69x?Rn|Gz?XaZ?`v1=|VM|K5FADSf zs_6Gs;}&rU)*DY*XX#Ulz8`7mzqeA|lHut~DQ&&9MdW_GxRxAcpX7&2wB-Kkv`s%6 zZTQ0khYei!*ZS6hhSyIEw*S^DYm*QAKUt-1_)3d1Hn!5gofBp9_)pQLBQGs1zww#@ z=wH39qoAxTEv%rd{44r*oBUIUf2WB9%Ikk!nIC=roj&VJlK*v$wtM|Moha*_|8ce6}{-b)E`D%UF@~0ig&F1yo4fmyN z0&ENXkv%pN`&K_cN>7OF#%|0%k*$}a+9LQL6%Ym1iww$a_RFH{?*wg7ZSMj6Gm*i1 zNx50v|D&jl<>mTvP(fYozaabXY4>Y^`p;eeTCDyv-Cs)Af7J4qQdUM@R*?d~I%3^^ zzm%%~EN*L4Wqs>ped=C^Up%`m&>D-TY~B2`C?k|N4!yn;@y|5B>;nAZ2e%`YDN80~sK7&Bi<$sE@ ztsMV9%xCidDDd}mrmn1@v>o|d{r*X3+cm=fJe?`1DEyw1w$qt1L}g=Px19riPG{WI{XYtSI{8=d$6Wsk{+R1u!5?$|EBIrse+7Tc^{?QMx&9UWG1tF>Kj!*Z z@W)*L3jUbuU%?-9{VVumF6QmC^eBv%wn(^$uFl$|7;^icu!^$sfSQ51HO=JuA^n}3 zcWF|ts-@frOGUxaQtmYc09}467l4LupD91(s#SoNpIQ}Qq#SIPS66`WQ)>bA5EY1$ zk}^NF&d=?-Kib#(p=F_n5`DOF)9Ct5l%)XWvQ=uzvuGi}15mB?u1x`K>u2=WuO$Vj z*7|`{06i@&EgdaA9UVOrJsmyM4n}%<#vLro%sZHwS$49l!{*1|1LXowRu)#CojZBB z+1S{)DZkjbIo63eHa=K3KmHyzFYu%SXs9@TT;Mqf&;r71O;lF_0ATp#8c$j}8ftnf zfPs;Tc?T6h{p%&4Q~)&%Egk(j^2ZII)btEAwAA#}Aym{f9JB!4UQURn%#1-G0!VG_JE!?R6YBXg+G(`kj(r0&sq@37d5*J>X3j4h~|!hOQy(u-=FU%mgT zX6Ec0apqEST}$tWZ<6Zf2hfr6mrHIxdHwM_Si{1_FN%;syz{hge31j7rlz8%p`)Xv zqo-x0p$S~SJd~EAF`YdZLWDl}c(OuXeidV0aW6bfbteC2ql9GV@a(D7f?L0;Y~r-7^grtSA5{MJj??2Y zmLEE5s&OP+5cEy0BccB38emDVG`PZPECGSHH29p3tuJQA*Cj06&(;K zlO!^+lnq>GNVq;%30E?R19=L1)q2-Pu{DE^T=`yEbTB5_JDKl{rxh$A(g*6wmv-Pd zlYPAgvLa6_d90L+_K=#iNh2sKFt&n!TrCr(dajwx$~PB!;T_@LQfp35PP&fUlW>2njqAI|HGS_|bG?0G2Um`f z4rG^yfC_K6xQ2pA9@^tEj)(8Qo?khQx4%`zV1;k?l#k z{IJgxL86NJ-2&{?>}Pt(#aH&s3n)x!4(gCyEsGN+ruHJwGk%t`g3alUdMuB;hX`JH zk1(%sR*vX7zH&`}!F9QM$+`4Hpd!38R0?&wvd;318&oTRZys6P)(8ryBRQqJ!KAyc z9@v=x8y&*V@N1M^X&x#dm)XTw^bm*Bnh!!9%mRY~9mpG>MeHY1nY*q#W<$nd%B$ots_q9zED(jtK zQRFiBabf37m|Qj(SrXdziBPC&?vemoYj=1$(*Jbdsn3W3Wbtdv$i2QWX)R48G3n#Q ziX}B73SH1w!f-Aa+Q-Ki1?)r?_XZqVb%V*Dcq}wRvX4jecAO<#6+NE?fw$yj#Mo80 ztpQ4*nl8~Uuk1t?+Z^AD92{W({_$A=Omu~x*viG7E8r*f4SpS*=JDZ0xeJvob50M$ z$$o_Wd7%F@)e`oeAvHeV(Q>Hcf_pvm+v*GOqLAM5+mxvs=VJ=(wqlwY$NaP_om?6s zJG~Nkp7`ii4mI!)IX}(PKOM9!;mZ$`X4UyZ$P2tLKYY9N($P?dTx?5cZvsq+Aw%g& z_knycQ=ZN+$V2zioEfrY@czXtO)TMtt#*tLsi^m9&pCm6!4;Ai+a{>cP5tH8B~j3k zmt(9)p|jdc*3#$ZgO-!|Q=T8qdN~^r^At(Em>~}>IbU=WYugBN=+5^I@Jiwp?k|*b zgU$PlES%jR{~epxM@OE~ll2z(J|JZGYIO$))nO?EfwDF}_a_vl3)U==OSH)r{%$ad zEU}V)klyoi?+Asp5Ki{<;50WQKYzmgwGJkl%0dXVuR~l6Su&bcYe6o#w-etFvI?AB zM3$uPYUm}Zs7dyN;Lg#NFt0dJMELT^*YxYVI*n(IGyS|eM^$QNjboUK9qy0J3VrS^ zeLh+3KkI!iN}AUDBtatld)v;t$P)LP+P5B@89nEIC07`_guOpVxbd1-U0hzi(3)|I zz4HyoOGD>&@d1OH_7-^CkP2Tn|7sa5JM!?0uQTeg4tyQTLkZ0xbwzHlhTw1tR zh}or`h5jy7UjhmFN{7)MvVIeKF$`&jM^%?iL5^L^WNDbQFiOvmcX@B>Jogu#QiiTI zKrz&^wC=SS<4uD3$8rX$hHjqHm-jlyEXy4}o6PJv1lLJL<}n;Ef=9*lBa7=rc=EyC zq3pI(byGTCc+!Ef%S!F8oW&`7`Hs-q9lpU%D5(0Vn(aGllRnyX%N1XrWlu=_YNwS& z1Q*aUOpq%o4pqhu4M|0$C)izW=KTgHP!Y;g29U*)<#Dm#lNX;>_k%2_q^Yj=5*7RMa?v`_`;-%Ng$uGgYY^ECnXrNEt_Kku+wknczB z%WzzcnA&G`LSbTFk15m>PV-^O5ai&9d@3p?=)n@sUTGo#dO34=^#%A+b6|)}o`>bB zg^5VHsFPn-guL}vZKYv~Gb@GtZ=~%jc8ilks*1I3Kat#YY z4z^+Rbv2`r8ZILF)ME|Og>hlWNY=7k+|N#GfsuD&{=NVCO>ab>ck6ujs7 z(Eut3Pk}4TIg9T>UKzYiABcLMoWTsG=Aej^tMxnd-h3*WA(z)JmLXA6FkF1oPUpS4 ze))MM#}yh!dWlD7^EsU(gP&fM-4}Jqge85ddR=;%ojb*-U|Gugv?2Tr=#cMCx5b8n zW7o&_>g)Mith|3$(MNJvu}83n6wm1G)phE0%DF{gP|zi(e!Kt5i{#w=;Y{G}?sW1U zEI}@Ylre zq&Kq9<_}LRxEbpUFIH#9mALd6XcKpX4iDFWueB0NG+AKm!q>rZ5s$&AGfsjmram@+ zo2z#NyrCrL!MDjzNFHn5rp8_vCACt;&Jukqm`*h}Kra5)i!4sVvcO>6nJ_M%Yv3~` z*TDT20Lfu##bJkkq?e~V*j9)iHuLJrtreY5c6aZ&Lg^3e>2rC7i=rAPRQm23S7&}u z-Xs*4G{*Fuca8+p7Gz0L_eHTjON9}q*bSE<(4ok8)!CXo%onty4TZi2G&y!rpFGPO zv#6u{1xYRql`6jMdX7rw2|UEU6PpwO3p*RtE`IG;I-5bIrv1Gb7|H(5wd*stVoiML z7@d#?Nx%o~FHrik#kuE=b#DQNugDIJ;sG!^uXbB4gk$E#ZcA71!AQ;nW2sqnOEIq+ zmm~>!*yNa-N`=Nv6Ol@UNE0oysrRe9R{~&kVl&F@)adRgUUn+NRq44;kDEQ>Tw1R@(!zQ zdCI6pM9@8|JpvQrxDGyd3R!#%0=sEbS#C~pzFt4JoG5I@2_5QCYpjiEoO>p%Doot9|?vX-Vy%}onbP} z)pPHh%7ot$2-J(WCM!@#JpEmXxF4?K_O)JOb6w~D;C-2E08MnYk{IvT{c#|hvQzr0 zyGHrsVfoC*2RcDMt2TEp*!CbU7Us__C|7hq;6=`nk2*qZ?Ko9F5sHGwlP#*9iq(h< zcLddlyDYCp@x#pGj=+Xudx@zxiWxu_6#_eXGht`_UY#|013J3)YIa}!;B!`}r+z=k zThMJbwXKEt!dUwY{Q7t7i+Ba_-BqP42-TAA;g>AtP($#s)C`Bh(CDQAz&-bnTm zI5LuV4N!fKED61SHZVE}RHtUb|KM6X`cNZ{Y$&6L5zAn~T{#9p%#Vv{|n9^J(oIez#V#mA~ccis{=5D9nPy&*_T*~ zjygWTPZMsgFq^~5FSGOBFEXJ&#c{s|+44q%&5g(W}3Ib@Z3nt)`@oxXmBt* zx8FU!ZKod_m|!em11{TR0`9cQMV17v<`RmIz|Q))#3KzdVdva$UAFkmP@D#f@W}nvwo4+^-Xa>?`9; zzbw^)p}}7Rr%6MHMR$!A4MPaLON7KmkWGNx-nsJ3FeVLw9{bZg7CM&CC(QyB5xE4 zg=6X~)}!xSx_R0N5miZbL{BW{>NSINF#2l=j8pm~$9m1<&Y}#*9h}zy;?=uC+2GlF zTL({~8-yy-?D4TBa!GbFQOo8!A1LbUg(Ht-Ma`aJ2{(&Jh|~~RinYx*BK_FHi8PXf zYYFOdF(&<0H!n3kSJ{zHK5Z{ z;(0?zAsC8x>|+|+|GvA9>{~f?)^?Zn(Oz<~VwtHH>WpBSPy9IvuvYkWaG~-@Ee9_C zq9KUB^^3$;p=v^5rJI@T@pPw96$JRN$*u+JE6d2 zW~dYHTMpJwh&pm-e(;`gm|CguopbMQp6p3&@jiDy+yNN_9ojpti{)>B7Z_#ktfviPeN_>F{*9-FXsP)~sQL8mq6KfgDfu&r*j* zKLB96Cs}KYNsjwEN1TnU{VH8bRu@I?T{@hB{Yox5ms)c|HJ->VaGM~Qt#s`h(f``e z!(iGDH&^Lo*TGyo(Q3q99b?eF zF8QD+_7r86^OIDXT!eb!i+Ptp>%&N*s%oeh4WV#GQ=J5Fse~Pt}fI#CMF3~Bg zm9BNn)CW6_L!2t1(}o#wXQO#a_Y?5qNm^#pgrXjoc~Y^{`y11QYcJpLuRHeG{R*-y zlEvXod_;&}PkHAQPpNdul;fdFOMM|!Il}-1TGL?}b_a5mwd=gzSCVt#Qmbc)r7&%| zum0))EIPK3>GoLBi3?xaRvUUt_uh5&m$NZTqLODRq=RNe=Qc4r_JfT2{K9tZzN&{7 zJax>^TD2NPQXOy%z=y5O88yt1rL_J@Y$SQY13zh{sM78L#yct;?B6 zS1obiul%NuB=vOMMM2hh87i4WDL(u4r7ia|CWPs}c(!1Ahg=M29mhq)C=-`8kJm?W zy!jps_0GxLH^Jrp!ZoYjszZ{cDCV?TKgd$HTHHKZR3vo`2+cN<$Xie&K6*8J;?kgJ z`b5UE_y9lb%E#n^{$AGy#gXP;lvT=)1jDnxFFZYLZS=grq%rE`Fro69<&EZ)0R5Gb zqc>-1K&aJ&_3v;ADmvh0~zwI72h zndE5gt}b>$!rt7w7fiU|0YID%j_5wSoL?Us4Q1pgb{K3$Ejrz2Sdu#nvbi_^Jvi6J z>Q!g|ql*=HE!D%{JPM#)Q*{6EEgo}rJHs;T`kK$cl0%$bi#?gXc)6-+%P!Y-5#S%MlX=cF+t6u>iHD+A;b&{UBq*L^pbNc~-zgJ0ll zT{AbXg9mNExA!Ku0wjCM!oeHGZZLa%X~TFh%=wmo(a|a!@Y6X~>bDx%++PFZh6(iy zrk!OpL^m5&$tRA781C}JRJucNOPkfU<(;Q~W-i+@D!B$gbE+Ut9^Vg+KB;ysp0_M5 z5lf-h%11_Ykt+^%~2UAI&N@anuD?LHF!`u<2jI%lpZE zF_6zp2;Jdi|7H?d;k0~jCN6zBx!|mf)}H+tiJ|zhDzmv|?wF_K5|6RfT7U8MhEirz znaO8VfqW_E+N|6(YXC2~LTBdw=v3ul%*}(35A8FSc~pjP4Ux-DUDq12EqLlmbgAq;nn97F{24nd99SecF5i+Y5*V4fhK$inm!~+D4O$orJa2zdA|1%Sl7F_e#p|B&&0}p6y4;DY#Vg6Hj>w9jna8K; zvI@L+idsY`cO}O3mhLx$%JvckBVy-xh|Ip$;U5Wk`{K$q$i-%56D~107bBnX{ZMNC zgQd@|gVX(E%sZ9Y&)iFxXTKGjd;S!4FzjNCeMX=1IgHO-svY%6j^H;UiXnZNrSQUK z_eAlg{`moNNqtQ=2lZ)y1;%r+vDOU+Lk!Q7+@OH}D-d!um{TQ7BA!N>m9gA(kkH^a zE6plbhH}`);>TC<<_!oDqIY-FkWh^|C2%*8P}*|gMlJ~&tx5PwvafOKRAfGB1>-o% zA1`1U029te(}k1l9Nf(`GGS{yqpvtFk^Bi|HFdO0rPrTSrb~>KXZDHAz3oIud+QLSvrfR{5%$9y}hbL~@lJAeY4C9cCr=m@={(GzY-ObT2goUVQwz zUZzLS;AsM*5QK0~)U9h@UG=^f6HRgScQaw12xpm~>LUQvtFh`nh2-$z$ym`D;`{L0Y*9I1h_|I35h0>6lL9A?iqS zXI~+g54h2~kV^v6Q|kQi0uU&-YTPHG-R|8a$3UHr=i0Q*rfk3&FN=qagIo78o4h^u zaiy-bZw-*r>L{|-4;5B`T#eJ+vj~BgHHsG#-iE#b!PyVqC6~IvK@JeR?mKL~rM7@J z9hGJR%<-IOgj8(Y@wuVKhh$tvF8dPoaWyJKK6V ztm;O|ry6hx>u9Gu3){ESwYGOs8e9!v!Z9N=VPr{p*+Npqv@ORp;o740*Ys=)Ta6P@ zSSy%7@qrH=Ceci>!+yNv6794Cb9ILY<-t(n)i_^K#k~SjHQ?scFY`lOCRicR_G(b5 z18?g1?(5*p?>^5JoyR3LAagybplL!w;>_-h(QcXaZe?wNr&QI{2|G-vu(RaquK|xH z%t{YxvcT*lNKU7;N(sc1!-TRhhL~O=311=(vQ)0zef6b_jKoN&;J4Bzp&qT)9tOAX zbcVW`O%2B_oh^RJ*`8D79CHsg9OE;qOd2ZMN7Cl;8O&cf_XT=JLfZ0tP*x+2J)wN~ zsfWEaybuCa{$#)^^@Sg1j7Vj(uN@>@gFFioW_Etn2(n9g-79E)n`C$OS%+Uw(RFYQ z`am32CrGclusABM6j^>Ni0zCN;r?3t+n_U!elsNd_JPxY1j$~)^OA$UJ)!Jwd!QiA zM@i05`a0r4bYO)ENu*TxLlMY2H_l_&=~!Y=u+vnvfQg!w%^q`-^Q`;Rn=wmKUwMe0 z=$O-wE>gKRkxOm`Kqc5eU$`Og1zxi1vWh&X;Ct(9B02d)takkuc)Nzc>$}wlY)yt5 z)QEw5NH7(WYcH~#ALhvdGcnEmOan5TZ?$rDegdv%&PqH^a%L-eAMbtcZHhgsr{~M! zQ41CrS;uEqD?H?E_mCZnYEssRPnC;&*TGGg>HCq+j2F9CpQ?<&ix(lVy*LpIlZe>y z1|DMf-MQ52V5s!YXGcR1euIO&g3(|4bG1#taa~i|JiN}SH|1X24-+bxl%sq`B|d2{N=#dxE%4a_I=nQW5gT>d>{Q5%x1A2Wv+&&XZz0Os48e z1sAJFaNWq{4>2tc!A=K8B`T_=K9qSK@6JK_H~>pu;8ngJ7k4kH29I+|q;Z~NXMs)X zxc2Nl-!7U20!tb|ob&}tXp%{f!SRa&M(~T^JDO=1^7=s@7?5Tvd2n}vsi`e zGCCSSPrAYO(Bq$?@;}Pm6R0kYsDSa|JH>{cC zoY+mcRyowSi14mES0Ea-69Rh@jxV2p(>K8TS!T6z^%7B5 z^RY`1bLs>=I3f0X0iD0$J3@v3dm-v0RvH&NL9p153nO|uy+oZIzn`cXlk!mhIPI^{#&^r( z*iuFyq5iDFY*E^Laavi0NcyE>s?#wOu>Y^KyKIVrVbnOjxJ#FGEi4U^(%sTXFCZ)^ zB?uzYAPv&7l2l@1FvnWF!y#>ySsR~2HM)xMRt*__QBTX5s;(# za`j55ZNs#VvlGc(n+@eV7L7aKa#jB71QzziXLsZ5xaV_JCQ-XWd1t?3pLRSdWt5MH zV*86u*RD$xf1ET>1X7uibL{#h@fxk4^cj~lmzKDa%=GC?d@5r_>7HZIE_KE&$V25f zvH2}Hfn)RK)Vo_LfG15bsIqb6XOX?$6q285U?^Yn#2+wq2rW1ep&V?&6NVT!Q#sN~ z#oigvUn_m%>Y5hu88`r0U;sn4EHzrF5~3O}D;{P}{b~d;w?a^j8?Qbne4)>j!#TE~ zYOm>K50$z)=5~yyQ~oX}vAMj#GPs&2h7lJAr6P8czNal`aUKZl>Y-BQaFU;!)PYiX z4DXh7=N=r$$|IqiQ}-3u&*k(gPBxong6ej?9ssfTVCWxnABA#)pse-h9rEB0{kx@{CX(%Y^smRD^S!n4Q86gk|1q~}Z zD-%1I3BvR*x{HmCjf;azf`>=KL`g=;^nc!eo1J(-{Qp9C{|$2fz5mZ}a6#CQfOuH= z{}8!y|0X$)fH)u!5D)8rpt~$MG>-TmF|6UqLD;bTJFyc4~RfvctqrzqR50=jR^B(FH3kNswNDUl@JUl6h zdb>!ldza)!6>T`ys3#4O;HTXNJ^-rTKd()E)t6Q_o;1cSQ(ymX*_SXbOU9)0exS?c zBTX-}?e8iiq^|guCowcF?28@Q_DlY(AJatnQ5n2V%gCIVzjwU>6zt|!%_qByT#8>M zw!YsZJEweLdnDE~`B&elO%G9b|;8Z>q+w&xU`et?{q3I*mOV z;AUOvC3>BfQ?cV=`KF#vC4k;_Y&B_O{P7F^5#1t@WTn%a1X133u}r=9`&~(8FuHQ9 zolo4U80`TP^rs>(&ZdQ>j`Q`Aql7zbMctu4-xSh>gArk*SZ-egl6$Kn(K%ubE@rUu zTyx8vJ0wT?d=|5sTzN3r@#oNQi*{dEV1=4^bgEKPClGoZq-Ys1JUP*X{loUn=u1>_r9!7``cLn3`GRmHZij zt_aSUcxLYT)h-&dBFY$bEBklbYmti*c647=gjs-9wdn!7dm{-HnYYISrVrby`R)ls zcSxN-&4pscPV1!R)J^70U>)zBRZkwGOY;%HfH9M|yO7-%2eOx8x1p zEs8b2aY=8b#q@SD!WTP3*~Nw*0R3ta^4WdTq%;eQm2o@_nu83~45bRJL23BV+Kr6v zepxK!DG@x~*r}Blm`+xc&oE6rc70-jopPvL8^-_jaOV1LGiUyu5-0re7w+W{$Vw5w z74Mj-s5>j(0Rd6#Dv!nX^dO{?Br%IdHXAeOf?T! zcAi^fArQSR;WyHU#nw#>dErL2Ia(IG00sXUDgikJbpae1nwE+dzJ$qmk&Jv-l)?l{ zCzCQ@8nJtMbbWZdDHBOOc$Mwjd4@1tjc#+(qT1NKt)AA^O&S9xE0Py?r3`g$BpFxR zx-i#0^K%le$*M@oNcm3X%par5)K{9D?*o%PqE6Kg5{0XR@|@tRLIhCM3G$3J1(z&mm2F zX{2Whx?m+i|}y z6@D+2>tyr$gwR(i0afv2LHDW0u_WXJ-Fn4_Z$d(6_LAlkz=tM@64>^-;;(zcv)2v3 zI!rA$Z%38S3Xs8JLZKI&xsjTx27i^h!$00gO`fUgb4CKDgHI%4I=5m+o5!^XbqrT7 z()VJ$Avb(RXnN?t)$5FnePh|c5=Mt`lqLVmOYN_1gM1N(xR8vLWf7Z?@h*wFURw#m@v&#kSwaT8TN#(m9)5aW^T>#w<W6Au9M!Zo_WFs??` z-m3MCs}$YABT6@_goY^<4~|le(`DiCjl9%zhJfEM4Zk|BW}A}LefHTv5zk0m=Kd0v z_dOGRR0Tk#0?{9O^5`Dl_&4nz@7U&NN8Dm|nAjfxphSzri#PL8q9W@F%S2bd{khi6}GHA0@#%MV9clvja1Wt>A_2M_@wKOiR|~&>zNjNS3cD*SQX4_&$1ac#tE`fWr|{e z3l`bBf%MTsz!LFIEbPvnMU=UdlITSYCcOYwrcg?%bH20Lj4r~$72f39GG@1q5+6Y4c|U1ed296nvs7n z9&_X)x$~DwwS2`sg}IW-Y$G?QCGSZ)pQqxHB>D3#-GwcNI|ZjQ$HI=5TUE^0d8KF; zMwuz;+ZYabu~T)R{Yza0xi*`?vfxcZMG(BK!i?_Qp*?g%ah>(4t|IXI?l;S_#h@%) zZU$M`(#z=(Kap)^Yb@U(MCOic*JA_xrQ=x zGIpnbUyo))x1Kif;{LRq3NNEq+A|-9o0mjEW1&n!S!qo?>bsQS^S+$?Q8y8lcX|SD z$XTCHDX^o1&t@L@_`)LLT7>wUZ5_Z;P9(io>u?YC?*(k*_-%l`pl^zEX0=YOfTG)~ z^$Y>!59S~CTeti(8XFtsXk?%x#?;0#-a$4zZxB6JUR6yk^)Xd-`Fkyn$ViYU5GGi# zYZ_p1ms7cGq(bVIjt~Qdy~q8T(6J{lG4Z~Ol9)@cBilHkJCywhZ@v!5mPV1B8sgDa zB+R!Jt9|35r@>2nt35QSIc1PLrJj%ZO`5JVThr|R05A?Wm=$$_3Km$Ys@89_F=;IT z;2*Fb*SE3k+nGd~&4Hr=zn`!T)uK?Xk-8^3As@j=c+~AQx$`K~_KUDZLIw;4Eze4f zqJjbK=}P{M2~549hiGZB9z-}d0MWUcAVoWI)aoF%zhKpB;!a zWs<}T7MSr%o-eUIO%yhI%k*~pz4VMO<8*#9ac?Wv;Yr1O9f< zIMw;KEiVV5@b6tgTgoBKK3&l!#sIFTy_TrzZo;T zIXfOf7L#Og4$Ye@BkgDu>ArS_MTgZaud}}@=i(>_(XZ4td7)0Bqx|f>Z2!#6LLyTA z_h#XL9G|SVWg~GK^?xo1j)$vDi`KQET7ri+rP%!^kkbC6vhTD+n8%jEx#rwc$%t-c zG#wh|60QjKK-18_uHvXC{~cvJI%7cm$uW8GU8Oteb(t92=;PeNdiR&;s`#_TJe5+a zc%o#buCPj}?Dk~!>gQmU@``6Jl!<0X9-I374VMial5#TzvhazvmMcGF85d>p`abMj z?;;;>DUUmDaVG?Fx;}k_bWPtIcOMG3nNS)ZCn%GrHY6d<$7xWi;=Mpr?ycYqA;3TW zeE4We%8ug`3A5$0SC|U7qd>Ly>aY#vM1MOwqqHt`PKjP`di-o1@JCqjboYrr4^4~N zF)@d%j|opUN;^pb+X@v54H$axHVWwK)U>L-!`_*4u)JE3C??x13A#y) z40T=<>mgyy3AOGN$|?@K5Q?8vc=Of5a=G5gq=M+nz8g)H!mdHnh(1GqQWMu29;2E* z5)Mm90KyGg%nA%ddy0KZr7Z_q+UyjI%w7ScXU(h9#|r(Zsyfl`9YS-Gd znNhL}2r<6CPBxo&DqhLb-G__VMd&;LHjH?qHnV&=P)!`;g1i1PT$kJF8KhaUBx`c4 z7Cv$tq>m^@>|!;dG2`hU0=aoztC`zFvs8h>$|tEtJ58!5+` za*c=Yp;VgcEmdMvEB8J!@K$fTJ^-AW_f#_)glg6#wh3~A8uss*WcX%LH_@mu=6ZjA z-ptp~)JNJ0CxGt@0rzQ-OtVxs5s563Q@%rC{{7$I0=HV`ZO7kkm0IB!f!ukb#-oYR zHTO@ZZ=We6kjmAFm4!NXUi$hWI!?$?2$<}o=yN6~k~5adpEpxYn>}_iEJ*g7!=_U8 zoDS;#n{--j-!c(4&le&2FAg8b+GapLB)QS4$*o9orST$(b2)bg3$s`7$oOTl5yS-` z^$0+ra^YjnKb(To^=0${&_?85(}S&kz>PIEb?x)QW+O}d^!fOR7o|tx{L+ixlcltW z3<0t2zs6|WX9WwIYiFl?XA*4%vg&GYAa#8r?=IzKrorw(bcm-w;hHBmHsQ!N!|A!B zN1DYt>mLjVuc}TdjUPE^OmHi^ z1EL=K`@LNu?W^!D&_)!p1DlRu>HgzkP;JA2w4300*Ctcj5n(wq$m97YCTDJSOqpxy zqa?iEdBHZzS39n*-H~H^3o_!T2*EZuE@_yorL~MuK|tgiz`0%|`8Wl$(m5&pJ0bRj zgYkZLzsL?x3ztN`mWkcGz$s2re`iqOD-y9huE4tF6tv$rp0vzCi5yu~XklLfFoEx=235-N)JT`Q|x$d^UU z*5W}>LjZs{f-nD9g4(cg%GR`5tMdLxk3z-zo+;v5zW5tqf-=mnJVfL)&&2!K*DHuG zY+AFvsX1L}#a%+CrdL4Yu7ZT|&y9({aZ5mEeG*7358_EnByYQ_D?wXrRMu36Gu%N4o)P;jgmIDM9rFyx*&i(Z2 zHI@!#BO2lCt}?vY0k{wEG51c!^>Kbwg6N@&EOQ|)&=j?nszXAgIW{pK#$f0`Bl(sv zno%ilyLwJ6^Wd|#Z(AB#U+pZm!{k=QqvxHjk8IlXdcSjr;ilb~spJ+dE5h_CRZb{Z z6|U0zsy@{CV|6bt?^S#DV@$^~=3y!VP}hoK4NZ+D(5?vbBNLiA zv=FfN(vPWg)v7;8I;msW`WhzYhpZiw)_;RS;jpvYtygJUh>iKFYBmB}%@@%GZb~#q zrEN*PV(@qANJs`lb^v{HXuM4rPl$MppXO;*gu4G!N4C9WUZ@vyJU9!q-pLlO)##1T zHAwg>E@q3KYkIt(xg@2Gqr~W(*_@kz+E=#7kv{R=jGzroJN7!yi|EVR-8JUpuGw~Sp?q-CjThm0mCrYoZRdnP7=9~S-t5Q12b literal 0 HcmV?d00001 diff --git a/interface/resources/qml/stylesUit/GraphikMedium.qml b/interface/resources/qml/stylesUit/GraphikMedium.qml new file mode 100644 index 0000000000..6374fa4488 --- /dev/null +++ b/interface/resources/qml/stylesUit/GraphikMedium.qml @@ -0,0 +1,21 @@ +// +// GraphikMedium.qml +// +// Created by Wayne Chen on 3 May 2019 +// Copyright 2019 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.7 + +Text { + id: root + property real size: 32 + font.pixelSize: size + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignLeft + font.family: "Graphik" + font.weight: Font.Medium +} diff --git a/interface/resources/qml/stylesUit/GraphikRegular.qml b/interface/resources/qml/stylesUit/GraphikRegular.qml new file mode 100644 index 0000000000..0c9adf2af4 --- /dev/null +++ b/interface/resources/qml/stylesUit/GraphikRegular.qml @@ -0,0 +1,20 @@ +// +// GraphikRegular.qml +// +// Created by Wayne Chen on 2 May 2019 +// Copyright 2019 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.7 + +Text { + id: root + property real size: 32 + font.pixelSize: size + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignLeft + font.family: "Graphik" +} diff --git a/interface/resources/qml/stylesUit/GraphikSemiBold.qml b/interface/resources/qml/stylesUit/GraphikSemiBold.qml new file mode 100644 index 0000000000..12dcb1d5a7 --- /dev/null +++ b/interface/resources/qml/stylesUit/GraphikSemiBold.qml @@ -0,0 +1,21 @@ +// +// GraphikSemiBold.qml +// +// Created by Wayne Chen on 2 May 2019 +// Copyright 2019 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.7 + +Text { + id: root + property real size: 32 + font.pixelSize: size + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignLeft + font.family: "Graphik" + font.weight: Font.DemiBold +} diff --git a/interface/resources/qml/stylesUit/qmldir b/interface/resources/qml/stylesUit/qmldir index 7257353c6e..9d942c7b23 100644 --- a/interface/resources/qml/stylesUit/qmldir +++ b/interface/resources/qml/stylesUit/qmldir @@ -5,12 +5,16 @@ FiraSansRegular 1.0 FiraSansRegular.qml FiraSansSemiBold 1.0 FiraSansSemiBold.qml HifiConstants 1.0 HifiConstants.qml HiFiGlyphs 1.0 HiFiGlyphs.qml +GraphikMedium 1.0 GraphikMedium.qml +GraphikRegular 1.0 GraphikRegular.qml +GraphikSemiBold 1.0 GraphikSemiBold.qml IconButton 1.0 IconButton.qml InfoItem 1.0 InfoItem.qml InputLabel 1.0 InputLabel.qml ListItem 1.0 ListItem.qml Logs 1.0 Logs.qml OverlayTitle 1.0 OverlayTitle.qml +Rawline 1.0 Rawline.qml RalewayBold 1.0 RalewayBold.qml RalewayLight 1.0 RalewayLight.qml RalewayRegular 1.0 RalewayRegular.qml @@ -19,4 +23,4 @@ SectionName 1.0 SectionName.qml Separator 1.0 Separator.qml ShortcutText 1.0 ShortcutText.qml TabName 1.0 TabName.qml -TextFieldInput 1.0 TextFieldInput.qml \ No newline at end of file +TextFieldInput 1.0 TextFieldInput.qml diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ef1ab23e1b..ab69e272da 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1116,6 +1116,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo QFontDatabase::addApplicationFont(PathUtils::resourcesPath() + "fonts/Raleway-Bold.ttf"); QFontDatabase::addApplicationFont(PathUtils::resourcesPath() + "fonts/Raleway-SemiBold.ttf"); QFontDatabase::addApplicationFont(PathUtils::resourcesPath() + "fonts/Cairo-SemiBold.ttf"); + QFontDatabase::addApplicationFont(PathUtils::resourcesPath() + "fonts/Graphik-SemiBold.ttf"); + QFontDatabase::addApplicationFont(PathUtils::resourcesPath() + "fonts/Graphik-Regular.ttf"); + QFontDatabase::addApplicationFont(PathUtils::resourcesPath() + "fonts/Graphik-Medium.ttf"); _window->setWindowTitle("High Fidelity Interface"); Model::setAbstractViewStateInterface(this); // The model class will sometimes need to know view state details from us @@ -3062,6 +3065,7 @@ void Application::initializeUi() { QmlContextCallback commerceCallback = [](QQmlContext* context) { context->setContextProperty("Commerce", DependencyManager::get().data()); }; + OffscreenQmlSurface::addWhitelistContextHandler({ QUrl{ "hifi/commerce/checkout/Checkout.qml" }, QUrl{ "hifi/commerce/common/CommerceLightbox.qml" }, @@ -3087,6 +3091,7 @@ void Application::initializeUi() { QUrl{ "hifi/dialogs/security/SecurityImageSelection.qml" }, QUrl{ "hifi/tablet/TabletMenu.qml" }, QUrl{ "hifi/commerce/marketplace/Marketplace.qml" }, + QUrl{ "hifi/simplifiedUI/avatarApp/AvatarApp.qml" }, }, commerceCallback); QmlContextCallback marketplaceCallback = [](QQmlContext* context) { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 7179c31d91..bb5e4c17df 100755 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -370,6 +370,8 @@ class MyAvatar : public Avatar { Q_PROPERTY(QUuid SELF_ID READ getSelfID CONSTANT) Q_PROPERTY(float walkSpeed READ getWalkSpeed WRITE setWalkSpeed); + Q_PROPERTY(float analogPlusWalkSpeed READ getAnalogPlusWalkSpeed WRITE setAnalogPlusWalkSpeed); + Q_PROPERTY(float analogPlusSprintSpeed READ getAnalogPlusSprintSpeed WRITE setAnalogPlusSprintSpeed); Q_PROPERTY(float walkBackwardSpeed READ getWalkBackwardSpeed WRITE setWalkBackwardSpeed); Q_PROPERTY(float sprintSpeed READ getSprintSpeed WRITE setSprintSpeed); Q_PROPERTY(bool isInSittingState READ getIsInSittingState WRITE setIsInSittingState); diff --git a/scripts/system/simplifiedNametag/resources/modules/defaultLocalEntityProps.js b/scripts/system/simplifiedNametag/resources/modules/defaultLocalEntityProps.js new file mode 100644 index 0000000000..1947a47220 --- /dev/null +++ b/scripts/system/simplifiedNametag/resources/modules/defaultLocalEntityProps.js @@ -0,0 +1,26 @@ +// +// Simplified Nametag +// defaultLocalEntityProps.js +// Created by Milad Nazeri on 2019-03-09 +// Copyright 2019 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 +// +// Base properties for the Local Entities +// + +var localEntityProps = { + dimensions: [1, 0.1, 0], + type: "Text", + lineHeight: 0.1, + textColor: "#ffffff", + textAlpha: 1.0, + backgroundColor: "#2d2d2d", + backgroundAlpha: 0.6, + billboardMode: "full", + lifetime: 3, + canCastShadow: true +}; + +module.exports = localEntityProps; \ No newline at end of file diff --git a/scripts/system/simplifiedNametag/resources/modules/entityMaker.js b/scripts/system/simplifiedNametag/resources/modules/entityMaker.js new file mode 100644 index 0000000000..5b254f9ba5 --- /dev/null +++ b/scripts/system/simplifiedNametag/resources/modules/entityMaker.js @@ -0,0 +1,154 @@ +// +// Simplified Nametag +// entityMaker.js +// Created by Milad Nazeri on 2019-02-19 +// Copyright 2019 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 +// +// A helper library to make entities +// + + +Script.require('./objectAssign.js'); + +function EntityMaker(type) { + this.properties = {}; + this.cache = {}; + this.id = null; + this.created = null; + this.type = type; +} + + +// ************************************* +// START API +// ************************************* +// #region API + + +// Add properties to the cache / temporary storage +function add(props){ + // You can either add an object of props or 2 arguments as key and value + if (arguments.length === 2) { + var property = arguments[0]; + var value = arguments[1]; + props = {}; + props[property] = value; + } + + this.properties = Object.assign({}, this.properties, props); + this.cache = Object.assign({}, this.cache, this.properties); + + return this; +} + + +// Sends the current temporary stroage to edit the entity +function sync(){ + Entities.editEntity(this.id, this.properties); + this.properties = {}; + + return this; +} + + +// Immediately edit the entity with the properties given +function edit(props){ + if (arguments.length === 2) { + var property = arguments[0]; + var value = arguments[1]; + props = {}; + props[property] = value; + } + this.properties = Object.assign({}, this.properties, props); + this.cache = Object.assign({}, this.cache, this.properties); + this.sync(); + + return this; +} + + +// Get a property either from the cache or by querying the entity directly +function get(propertyKeys, queryEntity){ + if (queryEntity && typeof propertyKeys === 'string') { + var propertyValue = Entities.getEntityProperties(this.id, propertyKeys)[propertyKeys]; + this.properties[propertyKeys] = propertyValue; + this.cache = Object.assign({}, this.cache, this.properties); + return propertyValue; + } + + if (queryEntity && Array.isArray(propertyKeys)) { + var entityProps = Entities.getEntityProperties(this.id, propertyKeys); + for (var prop in entityProps) { + if (propertyKeys.indexOf(prop) === -1) { + delete entityProps[prop]; + } else { + this.properties[prop] = entityProps[prop]; + } + } + return entityProps; + } + + if (Array.isArray(propertyKeys)) { + var recombinedProps = {}; + propertyKeys.forEach(function (prop) { + recombinedProps[prop] = this.cache[prop]; + }, this); + return recombinedProps; + } + + return this.cache[propertyKeys]; +} + + +// Show the entity +function show(){ + this.edit({ visible: true }); + + return this; +} + + +// Hide the enity +function hide(){ + this.edit({ visible: false }); +} + + +// Add an entity if it isn't created +function create(clearPropertiesAfter){ + this.id = Entities.addEntity(this.properties, this.type); + if (clearPropertiesAfter) { + this.properties = {}; + } + return this; +} + + +// Delete the entity +function destroy(){ + Entities.deleteEntity(this.id); + + return this; +} + + +// #endregion +// ************************************* +// END API +// ************************************* + +EntityMaker.prototype = { + add: add, + sync: sync, + edit: edit, + get: get, + show: show, + hide: hide, + create: create, + destroy: destroy +}; + +module.exports = EntityMaker; \ No newline at end of file diff --git a/scripts/system/simplifiedNametag/resources/modules/nameTagListManager.js b/scripts/system/simplifiedNametag/resources/modules/nameTagListManager.js new file mode 100644 index 0000000000..1d9e82338e --- /dev/null +++ b/scripts/system/simplifiedNametag/resources/modules/nameTagListManager.js @@ -0,0 +1,687 @@ +// +// Simplified Nametag +// nameTagListManager.js +// Created by Milad Nazeri on 2019-03-09 +// Copyright 2019 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 +// +// Helps manage the list of avatars added to the nametag list +// + + +var ON = 'ON'; +var OFF = 'OFF'; +var DEBUG_ON = true; +var DEBUG_OFF = false; +var log = Script.require( + 'https://hifi-content.s3.amazonaws.com/milad/ROLC/d/ROLC_High-Fidelity/02_Organize/O_Projects/Repos/hifi-content/developerTools/sharedLibraries/easyLog/easyLog.js?' + + Date.now())(DEBUG_OFF, 'nameTagListManager.js'); + + +var EntityMaker = Script.require('./entityMaker.js?' + Date.now()); +var entityProps = Script.require('./defaultLocalEntityProps.js?' + Date.now()); +var textHelper = new (Script.require('./textHelper.js?' + Date.now())); +var X = 0; +var Y = 1; +var Z = 2; +var HALF = 0.5; +var CLEAR_ENTITY_EDIT_PROPS = true; +var MILISECONDS_IN_SECOND = 1000; + +// ************************************* +// START UTILTY +// ************************************* +// #region UTILTY + + +// Properties to give new avatars added to the list +function NewAvatarProps() { + return { + avatarInfo: null, + previousDistance: null, + currentDistance: null, + initialDistance: null, + initialDimensions: null, + previousName: null, + timeoutStarted: false + }; +} + + +// Makes sure clear interval exists before changing +function maybeClearInterval() { + if (_this.redrawTimeout) { + Script.clearInterval(_this.redrawTimeout); + _this.redrawTimeout = null; + } +} + + +// Calculate our initial properties for the nametag +var Z_SIZE = 0.01; +var LINE_HEIGHT_SCALER = 0.99; +var DISTANCE_SCALER_ON = 0.35; +var DISTANCE_SCALER_ALWAYS_ON = 0.65; +var distanceScaler = DISTANCE_SCALER_ON; +var userScaler = 1.0; +var DEFAULT_LINE_HEIGHT = entityProps.lineHeight; +function calculateInitialProperties(uuid) { + var avatar = _this.avatars[uuid]; + var avatarInfo = avatar.avatarInfo; + + var adjustedScaler = null; + var distance = null; + var dimensions = null; + var lineHeight = null; + var scaledDimensions = null; + var name = null; + + // Handle if we are asking for the main or sub properties + name = avatarInfo.displayName; + + // Use the text helper to calculate what our dimensions for the text box should be + textHelper + .setText(name) + .setLineHeight(DEFAULT_LINE_HEIGHT); + + // Calculate the distance from the camera to the target avatar + distance = getDistance(uuid); + + // Adjust the distance by the distance scaler + distanceScaler = avatarNametagMode === "on" ? DISTANCE_SCALER_ON : DISTANCE_SCALER_ALWAYS_ON; + adjustedScaler = distance * distanceScaler; + // Get the new dimensions from the text helper + dimensions = [textHelper.getTotalTextLength(), DEFAULT_LINE_HEIGHT, Z_SIZE]; + // Adjust the dimensions by the modified distance scaler + scaledDimensions = Vec3.multiply(dimensions, adjustedScaler); + + // Adjust the lineheight to be the new scaled dimensions Y + lineHeight = scaledDimensions[Y] * LINE_HEIGHT_SCALER; + + return { + distance: distance, + scaledDimensions: scaledDimensions, + lineHeight: lineHeight + }; +} + + +// Used in alwaysOn mode to show or hide if they reached the max radius +function showHide(uuid, type) { + var avatar = _this.avatars[uuid]; + var nametag = avatar.nametag; + + if (type === "show") { + nametag.show(); + } else { + nametag.hide(); + } +} + + +// Go through the selected avatar list and see if any of the avatars need a redraw +function checkAllSelectedForRedraw() { + for (var avatar in _this.selectedAvatars) { + maybeRedraw(avatar); + } +} + + +// Remake the nametags if the display name changes +function updateName(uuid) { + var avatar = _this.avatars[uuid]; + avatar.nametag.destroy(); + + avatar.nametag = new EntityMaker('local').add(entityProps); + + makeNameTag(uuid); +} + + +// Get the current data for an avatar. +function getAvatarData(uuid) { + var avatar = _this.avatars[uuid]; + var avatarInfo = avatar.avatarInfo; + + var newAvatarInfo = AvatarManager.getAvatar(uuid); + // Save the username so it doesn't get overwritten when grabbing new avatarData + var combinedAvatarInfo = Object.assign({}, newAvatarInfo, { + username: avatarInfo === null ? null : avatarInfo.username + }); + + // Now combine that avatar data with the main avatar object + _this.avatars[uuid] = Object.assign({}, avatar, { avatarInfo: combinedAvatarInfo }); + + return _this; +} + + +// Calculate the distance between the camera and the target avatar +function getDistance(uuid, checkAvatar, shouldSave) { + checkAvatar = checkAvatar || false; + shouldSave = shouldSave || true; + var eye = checkAvatar ? MyAvatar.position : Camera.position; + var avatar = _this.avatars[uuid]; + var avatarInfo = avatar.avatarInfo; + + var target = avatarInfo.position; + + var currentDistance = Vec3.distance(target, eye); + + if (!checkAvatar && shouldSave) { + avatar.previousDistance = avatar.currentDistance; + avatar.currentDistance = currentDistance; + } + + return currentDistance; +} + + +// Check to see if we need to toggle our interval check because we went to 0 avatars +// or if we got our first avatar in the select list +function shouldToggleInterval() { + var currentNumberOfAvatarsSelected = Object.keys(_this.selectedAvatars).length; + + if (currentNumberOfAvatarsSelected === 0 && _this.redrawTimeout) { + toggleInterval(); + return; + } + + if (currentNumberOfAvatarsSelected > 0 && !_this.redrawTimeout) { + toggleInterval(); + return; + } +} + + +// Turn off and on the redraw check +var INTERVAL_CHECK_MS = 30; +function toggleInterval() { + if (_this.redrawTimeout) { + maybeClearInterval(); + } else { + _this.redrawTimeout = + Script.setInterval(checkAllSelectedForRedraw, INTERVAL_CHECK_MS); + } +} + + +// handle turning the peristenet mode on +function handleAlwaysOnMode(shouldTurnOnAlwaysOnMode) { + _this.reset(); + if (shouldTurnOnAlwaysOnMode) { + AvatarManager + .getAvatarIdentifiers() + .forEach(function (avatar) { + if (avatar) { + add(avatar); + } + }); + } +} + + +// #endregion +// ************************************* +// END UTILTY +// ************************************* + +// ************************************* +// START Nametag +// ************************************* +// #region Nametag + + +var _this = null; +function nameTagListManager() { + _this = this; + + _this.avatars = {}; + _this.selectedAvatars = {}; + _this.redrawTimeout = null; +} + + +// Create or make visible either the sub or the main tag. +var REDRAW_TIMEOUT_AMOUNT_MS = 500; +var LEFT_MARGIN_SCALER = 0.15; +var RIGHT_MARGIN_SCALER = 0.10; +var TOP_MARGIN_SCALER = 0.07; +var BOTTOM_MARGIN_SCALER = 0.03; +var ABOVE_HEAD_OFFSET = 0.30; +var DISTANCE_SCALER_INTERPOLATION_OFFSET_ALWAYSON = 25; +var DISTANCE_SCALER_INTERPOLATION_OFFSET_ON = 10; +var maxDistance = MAX_RADIUS_IGNORE_METERS; +var onModeScalar = 0.60; +var alwaysOnModeScalar = -0.55; +function makeNameTag(uuid) { + var avatar = _this.avatars[uuid]; + var avatarInfo = avatar.avatarInfo; + var nametag = avatar.nametag; + + // Make sure an anonymous name is covered before sending to calculate + + avatarInfo.displayName = avatarInfo.displayName === "" ? "anonymous" : avatarInfo.displayName.trim(); + avatar.previousName = avatarInfo.displayName; + + // Returns back the properties we need based on what we are looking for and the distance from the avatar + var calculatedProps = calculateInitialProperties(uuid); + var distance = calculatedProps.distance; + var scaledDimensions = calculatedProps.scaledDimensions; + var lineHeight = calculatedProps.lineHeight; + + // Capture the inital dimensions, distance, and displayName in case we need to redraw + avatar.previousDisplayName = avatarInfo.displayName; + avatar.initialDimensions = scaledDimensions; + avatar.initialDistance = distance; + var name = avatarInfo.displayName; + var parentID = uuid; + + nametag.add("text", name); + + // Multiply the new dimensions and line height with the user selected scaler + scaledDimensions = Vec3.multiply(scaledDimensions, userScaler); + + maxDistance = avatarNametagMode === "on" + ? MAX_ON_MODE_DISTANCE + DISTANCE_SCALER_INTERPOLATION_OFFSET_ON + : MAX_RADIUS_IGNORE_METERS + DISTANCE_SCALER_INTERPOLATION_OFFSET_ALWAYSON; + var finalScaler = (distance - maxDistance) / (MIN_DISTANCE - maxDistance); + + var remainder = 1 - finalScaler; + var multipliedRemainderOn = remainder * onModeScalar; + var multipliedRemainderAlwaysOn = remainder * alwaysOnModeScalar; + finalScaler = avatarNametagMode === "on" ? finalScaler + multipliedRemainderOn : finalScaler + multipliedRemainderAlwaysOn; + + scaledDimensions = Vec3.multiply(scaledDimensions, finalScaler); + + lineHeight = scaledDimensions[Y] * LINE_HEIGHT_SCALER; + // Add some room for the margin by using lineHeight as a reference + scaledDimensions[X] += (lineHeight * LEFT_MARGIN_SCALER) + (lineHeight * RIGHT_MARGIN_SCALER); + scaledDimensions[Y] += (lineHeight * TOP_MARGIN_SCALER) + (lineHeight * BOTTOM_MARGIN_SCALER); + + var scaledDimenionsYHalf = scaledDimensions[Y] * HALF; + var AvatarData = AvatarManager.getAvatar(uuid); + var headJointIndex = AvatarData.getJointIndex("Head"); + var jointInObjectFrame = AvatarData.getAbsoluteJointTranslationInObjectFrame(headJointIndex); + var nameTagPosition = jointInObjectFrame.y + scaledDimenionsYHalf + ABOVE_HEAD_OFFSET; + var localPosition = [0, nameTagPosition, 0]; + + var visible = true; + if (avatarNametagMode === "alwaysOn") { + var currentDistance = getDistance(uuid, CHECK_AVATAR, false); + visible = currentDistance > MAX_RADIUS_IGNORE_METERS ? false : true; + } + + nametag + .add("leftMargin", lineHeight * LEFT_MARGIN_SCALER) + .add("rightMargin", lineHeight * RIGHT_MARGIN_SCALER) + .add("topMargin", lineHeight * TOP_MARGIN_SCALER) + .add("bottomMargin", lineHeight * BOTTOM_MARGIN_SCALER) + .add("lineHeight", lineHeight) + .add("dimensions", scaledDimensions) + .add("parentID", parentID) + .add("localPosition", localPosition) + .add("visible", visible) + .create(CLEAR_ENTITY_EDIT_PROPS); + + Script.setTimeout(function () { + nametag.edit("visible", true); + }, REDRAW_TIMEOUT_AMOUNT_MS); +} + + +// Check to see if the display named changed or if the distance is big enough to need a redraw. +var MAX_RADIUS_IGNORE_METERS = 22; +var MAX_ON_MODE_DISTANCE = 30; +var CHECK_AVATAR = true; +var MIN_DISTANCE = 0.2; +function maybeRedraw(uuid) { + var avatar = _this.avatars[uuid]; + var avatarInfo = avatar.avatarInfo; + getAvatarData(uuid); + + getDistance(uuid); + var avatarDistance = getDistance(uuid, CHECK_AVATAR, false); + if (avatarNametagMode === "alwaysOn" && avatarDistance > MAX_RADIUS_IGNORE_METERS) { + showHide(uuid, "hide"); + } + + if (avatarNametagMode === "alwaysOn" && avatarDistance < MAX_RADIUS_IGNORE_METERS) { + showHide(uuid, "show"); + } + + avatarInfo.displayName = avatarInfo.displayName === "" ? "anonymous" : avatarInfo.displayName.trim(); + + if (avatar.previousName !== avatarInfo.displayName) { + updateName(uuid, avatarInfo.displayName); + } else { + redraw(uuid); + } + +} + + +// Handle redrawing if needed +function redraw(uuid) { + var avatar = _this.avatars[uuid]; + + var nametag = avatar.nametag; + var initialDimensions = null; + var initialDistance = null; + var currentDistance = null; + var newDimensions = null; + var lineHeight = null; + + initialDistance = avatar.initialDistance; + currentDistance = avatar.currentDistance; + + initialDimensions = avatar.initialDimensions; + + // Find our new dimensions from the new distance + newDimensions = [ + (initialDimensions[X] / initialDistance) * currentDistance, + (initialDimensions[Y] / initialDistance) * currentDistance, + (initialDimensions[Z] / initialDistance) * currentDistance + ]; + + // Multiply the new dimensions and line height with the user selected scaler + newDimensions = Vec3.multiply(newDimensions, userScaler); + + var distance = getDistance(uuid, false, false); + + maxDistance = avatarNametagMode === "on" + ? MAX_ON_MODE_DISTANCE + DISTANCE_SCALER_INTERPOLATION_OFFSET_ON + : MAX_RADIUS_IGNORE_METERS + DISTANCE_SCALER_INTERPOLATION_OFFSET_ALWAYSON; + var finalScaler = (distance - maxDistance) / (MIN_DISTANCE - maxDistance); + var remainder = 1 - finalScaler; + var multipliedRemainderOn = remainder * onModeScalar; + var multipliedRemainderAlwaysOn = remainder * alwaysOnModeScalar; + finalScaler = avatarNametagMode === "on" ? finalScaler + multipliedRemainderOn : finalScaler + multipliedRemainderAlwaysOn; + + newDimensions = Vec3.multiply(newDimensions, finalScaler); + + lineHeight = newDimensions[Y] * LINE_HEIGHT_SCALER; + + // Add some room for the margin by using lineHeight as a reference + newDimensions[X] += (lineHeight * LEFT_MARGIN_SCALER) + (lineHeight * RIGHT_MARGIN_SCALER); + newDimensions[Y] += (lineHeight * TOP_MARGIN_SCALER) + (lineHeight * BOTTOM_MARGIN_SCALER); + + // We can generalize some of the processes that are similar in makeNameTag() and redraw() if we wanted to reduce some code + var newDimenionsYHalf = newDimensions[Y] * HALF; + var AvatarData = AvatarManager.getAvatar(uuid); + var headJointIndex = AvatarData.getJointIndex("Head"); + var jointInObjectFrame = AvatarData.getAbsoluteJointTranslationInObjectFrame(headJointIndex); + var nameTagPosition = jointInObjectFrame.y + newDimenionsYHalf + ABOVE_HEAD_OFFSET; + var localPosition = [0, nameTagPosition, 0]; + + nametag + .add("leftMargin", lineHeight * LEFT_MARGIN_SCALER) + .add("rightMargin", lineHeight * RIGHT_MARGIN_SCALER) + .add("topMargin", lineHeight * TOP_MARGIN_SCALER) + .add("bottomMargin", lineHeight * BOTTOM_MARGIN_SCALER) + .add("lineHeight", lineHeight) + .add("dimensions", newDimensions) + .add("localPosition", localPosition) + .sync(); +} + +// Add a user to the list. +var DEFAULT_LIFETIME = entityProps.lifetime; + +// setup to get the outline in on mode +var NAMETAG_SELECTION_LIST = "NAMETAG_SELECTION_LIST"; +var nametagSelectionProps = { + outlineUnoccludedColor: { red: 255, green: 255, blue: 255 }, + outlineOccludedColor: { red: 235, green: 87, blue: 87 }, + fillUnoccludedColor: { red: 235, green: 87, blue: 87 }, + fillOccludedColor: { red: 235, green: 87, blue: 87 }, + outlineUnoccludedAlpha: 1, + outlineOccludedAlpha: 0, + fillUnoccludedAlpha: 0, + fillOccludedAlpha: 0, + outlineWidth: 3, + isOutlineSmooth: true +}; +Selection.enableListHighlight(NAMETAG_SELECTION_LIST, nametagSelectionProps); + + +// add a user to our current selections +function add(uuid) { + // User Doesn't exist so give them new props and save in the cache, and get their current avatar info. + if (!_this.avatars[uuid]) { + _this.avatars[uuid] = new NewAvatarProps(); + getAvatarData(uuid); + } + + var avatar = _this.avatars[uuid]; + + _this.selectedAvatars[uuid] = true; + if (avatarNametagMode === "alwaysOn") { + entityProps.lifetime = -1; + } else { + entityProps.lifetime = DEFAULT_LIFETIME; + } + + avatar.nametag = new EntityMaker('local').add(entityProps); + + // When the user clicks someone, we create their nametag + makeNameTag(uuid); + var deleteEnttyInMiliseconds = entityProps.lifetime * MILISECONDS_IN_SECOND; + + // Remove from list after lifetime is over + if (avatarNametagMode === "on") { + Selection.addToSelectedItemsList(NAMETAG_SELECTION_LIST, "avatar", uuid); + avatar.timeoutStarted = Script.setTimeout(function () { + removeNametag(uuid); + }, deleteEnttyInMiliseconds); + } + + // Check to see if anyone is in the selected list now to see if we need to start the interval checking + shouldToggleInterval(); + + return _this; +} + + +// Remove the avatar from the list. +function remove(uuid) { + if (_this.selectedAvatars[uuid]) { + delete _this.selectedAvatars[uuid]; + } + + removeNametag(uuid); + + shouldToggleInterval(); + delete _this.avatars[uuid]; + + return _this; +} + + +// Remove all the current nametags. +function removeAllNametags() { + for (var uuid in _this.selectedAvatars) { + removeNametag(uuid); + } + + return _this; +} + + +// Remove a single Nametag. +function removeNametag(uuid) { + var avatar = _this.avatars[uuid]; + + if (avatar) { + avatar.nametag.destroy(); + delete _this.selectedAvatars[uuid]; + Selection.removeFromSelectedItemsList(NAMETAG_SELECTION_LIST, "avatar", uuid); + return _this; + } + +} + + +// #endregion +// ************************************* +// END Nametag +// ************************************* + +// ************************************* +// START API +// ************************************* +// #region API + + +// Create the manager and hook up username signal +function create() { + + return _this; +} + + +// Destory the manager and disconnect from username signal +function destroy() { + _this.reset(); + return _this; +} + + +// Check to see if we need to delete any close by nametags +var MAX_DELETE_RANGE = 4; +function checkIfAnyAreClose(target) { + var targetPosition = AvatarManager.getAvatar(target).position; + for (var uuid in _this.selectedAvatars) { + var position = AvatarManager.getAvatar(uuid).position; + var distance = Vec3.distance(position, targetPosition); + if (distance <= MAX_DELETE_RANGE) { + var timeoutStarted = _this.avatars[uuid].timeoutStarted; + if (timeoutStarted) { + Script.clearTimeout(timeoutStarted); + timeoutStarted = null; + } + removeNametag(uuid); + } + } +} + +// Handles what happens when an avatar gets triggered on +function handleSelect(uuid) { + if (avatarNametagMode === "off" || avatarNametagMode === "alwaysOn") { + return; + } + + var inSelected = uuid in _this.selectedAvatars; + + if (inSelected) { + if (avatarNametagMode === "on") { + var timeoutStarted = _this.avatars[uuid].timeoutStarted; + if (timeoutStarted) { + Script.clearTimeout(timeoutStarted); + timeoutStarted = null; + } + } + + removeNametag(uuid); + + } else { + checkIfAnyAreClose(uuid); + add(uuid); + } +} + + +// Check to see if we need to clear timeouts for avatars +function maybeClearAllTimeouts() { + for (var uuid in _this.selectedAvatars) { + var timeoutStarted = _this.avatars[uuid].timeoutStarted; + if (timeoutStarted) { + Script.clearTimeout(timeoutStarted); + timeoutStarted = null; + } + } +} + + +// Check to see if the uuid is in the avatars list before removing +function maybeRemove(uuid) { + if (uuid in _this.avatars) { + remove(uuid); + } +} + + +// Check to see if we need to add this user to our list +function maybeAdd(uuid) { + if (uuid && avatarNametagMode === "alwaysOn" && !(uuid in _this.avatars)) { + add(uuid); + } +} + + +// Register the beggining scaler in case it was saved from a previous session +function registerInitialScaler(initalScaler) { + userScaler = initalScaler; +} + + +// Handle the user updating scale +function updateUserScaler(newUSerScaler) { + userScaler = newUSerScaler; + for (var avatar in _this.selectedAvatars) { + redraw(avatar); + } +} + + +// Reset the avatar list +function reset() { + maybeClearAllTimeouts(); + removeAllNametags(); + _this.avatars = {}; + shouldToggleInterval(); + + return _this; +} + + +// Update the nametag display mode +var avatarNametagMode = "on"; +function handleAvatarNametagMode(newAvatarNametagMode) { + if (avatarNametagMode === "alwaysOn") { + handleAlwaysOnMode(false); + } + + avatarNametagMode = newAvatarNametagMode; + if (avatarNametagMode === "alwaysOn") { + handleAlwaysOnMode(true); + } + + if (avatarNametagMode === "off" || avatarNametagMode === "on") { + reset(); + } +} + + +// #endregion +// ************************************* +// END API +// ************************************* + + +nameTagListManager.prototype = { + create: create, + destroy: destroy, + handleSelect: handleSelect, + maybeRemove: maybeRemove, + maybeAdd: maybeAdd, + registerInitialScaler: registerInitialScaler, + updateUserScaler: updateUserScaler, + handleAvatarNametagMode: handleAvatarNametagMode, + reset: reset +}; + + +module.exports = nameTagListManager; \ No newline at end of file diff --git a/scripts/system/simplifiedNametag/resources/modules/objectAssign.js b/scripts/system/simplifiedNametag/resources/modules/objectAssign.js new file mode 100644 index 0000000000..c408b0ebc8 --- /dev/null +++ b/scripts/system/simplifiedNametag/resources/modules/objectAssign.js @@ -0,0 +1,32 @@ +// taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign + +if (typeof Object.assign != 'function') { + // Must be writable: true, enumerable: false, configurable: true + Object.defineProperty(Object, "assign", { + value: function assign(target, varArgs) { // .length of function is 2 + 'use strict'; + if (target == null) { // TypeError if undefined or null + throw new TypeError('Cannot convert undefined or null to object'); + } + + var to = Object(target); + + for (var index = 1; index < arguments.length; index++) { + var nextSource = arguments[index]; + + if (nextSource != null) { // Skip over if undefined or null + for (var nextKey in nextSource) { + // Avoid bugs when hasOwnProperty is shadowed + if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { + to[nextKey] = nextSource[nextKey]; + } + } + } + } + return to; + }, + writable: true, + configurable: true + }); +} + diff --git a/scripts/system/simplifiedNametag/resources/modules/pickRayController.js b/scripts/system/simplifiedNametag/resources/modules/pickRayController.js new file mode 100644 index 0000000000..87d05fa838 --- /dev/null +++ b/scripts/system/simplifiedNametag/resources/modules/pickRayController.js @@ -0,0 +1,305 @@ +// +// Simplified Nametag +// pickRayController.js +// Created by Milad Nazeri on 2019-03-08 +// Copyright 2019 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 +// +// Easy pickray controllers for Entities, Overlays, and Avatars +// + + +var _this; +function PickRayController(){ + _this = this; + + _this.rayType = null; + _this.eventHandler = null; + _this.intersection = null; + _this.lastPick = null; + _this.currentPick = null; + _this.mappingName = null; + _this.mapping = null; + _this._boundMousePressHandler = null; + _this.shouldDoublePress = null; + _this.controllEnabled = false; +} + + +// ************************************* +// START UTILITY +// ************************************* +// #region UTILITY + + +// Returns the right UUID based on hand triggered +function getUUIDFromLaser(hand) { + hand = hand === Controller.Standard.LeftHand + ? Controller.Standard.LeftHand + : Controller.Standard.RightHand; + + var pose = getControllerWorldLocation(hand); + var start = pose.position; + // Get the direction that the hand is facing in the world + var direction = Vec3.multiplyQbyV(pose.orientation, [0, 1, 0]); + + pickRayTypeHandler(start, direction); + + if (_this.currentPick) { + _this.eventHandler(_this.currentPick, _this.intersection); + } +} + + +// The following two functions are a modified version of what's found in scripts/system/libraries/controllers.js + +// Utility function for the ControllerWorldLocation offset +function getGrabPointSphereOffset(handController) { + // These values must match what's in scripts/system/libraries/controllers.js + // x = upward, y = forward, z = lateral + var GRAB_POINT_SPHERE_OFFSET = { x: 0.04, y: 0.13, z: 0.039 }; + var offset = GRAB_POINT_SPHERE_OFFSET; + if (handController === Controller.Standard.LeftHand) { + offset = { + x: -GRAB_POINT_SPHERE_OFFSET.x, + y: GRAB_POINT_SPHERE_OFFSET.y, + z: GRAB_POINT_SPHERE_OFFSET.z + }; + } + + return Vec3.multiply(MyAvatar.sensorToWorldScale, offset); +} + + +// controllerWorldLocation is where the controller would be, in-world, with an added offset +function getControllerWorldLocation(handController, doOffset) { + var orientation; + var position; + var valid = false; + + if (handController >= 0) { + var pose = Controller.getPoseValue(handController); + valid = pose.valid; + var controllerJointIndex; + if (pose.valid) { + if (handController === Controller.Standard.RightHand) { + controllerJointIndex = MyAvatar.getJointIndex("_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND"); + } else { + controllerJointIndex = MyAvatar.getJointIndex("_CAMERA_RELATIVE_CONTROLLER_LEFTHAND"); + } + orientation = Quat.multiply(MyAvatar.orientation, MyAvatar.getAbsoluteJointRotationInObjectFrame(controllerJointIndex)); + position = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, MyAvatar.getAbsoluteJointTranslationInObjectFrame(controllerJointIndex))); + + // add to the real position so the grab-point is out in front of the hand, a bit + if (doOffset) { + var offset = getGrabPointSphereOffset(handController); + position = Vec3.sum(position, Vec3.multiplyQbyV(orientation, offset)); + } + + } else if (!HMD.isHandControllerAvailable()) { + // NOTE: keep _this offset in sync with scripts/system/controllers/handControllerPointer.js:493 + var VERTICAL_HEAD_LASER_OFFSET = 0.1 * MyAvatar.sensorToWorldScale; + position = Vec3.sum(Camera.position, Vec3.multiplyQbyV(Camera.orientation, { x: 0, y: VERTICAL_HEAD_LASER_OFFSET, z: 0 })); + orientation = Quat.multiply(Camera.orientation, Quat.angleAxis(-90, { x: 1, y: 0, z: 0 })); + valid = true; + } + } + + return { + position: position, + translation: position, + orientation: orientation, + rotation: orientation, + valid: valid + }; +} + + +// Handle if the uuid picked on is new or different +function handleUUID(uuid){ + if (!_this.lastPick && !_this.currentPick) { + _this.currentPick = uuid; + _this.lastPick = uuid; + } else { + _this.lastPick = _this.currentPick; + _this.currentPick = uuid; + } +} + + +function pickRayTypeHandler(pickRay){ + // Handle if pickray is system generated or user generated + if (arguments.length === 2) { + pickRay = { origin: arguments[0], direction: arguments[1] }; + } + + // Each different ray pick type needs a different findRayIntersection function + switch (_this.rayType) { + case 'avatar': + var avatarIntersection = AvatarList.findRayIntersection(pickRay, [], [MyAvatar.sessionUUID], false); + _this.intersection = avatarIntersection; + handleUUID(avatarIntersection.avatarID); + break; + case 'local': + var overlayIntersection = Overlays.findRayIntersection(pickRay, [], []); + _this.intersection = overlayIntersection; + handleUUID(overlayIntersection.overlayID); + break; + case 'entity': + var entityIntersection = Entities.findRayIntersection(pickRay, [], []); + _this.intersection = entityIntersection; + handleUUID(entityIntersection.avatarID); + break; + default: + console.log("ray type not handled"); + } +} + + +// Handle the interaction when in desktop and a mouse is pressed +function mousePressHandler(event) { + if (HMD.active || !event.isLeftButton) { + return; + } + var pickRay = Camera.computePickRay(event.x, event.y); + pickRayTypeHandler(pickRay); + if (_this.currentPick) { + _this.eventHandler(_this.currentPick, _this.intersection); + } +} + + +// Function to call when double press is singled +function doublePressHandler(event) { + mousePressHandler(event); +} + + +// #endregion +// ************************************* +// END UTILITY +// ************************************* + +// ************************************* +// START API +// ************************************* +// #region API + + +// After setup is given, this gets the Controller ready to be enabled +function create(){ + _this.mapping = Controller.newMapping(_this.mappingName); + + _this.mapping.from(Controller.Standard.LTClick).to(function (value) { + if (value === 0) { + return; + } + + getUUIDFromLaser(Controller.Standard.LeftHand); + }); + + + _this.mapping.from(Controller.Standard.RTClick).to(function (value) { + if (value === 0) { + return; + } + + getUUIDFromLaser(Controller.Standard.RightHand); + }); + + return _this; +} + + +// Set type of raypick for what kind of uuids to return +function setType(type){ + _this.rayType = type; + + return _this; +} + + +// Set if double presses should register as well +function setShouldDoublePress(shouldDoublePress){ + _this.shouldDoublePress = shouldDoublePress; + + return _this; +} + + +// Set the mapping name for the controller +function setMapName(name) { + _this.mappingName = name; + + return _this; +} + + +// Enables mouse press and trigger events +function enable(){ + if (!_this.controllEnabled) { + Controller.mousePressEvent.connect(mousePressHandler); + if (_this.shouldDoublePress) { + Controller.mouseDoublePressEvent.connect(doublePressHandler); + } + Controller.enableMapping(_this.mappingName); + _this.controllEnabled = true; + + return _this; + } + + return -1; +} + + +// Disable the controller and mouse press +function disable(){ + if (_this.controllEnabled) { + Controller.mousePressEvent.disconnect(mousePressHandler); + if (_this.shouldDoublePress){ + Controller.mouseDoublePressEvent.disconnect(doublePressHandler); + } + Controller.disableMapping(_this.mappingName); + _this.controllEnabled = false; + + return _this; + } + + return -1; +} + + +// Synonym for disable +function destroy(){ + _this.disable(); +} + + +// Register the function to be called on a click +function registerEventHandler(fn){ + _this.eventHandler = fn; + + return _this; +} + + +// #endregion +// ************************************* +// END API +// ************************************* + +PickRayController.prototype = { + create: create, + setType: setType, + setShouldDoublePress: setShouldDoublePress, + setMapName: setMapName, + enable: enable, + disable: disable, + destroy: destroy, + registerEventHandler: registerEventHandler +}; + + +module.exports = PickRayController; diff --git a/scripts/system/simplifiedNametag/resources/modules/textHelper.js b/scripts/system/simplifiedNametag/resources/modules/textHelper.js new file mode 100644 index 0000000000..72013a2ac5 --- /dev/null +++ b/scripts/system/simplifiedNametag/resources/modules/textHelper.js @@ -0,0 +1,224 @@ +// +// Simplified Nametag +// textHelper.js +// Created by Milad Nazeri on 2019-03-08 +// Copyright 2019 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 +// +// Module to help calculate text size +// + + +// ************************************* +// START MAPS +// ************************************* +// #region MAPS + + +var charMap = { + a: 0.05, + b: 0.051, + c: 0.05, + d: 0.051, + e: 0.05, + f: 0.035, + g: 0.051, + h: 0.051, + i: 0.025, + j: 0.025, + k: 0.05, + l: 0.025, + m: 0.0775, + n: 0.051, + o: 0.051, + p: 0.051, + q: 0.051, + r: 0.035, + s: 0.05, + t: 0.035, + u: 0.051, + v: 0.05, + w: 0.07, + x: 0.05, + y: 0.05, + z: 0.05, + A: 0.06, + B: 0.06, + C: 0.06, + D: 0.06, + E: 0.05, + F: 0.05, + G: 0.06, + H: 0.0625, + I: 0.0275, + J: 0.05, + K: 0.06, + L: 0.05, + M: 0.075, + N: 0.0625, + O: 0.0625, + P: 0.06, + Q: 0.0625, + R: 0.06, + S: 0.06, + T: 0.06, + U: 0.06, + V: 0.06, + W: 0.075, + X: 0.06, + Y: 0.06, + Z: 0.06 +}; + +var symbolMap = { + "!": 0.025, + "@": 0.08, + "#": 0.07, + "$": 0.058, + "%": 0.07, + "^": 0.04, + "&": 0.06, + "*": 0.04, + "(": 0.04, + ")": 0.04, + "_": 0.041, + "{": 0.034, + "}": 0.034, + "/": 0.04, + "|": 0.02, + "<": 0.049, + ">": 0.049, + "[": 0.0300, + "]": 0.0300, + ".": 0.0260, + ",": 0.0260, + "?": 0.048, + "~": 0.0610, + "`": 0.0310, + "+": 0.0510, + "=": 0.0510 +}; + + +// #endregion +// ************************************* +// END MAPS +// ************************************* + +var _this = null; +function TextHelper(){ + _this = this; + + this.text = ""; + this.textArray = ""; + this.lineHeight = 0; + this.totalTextLength = 0; + this.scaler = 1.0; +} + + +// ************************************* +// START UTILITY +// ************************************* +// #region UTILITY + + +// Split the string into a text array to be operated on +function createTextArray(){ + _this.textArray = _this.text.split(""); +} + + +// Account for the text length +function adjustForScale(defaultTextLength){ + _this.totalTextLength = defaultTextLength * _this.scaler; +} + + +// #endregion +// ************************************* +// END UTILITY +// ************************************* + +// #endregion +// ************************************* +// END name +// ************************************* + +// ************************************* +// START API +// ************************************* +// #region API + + +// Set the text that needs to be calculated on +function setText(newText){ + _this.text = newText; + createTextArray(); + + return _this; +} + + +// Set the line height which helps calculate the font size +var DEFAULT_LINE_HEIGHT = 0.1; +function setLineHeight(newLineHeight){ + _this.lineHeight = newLineHeight; + _this.scaler = _this.lineHeight / DEFAULT_LINE_HEIGHT; + + return _this; +} + + +// Calculate the sign dimensions +var DEFAULT_CHAR_SIZE = 0.025; +var NUMBER = 0.05; +var DIGIT_REGEX = /\d/g; +var WHITE_SPACE_REGEX = /[ ]/g; +var SPACE = 0.018; +function getTotalTextLength(){ + // Map the string array to it's sizes + var lengthArray = _this.textArray.map(function(letter){ + if (charMap[letter]){ + return charMap[letter]; + } else if (letter.match(DIGIT_REGEX)){ + return NUMBER; + } else if (symbolMap[letter]) { + return symbolMap[letter]; + } else if (letter.match(WHITE_SPACE_REGEX)) { + return SPACE; + } else { + return DEFAULT_CHAR_SIZE; + } + }); + + // add up all the values in the array + var defaultTextLength = lengthArray.reduce(function(prev, curr){ + return prev + curr; + }, 0); + + adjustForScale(defaultTextLength); + + return _this.totalTextLength; +} + + +// #endregion +// ************************************* +// END API +// ************************************* + +TextHelper.prototype = { + setText: setText, + setLineHeight: setLineHeight, + getTotalTextLength: getTotalTextLength +}; + +module.exports = TextHelper; + +// var text = new TextHelper(); +// text.setText("lowbar"); +// text.setLineHeight("0.1"); +// text.getTotalTextLength(); \ No newline at end of file diff --git a/scripts/system/simplifiedNametag/simplifiedNametag.js b/scripts/system/simplifiedNametag/simplifiedNametag.js new file mode 100644 index 0000000000..75379f4e02 --- /dev/null +++ b/scripts/system/simplifiedNametag/simplifiedNametag.js @@ -0,0 +1,96 @@ +// +// Simplified Nametag +// Created by Milad Nazeri on 2019-02-16 +// Copyright 2019 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 +// +// Click on someone to get a nametag for them +// + +var PickRayController = Script.require('./resources/modules/pickRayController.js?' + Date.now()); +var NameTagListManager = Script.require('./resources/modules/nameTagListManager.js?' + Date.now()); +var pickRayController = new PickRayController(); +var nameTagListManager = new NameTagListManager(); + +// Handles avatar being solo'd +pickRayController + .registerEventHandler(selectAvatar) + .setType("avatar") + .setMapName("hifi_simplifiedNametag") + .setShouldDoublePress(true) + .create() + .enable(); + + +function selectAvatar(uuid, intersection) { + nameTagListManager.handleSelect(uuid, intersection); +} + + +// Handles reset of list if you change domains +function onDomainChange() { + nameTagListManager.reset(); +} + + +// Handles removing an avatar from the list if they leave the domain +function onAvatarRemoved(uuid) { + nameTagListManager.maybeRemove(uuid); +} + + +// Automatically add an avatar if they come into the domain. Mainly used for alwaysOn mode. +function onAvatarAdded(uuid) { + nameTagListManager.maybeAdd(uuid); +} + + +// Called on init +var avatarNametagMode; +function create() { + nameTagListManager.create(); + handleAvatarNametagMode(Settings.getValue("simplifiedNametag/avatarNametagMode", "on")); + + Window.domainChanged.connect(onDomainChange); + AvatarManager.avatarRemovedEvent.connect(onAvatarRemoved); + AvatarManager.avatarAddedEvent.connect(onAvatarAdded); +} + + +// Called when the script is closing +function destroy() { + nameTagListManager.destroy(); + pickRayController.destroy(); + Window.domainChanged.disconnect(onDomainChange); + AvatarManager.avatarRemovedEvent.disconnect(onAvatarRemoved); + AvatarManager.avatarAddedEvent.disconnect(onAvatarAdded); +} + + +// chose which mode you want the nametags in. On, off, or alwaysOn. +function handleAvatarNametagMode(newAvatarNameTagMode) { + avatarNametagMode = newAvatarNameTagMode; + nameTagListManager.handleAvatarNametagMode(avatarNametagMode); + Settings.setValue("simplifiedNametag/avatarNametagMode", avatarNametagMode); +} + + +// ************************************* +// START api +// ************************************* +// #region api + + +module.exports = { + create: create, + destroy: destroy, + handleAvatarNametagMode: handleAvatarNametagMode +}; + + +// #endregion +// ************************************* +// END api +// ************************************* \ No newline at end of file diff --git a/scripts/system/simplifiedUI/images/inputDeviceMuted.svg b/scripts/system/simplifiedUI/images/inputDeviceMuted.svg new file mode 100644 index 0000000000..faeb14cdf8 --- /dev/null +++ b/scripts/system/simplifiedUI/images/inputDeviceMuted.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/scripts/system/simplifiedUI/images/outputDeviceMuted.svg b/scripts/system/simplifiedUI/images/outputDeviceMuted.svg new file mode 100644 index 0000000000..25daf83959 --- /dev/null +++ b/scripts/system/simplifiedUI/images/outputDeviceMuted.svg @@ -0,0 +1,4 @@ + + + + diff --git a/scripts/system/simplifiedUI/simplifiedUI.js b/scripts/system/simplifiedUI/simplifiedUI.js new file mode 100644 index 0000000000..3f73bc91c8 --- /dev/null +++ b/scripts/system/simplifiedUI/simplifiedUI.js @@ -0,0 +1,502 @@ +"use strict"; +/* jslint vars: true, plusplus: true */ + +// +// simplifiedUI.js +// +// Authors: Wayne Chen & Zach Fox +// Created on: 5/1/2019 +// Copyright 2019 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 +// + + +// START CONFIG OPTIONS +var DOCKED_QML_SUPPORTED = false; +var REMOVE_EXISTING_UI = true; +var TOOLBAR_NAME = "com.highfidelity.interface.toolbar.system"; +var DEFAULT_SCRIPTS_PATH_PREFIX = ScriptDiscoveryService.defaultScriptsPath + "/"; +// END CONFIG OPTIONS + + +var DEFAULT_SCRIPTS_SEPARATE = [ + DEFAULT_SCRIPTS_PATH_PREFIX + "system/controllers/controllerScripts.js" +]; +function loadSeparateDefaults() { + for (var i in DEFAULT_SCRIPTS_SEPARATE) { + Script.load(DEFAULT_SCRIPTS_SEPARATE[i]); + } +} + + +var DEFAULT_SCRIPTS_COMBINED = [ + DEFAULT_SCRIPTS_PATH_PREFIX + "system/request-service.js", + DEFAULT_SCRIPTS_PATH_PREFIX + "system/progress.js", + DEFAULT_SCRIPTS_PATH_PREFIX + "system/away.js" +]; +function runDefaultsTogether() { + for (var i in DEFAULT_SCRIPTS_COMBINED) { + Script.include(DEFAULT_SCRIPTS_COMBINED[i]); + } +} + + +var MENU_NAMES = ["File", "Edit", "Display", "View", "Navigate", "Settings", "Developer", "Help"]; +function removeDesktopMenu() { + MENU_NAMES.forEach(function(menu) { + Menu.removeMenu(menu); + }); +} + + +function handleUpdateAvatarThumbnailURL(avatarThumbnailURL) { + if (topBarWindow) { + topBarWindow.sendToQml({ + "source": "simplifiedUI.js", + "method": "updateAvatarThumbnailURL", + "data": { + "avatarThumbnailURL": avatarThumbnailURL + } + }); + } +} + + +var AVATAR_APP_MESSAGE_SOURCE = "AvatarApp.qml"; +function onMessageFromAvatarApp(message) { + if (message.source !== AVATAR_APP_MESSAGE_SOURCE) { + return; + } + + switch (message.method) { + case "updateAvatarThumbnailURL": + handleUpdateAvatarThumbnailURL(message.data.avatarThumbnailURL); + break; + + default: + console.log("Unrecognized message from " + AVATAR_APP_MESSAGE_SOURCE + ": " + JSON.stringify(message)); + break; + } +} + + +function onAvatarAppClosed() { + if (avatarAppWindow) { + avatarAppWindow.fromQml.disconnect(onMessageFromAvatarApp); + avatarAppWindow.closed.disconnect(onAvatarAppClosed); + } + avatarAppWindow = false; +} + + +var AVATAR_APP_QML_PATH = Script.resourcesPath() + "qml/hifi/simplifiedUI/avatarApp/AvatarApp.qml"; +var AVATAR_APP_WINDOW_TITLE = "Your Avatars"; +var AVATAR_APP_PRESENTATION_MODE = Desktop.PresentationMode.NATIVE; +var AVATAR_APP_WIDTH_PX = 480; +var AVATAR_APP_HEIGHT_PX = 615; +var avatarAppWindow = false; +function toggleAvatarApp() { + if (avatarAppWindow) { + avatarAppWindow.close(); + // This really shouldn't be necessary. + // This signal really should automatically be called by the signal handler set up below. + // But fixing that requires an engine change, so this workaround will do. + onAvatarAppClosed(); + return; + } + + avatarAppWindow = Desktop.createWindow(AVATAR_APP_QML_PATH, { + title: AVATAR_APP_WINDOW_TITLE, + presentationMode: AVATAR_APP_PRESENTATION_MODE, + size: { + x: AVATAR_APP_WIDTH_PX, + y: AVATAR_APP_HEIGHT_PX + } + }); + + avatarAppWindow.fromQml.connect(onMessageFromAvatarApp); + avatarAppWindow.closed.connect(onAvatarAppClosed); +} + + +function handleAvatarNametagMode(newAvatarNametagMode) { + simplifiedNametag.handleAvatarNametagMode(newAvatarNametagMode); +} + + +var SETTINGS_APP_MESSAGE_SOURCE = "SettingsApp.qml"; +function onMessageFromSettingsApp(message) { + if (message.source !== SETTINGS_APP_MESSAGE_SOURCE) { + return; + } + + switch (message.method) { + case "handleAvatarNametagMode": + handleAvatarNametagMode(message.avatarNametagMode); + break; + + default: + console.log("Unrecognized message from " + SETTINGS_APP_MESSAGE_SOURCE + ": " + JSON.stringify(message)); + break; + } +} + + +function onSettingsAppClosed() { + if (settingsAppWindow) { + settingsAppWindow.fromQml.disconnect(onMessageFromSettingsApp); + settingsAppWindow.closed.disconnect(onSettingsAppClosed); + } + settingsAppWindow = false; +} + + +var SETTINGS_APP_QML_PATH = Script.resourcesPath() + "qml/hifi/simplifiedUI/settingsApp/SettingsApp.qml"; +var SETTINGS_APP_WINDOW_TITLE = "Settings"; +var SETTINGS_APP_PRESENTATION_MODE = Desktop.PresentationMode.NATIVE; +var SETTINGS_APP_WIDTH_PX = 480; +var SETTINGS_APP_HEIGHT_PX = 615; +var settingsAppWindow = false; +function toggleSettingsApp() { + if (settingsAppWindow) { + settingsAppWindow.close(); + // This really shouldn't be necessary. + // This signal really should automatically be called by the signal handler set up below. + // But fixing that requires an engine change, so this workaround will do. + onSettingsAppClosed(); + return; + } + + settingsAppWindow = Desktop.createWindow(SETTINGS_APP_QML_PATH, { + title: SETTINGS_APP_WINDOW_TITLE, + presentationMode: SETTINGS_APP_PRESENTATION_MODE, + size: { + x: SETTINGS_APP_WIDTH_PX, + y: SETTINGS_APP_HEIGHT_PX + } + }); + + settingsAppWindow.fromQml.connect(onMessageFromSettingsApp); + settingsAppWindow.closed.connect(onSettingsAppClosed); +} + + +function maybeDeleteOutputDeviceMutedOverlay() { + if (outputDeviceMutedOverlay) { + Overlays.deleteOverlay(outputDeviceMutedOverlay); + outputDeviceMutedOverlay = false; + } +} + + +var outputDeviceMutedOverlay = false; +var OUTPUT_DEVICE_MUTED_OVERLAY_DEFAULT_DIMS_PX = 600; +var OUTPUT_DEVICE_MUTED_MARGIN_BOTTOM_PX = 20; +var OUTPUT_DEVICE_MUTED_MARGIN_LEFT_RIGHT_PX = 20; +function updateOutputDeviceMutedOverlay(isMuted) { + if (isMuted) { + var props = { + imageURL: Script.resolvePath("images/outputDeviceMuted.svg"), + alpha: 0.5 + }; + var overlayDims = OUTPUT_DEVICE_MUTED_OVERLAY_DEFAULT_DIMS_PX; + props.x = Window.innerWidth / 2 - overlayDims / 2; + props.y = Window.innerHeight / 2 - overlayDims / 2; + + var outputDeviceMutedOverlayBottomY = props.y + overlayDims; + var inputDeviceMutedOverlayTopY = getInputDeviceMutedOverlayTopY(); + if (outputDeviceMutedOverlayBottomY + OUTPUT_DEVICE_MUTED_MARGIN_BOTTOM_PX > inputDeviceMutedOverlayTopY) { + overlayDims = 2 * (inputDeviceMutedOverlayTopY - Window.innerHeight / 2 - OUTPUT_DEVICE_MUTED_MARGIN_BOTTOM_PX); + } + + if (overlayDims + OUTPUT_DEVICE_MUTED_MARGIN_LEFT_RIGHT_PX > Window.innerWidth) { + overlayDims = Math.min(Window.innerWidth - OUTPUT_DEVICE_MUTED_MARGIN_LEFT_RIGHT_PX, overlayDims); + } else { + overlayDims = Math.min(OUTPUT_DEVICE_MUTED_OVERLAY_DEFAULT_DIMS_PX, overlayDims); + } + + props.width = overlayDims; + props.height = overlayDims; + props.x = Window.innerWidth / 2 - overlayDims / 2; + props.y = Window.innerHeight / 2 - overlayDims / 2; + if (outputDeviceMutedOverlay) { + Overlays.editOverlay(outputDeviceMutedOverlay, props); + } else { + outputDeviceMutedOverlay = Overlays.addOverlay("image", props); + } + } else { + maybeDeleteOutputDeviceMutedOverlay(); + } +} + + +var savedAvatarGain = Audio.getAvatarGain(); +var savedInjectorGain = Audio.getInjectorGain(); +var savedLocalInjectorGain = Audio.getLocalInjectorGain(); +var savedSystemInjectorGain = Audio.getSystemInjectorGain(); +function setOutputMuted(outputMuted) { + updateOutputDeviceMutedOverlay(outputMuted); + + if (outputMuted) { + savedAvatarGain = Audio.getAvatarGain(); + savedInjectorGain = Audio.getInjectorGain(); + savedLocalInjectorGain = Audio.getLocalInjectorGain(); + savedSystemInjectorGain = Audio.getSystemInjectorGain(); + + Audio.setAvatarGain(-60); + Audio.setInjectorGain(-60); + Audio.setLocalInjectorGain(-60); + Audio.setSystemInjectorGain(-60); + } else { + if (savedAvatarGain === -60) { + savedAvatarGain = 0; + } + Audio.setAvatarGain(savedAvatarGain); + if (savedInjectorGain === -60) { + savedInjectorGain = 0; + } + Audio.setInjectorGain(savedInjectorGain); + if (savedLocalInjectorGain === -60) { + savedLocalInjectorGain = 0; + } + Audio.setLocalInjectorGain(savedLocalInjectorGain); + if (savedSystemInjectorGain === -60) { + savedSystemInjectorGain = 0; + } + Audio.setSystemInjectorGain(savedSystemInjectorGain); + } +} + + +var TOP_BAR_MESSAGE_SOURCE = "SimplifiedTopBar.qml"; +function onMessageFromTopBar(message) { + if (message.source !== TOP_BAR_MESSAGE_SOURCE) { + return; + } + + switch (message.method) { + case "toggleAvatarApp": + toggleAvatarApp(); + break; + + case "toggleSettingsApp": + toggleSettingsApp(); + break; + + case "setOutputMuted": + setOutputMuted(message.data.outputMuted); + break; + + default: + console.log("Unrecognized message from " + TOP_BAR_MESSAGE_SOURCE + ": " + JSON.stringify(message)); + break; + } +} + + +function onTopBarClosed() { + if (topBarWindow) { + topBarWindow.fromQml.disconnect(onMessageFromTopBar); + topBarWindow.closed.disconnect(onTopBarClosed); + } + topBarWindow = false; +} + + +function isOutputMuted() { + return Audio.getAvatarGain() === -60 && Audio.getInjectorGain() === -60 && Audio.getLocalInjectorGain() === -60 && Audio.getSystemInjectorGain() === -60; +} + + +var TOP_BAR_QML_PATH = Script.resourcesPath() + "qml/hifi/simplifiedUI/topBar/SimplifiedTopBar.qml"; +var TOP_BAR_WINDOW_TITLE = "Simplified Top Bar"; +var TOP_BAR_PRESENTATION_MODE = Desktop.PresentationMode.NATIVE; +var TOP_BAR_WIDTH_PX = Window.innerWidth; +var TOP_BAR_HEIGHT_PX = 48; +var topBarWindow = false; +function loadSimplifiedTopBar() { + var windowProps = { + title: TOP_BAR_WINDOW_TITLE, + presentationMode: TOP_BAR_PRESENTATION_MODE, + size: { + x: TOP_BAR_WIDTH_PX, + y: TOP_BAR_HEIGHT_PX + } + }; + if (DOCKED_QML_SUPPORTED) { + windowProps.presentationWindowInfo = { + dockArea: Desktop.DockArea.TOP + }; + } else { + windowProps.position = { + x: Window.x, + y: Window.y + }; + } + topBarWindow = Desktop.createWindow(TOP_BAR_QML_PATH, windowProps); + + topBarWindow.fromQml.connect(onMessageFromTopBar); + topBarWindow.closed.connect(onTopBarClosed); + + topBarWindow.sendToQml({ + "source": "simplifiedUI.js", + "method": "updateOutputMuted", + "data": { + "outputMuted": isOutputMuted() + } + }) +} + + +var pausedScriptList = []; +var SCRIPT_NAME_WHITELIST = ["simplifiedUI.js", "statusIndicator.js"]; +function pauseCurrentScripts() { + var currentlyRunningScripts = ScriptDiscoveryService.getRunning(); + + for (var i = 0; i < currentlyRunningScripts.length; i++) { + var currentScriptObject = currentlyRunningScripts[i]; + if (SCRIPT_NAME_WHITELIST.indexOf(currentScriptObject.name) === -1) { + ScriptDiscoveryService.stopScript(currentScriptObject.url); + pausedScriptList.push(currentScriptObject.url); + } + } +} + + +function maybeDeleteInputDeviceMutedOverlay() { + if (inputDeviceMutedOverlay) { + Overlays.deleteOverlay(inputDeviceMutedOverlay); + inputDeviceMutedOverlay = false; + } +} + + +function getInputDeviceMutedOverlayTopY() { + return (Window.innerHeight - INPUT_DEVICE_MUTED_OVERLAY_DEFAULT_Y_PX - INPUT_DEVICE_MUTED_MARGIN_BOTTOM_PX); +} + + +var inputDeviceMutedOverlay = false; +var INPUT_DEVICE_MUTED_OVERLAY_DEFAULT_X_PX = 320; +var INPUT_DEVICE_MUTED_OVERLAY_DEFAULT_Y_PX = 60; +var INPUT_DEVICE_MUTED_MARGIN_BOTTOM_PX = 20; +function updateInputDeviceMutedOverlay(isMuted) { + if (isMuted) { + var props = { + imageURL: Script.resolvePath("images/inputDeviceMuted.svg"), + alpha: 0.5 + }; + props.width = INPUT_DEVICE_MUTED_OVERLAY_DEFAULT_X_PX; + props.height = INPUT_DEVICE_MUTED_OVERLAY_DEFAULT_Y_PX; + props.x = Window.innerWidth / 2 - INPUT_DEVICE_MUTED_OVERLAY_DEFAULT_X_PX / 2; + props.y = getInputDeviceMutedOverlayTopY(); + if (inputDeviceMutedOverlay) { + Overlays.editOverlay(inputDeviceMutedOverlay, props); + } else { + inputDeviceMutedOverlay = Overlays.addOverlay("image", props); + } + } else { + maybeDeleteInputDeviceMutedOverlay(); + } +} + + +function onDesktopInputDeviceMutedChanged(isMuted) { + updateInputDeviceMutedOverlay(isMuted); +} + + +function onGeometryChanged(rect) { + updateInputDeviceMutedOverlay(Audio.muted); + updateOutputDeviceMutedOverlay(isOutputMuted()); + if (topBarWindow && !DOCKED_QML_SUPPORTED) { + topBarWindow.size = { + "x": rect.width, + "y": TOP_BAR_HEIGHT_PX + }; + topBarWindow.position = { + "x": rect.x, + "y": rect.y + }; + } +} + +function ensureFirstPersonCameraInHMD(isHMDMode) { + if (isHMDMode) { + Camera.setModeString("first person"); + } +} + + +var simplifiedNametag = Script.require("../simplifiedNametag/simplifiedNametag.js"); +function startup() { + if (REMOVE_EXISTING_UI) { + pauseCurrentScripts(); + removeDesktopMenu(); + runDefaultsTogether(); + loadSeparateDefaults(); + + if (!HMD.active) { + var toolbar = Toolbars.getToolbar(TOOLBAR_NAME); + toolbar.writeProperty("visible", false); + } + } + loadSimplifiedTopBar(); + + simplifiedNametag.create(); + updateInputDeviceMutedOverlay(Audio.muted); + updateOutputDeviceMutedOverlay(isOutputMuted()); + Audio.mutedDesktopChanged.connect(onDesktopInputDeviceMutedChanged); + Window.geometryChanged.connect(onGeometryChanged); + HMD.displayModeChanged.connect(ensureFirstPersonCameraInHMD); +} + + +function restoreScripts() { + pausedScriptList.forEach(function(url) { + ScriptDiscoveryService.loadScript(url); + }); + + pausedScriptList = []; +} + + +function shutdown() { + restoreScripts(); + + if (REMOVE_EXISTING_UI) { + Window.confirm("You'll have to restart Interface to get full functionality back. Clicking yes or no will dismiss this dialog."); + + if (!HMD.active) { + var toolbar = Toolbars.getToolbar(TOOLBAR_NAME); + toolbar.writeProperty("visible", true); + } + } + + if (topBarWindow) { + topBarWindow.close(); + } + + if (avatarAppWindow) { + avatarAppWindow.close(); + } + + if (settingsAppWindow) { + settingsAppWindow.close(); + } + + maybeDeleteInputDeviceMutedOverlay(); + maybeDeleteOutputDeviceMutedOverlay(); + + simplifiedNametag.destroy(); + + Audio.mutedDesktopChanged.disconnect(onDesktopInputDeviceMutedChanged); + Window.geometryChanged.disconnect(onGeometryChanged); + HMD.displayModeChanged.disconnect(ensureFirstPersonCameraInHMD); +} + + +Script.scriptEnding.connect(shutdown); +startup();