mirror of
https://github.com/tuxdotrs/tpanel.git
synced 2026-09-19 10:19:02 +05:30
feat(osd): add volume osd popup window
This commit is contained in:
@@ -138,4 +138,13 @@ Singleton {
|
|||||||
property int textSpacing: 2
|
property int textSpacing: 2
|
||||||
property real bodyOpacity: 0.8
|
property real bodyOpacity: 0.8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property QtObject volume: QtObject {
|
||||||
|
property int width: 300
|
||||||
|
property int height: 48
|
||||||
|
property int iconSize: 22
|
||||||
|
property int barHeight: 10
|
||||||
|
property int timeout: 1500
|
||||||
|
property real bottomMarginRatio: 0.2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
42
modules/osd/VolumeCard.qml
Normal file
42
modules/osd/VolumeCard.qml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import qs.config
|
||||||
|
import qs.services
|
||||||
|
import qs.ui
|
||||||
|
|
||||||
|
BarButton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
readonly property real level: Math.max(0, Math.min(Audio.muted ? 0 : Audio.volume, 1))
|
||||||
|
readonly property url iconUrl: `${Quickshell.shellPath("assets")}/icons/speaker.svg`
|
||||||
|
|
||||||
|
hoverHighlight: false
|
||||||
|
pointerCursor: false
|
||||||
|
iconOnly: true
|
||||||
|
iconSource: root.iconUrl
|
||||||
|
icon.width: Theme.volume.iconSize
|
||||||
|
icon.height: Theme.volume.iconSize
|
||||||
|
|
||||||
|
implicitWidth: Theme.volume.width
|
||||||
|
implicitHeight: Theme.volume.height
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: fill
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
implicitWidth: parent.width * root.level
|
||||||
|
radius: Theme.radius
|
||||||
|
color: Audio.muted ? Theme.colors.error : Theme.colors.accent
|
||||||
|
opacity: 0.35
|
||||||
|
|
||||||
|
Behavior on width {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.duration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,8 @@ Singleton {
|
|||||||
readonly property string inputName: truncateText(root.displayName(Pipewire.defaultAudioSource), 14)
|
readonly property string inputName: truncateText(root.displayName(Pipewire.defaultAudioSource), 14)
|
||||||
readonly property url outputIcon: `${Quickshell.shellPath("assets")}/icons/speaker.svg`
|
readonly property url outputIcon: `${Quickshell.shellPath("assets")}/icons/speaker.svg`
|
||||||
readonly property url inputIcon: `${Quickshell.shellPath("assets")}/icons/microphone.svg`
|
readonly property url inputIcon: `${Quickshell.shellPath("assets")}/icons/microphone.svg`
|
||||||
|
readonly property real volume: Pipewire.defaultAudioSink?.audio.volume ?? 0
|
||||||
|
readonly property bool muted: Pipewire.defaultAudioSink?.audio.muted ?? false
|
||||||
|
|
||||||
function truncateText(text, maxLength) {
|
function truncateText(text, maxLength) {
|
||||||
return text.length > maxLength ? text.slice(0, maxLength - 3) + "..." : text;
|
return text.length > maxLength ? text.slice(0, maxLength - 3) + "..." : text;
|
||||||
|
|||||||
@@ -4,4 +4,5 @@ import qs.windows
|
|||||||
Scope {
|
Scope {
|
||||||
Bar {}
|
Bar {}
|
||||||
Notification {}
|
Notification {}
|
||||||
|
Volume {}
|
||||||
}
|
}
|
||||||
|
|||||||
52
windows/Volume.qml
Normal file
52
windows/Volume.qml
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import qs.config
|
||||||
|
import qs.services
|
||||||
|
import "../modules/osd"
|
||||||
|
|
||||||
|
PanelWindow {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool shown: false
|
||||||
|
|
||||||
|
color: "transparent"
|
||||||
|
exclusionMode: ExclusionMode.Ignore
|
||||||
|
visible: shown
|
||||||
|
implicitWidth: card.implicitWidth
|
||||||
|
implicitHeight: card.implicitHeight
|
||||||
|
|
||||||
|
anchors.bottom: true
|
||||||
|
margins.bottom: screen.height * Theme.volume.bottomMarginRatio
|
||||||
|
|
||||||
|
// An empty click mask prevents the window from blocking mouse events.
|
||||||
|
mask: Region {}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: Audio
|
||||||
|
|
||||||
|
function onVolumeChanged() {
|
||||||
|
root.shown = true;
|
||||||
|
hideTimer.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onMutedChanged() {
|
||||||
|
root.shown = true;
|
||||||
|
hideTimer.restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: hideTimer
|
||||||
|
|
||||||
|
interval: Theme.volume.timeout
|
||||||
|
onTriggered: root.shown = false
|
||||||
|
}
|
||||||
|
|
||||||
|
VolumeCard {
|
||||||
|
id: card
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user