overte/interface/resources/qml/hifi/audio/Audio.qml
2019-03-11 17:09:37 -07:00

440 lines
16 KiB
QML

//
// Audio.qml
// qml/hifi/audio
//
// Audio setup
//
// Created by Vlad Stelmahovsky on 03/22/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.7
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import stylesUit 1.0
import controlsUit 1.0 as HifiControlsUit
import "../../windows"
import "./" as AudioControls
Rectangle {
id: root;
HifiConstants { id: hifi; }
property var eventBridge;
// leave as blank, this is user's volume for the avatar mixer
property var myAvatarUuid: ""
property string title: "Audio Settings"
property int switchHeight: 16
property int switchWidth: 40
signal sendToScript(var message);
color: hifi.colors.baseGray;
// only show the title if loaded through a "loader"
function showTitle() {
return (root.parent !== null) && root.parent.objectName == "loader";
}
property bool isVR: AudioScriptingInterface.context === "VR"
property real rightMostInputLevelPos: 450
//placeholder for control sizes and paddings
//recalculates dynamically in case of UI size is changed
QtObject {
id: margins
property real paddings: root.width / 20.25
property real sizeCheckBox: root.width / 13.5
property real sizeText: root.width / 2.5
property real sizeLevel: root.width / 5.8
property real sizeDesktop: root.width / 5.8
property real sizeVR: root.width / 13.5
}
TabBar {
id: bar
spacing: 0
width: parent.width
height: 42
currentIndex: isVR ? 1 : 0
AudioControls.AudioTabButton {
height: parent.height
text: qsTr("Desktop")
}
AudioControls.AudioTabButton {
height: parent.height
text: qsTr("VR")
}
}
property bool showPeaks: true;
function enablePeakValues() {
AudioScriptingInterface.devices.input.peakValuesEnabled = true;
AudioScriptingInterface.devices.input.peakValuesEnabledChanged.connect(function(enabled) {
if (!enabled && root.showPeaks) {
AudioScriptingInterface.devices.input.peakValuesEnabled = true;
}
});
}
function updateMyAvatarGainFromQML(sliderValue, isReleased) {
if (Users.getAvatarGain(myAvatarUuid) != sliderValue) {
Users.setAvatarGain(myAvatarUuid, sliderValue);
}
}
Component.onCompleted: enablePeakValues();
Column {
id: column
spacing: 12;
anchors.top: bar.bottom
anchors.bottom: parent.bottom
anchors.bottomMargin: 5
width: parent.width;
Separator { }
RowLayout {
x: 2 * margins.paddings;
width: parent.width;
// mute is in its own row
ColumnLayout {
id: columnOne
spacing: 24;
x: margins.paddings
HifiControlsUit.Switch {
id: muteMic;
height: root.switchHeight;
switchWidth: root.switchWidth;
labelTextOn: "Mute microphone";
backgroundOnColor: "#E3E3E3";
checked: AudioScriptingInterface.muted;
onClicked: {
if (AudioScriptingInterface.pushToTalk && !checked) {
// disable push to talk if unmuting
AudioScriptingInterface.pushToTalk = false;
}
AudioScriptingInterface.muted = checked;
checked = Qt.binding(function() { return AudioScriptingInterface.muted; }); // restore binding
}
}
HifiControlsUit.Switch {
height: root.switchHeight;
switchWidth: root.switchWidth;
labelTextOn: "Noise Reduction";
backgroundOnColor: "#E3E3E3";
checked: AudioScriptingInterface.noiseReduction;
onCheckedChanged: {
AudioScriptingInterface.noiseReduction = checked;
checked = Qt.binding(function() { return AudioScriptingInterface.noiseReduction; }); // restore binding
}
}
HifiControlsUit.Switch {
id: pttSwitch
height: root.switchHeight;
switchWidth: root.switchWidth;
labelTextOn: qsTr("Push To Talk (T)");
backgroundOnColor: "#E3E3E3";
checked: (bar.currentIndex === 0) ? AudioScriptingInterface.pushToTalkDesktop : AudioScriptingInterface.pushToTalkHMD;
onCheckedChanged: {
if (bar.currentIndex === 0) {
AudioScriptingInterface.pushToTalkDesktop = checked;
} else {
AudioScriptingInterface.pushToTalkHMD = checked;
}
checked = Qt.binding(function() {
if (bar.currentIndex === 0) {
return AudioScriptingInterface.pushToTalkDesktop;
} else {
return AudioScriptingInterface.pushToTalkHMD;
}
}); // restore binding
}
}
}
ColumnLayout {
spacing: 24;
HifiControlsUit.Switch {
id: warnMutedSwitch
height: root.switchHeight;
switchWidth: root.switchWidth;
labelTextOn: qsTr("Warn when muted");
backgroundOnColor: "#E3E3E3";
checked: AudioScriptingInterface.warnWhenMuted;
onClicked: {
AudioScriptingInterface.warnWhenMuted = checked;
checked = Qt.binding(function() { return AudioScriptingInterface.warnWhenMuted; }); // restore binding
}
}
HifiControlsUit.Switch {
id: audioLevelSwitch
height: root.switchHeight;
switchWidth: root.switchWidth;
labelTextOn: qsTr("Audio Level Meter");
backgroundOnColor: "#E3E3E3";
checked: AvatarInputs.showAudioTools;
onCheckedChanged: {
AvatarInputs.showAudioTools = checked;
checked = Qt.binding(function() { return AvatarInputs.showAudioTools; }); // restore binding
}
}
HifiControlsUit.Switch {
id: stereoInput;
height: root.switchHeight;
switchWidth: root.switchWidth;
labelTextOn: qsTr("Stereo input");
backgroundOnColor: "#E3E3E3";
checked: AudioScriptingInterface.isStereoInput;
onCheckedChanged: {
AudioScriptingInterface.isStereoInput = checked;
checked = Qt.binding(function() { return AudioScriptingInterface.isStereoInput; }); // restore binding
}
}
}
}
Item {
anchors.left: parent.left
width: rightMostInputLevelPos;
height: pttText.height;
RalewayRegular {
id: pttText
x: margins.paddings;
color: hifi.colors.white;
width: rightMostInputLevelPos;
height: paintedHeight;
wrapMode: Text.WordWrap;
font.italic: true
size: 16;
text: (bar.currentIndex === 0) ? qsTr("Press and hold the button \"T\" to talk.") :
qsTr("Press and hold grip triggers on both of your controllers to talk.");
}
}
Separator { }
Item {
x: margins.paddings;
width: parent.width - margins.paddings*2
height: 36
HiFiGlyphs {
width: margins.sizeCheckBox
text: hifi.glyphs.mic;
color: hifi.colors.white;
anchors.left: parent.left
anchors.leftMargin: -size/4 //the glyph has empty space at left about 25%
anchors.verticalCenter: parent.verticalCenter;
size: 30;
}
RalewayRegular {
anchors.verticalCenter: parent.verticalCenter;
width: margins.sizeText + margins.sizeLevel
anchors.left: parent.left
anchors.leftMargin: margins.sizeCheckBox
size: 16;
color: hifi.colors.white;
text: qsTr("Choose input device");
}
}
ListView {
id: inputView
width: parent.width - margins.paddings*2
x: margins.paddings
height: Math.min(150, contentHeight);
spacing: 4;
snapMode: ListView.SnapToItem;
clip: true;
model: AudioScriptingInterface.devices.input;
delegate: Item {
width: rightMostInputLevelPos
height: margins.sizeCheckBox > checkBoxInput.implicitHeight ?
margins.sizeCheckBox : checkBoxInput.implicitHeight
AudioControls.CheckBox {
id: checkBoxInput
anchors.left: parent.left
spacing: margins.sizeCheckBox - boxSize
anchors.verticalCenter: parent.verticalCenter
width: parent.width - inputLevel.width
clip: true
checkable: !checked
checked: bar.currentIndex === 0 ? selectedDesktop : selectedHMD;
boxSize: margins.sizeCheckBox / 2
isRound: true
text: devicename
onPressed: {
if (!checked) {
stereoInput.checked = false;
AudioScriptingInterface.setStereoInput(false); // the next selected audio device might not support stereo
AudioScriptingInterface.setInputDevice(info, bar.currentIndex === 1);
}
}
}
AudioControls.InputPeak {
id: inputLevel
anchors.right: parent.right
peak: model.peak;
anchors.verticalCenter: parent.verticalCenter
visible: ((bar.currentIndex === 1 && isVR) ||
(bar.currentIndex === 0 && !isVR)) &&
AudioScriptingInterface.devices.input.peakValuesAvailable;
}
}
}
AudioControls.LoopbackAudio {
x: margins.paddings
visible: (bar.currentIndex === 1 && isVR) ||
(bar.currentIndex === 0 && !isVR);
anchors { left: parent.left; leftMargin: margins.paddings }
}
Separator {}
Item {
x: margins.paddings;
width: parent.width - margins.paddings*2
height: 36
HiFiGlyphs {
anchors.left: parent.left
anchors.leftMargin: -size/4 //the glyph has empty space at left about 25%
anchors.verticalCenter: parent.verticalCenter;
width: margins.sizeCheckBox
text: hifi.glyphs.unmuted;
color: hifi.colors.white;
size: 36;
}
RalewayRegular {
width: margins.sizeText + margins.sizeLevel
anchors.left: parent.left
anchors.leftMargin: margins.sizeCheckBox
anchors.verticalCenter: parent.verticalCenter;
size: 16;
color: hifi.colors.white;
text: qsTr("Choose output device");
}
}
ListView {
id: outputView
width: parent.width - margins.paddings*2
x: margins.paddings
height: Math.min(360 - inputView.height, contentHeight);
spacing: 4;
snapMode: ListView.SnapToItem;
clip: true;
model: AudioScriptingInterface.devices.output;
delegate: Item {
width: rightMostInputLevelPos
height: margins.sizeCheckBox > checkBoxOutput.implicitHeight ?
margins.sizeCheckBox : checkBoxOutput.implicitHeight
AudioControls.CheckBox {
id: checkBoxOutput
width: parent.width
spacing: margins.sizeCheckBox - boxSize
boxSize: margins.sizeCheckBox / 2
isRound: true
checked: bar.currentIndex === 0 ? selectedDesktop : selectedHMD;
checkable: !checked
text: devicename
onPressed: {
if (!checked) {
AudioScriptingInterface.setOutputDevice(info, bar.currentIndex === 1);
}
}
}
}
}
Item {
id: gainContainer
x: margins.paddings;
width: parent.width - margins.paddings*2
height: gainSliderTextMetrics.height
HifiControlsUit.Slider {
id: gainSlider
anchors.right: parent.right
height: parent.height
width: 200
minimumValue: -60.0
maximumValue: 20.0
stepSize: 5
value: Users.getAvatarGain(myAvatarUuid)
onValueChanged: {
updateMyAvatarGainFromQML(value, false);
}
onPressedChanged: {
if (!pressed) {
updateMyAvatarGainFromQML(value, false);
}
}
MouseArea {
anchors.fill: parent
onWheel: {
// Do nothing.
}
onDoubleClicked: {
gainSlider.value = 0.0
}
onPressed: {
// Pass through to Slider
mouse.accepted = false
}
onReleased: {
// the above mouse.accepted seems to make this
// never get called, nonetheless...
mouse.accepted = false
}
}
}
TextMetrics {
id: gainSliderTextMetrics
text: gainSliderText.text
font: gainSliderText.font
}
RalewayRegular {
// The slider for my card is special, it controls the master gain
id: gainSliderText;
text: "Avatar volume";
size: 16;
anchors.left: parent.left;
color: hifi.colors.white;
horizontalAlignment: Text.AlignLeft;
verticalAlignment: Text.AlignTop;
}
}
AudioControls.PlaySampleSound {
x: margins.paddings
visible: (bar.currentIndex === 1 && isVR) ||
(bar.currentIndex === 0 && !isVR);
anchors { left: parent.left; leftMargin: margins.paddings }
}
}
}