summaryrefslogtreecommitdiff
path: root/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/AudioOutputDetail.qml
diff options
context:
space:
mode:
Diffstat (limited to 'raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/AudioOutputDetail.qml')
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/AudioOutputDetail.qml544
1 files changed, 0 insertions, 544 deletions
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/AudioOutputDetail.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/AudioOutputDetail.qml
deleted file mode 100644
index 7e86ae4..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/AudioOutputDetail.qml
+++ /dev/null
@@ -1,544 +0,0 @@
-import QtQuick
-import Quickshell
-import Quickshell.Services.Pipewire
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-Rectangle {
- id: root
-
- LayoutMirroring.enabled: I18n.isRtl
- LayoutMirroring.childrenInherit: true
-
- property bool hasVolumeSliderInCC: {
- const widgets = SettingsData.controlCenterWidgets || [];
- return widgets.some(widget => widget.id === "volumeSlider");
- }
-
- implicitHeight: headerRow.height + (!hasVolumeSliderInCC ? volumeSlider.height : 0) + audioContent.height + Theme.spacingM
- radius: Theme.cornerRadius
- color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
- border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
- border.width: 0
-
- Row {
- id: headerRow
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: parent.top
- anchors.leftMargin: Theme.spacingM
- anchors.rightMargin: Theme.spacingM
- anchors.topMargin: Theme.spacingS
- height: 40
-
- StyledText {
- id: headerText
- text: I18n.tr("Audio Devices")
- font.pixelSize: Theme.fontSizeLarge
- color: Theme.surfaceText
- font.weight: Font.Medium
- anchors.verticalCenter: parent.verticalCenter
- }
-
- Item {
- height: 1
- width: parent.width - headerText.width - settingsButton.width
- }
-
- DankActionButton {
- id: settingsButton
- anchors.verticalCenter: parent.verticalCenter
- iconName: "settings"
- buttonSize: 28
- iconSize: 16
- iconColor: Theme.surfaceVariantText
- onClicked: {
- PopoutService.closeControlCenter();
- PopoutService.openSettingsWithTab("audio");
- }
- }
- }
-
- Row {
- id: volumeSlider
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: headerRow.bottom
- anchors.leftMargin: Theme.spacingM
- anchors.rightMargin: Theme.spacingM
- anchors.topMargin: Theme.spacingXS
- height: 35
- spacing: 0
- visible: !hasVolumeSliderInCC
-
- Rectangle {
- width: Theme.iconSize + Theme.spacingS * 2
- height: Theme.iconSize + Theme.spacingS * 2
- anchors.verticalCenter: parent.verticalCenter
- radius: (Theme.iconSize + Theme.spacingS * 2) / 2
- color: iconArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
-
- DankRipple {
- id: muteRipple
- cornerRadius: parent.radius
- }
-
- MouseArea {
- id: iconArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onPressed: mouse => muteRipple.trigger(mouse.x, mouse.y)
- onClicked: {
- if (AudioService.sink && AudioService.sink.audio) {
- AudioService.sink.audio.muted = !AudioService.sink.audio.muted;
- }
- }
- }
-
- DankIcon {
- anchors.centerIn: parent
- name: {
- if (!AudioService.sink || !AudioService.sink.audio)
- return "volume_off";
- let muted = AudioService.sink.audio.muted;
- let volume = AudioService.sink.audio.volume;
- if (muted)
- return "volume_off";
- if (volume === 0.0)
- return "volume_mute";
- if (volume <= 0.33)
- return "volume_down";
- if (volume <= 0.66)
- return "volume_up";
- return "volume_up";
- }
- size: Theme.iconSize
- color: AudioService.sink && AudioService.sink.audio && !AudioService.sink.audio.muted && AudioService.sink.audio.volume > 0 ? Theme.primary : Theme.surfaceText
- }
- }
-
- DankSlider {
- readonly property real actualVolumePercent: AudioService.sink && AudioService.sink.audio ? Math.round(AudioService.sink.audio.volume * 100) : 0
-
- anchors.verticalCenter: parent.verticalCenter
- width: parent.width - (Theme.iconSize + Theme.spacingS * 2)
- enabled: AudioService.sink && AudioService.sink.audio
- minimum: 0
- maximum: AudioService.sinkMaxVolume
- value: AudioService.sink && AudioService.sink.audio ? Math.min(AudioService.sinkMaxVolume, Math.round(AudioService.sink.audio.volume * 100)) : 0
- showValue: true
- unit: "%"
- valueOverride: actualVolumePercent
- thumbOutlineColor: Theme.surfaceVariant
-
- onSliderValueChanged: function (newValue) {
- if (AudioService.sink && AudioService.sink.audio) {
- AudioService.sink.audio.volume = newValue / 100;
- if (newValue > 0 && AudioService.sink.audio.muted) {
- AudioService.sink.audio.muted = false;
- }
- AudioService.volumeChanged();
- }
- }
- }
- }
-
- DankFlickable {
- id: audioContent
- anchors.top: volumeSlider.visible ? volumeSlider.bottom : headerRow.bottom
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.bottom: parent.bottom
- anchors.margins: Theme.spacingM
- anchors.topMargin: volumeSlider.visible ? Theme.spacingS : Theme.spacingM
- contentHeight: audioColumn.height
- clip: true
-
- property int maxPinnedOutputs: 3
-
- function normalizePinList(value) {
- if (Array.isArray(value))
- return value.filter(v => v);
- if (typeof value === "string" && value.length > 0)
- return [value];
- return [];
- }
-
- function getPinnedOutputs() {
- const pins = SettingsData.audioOutputDevicePins || {};
- return normalizePinList(pins["preferredOutput"]);
- }
-
- Column {
- id: audioColumn
- width: parent.width
- spacing: Theme.spacingS
-
- Repeater {
- model: ScriptModel {
- values: {
- const hidden = SessionData.hiddenOutputDeviceNames ?? [];
- const nodes = Pipewire.nodes.values.filter(node => {
- if (!node.audio || !node.isSink || node.isStream)
- return false;
- return !hidden.includes(node.name);
- });
- const pinnedList = audioContent.getPinnedOutputs();
-
- let sorted = [...nodes];
- sorted.sort((a, b) => {
- // Pinned device first
- const aPinnedIndex = pinnedList.indexOf(a.name);
- const bPinnedIndex = pinnedList.indexOf(b.name);
- if (aPinnedIndex !== -1 || bPinnedIndex !== -1) {
- if (aPinnedIndex === -1)
- return 1;
- if (bPinnedIndex === -1)
- return -1;
- return aPinnedIndex - bPinnedIndex;
- }
- // Then active device
- if (a === AudioService.sink && b !== AudioService.sink)
- return -1;
- if (b === AudioService.sink && a !== AudioService.sink)
- return 1;
- return 0;
- });
- return sorted;
- }
- }
-
- delegate: Rectangle {
- id: outputDelegate
- required property var modelData
- required property int index
-
- width: parent.width
- height: 50
- radius: Theme.cornerRadius
- color: deviceMouseArea.containsMouse ? Theme.primaryHoverLight : Theme.surfaceLight
- border.color: modelData === AudioService.sink ? Theme.primary : Theme.outlineLight
- border.width: modelData === AudioService.sink ? 2 : 1
-
- DankRipple {
- id: deviceRipple
- cornerRadius: outputDelegate.radius
- }
-
- Row {
- anchors.left: parent.left
- anchors.verticalCenter: parent.verticalCenter
- anchors.leftMargin: Theme.spacingM
- spacing: Theme.spacingS
-
- DankIcon {
- name: AudioService.sinkIcon(modelData)
- size: Theme.iconSize - 4
- color: modelData === AudioService.sink ? Theme.primary : Theme.surfaceText
- anchors.verticalCenter: parent.verticalCenter
- }
-
- Column {
- anchors.verticalCenter: parent.verticalCenter
- width: {
- const iconWidth = Theme.iconSize;
- const pinButtonWidth = pinOutputRow.width + Theme.spacingS * 4 + Theme.spacingM;
- return parent.parent.width - iconWidth - parent.spacing - pinButtonWidth - Theme.spacingM * 2;
- }
-
- StyledText {
- text: AudioService.displayName(modelData)
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- font.weight: modelData === AudioService.sink ? Font.Medium : Font.Normal
- elide: Text.ElideRight
- width: parent.width
- wrapMode: Text.NoWrap
- horizontalAlignment: Text.AlignLeft
- }
-
- StyledText {
- text: modelData === AudioService.sink ? I18n.tr("Active") : I18n.tr("Available")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- elide: Text.ElideRight
- width: parent.width
- wrapMode: Text.NoWrap
- horizontalAlignment: Text.AlignLeft
- }
- }
- }
-
- Rectangle {
- anchors.right: parent.right
- anchors.rightMargin: Theme.spacingM
- anchors.verticalCenter: parent.verticalCenter
- width: pinOutputRow.width + Theme.spacingS * 2
- height: 28
- radius: height / 2
- color: {
- const isThisDevicePinned = audioContent.getPinnedOutputs().includes(modelData.name);
- return isThisDevicePinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05);
- }
-
- Row {
- id: pinOutputRow
- anchors.centerIn: parent
- spacing: 4
-
- DankIcon {
- name: "push_pin"
- size: 16
- color: {
- const isThisDevicePinned = audioContent.getPinnedOutputs().includes(modelData.name);
- return isThisDevicePinned ? Theme.primary : Theme.surfaceText;
- }
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: {
- const isThisDevicePinned = audioContent.getPinnedOutputs().includes(modelData.name);
- return isThisDevicePinned ? I18n.tr("Pinned") : I18n.tr("Pin");
- }
- font.pixelSize: Theme.fontSizeSmall
- color: {
- const isThisDevicePinned = audioContent.getPinnedOutputs().includes(modelData.name);
- return isThisDevicePinned ? Theme.primary : Theme.surfaceText;
- }
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- DankRipple {
- id: pinRipple
- cornerRadius: parent.radius
- }
-
- MouseArea {
- anchors.fill: parent
- cursorShape: Qt.PointingHandCursor
- onPressed: mouse => pinRipple.trigger(mouse.x, mouse.y)
- onClicked: {
- const pins = JSON.parse(JSON.stringify(SettingsData.audioOutputDevicePins || {}));
- let pinnedList = audioContent.normalizePinList(pins["preferredOutput"]);
- const pinIndex = pinnedList.indexOf(modelData.name);
-
- if (pinIndex !== -1) {
- pinnedList.splice(pinIndex, 1);
- } else {
- pinnedList.unshift(modelData.name);
- if (pinnedList.length > audioContent.maxPinnedOutputs)
- pinnedList = pinnedList.slice(0, audioContent.maxPinnedOutputs);
- }
-
- if (pinnedList.length > 0)
- pins["preferredOutput"] = pinnedList;
- else
- delete pins["preferredOutput"];
-
- SettingsData.set("audioOutputDevicePins", pins);
- }
- }
- }
-
- MouseArea {
- id: deviceMouseArea
- anchors.fill: parent
- anchors.rightMargin: pinOutputRow.width + Theme.spacingS * 4
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onPressed: mouse => {
- let mapped = deviceMouseArea.mapToItem(outputDelegate, mouse.x, mouse.y);
- deviceRipple.trigger(mapped.x, mapped.y);
- }
- onClicked: {
- if (modelData) {
- Pipewire.preferredDefaultAudioSink = modelData;
- }
- }
- }
- }
- }
- Row {
- id: playbackHeaderRow
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.leftMargin: Theme.spacingM
- anchors.rightMargin: Theme.spacingM
- height: 28
-
- StyledText {
- id: playbackHeaderText
- text: I18n.tr("Playback")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- font.weight: Font.Medium
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- Repeater {
- model: ScriptModel {
- values: {
- const nodes = Pipewire.nodes.values.filter(node => {
- return node.audio && node.isSink && node.isStream;
- });
- return nodes;
- }
- }
-
- delegate: Rectangle {
- required property var modelData
- required property int index
-
- width: parent.width
- height: 50
- radius: Theme.cornerRadius
- color: Theme.surfaceLight
- border.color: modelData === AudioService.sink ? Theme.primary : Theme.outlineLight
- border.width: modelData === AudioService.sink ? 2 : 1
-
- Row {
- anchors.left: parent.left
- anchors.verticalCenter: parent.verticalCenter
- anchors.leftMargin: Theme.spacingM
- spacing: Theme.spacingS
-
- DankIcon {
- name: "album"
- size: Theme.iconSize - 4
- color: !modelData.audio.muted ? Theme.primary : Theme.surfaceText
- anchors.verticalCenter: parent.verticalCenter
- }
-
- Column {
- anchors.verticalCenter: parent.verticalCenter
- width: {
- const iconWidth = Theme.iconSize;
- return parent.parent.width - iconWidth - parent.spacing - Theme.spacingM * 2;
- }
-
- StyledText {
- text: {
- const modelDataMediaName = modelData && modelData.properties ? (modelData.properties["media.name"] || "") : "";
- const mediaName = AudioService.displayName(modelData) + ": " + modelDataMediaName;
- const max = 35;
- return mediaName.length > max ? mediaName.substring(0, max) + "..." : mediaName;
- }
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- font.weight: modelData === AudioService.sink ? Font.Medium : Font.Normal
- elide: Text.ElideRight
- width: parent.width
- wrapMode: Text.NoWrap
- }
- }
- }
- Rectangle {
- anchors.right: parent.right
- anchors.rightMargin: 120
- anchors.verticalCenter: parent.verticalCenter
- width: appVolumeRow.width
- height: 28
- radius: height / 2
-
- Item {
- id: appVolumeRow
- property color sliderTrackColor: "transparent"
- anchors.centerIn: parent
-
- height: 40
- width: parent.width
-
- Rectangle {
- anchors.right: parent.right
- anchors.rightMargin: Theme.spacingM
- width: Theme.iconSize + Theme.spacingS * 2
- height: Theme.iconSize + Theme.spacingS * 2
- anchors.verticalCenter: parent.verticalCenter
- radius: Theme.cornerRadius
- color: appIconArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.primary, 0)
-
- DankRipple {
- id: appMuteRipple
- cornerRadius: parent.radius
- }
-
- MouseArea {
- id: appIconArea
- anchors.fill: parent
- visible: modelData !== null
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onPressed: mouse => appMuteRipple.trigger(mouse.x, mouse.y)
- onClicked: {
- if (modelData) {
- SessionData.suppressOSDTemporarily();
- modelData.audio.muted = !modelData.audio.muted;
- }
- }
- }
-
- DankIcon {
- anchors.centerIn: parent
- name: {
- if (!modelData)
- return "volume_off";
-
- let volume = modelData.audio.volume;
- let muted = modelData.audio.muted;
-
- if (muted)
- return "volume_off";
- if (volume === 0.0)
- return "volume_mute";
- if (volume <= 0.33)
- return "volume_down";
- if (volume <= 0.66)
- return "volume_up";
- return "volume_up";
- }
- size: Theme.iconSize
- color: modelData && !modelData.audio.muted && modelData.audio.volume > 0 ? Theme.primary : Theme.surfaceText
- }
- }
-
- DankSlider {
- readonly property real actualVolumePercent: modelData ? Math.round(modelData.audio.volume * 100) : 0
-
- anchors.verticalCenter: parent.verticalCenter
- width: 100
- enabled: modelData !== null
- minimum: 0
- maximum: 100
- value: modelData ? Math.min(100, Math.round(modelData.audio.volume * 100)) : 0
- showValue: true
- unit: "%"
- valueOverride: actualVolumePercent
- thumbOutlineColor: Theme.surfaceContainer
- trackColor: appVolumeRow.sliderTrackColor.a > 0 ? appVolumeRow.sliderTrackColor : Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
-
- onSliderValueChanged: function (newValue) {
- if (modelData) {
- SessionData.suppressOSDTemporarily();
- modelData.audio.volume = newValue / 100.0;
- if (newValue > 0 && modelData.audio.muted) {
- modelData.audio.muted = false;
- }
- AudioService.playVolumeChangeSoundIfEnabled();
- }
- }
- }
- }
- PwObjectTracker {
- objects: [modelData]
- }
- }
- }
- }
- }
- }
-}