make volume device selection use a combobox

This commit is contained in:
end-4
2025-11-08 16:48:00 +01:00
parent 769ed3bf71
commit 3b1d8fd262
3 changed files with 49 additions and 55 deletions
@@ -0,0 +1,15 @@
import QtQuick
import QtQuick.Controls.Material
import QtQuick.Controls
import qs.modules.common
ComboBox {
id: root
Material.theme: Material.System
Material.accent: Appearance.m3colors.m3primary
Material.primary: Appearance.m3colors.m3primary
Material.background: Appearance.m3colors.m3surface
Material.foreground: Appearance.m3colors.m3onSurface
Material.containerStyle: Material.Outlined
}
@@ -11,21 +11,23 @@ import Quickshell.Services.Pipewire
WindowDialog { WindowDialog {
id: root id: root
property bool isSink: true property bool isSink: true
backgroundHeight: 700 backgroundHeight: 600
WindowDialogTitle { WindowDialogTitle {
text: root.isSink ? Translation.tr("Audio output") : Translation.tr("Audio input") text: root.isSink ? Translation.tr("Audio output") : Translation.tr("Audio input")
} }
VolumeDialogContent {
isSink: root.isSink
}
WindowDialogSeparator { WindowDialogSeparator {
visible: root.hasApps
Layout.topMargin: -22
Layout.leftMargin: 0 Layout.leftMargin: 0
Layout.rightMargin: 0 Layout.rightMargin: 0
} }
VolumeDialogContent {
isSink: root.isSink
}
WindowDialogButtonRow { WindowDialogButtonRow {
DialogButton { DialogButton {
buttonText: Translation.tr("Details") buttonText: Translation.tr("Details")
@@ -16,25 +16,16 @@ ColumnLayout {
readonly property list<var> appPwNodes: Pipewire.nodes.values.filter((node) => { // Should be list<PwNode> but it breaks ScriptModel readonly property list<var> appPwNodes: Pipewire.nodes.values.filter((node) => { // Should be list<PwNode> but it breaks ScriptModel
return root.correctType(node) && node.isStream return root.correctType(node) && node.isStream
}) })
readonly property list<var> devices: Pipewire.nodes.values.filter(node => {
return root.correctType(node) && !node.isStream
})
readonly property bool hasApps: appPwNodes.length > 0 readonly property bool hasApps: appPwNodes.length > 0
spacing: 16 spacing: 16
WindowDialogSectionHeader {
visible: root.hasApps
text: Translation.tr("Applications")
}
WindowDialogSeparator {
visible: root.hasApps
Layout.topMargin: -22
Layout.leftMargin: 0
Layout.rightMargin: 0
color: Appearance.colors.colOutlineVariant
}
DialogSectionListView { DialogSectionListView {
visible: root.hasApps visible: root.hasApps
Layout.fillHeight: true Layout.fillHeight: true
topMargin: 14
model: ScriptModel { model: ScriptModel {
values: root.appPwNodes values: root.appPwNodes
@@ -49,44 +40,25 @@ ColumnLayout {
} }
} }
WindowDialogSectionHeader { StyledComboBox {
text: Translation.tr("Devices") id: deviceSelector
} Layout.fillWidth: true
Layout.bottomMargin: 6
WindowDialogSeparator { model: root.devices.map(node => node.description)
Layout.topMargin: -22 currentIndex: root.devices.findIndex(item => {
Layout.leftMargin: 0 if (root.isSink) {
Layout.rightMargin: 0 return item.id === Pipewire.preferredDefaultAudioSink?.id
color: Appearance.colors.colOutlineVariant } else {
} return item.id === Pipewire.preferredDefaultAudioSource?.id
DialogSectionListView {
Layout.fillHeight: !root.hasApps
Layout.preferredHeight: 180
model: ScriptModel {
values: Pipewire.nodes.values.filter(node => {
return root.correctType(node) && !node.isStream
})
}
delegate: StyledRadioButton {
id: radioButton
required property var modelData
anchors {
left: parent?.left
right: parent?.right
} }
})
description: modelData.description onActivated: (index) => {
checked: modelData.id === (root.isSink ? Pipewire.preferredDefaultAudioSink?.id : Pipewire.preferredDefaultAudioSource?.id) print(index)
const item = root.devices[index]
onCheckedChanged: { if (root.isSink) {
if (!checked) return; Pipewire.preferredDefaultAudioSink = item
if (root.isSink) { } else {
Pipewire.preferredDefaultAudioSink = modelData Pipewire.preferredDefaultAudioSource = item
} else {
Pipewire.preferredDefaultAudioSource = modelData
}
} }
} }
} }
@@ -106,4 +78,9 @@ ColumnLayout {
spacing: 4 spacing: 4
animateAppearance: false animateAppearance: false
} }
Component {
id: listElementComp
ListElement {}
}
} }