diff --git a/src/kcm/package/contents/ui/DeviceListItem.qml b/src/kcm/package/contents/ui/DeviceListItem.qml index 2b90787..bd313f7 100644 --- a/src/kcm/package/contents/ui/DeviceListItem.qml +++ b/src/kcm/package/contents/ui/DeviceListItem.qml @@ -1,104 +1,117 @@ /* Copyright 2014-2015 Harald Sitter Copyright 2019 Sefa Eyeoglu This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ import QtQuick 2.0 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.0 import org.kde.kirigami 2.5 as Kirigami import org.kde.plasma.private.volume 0.1 import "../code/icon.js" as Icon ColumnLayout { id: delegate + spacing: Kirigami.Units.smallSpacing * 2 width: parent.width property bool isPlayback: type.substring(0, 4) == "sink" readonly property var currentPort: Ports[ActivePortIndex] RowLayout { - Kirigami.Icon { - Layout.alignment: Qt.AlignHCenter - Layout.preferredHeight: delegateColumn.height * 0.75 - Layout.preferredWidth: Layout.preferredHeight - source: Icon.formFactorIcon(FormFactor) || IconName || "audio-card" + spacing: Kirigami.Units.smallSpacing + Layout.minimumHeight: portbox.implicitHeight + + RadioButton { + id: defaultButton + // Maximum width of the button need to match the text. Empty area must not change the default device. + Layout.maximumWidth: delegate.width - Layout.leftMargin - Layout.rightMargin + - (portbox.visible ? Kirigami.Units.gridUnit + portLabel.implicitWidth + Kirigami.Units.smallSpacing + portbox.implicitWidth : 0) + // Margins and spacing are set to center RadioButton with muteButton, and text with VolumeSlider. + Layout.leftMargin: LayoutMirroring.enabled ? 0 : Math.round((muteButton.width - defaultButton.indicator.width) / 2) + Layout.rightMargin: LayoutMirroring.enabled ? Math.round((muteButton.width - defaultButton.indicator.width) / 2) : 0 + spacing: Kirigami.Units.smallSpacing + Math.round((muteButton.width - defaultButton.indicator.width) / 2) + checked: Default + visible: delegate.ListView.view.count > 1 + onClicked: Default = true + text: !currentPort ? Description : i18ndc("kcm_pulseaudio", "label of device items", "%1 (%2)", currentPort.description, Description) } - ColumnLayout { - id: delegateColumn + Label { + id: soloLabel + Layout.maximumWidth: delegate.width - (portbox.visible ? Kirigami.Units.gridUnit + portLabel.implicitWidth + Kirigami.Units.smallSpacing + portbox.implicitWidth : 0) + text: defaultButton.text + visible: delegate.ListView.view.count <= 1 + elide: Text.ElideRight + } + + Item { Layout.fillWidth: true + visible: portbox.visible + } - RowLayout { - Label { - id: inputText - Layout.fillWidth: true - visible: !portbox.visible - elide: Text.ElideRight - text: !currentPort ? Description : i18ndc("kcm_pulseaudio", "label of device items", "%1 (%2)", currentPort.description, Description) - } + Label { + id: portLabel + visible: portbox.visible + text: i18nd("kcm_pulseaudio", "Port:") + } - ComboBox { - id: portbox - visible: portbox.count > 1 - model: { - var items = []; - for (var i = 0; i < Ports.length; ++i) { - var port = Ports[i]; - if (port.availability != Port.Unavailable) { - items.push(port.description); - } + ComboBox { + id: portbox + readonly property var ports: Ports + visible: portbox.count > 1 && delegate.width - Kirigami.Units.gridUnit * 8 > implicitWidth + onModelChanged: currentIndex = ActivePortIndex + currentIndex: ActivePortIndex + onActivated: ActivePortIndex = index + + onPortsChanged: { + var items = []; + for (var i = 0; i < ports.length; ++i) { + var port = ports[i]; + var text = port.description; + if (port.availability == Port.Unavailable) { + if (port.name == "analog-output-speaker" || port.name == "analog-input-microphone-internal") { + text += i18ndc("kcm_pulseaudio", "Port is unavailable", " (unavailable)"); + } else { + text += i18ndc("kcm_pulseaudio", "Port is unplugged", " (unplugged)"); } - return items } - currentIndex: ActivePortIndex - onActivated: ActivePortIndex = index - } - - Item { - visible: portbox.visible - Layout.fillWidth: true - } - - Button { - text: i18n("Default Device") - icon.name: Default ? "starred-symbolic" : "non-starred-symbolic" - visible: delegate.ListView.view.count > 1 - checkable: true - checked: Default - onClicked: Default = true; + items.push(text); } - } - - RowLayout { - MuteButton { - Layout.topMargin: -(height - icon.height) / 2 - muted: Muted - onCheckedChanged: Muted = checked - } - - VolumeSlider {} + model = items; } } } - ListItemSeperator { view: delegate.ListView.view } + RowLayout { + spacing: Kirigami.Units.smallSpacing + + MuteButton { + id: muteButton + Layout.topMargin: -(height - icon.height) / 2 + muted: Muted + onCheckedChanged: Muted = checked + toolTipText: !currentPort ? Description : currentPort.description + } + + VolumeSlider {} + } } diff --git a/src/kcm/package/contents/ui/Devices.qml b/src/kcm/package/contents/ui/Devices.qml index 20fa7eb..c9ce395 100644 --- a/src/kcm/package/contents/ui/Devices.qml +++ b/src/kcm/package/contents/ui/Devices.qml @@ -1,81 +1,84 @@ /* Copyright 2014-2015 Harald Sitter Copyright 2019 Sefa Eyeoglu This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ import QtQuick 2.0 import QtQuick.Layouts 1.1 import QtQuick.Controls 2.3 +import org.kde.kirigami 2.5 as Kirigami + ScrollView { id: scrollView contentHeight: contentItem.height clip: true Item { id: contentItem width: scrollView.availableWidth height: contentLayout.implicitHeight ColumnLayout { id: contentLayout width: scrollView.availableWidth Header { Layout.fillWidth: true enabled: sinks.count > 0 text: i18nd("kcm_pulseaudio", "Playback Devices") disabledText: i18ndc("kcm_pulseaudio", "@label", "No Playback Devices Available") } ListView { id: sinks Layout.fillWidth: true Layout.preferredHeight: contentHeight - Layout.margins: units.gridUnit / 2 + Layout.margins: Kirigami.Units.gridUnit / 2 interactive: false - spacing: units.smallSpacing * 2 + spacing: Kirigami.Units.gridUnit model: sinkModel delegate: DeviceListItem { isPlayback: true } } Header { Layout.fillWidth: true enabled: sources.count > 0 text: i18nd("kcm_pulseaudio", "Recording Devices") disabledText: i18ndc("kcm_pulseaudio", "@label", "No Recording Devices Available") } ListView { id: sources Layout.fillWidth: true Layout.preferredHeight: contentHeight - Layout.margins: units.gridUnit / 2 + Layout.margins: Kirigami.Units.gridUnit / 2 interactive: false + spacing: Kirigami.Units.gridUnit model: sourceModel delegate: DeviceListItem { isPlayback: false } } } } } diff --git a/src/kcm/package/contents/ui/MuteButton.qml b/src/kcm/package/contents/ui/MuteButton.qml index f73a3dd..5e73287 100644 --- a/src/kcm/package/contents/ui/MuteButton.qml +++ b/src/kcm/package/contents/ui/MuteButton.qml @@ -1,37 +1,38 @@ /* Copyright 2014-2015 Harald Sitter Copyright 2019 Sefa Eyeoglu This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ import QtQuick 2.0 import QtQuick.Controls 2.5 as QQC2 import "../code/icon.js" as Icon QQC2.ToolButton { property bool muted: true + property var toolTipText icon.name: Icon.name(Volume, Muted, isPlayback ? "audio-volume" : "microphone-sensitivity") checkable: true checked: muted onMutedChanged: checked = muted QQC2.ToolTip { - text: i18ndc("kcm_pulseaudio", "Mute audio stream", "Mute %1", inputText.text) // a little hacky + text: i18ndc("kcm_pulseaudio", "Mute audio stream", "Mute %1", toolTipText) } } diff --git a/src/kcm/package/contents/ui/StreamListItem.qml b/src/kcm/package/contents/ui/StreamListItem.qml index 5862445..6e805f8 100644 --- a/src/kcm/package/contents/ui/StreamListItem.qml +++ b/src/kcm/package/contents/ui/StreamListItem.qml @@ -1,100 +1,101 @@ /* Copyright 2014-2015 Harald Sitter Copyright 2019 Sefa Eyeoglu This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ import QtQuick 2.0 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.0 import org.kde.kirigami 2.5 as Kirigami import org.kde.plasma.private.volume 0.1 ColumnLayout { id: delegate property alias deviceModel: deviceComboBox.model readonly property bool isEventStream: Name == "sink-input-by-media-role:event" property bool isPlayback: type.substring(0, 4) == "sink" width: parent.width RowLayout { Layout.fillWidth: true spacing: units.smallSpacing * 2 Kirigami.Icon { Layout.alignment: Qt.AlignHCenter Layout.preferredHeight: delegateColumn.height * 0.75 Layout.preferredWidth: Layout.preferredHeight source: IconName || "unknown" } ColumnLayout { id: delegateColumn Layout.fillWidth: true RowLayout { Label { id: inputText Layout.fillWidth: true text: { if (isEventStream) { return i18nd("kcm_pulseaudio", "Notification Sounds"); } else if (Client) { return i18ndc("kcm_pulseaudio", "label of stream items", "%1: %2", Client.name, Name); } else { return Name; } } elide: Text.ElideRight } DeviceComboBox { id: deviceComboBox Layout.leftMargin: units.smallSpacing Layout.rightMargin: units.smallSpacing Layout.preferredWidth: delegate.width / 3 visible: !isEventStream && count > 1 } } RowLayout { MuteButton { muted: Muted onCheckedChanged: Muted = checked + toolTipText: inputText.text } VolumeSlider {} } } } ListItemSeperator { view: delegate.ListView.view Component.onCompleted: { if (isEventStream) { visible = Qt.binding(function() { return sinkInputView.count > 0; }); } } } }