basic volume mixer

This commit is contained in:
kossLAN 2025-11-01 22:43:12 -04:00
parent e33d3d574a
commit 65894a08c9
Signed by: kossLAN
SSH key fingerprint: SHA256:bdV0x+wdQHGJ6LgmstH3KV8OpWY+OOFmJcPcB0wQPV8
6 changed files with 97 additions and 91 deletions

View file

@ -73,11 +73,11 @@ Variants {
Layout.fillHeight: true Layout.fillHeight: true
} }
// VolumeIndicator { VolumeIndicator {
// bar: root bar: root
// Layout.preferredWidth: this.height Layout.preferredWidth: this.height
// Layout.fillHeight: true Layout.fillHeight: true
// } }
PowerMenu { PowerMenu {
bar: root bar: root

View file

@ -63,7 +63,7 @@ Scope {
LazyLoader { LazyLoader {
id: popupLoader id: popupLoader
activeAsync: root.shownItem != null active: root.shownItem != null
PopupWindow { PopupWindow {
id: popup id: popup

View file

@ -5,19 +5,20 @@ import QtQuick.Layouts
import QtQuick.Controls import QtQuick.Controls
import Quickshell.Widgets import Quickshell.Widgets
import Quickshell.Services.Pipewire import Quickshell.Services.Pipewire
import qs
import qs.widgets import qs.widgets
import qs
Loader { Loader {
id: root id: root
active: node !== null active: node != null
required property PwNode node required property PwNode node
property string label: node.nickname
sourceComponent: WrapperRectangle { sourceComponent: WrapperRectangle {
id: comp id: comp
color: ShellSettings.colors.surface_container_translucent color: ShellSettings.colors.surface_container_translucent
radius: 12 radius: 12
margin: 6 margin: 6
border { border {
@ -25,7 +26,6 @@ Loader {
color: ShellSettings.colors.active_translucent color: ShellSettings.colors.active_translucent
} }
// property string text
// property Component button // property Component button
// property Component icon // property Component icon
@ -35,23 +35,48 @@ Loader {
} }
RowLayout { RowLayout {
Slider { ColumnLayout {
value: root.node.audio.volume ?? 0
// text: root.text
// icon: root.icon
onValueChanged: {
// only allow changes when the node is ready other wise you will combust
if (!root.node.ready)
return;
root.node.audio.volume = value;
}
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
Text {
text: root.label
color: ShellSettings.colors.active
elide: Text.ElideRight
Layout.fillWidth: true
Layout.fillHeight: true
}
StyledSlider {
value: root.node.audio.volume ?? 0
// text: root.text
// icon: root.icon
onValueChanged: {
// only allow changes when the node is ready other wise you will combust
if (!root.node.ready)
return;
root.node.audio.volume = value;
}
Layout.fillWidth: true
Layout.fillHeight: true
}
} }
// StyledMouseArea {
// id: rightArrow
// Layout.preferredWidth: rightArrow.height
// // Layout.fillWidth: true
// Layout.fillHeight: true
//
// IconImage {
// source: "root:resources/general/right-arrow.svg"
// anchors.fill: parent
// }
// }
// Loader { // Loader {
// id: buttonLoader // id: buttonLoader
// sourceComponent: root.button // sourceComponent: root.button

View file

@ -6,6 +6,7 @@ import Quickshell.Widgets
import Quickshell.Services.Pipewire import Quickshell.Services.Pipewire
import qs.widgets import qs.widgets
import qs.bar import qs.bar
import qs
StyledMouseArea { StyledMouseArea {
id: root id: root
@ -34,31 +35,66 @@ StyledMouseArea {
implicitWidth: 300 implicitWidth: 300
implicitHeight: container.implicitHeight + (2 * 8) implicitHeight: container.implicitHeight + (2 * 8)
// implicitWidth: volumeMenu.implicitWidth property PwNode sink: Pipewire.defaultAudioSink
// implicitHeight: volumeMenu.implicitHeight property real entryHeight: 45
// VolumeControl {
// id: volumeMenu
// }
ColumnLayout { ColumnLayout {
id: container id: container
spacing: 4
anchors { anchors {
fill: parent fill: parent
margins: 8 margins: 8
} }
// Default Audio
VolumeCard { VolumeCard {
node: Pipewire.defaultAudioSink node: menu.sink
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: 45 Layout.preferredHeight: menu.entryHeight
} }
VolumeCard { Rectangle {
node: Pipewire.defaultAudioSource color: ShellSettings.colors.active_translucent
radius: height / 2
Layout.leftMargin: 3
Layout.rightMargin: 3
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: 45 Layout.preferredHeight: 2
}
// Application Mixer
Loader {
id: sinkLoader
active: menu.sink
Layout.fillWidth: true
Layout.preferredHeight: 5 * menu.entryHeight
PwNodeLinkTracker {
id: linkTracker
node: menu.sink
}
sourceComponent: ListView {
anchors.fill: parent
spacing: 6
model: linkTracker.linkGroups
delegate: Loader {
id: nodeLoader
active: modelData.source != null
width: ListView.view.width
height: menu.entryHeight
required property PwLinkGroup modelData
sourceComponent: VolumeCard {
node: nodeLoader.modelData.source
label: node.properties["media.name"] ?? ""
}
}
}
} }
} }
} }

View file

@ -1,6 +1,6 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools --> <!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
<svg fill="#ffffff" width="800px" height="800px" viewBox="0 -32 576 576" xmlns="http://www.w3.org/2000/svg"> <svg fill="#ffffff" width="128px" height="128px" viewBox="0 -32 576 576" xmlns="http://www.w3.org/2000/svg" stroke="#ffffff">
<g id="SVGRepo_bgCarrier" stroke-width="0"/> <g id="SVGRepo_bgCarrier" stroke-width="0"/>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/> <g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
<g id="SVGRepo_iconCarrier"> <g id="SVGRepo_iconCarrier">

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before After
Before After

View file

@ -1,55 +0,0 @@
pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Controls
import Qt5Compat.GraphicalEffects
import ".."
Slider {
id: slider
implicitHeight: 8
property var accentColor: ShellSettings.colors["primary"]
background: Rectangle {
id: sliderContainer
width: slider.availableWidth
height: slider.implicitHeight
color: ShellSettings.colors["inverse_surface"]
radius: 4
anchors.verticalCenter: parent.verticalCenter
layer.enabled: true
layer.effect: OpacityMask {
source: Rectangle {
width: sliderContainer.width
height: sliderContainer.height
radius: sliderContainer.radius
color: "white"
}
maskSource: Rectangle {
width: sliderContainer.width
height: sliderContainer.height
radius: sliderContainer.radius
color: "black"
}
}
Rectangle {
id: fill
width: slider.handle.width / 2 + slider.visualPosition * (sliderContainer.width - slider.handle.width)
height: sliderContainer.height
color: Qt.color(slider.accentColor ?? "purple").darker(1.2)
}
}
handle: Rectangle {
id: handleRect
x: slider.visualPosition * (slider.availableWidth - width)
y: slider.topPadding + slider.availableHeight / 2 - height / 2
width: 16
height: 16
radius: width / 2
color: slider.pressed ? Qt.color(slider.accentColor ?? "purple").darker(1.5) : slider.accentColor ?? "purple"
}
}