diff options
| author | nippy <you@example.com> | 2026-04-18 13:49:56 +0200 |
|---|---|---|
| committer | nippy <you@example.com> | 2026-04-18 13:49:56 +0200 |
| commit | 5d94c0a7d44a2255b81815a52a7056a94a39842d (patch) | |
| tree | 759bdea9645c6a62f9e1e4c001f7d81cccd120d2 /raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/OSD/MediaVolumeOSD.qml | |
| parent | e79cdf210b267f21a186255ce1a4d50029439d54 (diff) | |
| download | RaveOS-PKGBUILD-5d94c0a7d44a2255b81815a52a7056a94a39842d.tar.gz RaveOS-PKGBUILD-5d94c0a7d44a2255b81815a52a7056a94a39842d.zip | |
update Raveos themes
Diffstat (limited to 'raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/OSD/MediaVolumeOSD.qml')
| -rw-r--r-- | raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/OSD/MediaVolumeOSD.qml | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/OSD/MediaVolumeOSD.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/OSD/MediaVolumeOSD.qml new file mode 100644 index 0000000..147d81e --- /dev/null +++ b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/OSD/MediaVolumeOSD.qml @@ -0,0 +1,264 @@ +import QtQuick +import qs.Common +import qs.Services +import qs.Widgets + +DankOSD { + id: root + + readonly property bool useVertical: isVerticalLayout + readonly property var player: MprisController.activePlayer + readonly property bool volumeSupported: player?.volumeSupported ?? false + property bool _suppressNewPlayer: false + property int _displayVolume: 0 + + function _syncVolume() { + if (!player) + return; + _displayVolume = Math.min(100, Math.round(player.volume * 100)); + } + + onPlayerChanged: { + _suppressNewPlayer = true; + _suppressTimer.restart(); + _syncVolume(); + } + + Timer { + id: _suppressTimer + interval: 2000 + onTriggered: _suppressNewPlayer = false + } + + 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 + + function getVolumeIcon(volume) { + if (!player) + return "music_note"; + if (volume === 0) + return "music_off"; + return "music_note"; + } + + function toggleMute() { + if (!player) + return; + player.volume = player.volume > 0 ? 0 : 1; + } + + function setVolume(volumePercent) { + if (!player) + return; + player.volume = volumePercent / 100; + resetHideTimer(); + } + + Connections { + target: player + + function onVolumeChanged() { + root._syncVolume(); + if (SettingsData.osdMediaVolumeEnabled && volumeSupported && !_suppressNewPlayer) + 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: getVolumeIcon(player?.volume ?? 0) + size: Theme.iconSize + color: muteButton.containsMouse ? Theme.primary : Theme.surfaceText + } + + MouseArea { + id: muteButton + + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: 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: 100 + enabled: volumeSupported + showValue: true + unit: "%" + thumbOutlineColor: Theme.surfaceContainer + valueOverride: root._displayVolume + alwaysShowValue: SettingsData.osdAlwaysShowValue + + Component.onCompleted: { + root._syncVolume(); + value = root._displayVolume; + } + + onSliderValueChanged: newValue => setVolume(newValue) + + 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: getVolumeIcon(player?.volume ?? 0) + size: Theme.iconSize + color: muteButtonVert.containsMouse ? Theme.primary : Theme.surfaceText + } + + MouseArea { + id: muteButtonVert + + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: 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 / 100) * 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 / 100; + 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: volumeSupported + 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) { + const ratio = 1.0 - (mouse.y / height); + const volume = Math.max(0, Math.min(100, Math.round(ratio * 100))); + setVolume(volume); + } + } + } + + 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 + } + } + } +} |