Luigit
repositories / dotfiles

dotfiles

bugabingas dorkfiles

owned by admin

pi/agent/skills/optional/quickshell/examples/04-pipewire-volume/Bar.qml

Raw
// 04-pipewire-volume/Bar.qml
// A bar showing the default audio sink volume. Drag the slider to change it.

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import Quickshell.Services.Pipewire
import Quickshell.Widgets

PanelWindow {
    id: bar
    anchors { top: true; left: true; right: true }
    implicitHeight: 36
    color: "#cc1e1e2e"
    readonly property var sinkAudio: Pipewire.defaultAudioSink ? Pipewire.defaultAudioSink.audio : null

    // Keep the default sink tracked so its audio object remains available.
    PwObjectTracker {
        objects: [ Pipewire.defaultAudioSink ]
    }

    RowLayout {
        anchors.fill: parent
        anchors.leftMargin: 12
        anchors.rightMargin: 12
        spacing: 12

        // Icon. `Quickshell.iconPath` resolves against the system icon theme.
        IconImage {
            implicitSize: 18
            source: Quickshell.iconPath(
                bar.sinkAudio && bar.sinkAudio.muted
                    ? "audio-volume-muted-symbolic"
                    : "audio-volume-high-symbolic"
            )
        }

        // Mute toggle. The `Connections` watches the service for changes.
        Text {
            text: "Mute"
            color: "white"
            font.pointSize: 11
            MouseArea {
                anchors.fill: parent
                cursorShape: Qt.PointingHandCursor
                onClicked: if (bar.sinkAudio) bar.sinkAudio.muted = !bar.sinkAudio.muted
            }
        }

        Item { Layout.fillWidth: true; Layout.preferredWidth: 1 }  // spacer

        // Service changes update the slider through the value binding.
        // User movement writes back through onMoved without reacting to initialization.
        Slider {
            Layout.preferredWidth: 240
            from: 0
            to: 1.5
            value: bar.sinkAudio ? bar.sinkAudio.volume : 0
            onMoved: if (bar.sinkAudio) bar.sinkAudio.volume = value
        }

        Text {
            text: `${Math.floor((bar.sinkAudio ? bar.sinkAudio.volume : 0) * 100)}%`
            color: "white"
            font.pointSize: 11
            Layout.preferredWidth: 40
        }
    }
}