init: working version
This commit is contained in:
commit
7d8d7dacae
109 changed files with 15066 additions and 0 deletions
208
modules/dashboard/Mixer.qml
Normal file
208
modules/dashboard/Mixer.qml
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.config
|
||||
import qs.custom
|
||||
import qs.services
|
||||
import qs.util
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.Services.Pipewire
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
required property PersistentProperties uiState
|
||||
required property int index
|
||||
readonly property list<PwNode> nodes: Pipewire.nodes.values.filter(node => node.isSink && node.isStream)
|
||||
|
||||
width: Config.dashboard.mixerWidth
|
||||
height: Config.dashboard.mixerHeight
|
||||
|
||||
PwObjectTracker {
|
||||
objects: root.nodes
|
||||
}
|
||||
|
||||
Binding {
|
||||
target: root.uiState
|
||||
when: root.uiState.dashboardTab === root.index
|
||||
property: "osdVolumeReact"
|
||||
value: false
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
|
||||
anchors.fill: parent
|
||||
spacing: 7
|
||||
|
||||
CustomText {
|
||||
Layout.topMargin: 6
|
||||
text: qsTr("Master Volume")
|
||||
color: Config.colors.secondary
|
||||
}
|
||||
|
||||
CustomMouseArea {
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: Config.osd.sliderWidth
|
||||
|
||||
function onWheel(event: WheelEvent) {
|
||||
if (event.angleDelta.y > 0)
|
||||
Audio.increaseVolume();
|
||||
else if (event.angleDelta.y < 0)
|
||||
Audio.decreaseVolume();
|
||||
}
|
||||
|
||||
acceptedButtons: Qt.RightButton
|
||||
onClicked: Audio.sink.audio.muted = !Audio.muted
|
||||
|
||||
CustomFilledSlider {
|
||||
anchors.fill: parent
|
||||
|
||||
orientation: Qt.Horizontal
|
||||
color: Audio.muted ? Config.colors.error : Config.colors.volume
|
||||
icon: Icons.getVolumeIcon(value, Audio.muted)
|
||||
value: Audio.volume
|
||||
onMoved: Audio.setVolume(value)
|
||||
|
||||
Behavior on color {
|
||||
CAnim {
|
||||
duration: Config.anim.durations.small
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CustomRect {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 5
|
||||
Layout.bottomMargin: 5
|
||||
height: 1
|
||||
color: Config.colors.inactive
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
CustomListView {
|
||||
id: list
|
||||
|
||||
anchors.fill: parent
|
||||
spacing: 12
|
||||
|
||||
model: ScriptModel {
|
||||
values: [...root.nodes]
|
||||
objectProp: "id"
|
||||
}
|
||||
|
||||
CustomScrollBar.vertical: CustomScrollBar {
|
||||
flickable: list
|
||||
}
|
||||
|
||||
delegate: RowLayout {
|
||||
id: entry
|
||||
|
||||
required property PwNode modelData
|
||||
spacing: 6
|
||||
|
||||
width: root.width
|
||||
|
||||
IconImage {
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
visible: source != ""
|
||||
implicitSize: slider.height * 1.4
|
||||
source: {
|
||||
const icon = entry.modelData.properties["application.icon-name"];
|
||||
if (icon)
|
||||
return Icons.getAppIcon(icon, "image-missing");
|
||||
Icons.getAppIcon(entry.modelData.name, "image-missing")
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 6
|
||||
|
||||
CustomText {
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
text: {
|
||||
// application.name -> description -> name
|
||||
const app = entry.modelData.properties["application.name"]
|
||||
?? (entry.modelData.description != "" ? entry.modelData.description : entry.modelData.name);
|
||||
const media = entry.modelData.properties["media.name"];
|
||||
return media != undefined ? `${app} 🞄 ${media}` : app;
|
||||
}
|
||||
color: Config.colors.secondary
|
||||
}
|
||||
|
||||
CustomMouseArea {
|
||||
id: slider
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: Config.osd.sliderWidth
|
||||
|
||||
acceptedButtons: Qt.RightButton
|
||||
onClicked: entry.modelData.audio.muted = !entry.modelData.audio.muted
|
||||
|
||||
CustomFilledSlider {
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
orientation: Qt.Horizontal
|
||||
color: entry.modelData.audio.muted ? Config.colors.error : Config.colors.volume
|
||||
icon: Icons.getVolumeIcon(value, entry.modelData.audio.muted)
|
||||
value: entry.modelData.audio.volume
|
||||
onMoved: {
|
||||
if (entry.modelData.ready)
|
||||
entry.modelData.audio.volume = Math.max(0, Math.min(1, value));
|
||||
}
|
||||
|
||||
|
||||
Behavior on color {
|
||||
CAnim {
|
||||
duration: Config.anim.durations.small
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CustomText {
|
||||
anchors.centerIn: parent
|
||||
|
||||
opacity: list.count === 0 ? 1 : 0
|
||||
visible: opacity > 0
|
||||
|
||||
text: qsTr("No audio sources")
|
||||
color: Config.colors.tertiary
|
||||
font.pointSize: Config.font.size.normal
|
||||
|
||||
Behavior on opacity {
|
||||
Anim {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* RowLayout { */
|
||||
/* id: deviceSelectorRowLayout */
|
||||
/* Layout.fillWidth: true */
|
||||
/* uniformCellSizes: true */
|
||||
|
||||
/* AudioDeviceSelectorButton { */
|
||||
/* Layout.fillWidth: true */
|
||||
/* input: false */
|
||||
/* onClicked: root.showDeviceSelectorDialog(input) */
|
||||
/* } */
|
||||
/* AudioDeviceSelectorButton { */
|
||||
/* Layout.fillWidth: true */
|
||||
/* input: true */
|
||||
/* onClicked: root.showDeviceSelectorDialog(input) */
|
||||
/* } */
|
||||
/* } */
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue