diff --git a/src/kcm/package/contents/ui/Advanced.qml b/src/kcm/package/contents/ui/Advanced.qml --- a/src/kcm/package/contents/ui/Advanced.qml +++ b/src/kcm/package/contents/ui/Advanced.qml @@ -29,225 +29,224 @@ ScrollView { id: scrollView - contentWidth: contentLayout.width - contentHeight: contentLayout.height + contentHeight: contentItem.height clip: true - ColumnLayout { - id: contentLayout + Item { + id: contentItem + width: scrollView.availableWidth + height: contentLayout.implicitHeight - Component.onCompleted: { - // Normal binding causes binding loops - width = Qt.binding(function() { - return scrollView.width; - }); - } - - Header { - Layout.fillWidth: true - enabled: view.count > 0 - text: i18nd("kcm_pulseaudio", "Device Profiles") - disabledText: i18ndc("kcm_pulseaudio", "@label", "No Device Profiles Available") - } + ColumnLayout { + id: contentLayout + anchors.fill: parent - ListView { - id: view - Layout.fillWidth: true - Layout.preferredHeight: contentHeight - Layout.margins: units.gridUnit / 2 - interactive: false - spacing: units.smallSpacing * 2 - model: CardModel {} - delegate: CardListItem {} - } - - Header { - Layout.fillWidth: true - text: i18nd("kcm_pulseaudio", "Advanced Output Configuration") - visible: moduleManager.settingsSupported - } - - ModuleManager { - id: moduleManager - } + Header { + Layout.fillWidth: true + enabled: view.count > 0 + text: i18nd("kcm_pulseaudio", "Device Profiles") + disabledText: i18ndc("kcm_pulseaudio", "@label", "No Device Profiles Available") + } - CheckBox { - Layout.fillWidth: true - Layout.topMargin: units.smallSpacing - Layout.leftMargin: units.gridUnit / 2 - Layout.rightMargin: units.gridUnit / 2 - text: i18nd("kcm_pulseaudio", "Add virtual output device for simultaneous output on all local sound cards") - checked: moduleManager.combineSinks - onCheckedChanged: moduleManager.combineSinks = checked; - enabled: moduleManager.configModuleLoaded - visible: moduleManager.settingsSupported - } + ListView { + id: view + Layout.fillWidth: true + Layout.preferredHeight: contentHeight + Layout.margins: units.gridUnit / 2 + interactive: false + spacing: units.smallSpacing * 2 + model: CardModel {} + delegate: CardListItem {} + } - CheckBox { - Layout.fillWidth: true - Layout.leftMargin: units.gridUnit / 2 - Layout.rightMargin: units.gridUnit / 2 - text: i18nd("kcm_pulseaudio", "Automatically switch all running streams when a new output becomes available") - checked: moduleManager.switchOnConnect - onCheckedChanged: moduleManager.switchOnConnect = checked; - enabled: moduleManager.configModuleLoaded - visible: moduleManager.settingsSupported - } + Header { + Layout.fillWidth: true + text: i18nd("kcm_pulseaudio", "Advanced Output Configuration") + visible: moduleManager.settingsSupported + } - Label { - Layout.alignment: Qt.AlignHCenter - enabled: false - font.italic: true - text: i18nd("kcm_pulseaudio", "Requires %1 PulseAudio module", moduleManager.configModuleName) - visible: moduleManager.settingsSupported && !moduleManager.configModuleLoaded - } + ModuleManager { + id: moduleManager + } - Header { - Layout.fillWidth: true - text: i18nd("kcm_pulseaudio", "Speaker Placement and Testing") - } + CheckBox { + Layout.fillWidth: true + Layout.topMargin: units.smallSpacing + Layout.leftMargin: units.gridUnit / 2 + Layout.rightMargin: units.gridUnit / 2 + text: i18nd("kcm_pulseaudio", "Add virtual output device for simultaneous output on all local sound cards") + checked: moduleManager.combineSinks + onCheckedChanged: moduleManager.combineSinks = checked; + enabled: moduleManager.configModuleLoaded + visible: moduleManager.settingsSupported + } - RowLayout { - Layout.margins: units.gridUnit / 2 - visible: sinks.count > 1 + CheckBox { + Layout.fillWidth: true + Layout.leftMargin: units.gridUnit / 2 + Layout.rightMargin: units.gridUnit / 2 + text: i18nd("kcm_pulseaudio", "Automatically switch all running streams when a new output becomes available") + checked: moduleManager.switchOnConnect + onCheckedChanged: moduleManager.switchOnConnect = checked; + enabled: moduleManager.configModuleLoaded + visible: moduleManager.settingsSupported + } Label { - text: i18ndc("kcm_pulseaudio", "@label", "Output:") - font.bold: true + Layout.alignment: Qt.AlignHCenter + enabled: false + font.italic: true + text: i18nd("kcm_pulseaudio", "Requires %1 PulseAudio module", moduleManager.configModuleName) + visible: moduleManager.settingsSupported && !moduleManager.configModuleLoaded } - ComboBox { - id: sinks + Header { + Layout.fillWidth: true + text: i18nd("kcm_pulseaudio", "Speaker Placement and Testing") + } - property var pulseObject: null + RowLayout { + Layout.margins: units.gridUnit / 2 + visible: sinks.count > 1 - Layout.fillWidth: true - textRole: "Description" - model: SinkModel { - onRowsInserted: sinks.updatePulseObject() - onRowsRemoved: sinks.updatePulseObject() - onDataChanged: sinks.updatePulseObject() - } - onCurrentIndexChanged: updatePulseObject() - onCurrentTextChanged: updatePulseObject() - Component.onCompleted: { - sinks.currentIndex = 0 - updatePulseObject() + Label { + text: i18ndc("kcm_pulseaudio", "@label", "Output:") + font.bold: true } - function updatePulseObject() { - Qt.callLater(function() { - // When the combobox isn't shown currentIndex is -1, so use 0 in that case - pulseObject = model.data(model.index(Math.max(sinks.currentIndex, 0), 0), model.role("PulseObject")); - }); + ComboBox { + id: sinks + + property var pulseObject: null + + Layout.fillWidth: true + textRole: "Description" + model: SinkModel { + onRowsInserted: sinks.updatePulseObject() + onRowsRemoved: sinks.updatePulseObject() + onDataChanged: sinks.updatePulseObject() + } + onCurrentIndexChanged: updatePulseObject() + onCurrentTextChanged: updatePulseObject() + Component.onCompleted: { + sinks.currentIndex = 0 + updatePulseObject() + } + + function updatePulseObject() { + Qt.callLater(function() { + // When the combobox isn't shown currentIndex is -1, so use 0 in that case + pulseObject = model.data(model.index(Math.max(sinks.currentIndex, 0), 0), model.role("PulseObject")); + }); + } } } - } - Grid { - id: grid - columns: 3 - spacing: 5 - Layout.fillWidth: true - - Item { - width: grid.width/3 - height: 50 - - Button{ - text: i18nd("kcm_pulseaudio", "Front Left") - anchors.centerIn: parent - visible: sinks.pulseObject ? sinks.pulseObject.rawChannels.indexOf("front-left") > -1 : false - onClicked: sinks.pulseObject.testChannel("front-left") + Grid { + id: grid + columns: 3 + spacing: 0 + Layout.fillWidth: true + + Item { + width: grid.width/3 + height: 50 + + Button{ + text: i18nd("kcm_pulseaudio", "Front Left") + anchors.centerIn: parent + visible: sinks.pulseObject ? sinks.pulseObject.rawChannels.indexOf("front-left") > -1 : false + onClicked: sinks.pulseObject.testChannel("front-left") + } } - } - Item { - width: grid.width/3 - height: 50 - - Button{ - text: i18nd("kcm_pulseaudio", "Front Center") - anchors.centerIn: parent - visible: sinks.pulseObject ? sinks.pulseObject.rawChannels.indexOf("front-center") > -1 : false - onClicked: sinks.pulseObject.testChannel("front-center") + Item { + width: grid.width/3 + height: 50 + + Button{ + text: i18nd("kcm_pulseaudio", "Front Center") + anchors.centerIn: parent + visible: sinks.pulseObject ? sinks.pulseObject.rawChannels.indexOf("front-center") > -1 : false + onClicked: sinks.pulseObject.testChannel("front-center") + } } - } - Item { - width: grid.width/3 - height: 50 - - Button{ - text: i18nd("kcm_pulseaudio", "Front Right") - anchors.centerIn: parent - visible: sinks.pulseObject ? sinks.pulseObject.rawChannels.indexOf("front-right") > -1 : false - onClicked: sinks.pulseObject.testChannel("front-right") + Item { + width: grid.width/3 + height: 50 + + Button{ + text: i18nd("kcm_pulseaudio", "Front Right") + anchors.centerIn: parent + visible: sinks.pulseObject ? sinks.pulseObject.rawChannels.indexOf("front-right") > -1 : false + onClicked: sinks.pulseObject.testChannel("front-right") + } } - } - Item { - width: grid.width/3 - height: 50 - - Button{ - text: i18nd("kcm_pulseaudio", "Side Left") - anchors.centerIn: parent - visible: sinks.pulseObject ? sinks.pulseObject.rawChannels.indexOf("side-left") > -1 : false - onClicked: sinks.pulseObject.testChannel("side-left") + Item { + width: grid.width/3 + height: 50 - } - } - Item { - width: grid.width/3 - height: 50 + Button{ + text: i18nd("kcm_pulseaudio", "Side Left") + anchors.centerIn: parent + visible: sinks.pulseObject ? sinks.pulseObject.rawChannels.indexOf("side-left") > -1 : false + onClicked: sinks.pulseObject.testChannel("side-left") - KCoreAddons.KUser { - id: kuser + } } - - Image { - source: kuser.faceIconUrl - anchors.centerIn: parent - sourceSize.width: 50 - sourceSize.height: 50 + Item { + width: grid.width/3 + height: 50 + + KCoreAddons.KUser { + id: kuser + } + + Image { + source: kuser.faceIconUrl + anchors.centerIn: parent + sourceSize.width: 50 + sourceSize.height: 50 + } } - } - Item { - width: grid.width/3 - height: 50 - Button{ - text: i18nd("kcm_pulseaudio", "Side Right") - anchors.centerIn: parent - visible: sinks.pulseObject ? sinks.pulseObject.rawChannels.indexOf("side-right") > -1 : false - onClicked: sinks.pulseObject.testChannel("side-right") + Item { + width: grid.width/3 + height: 50 + Button{ + text: i18nd("kcm_pulseaudio", "Side Right") + anchors.centerIn: parent + visible: sinks.pulseObject ? sinks.pulseObject.rawChannels.indexOf("side-right") > -1 : false + onClicked: sinks.pulseObject.testChannel("side-right") + } } - } - Item { - width: grid.width/3 - height: 50 - Button{ - text: i18nd("kcm_pulseaudio", "Rear Left") - anchors.centerIn: parent - visible: sinks.pulseObject ? sinks.pulseObject.rawChannels.indexOf("rear-left") > -1 : false - onClicked: sinks.pulseObject.testChannel("rear-left") + Item { + width: grid.width/3 + height: 50 + Button{ + text: i18nd("kcm_pulseaudio", "Rear Left") + anchors.centerIn: parent + visible: sinks.pulseObject ? sinks.pulseObject.rawChannels.indexOf("rear-left") > -1 : false + onClicked: sinks.pulseObject.testChannel("rear-left") + } } - } - Item { - width: grid.width/3 - height: 50 - Button{ - text: i18nd("kcm_pulseaudio", "Subwoofer") - anchors.centerIn: parent - visible: sinks.pulseObject ? sinks.pulseObject.rawChannels.indexOf("lfe") > -1 : false - onClicked: sinks.pulseObject.testChannel("subwoofer") + Item { + width: grid.width/3 + height: 50 + Button{ + text: i18nd("kcm_pulseaudio", "Subwoofer") + anchors.centerIn: parent + visible: sinks.pulseObject ? sinks.pulseObject.rawChannels.indexOf("lfe") > -1 : false + onClicked: sinks.pulseObject.testChannel("subwoofer") + } } - } - Item { - width: grid.width/3 - height: 50 - Button{ - text: i18nd("kcm_pulseaudio", "Rear Right") - anchors.centerIn: parent - visible: sinks.pulseObject ? sinks.pulseObject.rawChannels.indexOf("rear-right") > -1 : false - onClicked: sinks.pulseObject.testChannel("rear-right") + Item { + width: grid.width/3 + height: 50 + Button{ + text: i18nd("kcm_pulseaudio", "Rear Right") + anchors.centerIn: parent + visible: sinks.pulseObject ? sinks.pulseObject.rawChannels.indexOf("rear-right") > -1 : false + onClicked: sinks.pulseObject.testChannel("rear-right") + } } } } diff --git a/src/kcm/package/contents/ui/Applications.qml b/src/kcm/package/contents/ui/Applications.qml --- a/src/kcm/package/contents/ui/Applications.qml +++ b/src/kcm/package/contents/ui/Applications.qml @@ -29,83 +29,82 @@ ScrollView { id: scrollView - contentWidth: contentLayout.width - contentHeight: contentLayout.height + contentHeight: contentItem.height clip: true - ColumnLayout { - id: contentLayout + Item { + id: contentItem + width: scrollView.availableWidth + height: contentLayout.implicitHeight - Component.onCompleted: { - // Normal binding causes binding loops - width = Qt.binding(function() { - return scrollView.width; - }); - } - - Header { - Layout.fillWidth: true - enabled: eventStreamView.count || sinkInputView.count - text: i18nd("kcm_pulseaudio", "Playback Streams") - disabledText: i18ndc("kcm_pulseaudio", "@label", "No Applications Playing Audio") - } + ColumnLayout { + id: contentLayout + anchors.fill: parent - ListView { - id: eventStreamView - Layout.fillWidth: true - Layout.preferredHeight: contentHeight - Layout.margins: units.gridUnit / 2 - interactive: false - spacing: units.largeSpacing - model: PulseObjectFilterModel { - filters: [ { role: "Name", value: "sink-input-by-media-role:event" } ] - sourceModel: StreamRestoreModel {} + Header { + Layout.fillWidth: true + enabled: eventStreamView.count || sinkInputView.count + text: i18nd("kcm_pulseaudio", "Playback Streams") + disabledText: i18ndc("kcm_pulseaudio", "@label", "No Applications Playing Audio") } - delegate: StreamListItem { - deviceModel: sinkModel - isPlayback: true - } - } - ListView { - id: sinkInputView - Layout.fillWidth: true - Layout.preferredHeight: contentHeight - Layout.margins: units.gridUnit / 2 - interactive: false - spacing: units.largeSpacing - model: PulseObjectFilterModel { - filters: [ { role: "VirtualStream", value: false } ] - sourceModel: SinkInputModel {} + ListView { + id: eventStreamView + Layout.fillWidth: true + Layout.preferredHeight: contentHeight + Layout.margins: units.gridUnit / 2 + interactive: false + spacing: units.largeSpacing + model: PulseObjectFilterModel { + filters: [ { role: "Name", value: "sink-input-by-media-role:event" } ] + sourceModel: StreamRestoreModel {} + } + delegate: StreamListItem { + deviceModel: sinkModel + isPlayback: true + } } - delegate: StreamListItem { - deviceModel: sinkModel - isPlayback: true - } - } - Header { - Layout.fillWidth: true - enabled: sourceOutputView.count > 0 - text: i18nd("kcm_pulseaudio", "Recording Streams") - disabledText: i18ndc("kcm_pulseaudio", "@label", "No Applications Recording Audio") - } + ListView { + id: sinkInputView + Layout.fillWidth: true + Layout.preferredHeight: contentHeight + Layout.margins: units.gridUnit / 2 + interactive: false + spacing: units.largeSpacing + model: PulseObjectFilterModel { + filters: [ { role: "VirtualStream", value: false } ] + sourceModel: SinkInputModel {} + } + delegate: StreamListItem { + deviceModel: sinkModel + isPlayback: true + } + } - ListView { - id: sourceOutputView - Layout.fillWidth: true - Layout.preferredHeight: contentHeight - Layout.margins: units.gridUnit / 2 - interactive: false - spacing: units.largeSpacing - model: PulseObjectFilterModel { - filters: [ { role: "VirtualStream", value: false } ] - sourceModel: SourceOutputModel {} + Header { + Layout.fillWidth: true + enabled: sourceOutputView.count > 0 + text: i18nd("kcm_pulseaudio", "Recording Streams") + disabledText: i18ndc("kcm_pulseaudio", "@label", "No Applications Recording Audio") } - delegate: StreamListItem { - deviceModel: sourceModel - isPlayback: false + ListView { + id: sourceOutputView + Layout.fillWidth: true + Layout.preferredHeight: contentHeight + Layout.margins: units.gridUnit / 2 + interactive: false + spacing: units.largeSpacing + model: PulseObjectFilterModel { + filters: [ { role: "VirtualStream", value: false } ] + sourceModel: SourceOutputModel {} + } + + delegate: StreamListItem { + deviceModel: sourceModel + isPlayback: false + } } } } diff --git a/src/kcm/package/contents/ui/Devices.qml b/src/kcm/package/contents/ui/Devices.qml --- a/src/kcm/package/contents/ui/Devices.qml +++ b/src/kcm/package/contents/ui/Devices.qml @@ -26,56 +26,55 @@ ScrollView { id: scrollView - contentWidth: contentLayout.width - contentHeight: contentLayout.height + contentHeight: contentItem.height clip: true - ColumnLayout { - id: contentLayout + Item { + id: contentItem + width: scrollView.availableWidth + height: contentLayout.implicitHeight - Component.onCompleted: { - // Normal binding causes binding loops - width = Qt.binding(function() { - return scrollView.width; - }); - } + 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") - } + 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 - interactive: false - spacing: units.smallSpacing * 2 - model: sinkModel - delegate: DeviceListItem { - isPlayback: true + ListView { + id: sinks + Layout.fillWidth: true + Layout.preferredHeight: contentHeight + Layout.margins: units.gridUnit / 2 + interactive: false + spacing: units.smallSpacing * 2 + 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") - } + 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 - interactive: false - model: sourceModel - delegate: DeviceListItem { - isPlayback: false + ListView { + id: sources + Layout.fillWidth: true + Layout.preferredHeight: contentHeight + Layout.margins: units.gridUnit / 2 + interactive: false + model: sourceModel + delegate: DeviceListItem { + isPlayback: false + } } } } diff --git a/src/kcm/package/contents/ui/Header.qml b/src/kcm/package/contents/ui/Header.qml --- a/src/kcm/package/contents/ui/Header.qml +++ b/src/kcm/package/contents/ui/Header.qml @@ -33,14 +33,19 @@ Label { id: heading - anchors.centerIn: parent + anchors.fill: parent + horizontalAlignment: Text.AlignHCenter + elide: Text.ElideRight font.weight: Font.DemiBold } } Label { id: disabledLabel Layout.alignment: Qt.AlignCenter + Layout.fillWidth: true + horizontalAlignment: Text.AlignHCenter + elide: Text.ElideRight visible: text && !parent.enabled font.italic: true } diff --git a/src/kcm/package/contents/ui/main.qml b/src/kcm/package/contents/ui/main.qml --- a/src/kcm/package/contents/ui/main.qml +++ b/src/kcm/package/contents/ui/main.qml @@ -68,6 +68,7 @@ StackLayout { anchors.fill: parent + anchors.margins: -Kirigami.Units.smallSpacing currentIndex: tabView.currentIndex