Simplified UI v1
BIN
interface/resources/fonts/Graphik-Medium.ttf
Normal file
BIN
interface/resources/fonts/Graphik-Regular.ttf
Normal file
BIN
interface/resources/fonts/Graphik-Semibold.ttf
Normal file
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<svg width="94" height="175" viewBox="0 0 94 175" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 175L93.4322 175L73.3124 166.208L0 175Z" fill="#009036"/>
|
||||
<path d="M73.3124 166.208L93.4322 175L93.4322 -1.34999e-05L73.3124 166.208Z" fill="#FF42A7"/>
|
||||
</svg>
|
After Width: | Height: | Size: 268 B |
BIN
interface/resources/qml/hifi/simplifiedUI/images/loading.gif
Normal file
After Width: | Height: | Size: 69 KiB |
|
@ -0,0 +1,193 @@
|
|||
//
|
||||
// InputDeviceButton.qml
|
||||
//
|
||||
// Created by Zach Fox on 2019-05-02
|
||||
// Based off of MicBarApplication.qml by Zach Pomerantz and Wayne Chen
|
||||
// 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 QtGraphicalEffects 1.0
|
||||
import stylesUit 1.0
|
||||
import TabletScriptingInterface 1.0
|
||||
import "../simplifiedConstants" as SimplifiedConstants
|
||||
|
||||
Rectangle {
|
||||
id: micBar;
|
||||
|
||||
SimplifiedConstants.SimplifiedConstants {
|
||||
id: simplifiedUI
|
||||
}
|
||||
|
||||
readonly property var level: AudioScriptingInterface.inputLevel;
|
||||
readonly property var clipping: AudioScriptingInterface.clipping;
|
||||
property var muted: AudioScriptingInterface.muted;
|
||||
property var pushToTalk: AudioScriptingInterface.pushToTalk;
|
||||
property var pushingToTalk: AudioScriptingInterface.pushingToTalk;
|
||||
readonly property var userSpeakingLevel: 0.4;
|
||||
property bool gated: false;
|
||||
|
||||
readonly property string unmutedIcon: "images/mic-unmute-i.svg";
|
||||
readonly property string mutedIcon: "images/mic-mute-i.svg";
|
||||
readonly property string pushToTalkIcon: "images/mic-ptt-i.svg";
|
||||
readonly property string clippingIcon: "images/mic-clip-i.svg";
|
||||
readonly property string gatedIcon: "images/mic-gate-i.svg";
|
||||
|
||||
Connections {
|
||||
target: AudioScriptingInterface;
|
||||
|
||||
onNoiseGateOpened: {
|
||||
gated = false;
|
||||
}
|
||||
|
||||
onNoiseGateClosed: {
|
||||
gated = false;
|
||||
}
|
||||
}
|
||||
|
||||
height: parent.height;
|
||||
width: 40;
|
||||
|
||||
radius: 5;
|
||||
opacity: 0.7;
|
||||
|
||||
onLevelChanged: {
|
||||
var rectOpacity = (muted && (level >= 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M25.3383 4.13446L23.8713 5.60152C21.9374 3.46761 19.2033 2.06723 16.0691 2.06723C13.0683 2.06723 10.4009 3.40093 8.46707 5.40147L7 3.9344C9.26728 1.53375 12.5348 0 16.0691 0C19.7368 0 23.071 1.60044 25.3383 4.13446ZM21.9376 7.53584L20.4705 9.0029C19.4703 7.66921 17.8698 6.86899 16.0693 6.86899C14.4022 6.86899 12.9351 7.66921 11.8682 8.80285L10.4011 7.33578C11.8015 5.80203 13.802 4.80176 16.0693 4.80176C18.4033 4.80176 20.5372 5.86871 21.9376 7.53584ZM17.9575 30.1572C17.9575 31.1771 17.1307 32.0039 16.1108 32.0039C15.0909 32.0039 14.2642 31.1771 14.2642 30.1572C14.2642 29.1373 15.0909 28.3105 16.1108 28.3105C17.1307 28.3105 17.9575 29.1373 17.9575 30.1572ZM18.3632 11.0801H14.1597L15.0116 25.8539H17.4867L18.3632 11.0801Z" fill="#EA4C5F"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0">
|
||||
<rect width="32" height="32" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 1 KiB |
|
@ -0,0 +1,3 @@
|
|||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.1999 4.72587C17.5049 4.72587 18.5628 3.66795 18.5628 2.36294C18.5628 1.05792 17.5049 0 16.1999 0C14.8948 0 13.8369 1.05792 13.8369 2.36294C13.8369 3.66795 14.8948 4.72587 16.1999 4.72587ZM18.6667 11.8004V14.7337H13.7334V11.8004C13.7334 10.467 14.8667 9.40039 16.2 9.40039C17.6 9.40039 18.6667 10.467 18.6667 11.8004ZM13.7334 20.1332V17.2666H18.6667V20.1332C18.6667 21.4665 17.5333 22.5332 16.2 22.5332C14.8667 22.5332 13.7334 21.4665 13.7334 20.1332ZM23.6665 20.6V17.0667C23.6665 16.4 23.0665 15.9334 22.4665 15.9334C21.7998 15.9334 21.3332 16.4667 21.3332 17.1333V20.6C21.3332 23.0666 19.0665 25.0666 16.3332 25.0666C13.5999 25.0666 11.3333 23.0666 11.3333 20.6V17.0667C11.3333 16.4 10.8666 15.8667 10.2666 15.8667C9.59999 15.8 9 16.2667 9 16.9333V20.6C9 23.9999 11.6666 26.7999 15.1333 27.3332V29.5998H12.2666C11.6 29.5998 11.0666 30.1332 11.0666 30.7998C11.0666 31.4665 11.6 31.9998 12.2666 31.9998H20.4665C21.1332 31.9998 21.6665 31.4665 21.6665 30.7998C21.6665 30.1332 21.1332 29.5998 20.4665 29.5998H17.5332V27.3332C20.9998 26.7332 23.6665 23.9999 23.6665 20.6Z" fill="#00B4EF" fill-opacity="0.7"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
|
@ -0,0 +1,3 @@
|
|||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M25.6441 4.13328L24.1775 5.59992C22.2442 3.46662 19.5109 2.06664 16.3776 2.06664C13.3776 2.06664 10.711 3.39995 8.77768 5.39993L7.31104 3.93328C9.57767 1.53331 12.8443 0 16.3776 0C20.0442 0 23.3775 1.59998 25.6441 4.13328ZM20.7777 9.00072L22.2444 7.53408C20.8444 5.86743 18.7111 4.80078 16.3778 4.80078C14.1111 4.80078 12.1112 5.80077 10.7112 7.33408L12.1778 8.80073C13.2445 7.66741 14.7111 6.86742 16.3778 6.86742C18.1777 6.86742 19.7777 7.66741 20.7777 9.00072ZM18.8803 12.0758V11.7496C18.8803 10.4445 17.7763 9.40039 16.4775 9.40039C15.1787 9.40039 14.0747 10.4445 14.0747 11.7496V16.2521L18.8803 12.0758ZM14.543 21.5129L12.6113 23.2103C13.4959 24.2599 14.9141 24.9311 16.4774 24.9311C19.14 24.9311 21.348 22.9735 21.348 20.559V17.1658C21.348 16.5132 21.8026 15.9912 22.452 15.9912C23.0364 15.9912 23.6209 16.448 23.6209 17.1005V20.559C23.6209 23.887 21.0233 26.6277 17.6464 27.1498V29.3684H20.5038C21.1532 29.3684 21.6727 29.8905 21.6727 30.543C21.6727 31.1956 21.1532 31.7176 20.5038 31.7176H12.5161C11.8667 31.7176 11.3471 31.1956 11.3471 30.543C11.3471 29.8905 11.8667 29.3684 12.5161 29.3684H15.3085V27.1498C13.5328 26.915 11.9589 26.0045 10.8771 24.7343L8.9443 26.4327C8.48972 26.8242 7.77537 26.759 7.38573 26.3022L7.25585 26.1717C6.8662 25.7149 6.93114 24.9971 7.38573 24.6056L23.8806 9.98853C24.3352 9.597 25.0495 9.66226 25.4392 10.119L25.5691 10.2495C25.9587 10.7716 25.8938 11.4241 25.5041 11.8809L18.8803 17.7015V20.1017C18.8803 21.4068 17.7763 22.4509 16.4775 22.4509C15.6689 22.4509 14.9744 22.0838 14.543 21.5129ZM10.5679 15.9919C11.1523 15.9919 11.6069 16.5139 11.6069 17.1664V18.4715L9.33398 20.4944V17.0359C9.39892 16.4486 9.91845 15.9266 10.5679 15.9919Z" fill="#EA4C5F"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
|
@ -0,0 +1,3 @@
|
|||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M25.6441 4.13328L24.1775 5.59992C22.2442 3.46662 19.5109 2.06664 16.3776 2.06664C13.3776 2.06664 10.711 3.39995 8.77768 5.39993L7.31104 3.93328C9.57767 1.53331 12.8443 0 16.3776 0C20.0442 0 23.3775 1.59998 25.6441 4.13328ZM20.7777 9.00072L22.2444 7.53408C20.8444 5.86743 18.7111 4.80078 16.3778 4.80078C14.1111 4.80078 12.1112 5.80077 10.7112 7.33408L12.1778 8.80073C13.2445 7.66741 14.7111 6.86742 16.3778 6.86742C18.1777 6.86742 19.7777 7.66741 20.7777 9.00072ZM18.8803 12.0758V11.7496C18.8803 10.4445 17.7763 9.40039 16.4775 9.40039C15.1787 9.40039 14.0747 10.4445 14.0747 11.7496V16.2521L18.8803 12.0758ZM14.543 21.5129L12.6113 23.2103C13.4959 24.2599 14.9141 24.9311 16.4774 24.9311C19.14 24.9311 21.348 22.9735 21.348 20.559V17.1658C21.348 16.5132 21.8026 15.9912 22.452 15.9912C23.0364 15.9912 23.6209 16.448 23.6209 17.1005V20.559C23.6209 23.887 21.0233 26.6277 17.6464 27.1498V29.3684H20.5038C21.1532 29.3684 21.6727 29.8905 21.6727 30.543C21.6727 31.1956 21.1532 31.7176 20.5038 31.7176H12.5161C11.8667 31.7176 11.3471 31.1956 11.3471 30.543C11.3471 29.8905 11.8667 29.3684 12.5161 29.3684H15.3085V27.1498C13.5328 26.915 11.9589 26.0045 10.8771 24.7343L8.9443 26.4327C8.48972 26.8242 7.77537 26.759 7.38573 26.3022L7.25585 26.1717C6.8662 25.7149 6.93114 24.9971 7.38573 24.6056L23.8806 9.98853C24.3352 9.597 25.0495 9.66226 25.4392 10.119L25.5691 10.2495C25.9587 10.7716 25.8938 11.4241 25.5041 11.8809L18.8803 17.7015V20.1017C18.8803 21.4068 17.7763 22.4509 16.4775 22.4509C15.6689 22.4509 14.9744 22.0838 14.543 21.5129ZM10.5679 15.9919C11.1523 15.9919 11.6069 16.5139 11.6069 17.1664V18.4715L9.33398 20.4944V17.0359C9.39893 16.4486 9.91845 15.9266 10.5679 15.9919Z" fill="#EA4C5F"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
|
@ -0,0 +1 @@
|
|||
<svg id="Art" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50"><defs><style>.cls-1{fill-rule:evenodd;}</style></defs><title>mic-ptt-a</title><path class="cls-1" d="M34.52,10.09l-1.85,1.85a13.19,13.19,0,0,0-9.82-4.46,13.35,13.35,0,0,0-9.58,4.2L11.42,9.84a15.66,15.66,0,0,1,23.1.25Zm-6.13,6.13,1.85-1.85a9.62,9.62,0,0,0-14.53-.25L17.55,16a7.34,7.34,0,0,1,5.3-2.44A6.85,6.85,0,0,1,28.39,16.22ZM23,16a3.58,3.58,0,0,1,1.51.3,3.68,3.68,0,0,1,1.26.88,3.88,3.88,0,0,1,.84,1.3A3.94,3.94,0,0,1,26.9,20v5.07a1.91,1.91,0,0,1,.48-.05A3.93,3.93,0,0,1,30,26.07a3.38,3.38,0,0,1,1.5-.32,3.27,3.27,0,0,1,2.77,1.36,2.75,2.75,0,0,1,.85-.1,3.35,3.35,0,0,1,1.33.25,3.18,3.18,0,0,1,1.12.76,3.23,3.23,0,0,1,.73,1.13,3.32,3.32,0,0,1,.24,1.32v3.31a12.27,12.27,0,0,1-.43,3.41l-1.36,5.65a2.67,2.67,0,0,1-1,1.55A2.89,2.89,0,0,1,34,45H23a4.47,4.47,0,0,1-1.76-.43,3.88,3.88,0,0,1-1.36-1.12L14.1,35.7a3.72,3.72,0,0,1-.8-2.35,3.64,3.64,0,0,1,.28-1.5,3.75,3.75,0,0,1,.84-1.27,3.9,3.9,0,0,1,2.77-1.18,4.5,4.5,0,0,1,2,.54V19.88a4.06,4.06,0,0,1,1.13-2.78,3.74,3.74,0,0,1,1.25-.83A3.85,3.85,0,0,1,23,16Zm0,2a1.89,1.89,0,0,0-.74.12,2,2,0,0,0-1.06,1,1.92,1.92,0,0,0-.15.74V35.21l-2.32-3.06a2,2,0,0,0-.7-.59,1.88,1.88,0,0,0-.9-.2,1.85,1.85,0,0,0-.74.15,2,2,0,0,0-.63.43,2,2,0,0,0-.4.63,1.9,1.9,0,0,0-.13.74,2,2,0,0,0,.38,1.17l5.86,7.79a1.79,1.79,0,0,0,.68.57A1.74,1.74,0,0,0,23,43H34a1.23,1.23,0,0,0,.59-.15.88.88,0,0,0,.24-.23.71.71,0,0,0,.13-.31l1.37-5.6a12,12,0,0,0,.37-3V30.43a1.7,1.7,0,0,0-.43-1.07,1.31,1.31,0,0,0-.47-.37,1.35,1.35,0,0,0-.59-.11,1.46,1.46,0,0,0-.55.11,1.23,1.23,0,0,0-.46.32,1.64,1.64,0,0,0-.43,1.07h-.48v-1a1.52,1.52,0,0,0-.12-.66,1.61,1.61,0,0,0-.37-.56,1.63,1.63,0,0,0-1.22-.54,2,2,0,0,0-1.23.54,1.77,1.77,0,0,0-.36.53,1.57,1.57,0,0,0-.11.64v1h-.49V29a2.22,2.22,0,0,0-.58-1.44,1.71,1.71,0,0,0-.62-.44A1.88,1.88,0,0,0,27.4,27a2,2,0,0,0-.74.13,1.85,1.85,0,0,0-.63.41,2,2,0,0,0-.53,1.36v1.5h-.57V20a2,2,0,0,0-.54-1.44,1.75,1.75,0,0,0-.63-.44A1.73,1.73,0,0,0,23,18Z"/></svg>
|
After Width: | Height: | Size: 1.9 KiB |
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 23.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Art" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;}
|
||||
</style>
|
||||
<path class="st0" d="M16.7,13.2c-0.3,0.3-0.7,0.6-1,0.9l1.8,1.9c1.4-1.5,3.3-2.4,5.3-2.4c2.2,0,4.2,0.9,5.5,2.7l1.8-1.8
|
||||
C26.8,10.3,20.8,9.8,16.7,13.2z M32.7,11.9l1.9-1.9c-0.3-0.3-0.6-0.7-1-1c-6.3-5.9-16.2-5.6-22.1,0.7l1.9,1.8
|
||||
c2.5-2.6,5.9-4.2,9.6-4.2C26.6,7.5,30.2,9.1,32.7,11.9z M38.3,29.1c-0.2-0.4-0.4-0.8-0.7-1.1c-0.3-0.3-0.7-0.6-1.1-0.8
|
||||
C36,27.1,35.6,27,35.1,27c-0.3,0-0.6,0-0.8,0.1c-0.6-0.9-1.7-1.4-2.8-1.4c-0.5,0-1,0.1-1.5,0.3c-0.7-0.7-1.6-1-2.6-1.1
|
||||
c-0.2,0-0.3,0-0.5,0.1V20c0-0.5-0.1-1-0.3-1.5c-0.2-0.5-0.5-0.9-0.8-1.3c-0.4-0.4-0.8-0.7-1.3-0.9C24,16.1,23.5,16,23,16
|
||||
c-0.5,0-1,0.1-1.4,0.3c-0.5,0.2-0.9,0.5-1.3,0.8c-0.7,0.7-1.1,1.7-1.1,2.8v10.1c-0.6-0.3-1.3-0.5-2-0.5c-1,0-2,0.4-2.8,1.2
|
||||
c-0.4,0.4-0.6,0.8-0.8,1.3c-0.2,0.5-0.3,1-0.3,1.5c0,0.9,0.3,1.7,0.8,2.4l5.8,7.8c0.4,0.5,0.8,0.9,1.4,1.1c0.6,0.3,1.2,0.4,1.8,0.4
|
||||
h11c0.6,0,1.2-0.2,1.8-0.6c0.5-0.4,0.9-0.9,1-1.6l1.4-5.6c0.3-1.1,0.4-2.3,0.4-3.4v-3.3C38.6,30,38.5,29.6,38.3,29.1z M36.7,33.7
|
||||
c0,1-0.1,2-0.4,3L35,42.3c0,0.1-0.1,0.2-0.1,0.3c-0.1,0.1-0.1,0.2-0.2,0.2C34.4,42.9,34.2,43,34,43H23c-0.3,0-0.6,0-0.8-0.2
|
||||
c-0.3-0.1-0.5-0.3-0.7-0.6l-5.9-7.8c-0.2-0.3-0.4-0.7-0.4-1.2c0-0.3,0-0.5,0.1-0.7c0.1-0.2,0.2-0.4,0.4-0.6c0.2-0.2,0.4-0.3,0.6-0.4
|
||||
c0.2-0.1,0.5-0.2,0.7-0.2c0.3,0,0.6,0.1,0.9,0.2c0.3,0.1,0.5,0.3,0.7,0.6l2.3,3.1V19.9c0-0.3,0.1-0.5,0.2-0.7c0.2-0.5,0.6-0.8,1.1-1
|
||||
C22.5,18,22.7,18,23,18c0.3,0,0.5,0,0.8,0.1c0.2,0.1,0.5,0.2,0.6,0.4c0.4,0.4,0.6,0.9,0.5,1.4v10.4h0.6v-1.5c0-0.5,0.2-1,0.5-1.4
|
||||
c0.2-0.2,0.4-0.3,0.6-0.4c0.2-0.1,0.5-0.1,0.7-0.1c0.3,0,0.5,0,0.8,0.1c0.2,0.1,0.4,0.2,0.6,0.4c0.4,0.4,0.6,0.9,0.6,1.4v1.3h0.5v-1
|
||||
c0-0.2,0-0.4,0.1-0.6c0.1-0.2,0.2-0.4,0.4-0.5c0.3-0.3,0.8-0.5,1.2-0.5c0.5,0,0.9,0.2,1.2,0.5c0.2,0.2,0.3,0.3,0.4,0.6
|
||||
c0.1,0.2,0.1,0.4,0.1,0.7v1h0.5c0-0.4,0.2-0.8,0.4-1.1c0.1-0.1,0.3-0.3,0.5-0.3c0.2-0.1,0.4-0.1,0.6-0.1c0.2,0,0.4,0,0.6,0.1
|
||||
c0.2,0.1,0.3,0.2,0.5,0.4c0.3,0.3,0.4,0.7,0.4,1.1V33.7z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
|
@ -0,0 +1,3 @@
|
|||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M23.8664 5.59992L25.3331 4.13328C23.0664 1.59998 19.7332 0 16.0665 0C12.5333 0 9.26664 1.53331 7 3.93328L8.46665 5.39993C10.4 3.39995 13.0666 2.06664 16.0665 2.06664C19.1998 2.06664 21.9331 3.46662 23.8664 5.59992ZM20.4664 8.99975L21.9331 7.5331C20.5331 5.86646 18.3998 4.7998 16.0665 4.7998C13.7999 4.7998 11.7999 5.79979 10.3999 7.3331L11.8665 8.79975C12.9332 7.66643 14.3998 6.86644 16.0665 6.86644C17.8665 6.86644 19.4664 7.66643 20.4664 8.99975ZM18.5334 11.8004V14.7337H13.6001V11.8004C13.6001 10.467 14.7334 9.40039 16.0667 9.40039C17.4667 9.40039 18.5334 10.467 18.5334 11.8004ZM13.6001 17.2666V20.1332C13.6001 21.4665 14.7334 22.5332 16.0667 22.5332C17.4 22.5332 18.5334 21.4665 18.5334 20.1332V17.2666H13.6001ZM23.5332 17.0667V20.6C23.5332 23.9999 20.8665 26.7332 17.3999 27.3332V29.5998H20.3332C20.9999 29.5998 21.5332 30.1332 21.5332 30.7998C21.5332 31.4665 20.9999 31.9998 20.3332 31.9998H12.1333C11.4667 31.9998 10.9333 31.4665 10.9333 30.7998C10.9333 30.1332 11.4667 29.5998 12.1333 29.5998H14.9999V27.3332C11.5333 26.7999 8.8667 23.9999 8.8667 20.6V16.9333C8.8667 16.2667 9.46669 15.8 10.1333 15.8667C10.7333 15.8667 11.2 16.4 11.2 17.0667V20.6C11.2 23.0666 13.4666 25.0666 16.1999 25.0666C18.9332 25.0666 21.1999 23.0666 21.1999 20.6V17.1333C21.1999 16.4667 21.6665 15.9334 22.3332 15.9334C22.9332 15.9334 23.5332 16.4 23.5332 17.0667Z" fill="white"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
|
@ -0,0 +1,3 @@
|
|||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M23.8664 5.59992L25.3331 4.13328C23.0664 1.59998 19.7332 0 16.0665 0C12.5333 0 9.26664 1.53331 7 3.93328L8.46665 5.39993C10.4 3.39995 13.0666 2.06664 16.0665 2.06664C19.1998 2.06664 21.9331 3.46662 23.8664 5.59992ZM20.4664 8.99975L21.9331 7.5331C20.5331 5.86646 18.3998 4.7998 16.0665 4.7998C13.7999 4.7998 11.7999 5.79979 10.3999 7.3331L11.8665 8.79975C12.9332 7.66643 14.3998 6.86644 16.0665 6.86644C17.8665 6.86644 19.4664 7.66643 20.4664 8.99975ZM18.5334 11.8004V14.7337H13.6001V11.8004C13.6001 10.467 14.7334 9.40039 16.0667 9.40039C17.4667 9.40039 18.5334 10.467 18.5334 11.8004ZM13.6001 17.2666V20.1332C13.6001 21.4665 14.7334 22.5332 16.0667 22.5332C17.4 22.5332 18.5334 21.4665 18.5334 20.1332V17.2666H13.6001ZM23.5332 17.0667V20.6C23.5332 23.9999 20.8665 26.7332 17.3999 27.3332V29.5998H20.3332C20.9999 29.5998 21.5332 30.1332 21.5332 30.7998C21.5332 31.4665 20.9999 31.9998 20.3332 31.9998H12.1333C11.4667 31.9998 10.9333 31.4665 10.9333 30.7998C10.9333 30.1332 11.4667 29.5998 12.1333 29.5998H14.9999V27.3332C11.5333 26.7999 8.8667 23.9999 8.8667 20.6V16.9333C8.8667 16.2667 9.46669 15.8 10.1333 15.8667C10.7333 15.8667 11.2 16.4 11.2 17.0667V20.6C11.2 23.0666 13.4666 25.0666 16.1999 25.0666C18.9332 25.0666 21.1999 23.0666 21.1999 20.6V17.1333C21.1999 16.4667 21.6665 15.9334 22.3332 15.9334C22.9332 15.9334 23.5332 16.4 23.5332 17.0667Z" fill="white"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
|
@ -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);
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
418
interface/resources/qml/hifi/simplifiedUI/settingsApp/vr/VR.qml
Normal file
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
After Width: | Height: | Size: 36 KiB |
21
interface/resources/qml/stylesUit/GraphikMedium.qml
Normal file
|
@ -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
|
||||
}
|
20
interface/resources/qml/stylesUit/GraphikRegular.qml
Normal file
|
@ -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"
|
||||
}
|
21
interface/resources/qml/stylesUit/GraphikSemiBold.qml
Normal file
|
@ -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
|
||||
}
|
|
@ -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
|
||||
TextFieldInput 1.0 TextFieldInput.qml
|
||||
|
|
|
@ -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<QmlCommerce>().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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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
|
||||
});
|
||||
}
|
||||
|
|
@ -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;
|
224
scripts/system/simplifiedNametag/resources/modules/textHelper.js
Normal file
|
@ -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();
|
96
scripts/system/simplifiedNametag/simplifiedNametag.js
Normal file
|
@ -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
|
||||
// *************************************
|
12
scripts/system/simplifiedUI/images/inputDeviceMuted.svg
Normal file
|
@ -0,0 +1,12 @@
|
|||
<svg width="531" height="95" viewBox="0 0 531 95" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="64" width="353" height="95" rx="10" fill="white"/>
|
||||
<g clip-path="url(#clip0)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M115.081 28.5049L112.537 31.049C109.183 27.3485 104.442 24.92 99.007 24.92C93.8031 24.92 89.1775 27.2328 85.8239 30.7021L83.2798 28.158C87.2116 23.9949 92.878 21.3351 99.007 21.3351C105.367 21.3351 111.149 24.1105 115.081 28.5049ZM106.639 36.9481L109.184 34.404C106.755 31.513 103.055 29.6628 99.0072 29.6628C95.0754 29.6628 91.6062 31.3974 89.1777 34.0571L91.7218 36.6012C93.5721 34.6353 96.1162 33.2476 99.0072 33.2476C102.129 33.2476 104.905 34.6353 106.639 36.9481ZM103.348 42.2823V41.7164C103.348 39.4525 101.433 37.6414 99.1803 37.6414C96.9273 37.6414 95.0123 39.4525 95.0123 41.7164V49.5267L103.348 42.2823ZM95.8246 58.6522L92.4739 61.5966C94.0083 63.4173 96.4683 64.5816 99.1802 64.5816C103.799 64.5816 107.629 61.1858 107.629 56.9976V51.1116C107.629 49.9796 108.417 49.0741 109.544 49.0741C110.558 49.0741 111.571 49.8664 111.571 50.9984V56.9976C111.571 62.7705 107.066 67.5246 101.208 68.4301V72.2787H106.164C107.291 72.2787 108.192 73.1842 108.192 74.3162C108.192 75.4481 107.291 76.3536 106.164 76.3536H92.3086C91.1821 76.3536 90.281 75.4481 90.281 74.3162C90.281 73.1842 91.1821 72.2787 92.3086 72.2787H97.1525V68.4301C94.0724 68.0229 91.3422 66.4435 89.4655 64.2402L86.1129 67.1863C85.3244 67.8655 84.0852 67.7523 83.4093 66.9599L83.184 66.7335C82.5081 65.9412 82.6208 64.6961 83.4093 64.0169L112.022 38.6616C112.811 37.9825 114.05 38.0957 114.726 38.888L114.951 39.1144C115.627 40.0199 115.514 41.1519 114.838 41.9442L103.348 52.0408V56.2044C103.348 58.4682 101.433 60.2793 99.1803 60.2793C97.7776 60.2793 96.5729 59.6425 95.8246 58.6522ZM88.9292 49.0752C89.943 49.0752 90.7315 49.9808 90.7315 51.1127V53.3766L86.7888 56.8856V50.8863C86.9015 49.8676 87.8027 48.962 88.9292 49.0752Z" fill="#B20012"/>
|
||||
</g>
|
||||
<path d="M132.308 77H141.908V33.8L159.268 77H162.708L179.748 33.8V77H190.388V19.8H176.308L161.588 58.84L146.548 19.8H132.308V77ZM225.48 77.8C240.6 77.8 248.68 69.56 248.68 54.6V19.8H237.96V53.72C237.96 65.56 233.8 69.24 225.56 69.24C217.08 69.24 213.72 64.92 213.72 54.44V19.8H203V55.24C203 69.96 211.16 77.8 225.48 77.8ZM272.733 77H283.453V28.2H299.373V19.8H256.813V28.2H272.733V77ZM307.933 77H345.053V68.6H318.573V51.88H338.733V43.88H318.573V28.2H343.693V19.8H307.933V77ZM365.292 68.6V28.2H371.452C384.892 28.2 390.492 35.64 390.492 47.96V48.6C390.492 61.24 384.332 68.6 371.532 68.6H365.292ZM354.652 77H371.852C391.932 77 401.612 65.16 401.612 48.52V47.8C401.612 31.16 391.932 19.8 372.012 19.8H354.652V77Z" fill="#B20012"/>
|
||||
<defs>
|
||||
<clipPath id="clip0">
|
||||
<rect width="55.5084" height="55.5084" fill="white" transform="translate(70.5977 21.3351)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 2.8 KiB |
4
scripts/system/simplifiedUI/images/outputDeviceMuted.svg
Normal file
|
@ -0,0 +1,4 @@
|
|||
<svg width="553" height="553" viewBox="0 0 553 553" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="276.5" cy="276.5" r="276.5" fill="white"/>
|
||||
<path d="M292.112 239.537V388.865C292.957 396.799 291.001 404.778 286.583 411.421C282.164 418.064 275.561 422.953 267.916 425.243C263.762 426.761 259.413 427.679 255 427.971C249.454 428.205 243.94 427.025 238.976 424.544C234.011 422.062 229.759 418.359 226.619 413.784C220.979 408.145 212.61 399.415 201.695 387.592C190.779 375.77 182.593 367.039 176.953 361.219C175.486 359.629 173.471 358.654 171.313 358.491H155.304C148.119 358.643 140.935 358.156 133.836 357.035C125.817 355.846 118.507 351.771 113.279 345.577C107.506 339.98 104.172 332.334 104 324.296V220.621C103.989 215.99 105.012 211.415 106.995 207.23C108.978 203.045 111.87 199.355 115.462 196.43C122.88 189.865 132.48 186.298 142.387 186.426H170.949L172.223 185.153C173.774 184.335 175.237 183.36 176.589 182.243C188.778 169.875 205.515 152.414 226.255 129.678C231.222 123.895 237.881 119.818 245.292 118.023C252.702 116.228 260.489 116.806 267.553 119.674C275.013 121.964 281.472 126.722 285.869 133.168C290.266 139.613 292.34 147.362 291.749 155.142L292.112 239.537ZM240.809 169.875L196.783 218.257C195.369 219.895 193.644 221.237 191.708 222.205C189.772 223.173 187.663 223.747 185.504 223.895H142.751V319.203H186.777C189.465 319.135 192.074 320.113 194.054 321.931C199.375 328.283 205.022 334.354 210.973 340.12C218.614 347.759 224.254 353.761 228.074 358.309L240.809 371.223C243.866 375.22 247.21 378.989 250.815 382.499L252.27 383.955V158.598L240.809 169.875ZM452.572 218.257C451.101 216.263 449.182 214.643 446.97 213.527C444.758 212.411 442.315 211.829 439.837 211.829C437.36 211.829 434.916 212.411 432.704 213.527C430.492 214.643 428.574 216.263 427.102 218.257L345.963 299.196C344 300.708 342.41 302.65 341.317 304.874C340.223 307.097 339.654 309.541 339.654 312.019C339.654 314.496 340.223 316.941 341.317 319.164C342.41 321.387 344 323.33 345.963 324.842C347.454 326.836 349.389 328.456 351.616 329.572C353.842 330.687 356.298 331.268 358.789 331.268C361.279 331.268 363.735 330.687 365.962 329.572C368.188 328.456 370.124 326.836 371.615 324.842L452.572 243.903C454.567 242.412 456.187 240.477 457.303 238.251C458.419 236.025 459 233.569 459 231.08C459 228.59 458.419 226.134 457.303 223.908C456.187 221.682 454.567 219.747 452.572 218.257V218.257ZM452.572 324.842C454.567 323.351 456.187 321.416 457.303 319.19C458.419 316.964 459 314.509 459 312.019C459 309.529 458.419 307.073 457.303 304.847C456.187 302.621 454.567 300.686 452.572 299.196L371.615 218.257C370.124 216.262 368.188 214.642 365.962 213.526C363.735 212.411 361.279 211.83 358.789 211.83C356.298 211.83 353.842 212.411 351.616 213.526C349.389 214.642 347.454 216.262 345.963 218.257C344 219.769 342.41 221.711 341.317 223.934C340.223 226.157 339.654 228.602 339.654 231.08C339.654 233.557 340.223 236.002 341.317 238.225C342.41 240.448 344 242.39 345.963 243.903L427.102 324.842C428.574 326.835 430.492 328.455 432.704 329.571C434.916 330.688 437.36 331.269 439.837 331.269C442.315 331.269 444.758 330.688 446.97 329.571C449.182 328.455 451.101 326.835 452.572 324.842V324.842Z" fill="#B20012"/>
|
||||
</svg>
|
After Width: | Height: | Size: 3.1 KiB |
502
scripts/system/simplifiedUI/simplifiedUI.js
Normal file
|
@ -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();
|