Changeset View
Changeset View
Standalone View
Standalone View
applet/contents/ui/main.qml
Show All 17 Lines | 1 | /* | |||
---|---|---|---|---|---|
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
19 | */ | 19 | */ | ||
20 | 20 | | |||
21 | import QtQuick 2.2 | 21 | import QtQuick 2.2 | ||
22 | import QtQuick.Layouts 1.0 | 22 | import QtQuick.Layouts 1.0 | ||
23 | 23 | | |||
24 | import org.kde.plasma.core 2.1 as PlasmaCore | 24 | import org.kde.plasma.core 2.1 as PlasmaCore | ||
25 | import org.kde.plasma.components 2.0 as PlasmaComponents | 25 | import org.kde.plasma.components 2.0 as PlasmaComponents | ||
26 | import org.kde.plasma.components 3.0 as PlasmaComponents3 | ||||
26 | import org.kde.plasma.extras 2.0 as PlasmaExtras | 27 | import org.kde.plasma.extras 2.0 as PlasmaExtras | ||
27 | import org.kde.plasma.plasmoid 2.0 | 28 | import org.kde.plasma.plasmoid 2.0 | ||
28 | 29 | | |||
29 | import org.kde.plasma.private.volume 0.1 | 30 | import org.kde.plasma.private.volume 0.1 | ||
30 | 31 | | |||
31 | import "../code/icon.js" as Icon | 32 | import "../code/icon.js" as Icon | ||
32 | 33 | | |||
33 | Item { | 34 | Item { | ||
Show All 24 Lines | 55 | Plasmoid.toolTipMainText: { | |||
58 | } | 59 | } | ||
59 | 60 | | |||
60 | if (sink.muted) { | 61 | if (sink.muted) { | ||
61 | return i18n("Audio Muted"); | 62 | return i18n("Audio Muted"); | ||
62 | } else { | 63 | } else { | ||
63 | return i18n("Volume at %1%", volumePercent(sink.volume)); | 64 | return i18n("Volume at %1%", volumePercent(sink.volume)); | ||
64 | } | 65 | } | ||
65 | } | 66 | } | ||
66 | Plasmoid.toolTipSubText: paSinkModel.preferredSink && !isDummyOutput(paSinkModel.preferredSink) ? paSinkModel.preferredSink.description : "" | 67 | Plasmoid.toolTipSubText: { | ||
68 | if (paSinkModel.preferredSink && !isDummyOutput(paSinkModel.preferredSink)) { | ||||
69 | var port = paSinkModel.preferredSink.ports[paSinkModel.preferredSink.activePortIndex]; | ||||
70 | if (port) { | ||||
71 | return port.description | ||||
72 | } | ||||
73 | return paSinkModel.preferredSink.name | ||||
74 | } | ||||
75 | return "" | ||||
76 | } | ||||
67 | 77 | | |||
68 | function isDummyOutput(output) { | 78 | function isDummyOutput(output) { | ||
69 | return output && output.name === dummyOutputName; | 79 | return output && output.name === dummyOutputName; | ||
70 | } | 80 | } | ||
71 | 81 | | |||
72 | function boundVolume(volume) { | 82 | function boundVolume(volume) { | ||
73 | return Math.max(PulseAudio.MinimalVolume, Math.min(volume, maxVolumeValue)); | 83 | return Math.max(PulseAudio.MinimalVolume, Math.min(volume, maxVolumeValue)); | ||
74 | } | 84 | } | ||
▲ Show 20 Lines • Show All 218 Lines • ▼ Show 20 Line(s) | |||||
293 | VolumeOSD { | 303 | VolumeOSD { | ||
294 | id: osd | 304 | id: osd | ||
295 | } | 305 | } | ||
296 | 306 | | |||
297 | VolumeFeedback { | 307 | VolumeFeedback { | ||
298 | id: feedback | 308 | id: feedback | ||
299 | } | 309 | } | ||
300 | 310 | | |||
311 | PlasmaCore.Svg { | ||||
312 | id: lineSvg | ||||
313 | imagePath: "widgets/line" | ||||
314 | } | ||||
315 | | ||||
301 | Plasmoid.fullRepresentation: ColumnLayout { | 316 | Plasmoid.fullRepresentation: ColumnLayout { | ||
302 | spacing: units.smallSpacing | 317 | spacing: units.smallSpacing * 0.75 | ||
ngraham: Revert this change | |||||
303 | Layout.minimumHeight: main.Layout.minimumHeight | 318 | Layout.minimumHeight: main.Layout.minimumHeight | ||
304 | Layout.minimumWidth: main.Layout.minimumWidth | 319 | Layout.minimumWidth: main.Layout.minimumWidth | ||
305 | 320 | | |||
306 | function beginMoveStream(type, stream) { | 321 | function beginMoveStream(type, stream) { | ||
307 | if (type == "sink") { | 322 | if (type == "sink") { | ||
308 | sourceView.visible = false; | 323 | sourceView.visible = false; | ||
309 | sourceViewHeader.visible = false; | 324 | sourceViewHeader.visible = false; | ||
310 | } else if (type == "source") { | 325 | } else if (type == "source") { | ||
Show All 27 Lines | 351 | PlasmaComponents.TabButton { | |||
338 | text: i18n("Devices") | 353 | text: i18n("Devices") | ||
339 | } | 354 | } | ||
340 | 355 | | |||
341 | PlasmaComponents.TabButton { | 356 | PlasmaComponents.TabButton { | ||
342 | id: streamsTab | 357 | id: streamsTab | ||
343 | text: i18n("Applications") | 358 | text: i18n("Applications") | ||
344 | } | 359 | } | ||
345 | } | 360 | } | ||
346 | | ||||
347 | PlasmaComponents.ToolButton { | | |||
348 | Layout.alignment: Qt.AlignBottom | | |||
349 | tooltip: plasmoid.action("configure").text | | |||
350 | iconName: "configure" | | |||
351 | Accessible.name: tooltip | | |||
352 | onClicked: { | | |||
353 | plasmoid.action("configure").trigger(); | | |||
354 | } | | |||
355 | } | | |||
356 | } | 361 | } | ||
357 | 362 | | |||
358 | PlasmaExtras.ScrollArea { | 363 | PlasmaExtras.ScrollArea { | ||
359 | id: scrollView; | 364 | id: scrollView; | ||
360 | 365 | | |||
361 | Layout.fillWidth: true | 366 | Layout.fillWidth: true | ||
362 | Layout.fillHeight: true | 367 | Layout.fillHeight: true | ||
363 | 368 | | |||
Show All 10 Lines | 375 | Item { | |||
374 | ColumnLayout { | 379 | ColumnLayout { | ||
375 | id: streamsView | 380 | id: streamsView | ||
376 | visible: tabBar.currentTab == streamsTab | 381 | visible: tabBar.currentTab == streamsTab | ||
377 | readonly property bool simpleMode: (sinkInputView.count >= 1 && sourceOutputView.count == 0) || (sinkInputView.count == 0 && sourceOutputView.count >= 1) | 382 | readonly property bool simpleMode: (sinkInputView.count >= 1 && sourceOutputView.count == 0) || (sinkInputView.count == 0 && sourceOutputView.count >= 1) | ||
378 | property int maximumWidth: scrollView.viewport.width | 383 | property int maximumWidth: scrollView.viewport.width | ||
379 | width: maximumWidth | 384 | width: maximumWidth | ||
380 | Layout.maximumWidth: maximumWidth | 385 | Layout.maximumWidth: maximumWidth | ||
381 | 386 | | |||
382 | Header { | | |||
383 | Layout.fillWidth: true | | |||
384 | visible: sinkInputView.count > 0 && !streamsView.simpleMode | | |||
385 | text: i18n("Playback Streams") | | |||
386 | } | | |||
387 | ListView { | 387 | ListView { | ||
388 | id: sinkInputView | 388 | id: sinkInputView | ||
389 | 389 | | |||
390 | Layout.fillWidth: true | 390 | Layout.fillWidth: true | ||
391 | Layout.minimumHeight: contentHeight | 391 | Layout.minimumHeight: contentHeight | ||
392 | Layout.maximumHeight: contentHeight | 392 | Layout.maximumHeight: contentHeight | ||
393 | 393 | | |||
394 | model: PulseObjectFilterModel { | 394 | model: PulseObjectFilterModel { | ||
395 | filters: [ { role: "VirtualStream", value: false } ] | 395 | filters: [ { role: "VirtualStream", value: false } ] | ||
396 | sourceModel: SinkInputModel {} | 396 | sourceModel: SinkInputModel {} | ||
397 | } | 397 | } | ||
398 | boundsBehavior: Flickable.StopAtBounds; | 398 | boundsBehavior: Flickable.StopAtBounds; | ||
399 | delegate: StreamListItem { | 399 | delegate: StreamListItem { | ||
400 | type: "sink-input" | 400 | type: "sink-input" | ||
401 | draggable: sinkView.count > 1 | 401 | draggable: sinkView.count > 1 | ||
402 | onlyOne: streamsView.simpleMode | 402 | onlyOne: streamsView.simpleMode | ||
403 | } | 403 | } | ||
404 | } | 404 | } | ||
405 | 405 | | |||
406 | Header { | 406 | PlasmaCore.SvgItem { | ||
ngraham: I think there isn't a line here in the mockup, right? | |||||
407 | elementId: "horizontal-line" | ||||
408 | Layout.topMargin: naturalSize.height | ||||
407 | Layout.fillWidth: true | 409 | Layout.fillWidth: true | ||
408 | visible: sourceOutputView.count > 0 && !streamsView.simpleMode | 410 | Layout.preferredHeight: naturalSize.height | ||
409 | text: i18n("Recording Streams") | 411 | svg: lineSvg | ||
This is the line that separates the playback and recording applications. gvgeo: This is the line that separates the playback and recording applications.
Just notice that… | |||||
410 | } | 412 | } | ||
413 | | ||||
411 | ListView { | 414 | ListView { | ||
412 | id: sourceOutputView | 415 | id: sourceOutputView | ||
413 | 416 | | |||
414 | Layout.fillWidth: true | 417 | Layout.fillWidth: true | ||
415 | Layout.minimumHeight: contentHeight | 418 | Layout.minimumHeight: contentHeight | ||
416 | Layout.maximumHeight: contentHeight | 419 | Layout.maximumHeight: contentHeight | ||
417 | 420 | | |||
418 | model: PulseObjectFilterModel { | 421 | model: PulseObjectFilterModel { | ||
Show All 12 Lines | |||||
431 | ColumnLayout { | 434 | ColumnLayout { | ||
432 | id: devicesView | 435 | id: devicesView | ||
433 | visible: tabBar.currentTab == devicesTab | 436 | visible: tabBar.currentTab == devicesTab | ||
434 | readonly property bool simpleMode: sinkView.count == 1 && sourceView.count == 1 | 437 | readonly property bool simpleMode: sinkView.count == 1 && sourceView.count == 1 | ||
435 | property int maximumWidth: scrollView.viewport.width | 438 | property int maximumWidth: scrollView.viewport.width | ||
436 | width: maximumWidth | 439 | width: maximumWidth | ||
437 | Layout.maximumWidth: maximumWidth | 440 | Layout.maximumWidth: maximumWidth | ||
438 | 441 | | |||
439 | Header { | | |||
440 | id: sinkViewHeader | | |||
441 | Layout.fillWidth: true | | |||
442 | visible: sinkView.count > 0 && !devicesView.simpleMode | | |||
443 | text: i18n("Playback Devices") | | |||
444 | } | | |||
445 | ListView { | 442 | ListView { | ||
446 | id: sinkView | 443 | id: sinkView | ||
447 | 444 | | |||
448 | Layout.fillWidth: true | 445 | Layout.fillWidth: true | ||
449 | Layout.minimumHeight: contentHeight | 446 | Layout.minimumHeight: contentHeight | ||
450 | Layout.maximumHeight: contentHeight | 447 | Layout.maximumHeight: contentHeight | ||
451 | 448 | | |||
452 | model: PlasmaCore.SortFilterModel { | 449 | model: PlasmaCore.SortFilterModel { | ||
Show All 13 Lines | |||||
466 | } | 463 | } | ||
467 | boundsBehavior: Flickable.StopAtBounds; | 464 | boundsBehavior: Flickable.StopAtBounds; | ||
468 | delegate: DeviceListItem { | 465 | delegate: DeviceListItem { | ||
469 | type: "sink" | 466 | type: "sink" | ||
470 | onlyOne: devicesView.simpleMode | 467 | onlyOne: devicesView.simpleMode | ||
471 | } | 468 | } | ||
472 | } | 469 | } | ||
473 | 470 | | |||
474 | Header { | 471 | PlasmaCore.SvgItem { | ||
ngraham: ditto | |||||
475 | id: sourceViewHeader | 472 | elementId: "horizontal-line" | ||
473 | Layout.topMargin: naturalSize.height | ||||
476 | Layout.fillWidth: true | 474 | Layout.fillWidth: true | ||
477 | visible: sourceView.count > 0 && !devicesView.simpleMode | 475 | Layout.preferredHeight: naturalSize.height | ||
478 | text: i18n("Recording Devices") | 476 | svg: lineSvg | ||
479 | } | 477 | } | ||
478 | | ||||
480 | ListView { | 479 | ListView { | ||
481 | id: sourceView | 480 | id: sourceView | ||
482 | 481 | | |||
483 | Layout.fillWidth: true | 482 | Layout.fillWidth: true | ||
484 | Layout.minimumHeight: contentHeight | 483 | Layout.minimumHeight: contentHeight | ||
485 | Layout.maximumHeight: contentHeight | 484 | Layout.maximumHeight: contentHeight | ||
486 | 485 | | |||
487 | model: PulseObjectFilterModel { | 486 | model: PulseObjectFilterModel { | ||
Show All 29 Lines | 511 | PlasmaExtras.Heading { | |||
517 | visible: devicesView.visible && !sinkView.count && !sourceView.count | 516 | visible: devicesView.visible && !sinkView.count && !sourceView.count | ||
518 | text: i18n("No output or input devices found") | 517 | text: i18n("No output or input devices found") | ||
519 | wrapMode: Text.WordWrap | 518 | wrapMode: Text.WordWrap | ||
520 | verticalAlignment: Text.AlignVCenter | 519 | verticalAlignment: Text.AlignVCenter | ||
521 | horizontalAlignment: Text.AlignHCenter | 520 | horizontalAlignment: Text.AlignHCenter | ||
522 | } | 521 | } | ||
523 | } | 522 | } | ||
524 | } | 523 | } | ||
524 | | ||||
525 | PlasmaCore.SvgItem { | ||||
you can give it negative side margins to get it to touch the sides of the pop-up, as in the mockup ngraham: you can give it negative side margins to get it to touch the sides of the pop-up, as in the… | |||||
526 | elementId: "horizontal-line" | ||||
527 | Layout.fillWidth: true | ||||
528 | Layout.preferredHeight: naturalSize.height | ||||
529 | Layout.topMargin: 0 - units.smallSpacing / 4 | ||||
530 | svg: lineSvg | ||||
531 | } | ||||
532 | | ||||
533 | RowLayout { | ||||
534 | spacing: units.smallSpacing | ||||
535 | | ||||
536 | PlasmaComponents3.CheckBox { | ||||
537 | id: raiseMaximumVolumeCheckbox | ||||
538 | Layout.leftMargin: units.smallSpacing * 0.75 + 4 | ||||
539 | onClicked: console.log(raiseMaximumVolumeCheckbox.Layout.rightMargin) | ||||
So this doesn't actually do anything yet? Obviously that needs to change before this can land. :) Also the checked state needs to be saved somewhere. ngraham: So this doesn't actually do anything yet? Obviously that needs to change before this can land. | |||||
540 | } | ||||
541 | | ||||
542 | PlasmaExtras.Heading { | ||||
ngraham: Don't use a separate Heading here; give the Checkbox a `text:` property | |||||
543 | Layout.fillWidth: true | ||||
544 | Layout.leftMargin: units.smallSpacing / 4 | ||||
545 | level: 5 | ||||
546 | text: i18n("Raise maximum volume") | ||||
547 | elide: Text.ElideRight | ||||
548 | } | ||||
549 | | ||||
550 | PlasmaComponents.ToolButton { | ||||
551 | tooltip: plasmoid.action("configure").text | ||||
552 | iconName: "configure" | ||||
553 | Accessible.name: tooltip | ||||
554 | onClicked: { | ||||
555 | plasmoid.action("configure").trigger(); | ||||
556 | } | ||||
557 | } | ||||
558 | } | ||||
525 | } | 559 | } | ||
526 | 560 | | |||
527 | Component.onCompleted: { | 561 | Component.onCompleted: { | ||
528 | MicrophoneIndicator.init(); | 562 | MicrophoneIndicator.init(); | ||
529 | } | 563 | } | ||
530 | } | 564 | } |
Revert this change