1/* Webcamoid, webcam capture application. 2 * Copyright (C) 2016 Gonzalo Exequiel Pedone 3 * 4 * Webcamoid is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * Webcamoid is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with Webcamoid. If not, see <http://www.gnu.org/licenses/>. 16 * 17 * Web-Site: http://webcamoid.github.io/ 18 */ 19 20import QtQuick 2.7 21import QtQuick.Controls 2.0 22import QtQuick.Layouts 1.3 23import AkQmlControls 1.0 24 25Rectangle { 26 id: recAudioConfig 27 color: Qt.rgba(0, 0, 0, 0) 28 clip: true 29 width: 200 30 height: 400 31 32 function updateInputs(inputs) 33 { 34 lsvInputs.model.clear(); 35 36 for (var input in inputs) { 37 if (inputs[input] === ":dummyin:") 38 continue; 39 40 lsvInputs.model.append({ 41 input: inputs[input], 42 description: AudioLayer.description(inputs[input]) 43 }) 44 } 45 46 if (AudioLayer.audioInput.indexOf(":dummyin:") >= 0) { 47 lsvInputs.currentIndex = -1 48 noInput.selected = true 49 } else 50 lsvInputs.currentIndex = inputs.indexOf(AudioLayer.audioInput[0]) - 1 51 } 52 53 function updateOutputs(outputs) 54 { 55 lsvOutputs.model.clear(); 56 57 for (var output in outputs) { 58 if (outputs[output] === ":dummyout:") 59 continue; 60 61 lsvOutputs.model.append({ 62 output: outputs[output], 63 description: AudioLayer.description(outputs[output])}) 64 } 65 66 if (AudioLayer.audioOutput === ":dummyout:") { 67 lsvOutputs.currentIndex = -1 68 noOutput.selected = true 69 } else 70 lsvOutputs.currentIndex = outputs.indexOf(AudioLayer.audioOutput) 71 } 72 73 Component.onCompleted: { 74 updateInputs(AudioLayer.inputs) 75 updateOutputs(AudioLayer.outputs) 76 } 77 78 Connections { 79 target: AudioLayer 80 81 onInputsChanged: updateInputs(inputs) 82 onOutputsChanged: updateOutputs(outputs) 83 onAudioInputChanged: { 84 lsvInputs.lock = true 85 86 if (audioInput.length > 0) 87 lsvInputs.currentIndex = AudioLayer.inputs.indexOf(audioInput[0]) - 1 88 89 lsvInputs.lock = false 90 } 91 onAudioOutputChanged: { 92 lsvOutputs.lock = true 93 94 if (AudioLayer.audioOutput === ":dummyout:") { 95 lsvOutputs.currentIndex = -1 96 noOutput.selected = true 97 } else 98 lsvOutputs.currentIndex = AudioLayer.outputs.indexOf(audioOutput) 99 100 lsvOutputs.lock = false 101 } 102 103 onInputDescriptionChanged: { 104 lsvInputs.lock = true 105 updateInputs(AudioLayer.inputs) 106 lsvInputs.lock = false 107 } 108 } 109 110 RowLayout { 111 id: rlyDevices 112 anchors.left: parent.left 113 anchors.right: parent.right 114 115 AkToolButton { 116 id: btnOutputs 117 label: qsTr("Outputs") 118 checked: true 119 Layout.fillWidth: true 120 ToolTip.visible: hovered 121 ToolTip.text: qsTr("Select the output device for audio playing") 122 checkable: true 123 iconRc: "image://icons/webcamoid-headphones" 124 125 onCheckedChanged: { 126 if (checked) { 127 btnInputs.checked = false 128 recAudioConfig.state = "" 129 } 130 } 131 } 132 AkToolButton { 133 id: btnInputs 134 label: qsTr("Inputs") 135 Layout.fillWidth: true 136 ToolTip.visible: hovered 137 ToolTip.text: qsTr("Select the device for audio capturing") 138 checkable: true 139 iconRc: "image://icons/webcamoid-mic" 140 141 onCheckedChanged: { 142 if (checked) { 143 btnOutputs.checked = false 144 recAudioConfig.state = "showInputs" 145 } 146 } 147 } 148 } 149 150 // Output devices 151 152 Rectangle { 153 id: noOutput 154 height: 32 155 anchors.top: rlyDevices.bottom 156 anchors.right: parent.right 157 anchors.left: parent.left 158 159 property bool selected: false 160 161 property color gradUp: selected? 162 Qt.rgba(0.75, 0, 0, 1): 163 Qt.rgba(0.25, 0, 0, 1) 164 property color gradLow: selected? 165 Qt.rgba(1, 0, 0, 1): 166 Qt.rgba(0.5, 0, 0, 1) 167 168 onSelectedChanged: { 169 gradUp = selected? 170 Qt.rgba(0.75, 0, 0, 1): 171 Qt.rgba(0.25, 0, 0, 1) 172 gradLow = selected? 173 Qt.rgba(1, 0, 0, 1): 174 Qt.rgba(0.5, 0, 0, 1) 175 } 176 177 gradient: Gradient { 178 GradientStop { 179 position: 0 180 color: noOutput.gradUp 181 } 182 183 GradientStop { 184 position: 1 185 color: noOutput.gradLow 186 } 187 } 188 189 Label { 190 id: txtNoOutputButton 191 anchors.verticalCenter: parent.verticalCenter 192 anchors.horizontalCenter: parent.horizontalCenter 193 text: qsTr("Silence") 194 color: noOutput.selected? Qt.rgba(1, 1, 1, 1): Qt.rgba(0.75, 0.75, 0.75, 1) 195 } 196 197 MouseArea { 198 id: msaNoOutputButton 199 hoverEnabled: true 200 cursorShape: Qt.PointingHandCursor 201 anchors.fill: parent 202 203 onEntered: { 204 txtNoOutputButton.font.bold = true 205 noOutput.gradUp = noOutput.selected? 206 Qt.rgba(1, 0.25, 0.25, 1): 207 Qt.rgba(0.5, 0.25, 0.25, 1) 208 noOutput.gradLow = noOutput.selected? 209 Qt.rgba(1, 0.25, 0.25, 1): 210 Qt.rgba(0.75, 0.25, 0.25, 1) 211 } 212 onExited: { 213 txtNoOutputButton.font.bold = false 214 txtNoOutputButton.scale = 1 215 noOutput.gradUp = noOutput.selected? 216 Qt.rgba(0.75, 0, 0, 1): 217 Qt.rgba(0.25, 0, 0, 1) 218 noOutput.gradLow = noOutput.selected? 219 Qt.rgba(1, 0, 0, 1): 220 Qt.rgba(0.5, 0, 0, 1) 221 } 222 onPressed: txtNoOutputButton.scale = 0.75 223 onReleased: txtNoOutputButton.scale = 1 224 onClicked: { 225 AudioLayer.audioOutput = ":dummyout:" 226 lsvOutputs.currentIndex = -1 227 noOutput.selected = true 228 } 229 } 230 } 231 OptionList { 232 id: lsvOutputs 233 anchors.left: parent.left 234 anchors.right: parent.right 235 anchors.top: noOutput.bottom 236 anchors.bottom: parent.bottom 237 textRole: "description" 238 239 property bool lock: false 240 241 onCurrentIndexChanged: { 242 if (lock) 243 return; 244 245 var option = model.get(currentIndex) 246 AudioLayer.audioOutput = option? option.output: ":dummyout:" 247 noOutput.selected = false 248 } 249 } 250 251 // Input devices 252 253 Rectangle { 254 id: noInput 255 height: 0 256 anchors.top: rlyDevices.bottom 257 anchors.right: parent.right 258 anchors.left: parent.left 259 visible: false 260 261 property bool selected: false 262 263 property color gradUp: selected? 264 Qt.rgba(0.75, 0, 0, 1): 265 Qt.rgba(0.25, 0, 0, 1) 266 property color gradLow: selected? 267 Qt.rgba(1, 0, 0, 1): 268 Qt.rgba(0.5, 0, 0, 1) 269 270 onSelectedChanged: { 271 gradUp = selected? 272 Qt.rgba(0.75, 0, 0, 1): 273 Qt.rgba(0.25, 0, 0, 1) 274 gradLow = selected? 275 Qt.rgba(1, 0, 0, 1): 276 Qt.rgba(0.5, 0, 0, 1) 277 } 278 279 gradient: Gradient { 280 GradientStop { 281 position: 0 282 color: noInput.gradUp 283 } 284 285 GradientStop { 286 position: 1 287 color: noInput.gradLow 288 } 289 } 290 291 Label { 292 id: txtNoInputButton 293 anchors.verticalCenter: parent.verticalCenter 294 anchors.horizontalCenter: parent.horizontalCenter 295 text: qsTr("Silence") 296 color: noInput.selected? Qt.rgba(1, 1, 1, 1): Qt.rgba(0.75, 0.75, 0.75, 1) 297 } 298 299 MouseArea { 300 id: msaNoInputButton 301 hoverEnabled: true 302 cursorShape: Qt.PointingHandCursor 303 anchors.fill: parent 304 305 onEntered: { 306 txtNoInputButton.font.bold = true 307 noInput.gradUp = noInput.selected? 308 Qt.rgba(1, 0.25, 0.25, 1): 309 Qt.rgba(0.5, 0.25, 0.25, 1) 310 noInput.gradLow = noInput.selected? 311 Qt.rgba(1, 0.25, 0.25, 1): 312 Qt.rgba(0.75, 0.25, 0.25, 1) 313 } 314 onExited: { 315 txtNoInputButton.font.bold = false 316 txtNoInputButton.scale = 1 317 noInput.gradUp = noInput.selected? 318 Qt.rgba(0.75, 0, 0, 1): 319 Qt.rgba(0.25, 0, 0, 1) 320 noInput.gradLow = noInput.selected? 321 Qt.rgba(1, 0, 0, 1): 322 Qt.rgba(0.5, 0, 0, 1) 323 } 324 onPressed: txtNoInputButton.scale = 0.75 325 onReleased: txtNoInputButton.scale = 1 326 onClicked: { 327 AudioLayer.audioInput = [":dummyin:"] 328 lsvInputs.currentIndex = -1 329 noInput.selected = true 330 } 331 } 332 } 333 OptionList { 334 id: lsvInputs 335 anchors.left: parent.left 336 anchors.right: parent.right 337 anchors.top: noInput.bottom 338 anchors.bottom: parent.bottom 339 textRole: "description" 340 visible: false 341 342 property bool lock: false 343 344 onCurrentIndexChanged: { 345 if (lock) 346 return; 347 348 var option = model.get(currentIndex) 349 AudioLayer.audioInput = option? [option.input]: [":dummyin:"] 350 noInput.selected = false 351 } 352 } 353 354 states: [ 355 State { 356 name: "showInputs" 357 358 PropertyChanges { 359 target: noOutput 360 height: 0 361 visible: false 362 } 363 PropertyChanges { 364 target: lsvOutputs 365 visible: false 366 } 367 PropertyChanges { 368 target: noInput 369 height: 32 370 visible: true 371 } 372 PropertyChanges { 373 target: lsvInputs 374 visible: true 375 } 376 } 377 ] 378} 379