summaryrefslogtreecommitdiff
path: root/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/OSD/VolumeOSD.qml
diff options
context:
space:
mode:
Diffstat (limited to 'raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/OSD/VolumeOSD.qml')
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/OSD/VolumeOSD.qml254
1 files changed, 254 insertions, 0 deletions
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/OSD/VolumeOSD.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/OSD/VolumeOSD.qml
new file mode 100644
index 0000000..89c07b7
--- /dev/null
+++ b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/OSD/VolumeOSD.qml
@@ -0,0 +1,254 @@
+import QtQuick
+import qs.Common
+import qs.Services
+import qs.Widgets
+
+DankOSD {
+ id: root
+
+ readonly property bool useVertical: isVerticalLayout
+ property int _displayVolume: 0
+
+ function _syncVolume() {
+ if (!AudioService.sink?.audio)
+ return;
+ _displayVolume = Math.min(AudioService.sinkMaxVolume, Math.round(AudioService.sink.audio.volume * 100));
+ }
+
+ osdWidth: useVertical ? (40 + Theme.spacingS * 2) : Math.min(260, Screen.width - Theme.spacingM * 2)
+ osdHeight: useVertical ? Math.min(260, Screen.height - Theme.spacingM * 2) : (40 + Theme.spacingS * 2)
+ autoHideInterval: 3000
+ enableMouseInteraction: true
+
+ Connections {
+ target: AudioService.sink?.audio ?? null
+
+ function onVolumeChanged() {
+ root._syncVolume();
+ if (SettingsData.osdVolumeEnabled)
+ root.show();
+ }
+
+ function onMutedChanged() {
+ if (SettingsData.osdVolumeEnabled)
+ root.show();
+ }
+ }
+
+ Connections {
+ target: AudioService
+
+ function onSinkChanged() {
+ root._syncVolume();
+ if (root.shouldBeVisible && SettingsData.osdVolumeEnabled)
+ root.show();
+ }
+ }
+
+ content: Loader {
+ anchors.fill: parent
+ sourceComponent: useVertical ? verticalContent : horizontalContent
+ }
+
+ Component {
+ id: horizontalContent
+
+ Item {
+ property int gap: Theme.spacingS
+
+ anchors.centerIn: parent
+ width: parent.width - Theme.spacingS * 2
+ height: 40
+
+ Rectangle {
+ width: Theme.iconSize
+ height: Theme.iconSize
+ radius: Theme.iconSize / 2
+ color: "transparent"
+ x: parent.gap
+ anchors.verticalCenter: parent.verticalCenter
+
+ DankIcon {
+ anchors.centerIn: parent
+ name: AudioService.sink?.audio?.muted ? "volume_off" : "volume_up"
+ size: Theme.iconSize
+ color: muteButton.containsMouse ? Theme.primary : Theme.surfaceText
+ }
+
+ MouseArea {
+ id: muteButton
+
+ anchors.fill: parent
+ hoverEnabled: true
+ cursorShape: Qt.PointingHandCursor
+ onClicked: AudioService.toggleMute()
+ onContainsMouseChanged: setChildHovered(containsMouse || volumeSlider.containsMouse)
+ }
+ }
+
+ DankSlider {
+ id: volumeSlider
+
+ width: parent.width - Theme.iconSize - parent.gap * 3
+ height: 40
+ x: parent.gap * 2 + Theme.iconSize
+ anchors.verticalCenter: parent.verticalCenter
+ minimum: 0
+ maximum: AudioService.sinkMaxVolume
+ enabled: AudioService.sink?.audio ?? false
+ showValue: true
+ unit: "%"
+ thumbOutlineColor: Theme.surfaceContainer
+ valueOverride: root._displayVolume
+ alwaysShowValue: SettingsData.osdAlwaysShowValue
+
+ Component.onCompleted: {
+ root._syncVolume();
+ value = root._displayVolume;
+ }
+
+ onSliderValueChanged: newValue => {
+ if (!AudioService.sink?.audio)
+ return;
+ SessionData.suppressOSDTemporarily();
+ AudioService.sink.audio.volume = newValue / 100;
+ resetHideTimer();
+ }
+
+ onContainsMouseChanged: setChildHovered(containsMouse || muteButton.containsMouse)
+
+ Binding on value {
+ value: root._displayVolume
+ when: !volumeSlider.pressed
+ }
+ }
+ }
+ }
+
+ Component {
+ id: verticalContent
+
+ Item {
+ anchors.fill: parent
+ property int gap: Theme.spacingS
+
+ Rectangle {
+ width: Theme.iconSize
+ height: Theme.iconSize
+ radius: Theme.iconSize / 2
+ color: "transparent"
+ anchors.horizontalCenter: parent.horizontalCenter
+ y: gap
+
+ DankIcon {
+ anchors.centerIn: parent
+ name: AudioService.sink?.audio?.muted ? "volume_off" : "volume_up"
+ size: Theme.iconSize
+ color: muteButtonVert.containsMouse ? Theme.primary : Theme.surfaceText
+ }
+
+ MouseArea {
+ id: muteButtonVert
+
+ anchors.fill: parent
+ hoverEnabled: true
+ cursorShape: Qt.PointingHandCursor
+ onClicked: AudioService.toggleMute()
+ onContainsMouseChanged: setChildHovered(containsMouse || vertSliderArea.containsMouse)
+ }
+ }
+
+ Item {
+ id: vertSlider
+ width: 12
+ height: parent.height - Theme.iconSize - gap * 3 - 24
+ anchors.horizontalCenter: parent.horizontalCenter
+ y: gap * 2 + Theme.iconSize
+
+ property bool dragging: false
+ property int value: root._displayVolume
+
+ Rectangle {
+ id: vertTrack
+ width: parent.width
+ height: parent.height
+ anchors.centerIn: parent
+ color: Theme.outline
+ radius: Theme.cornerRadius
+ }
+
+ Rectangle {
+ id: vertFill
+ width: parent.width
+ height: (vertSlider.value / AudioService.sinkMaxVolume) * parent.height
+ anchors.bottom: parent.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ color: Theme.primary
+ radius: Theme.cornerRadius
+ }
+
+ Rectangle {
+ id: vertHandle
+ width: 24
+ height: 8
+ radius: Theme.cornerRadius
+ y: {
+ const ratio = vertSlider.value / AudioService.sinkMaxVolume;
+ const travel = parent.height - height;
+ return Math.max(0, Math.min(travel, travel * (1 - ratio)));
+ }
+ anchors.horizontalCenter: parent.horizontalCenter
+ color: Theme.primary
+ border.width: 3
+ border.color: Theme.surfaceContainer
+ }
+
+ MouseArea {
+ id: vertSliderArea
+ anchors.fill: parent
+ anchors.margins: -12
+ enabled: AudioService.sink?.audio ?? false
+ hoverEnabled: true
+ cursorShape: Qt.PointingHandCursor
+
+ onContainsMouseChanged: setChildHovered(containsMouse || muteButtonVert.containsMouse)
+
+ onPressed: mouse => {
+ vertSlider.dragging = true;
+ updateVolume(mouse);
+ }
+
+ onReleased: vertSlider.dragging = false
+
+ onPositionChanged: mouse => {
+ if (pressed)
+ updateVolume(mouse);
+ }
+
+ onClicked: mouse => updateVolume(mouse)
+
+ function updateVolume(mouse) {
+ if (!AudioService.sink?.audio)
+ return;
+ const maxVol = AudioService.sinkMaxVolume;
+ const ratio = 1.0 - (mouse.y / height);
+ const volume = Math.max(0, Math.min(maxVol, Math.round(ratio * maxVol)));
+ SessionData.suppressOSDTemporarily();
+ AudioService.sink.audio.volume = volume / 100;
+ resetHideTimer();
+ }
+ }
+ }
+
+ StyledText {
+ anchors.bottom: parent.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottomMargin: gap
+ text: vertSlider.value + "%"
+ font.pixelSize: Theme.fontSizeSmall
+ color: Theme.surfaceText
+ visible: SettingsData.osdAlwaysShowValue
+ }
+ }
+ }
+}