105 lines
3.5 KiB
QML
105 lines
3.5 KiB
QML
import QtQuick
|
|
import QtQuick.Effects
|
|
import QtQuick.Controls
|
|
import Quickshell
|
|
import Quickshell.Widgets
|
|
import Quickshell.Services.Pipewire
|
|
import qs.Widgets as Widgets
|
|
|
|
Row {
|
|
anchors {
|
|
top: parent.top
|
|
horizontalCenter: parent.horizontalCenter
|
|
}
|
|
padding: 6
|
|
height: 316
|
|
spacing: 6
|
|
|
|
PwObjectTracker {
|
|
objects: Pipewire.nodes.values.filter(node => [17, 21].includes(node.type))
|
|
}
|
|
|
|
component NodeList: ClippingRectangle {
|
|
id: nodeListRect
|
|
width: 350
|
|
color: "transparent"
|
|
anchors {
|
|
top: parent.top
|
|
bottom: parent.bottom
|
|
bottomMargin: 6
|
|
}
|
|
radius: 10
|
|
property var model
|
|
clip: true
|
|
ListView {
|
|
anchors.fill: parent
|
|
spacing: 6
|
|
header: Item {width: 1; height: 6}
|
|
footer: header
|
|
model: nodeListRect.model
|
|
delegate: Rectangle {
|
|
anchors {
|
|
left: parent.left
|
|
right: parent.right
|
|
}
|
|
radius: 12
|
|
color: "#111"
|
|
height: children[1].height
|
|
Image {
|
|
anchors {
|
|
left: parent.left
|
|
verticalCenter: parent.verticalCenter
|
|
leftMargin: 6
|
|
}
|
|
sourceSize {width: width; height: height}
|
|
source: Quickshell.iconPath((() => {
|
|
const description = modelData.description.toLowerCase();
|
|
if (description.search("hdmi") !== -1)
|
|
return "display"
|
|
if (description.search("speaker") !== -1)
|
|
return "audio-speakers"
|
|
if (description.search("earphone") !== -1 || description.search("headphone") !== -1)
|
|
return "audio-headset"
|
|
if (modelData.properties["device.icon-name"])
|
|
return modelData.properties["device.icon-name"]
|
|
return modelData.properties["application.name"]
|
|
})()?.toLowerCase(), "audio-on")
|
|
width: 32
|
|
height: width
|
|
}
|
|
Column {
|
|
anchors {
|
|
left: parent.children[0].right
|
|
right: parent.right
|
|
verticalCenter: parent.verticalCenter
|
|
margins: 6
|
|
rightMargin: 12
|
|
}
|
|
topPadding: 6
|
|
bottomPadding: 6
|
|
spacing: 2
|
|
Text {
|
|
text: {
|
|
if (modelData.nickname !== "") return modelData.nickname
|
|
if (modelData.description !== "") return description
|
|
return modelData.name
|
|
}
|
|
color: "white"
|
|
font.pixelSize: 16
|
|
}
|
|
Widgets.Slider {
|
|
value: modelData.audio.volume
|
|
onMoved: modelData.audio.volume = position
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
NodeList {
|
|
model: Pipewire.nodes.values.filter(node => node.type === 17)
|
|
}
|
|
NodeList {
|
|
model: Pipewire.nodes.values.filter(node => node.type === 21)
|
|
}
|
|
}
|