Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 4 additions & 18 deletions modules/controlcenter/Panes.qml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
pragma ComponentBehavior: Bound

import "audio"
import "bluetooth"
import "network"
import qs.components
import qs.services
import qs.config
Expand All @@ -23,15 +25,7 @@ ClippingRectangle {

Pane {
index: 0
sourceComponent: Item {
StyledText {
anchors.centerIn: parent
text: qsTr("Work in progress")
color: Colours.palette.m3outline
font.pointSize: Appearance.font.size.extraLarge
font.weight: 500
}
}
sourceComponent: NetworkPane {}
}

Pane {
Expand All @@ -43,15 +37,7 @@ ClippingRectangle {

Pane {
index: 2
sourceComponent: Item {
StyledText {
anchors.centerIn: parent
text: qsTr("Work in progress")
color: Colours.palette.m3outline
font.pointSize: Appearance.font.size.extraLarge
font.weight: 500
}
}
sourceComponent: AudioPane {}
}

Behavior on y {
Expand Down
81 changes: 81 additions & 0 deletions modules/controlcenter/audio/AudioPane.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
pragma ComponentBehavior: Bound

import qs.components.effects
import qs.components.containers
import qs.config
import Quickshell.Widgets
import QtQuick
import QtQuick.Layouts

RowLayout {
id: root

anchors.fill: parent
spacing: 0

// Left panel - Device List
Item {
Layout.preferredWidth: Math.floor(parent.width * 0.4)
Layout.minimumWidth: 420
Layout.fillHeight: true

StyledFlickable {
anchors.fill: parent
anchors.margins: Appearance.padding.large + Appearance.padding.normal
anchors.leftMargin: Appearance.padding.large
anchors.rightMargin: Appearance.padding.large + Appearance.padding.normal / 2

flickableDirection: Flickable.VerticalFlick
contentHeight: deviceList.height

DeviceList {
id: deviceList

anchors.left: parent.left
anchors.right: parent.right
}
}

InnerBorder {
leftThickness: 0
rightThickness: Appearance.padding.normal / 2
}
}

// Right panel - Settings
Item {
Layout.fillWidth: true
Layout.fillHeight: true

ClippingRectangle {
anchors.fill: parent
anchors.margins: Appearance.padding.normal
anchors.leftMargin: 0
anchors.rightMargin: Appearance.padding.normal / 2

radius: rightBorder.innerRadius
color: "transparent"

StyledFlickable {
anchors.fill: parent
anchors.margins: Appearance.padding.large * 2

flickableDirection: Flickable.VerticalFlick
contentHeight: settings.height

AudioSettings {
id: settings

anchors.left: parent.left
anchors.right: parent.right
}
}
}

InnerBorder {
id: rightBorder

leftThickness: Appearance.padding.normal / 2
}
}
}
252 changes: 252 additions & 0 deletions modules/controlcenter/audio/AudioSettings.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
pragma ComponentBehavior: Bound

import qs.components
import qs.components.controls
import qs.services
import qs.config
import Quickshell
import QtQuick
import QtQuick.Layouts

ColumnLayout {
id: root

spacing: Appearance.spacing.normal

MaterialIcon {
Layout.alignment: Qt.AlignHCenter
text: "graphic_eq"
font.pointSize: Appearance.font.size.extraLarge * 3
font.bold: true
}

StyledText {
Layout.alignment: Qt.AlignHCenter
text: qsTr("Audio settings")
font.pointSize: Appearance.font.size.large
font.bold: true
}

// Output Volume Section
StyledText {
Layout.topMargin: Appearance.spacing.large
text: qsTr("Output volume")
font.pointSize: Appearance.font.size.larger
font.weight: 500
}

StyledText {
text: qsTr("Control output volume and mute")
color: Colours.palette.m3outline
}

StyledRect {
Layout.fillWidth: true
implicitHeight: outputVolume.implicitHeight + Appearance.padding.large * 2

radius: Appearance.rounding.normal
color: Colours.tPalette.m3surfaceContainer

ColumnLayout {
id: outputVolume

anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.margins: Appearance.padding.large

spacing: Appearance.spacing.larger

RowLayout {
Layout.fillWidth: true
spacing: Appearance.spacing.normal

MaterialIcon {
text: Audio.muted ? "volume_off" : (Audio.volume > 0.5 ? "volume_up" : "volume_down")
font.pointSize: Appearance.font.size.extraLarge
color: Colours.palette.m3primary

StateLayer {
function onClicked(): void {
if (Audio.sink?.audio)
Audio.sink.audio.muted = !Audio.sink.audio.muted;
}
}
}

CustomMouseArea {
Layout.fillWidth: true
implicitHeight: Appearance.padding.normal * 3

onWheel: event => {
if (event.angleDelta.y > 0)
Audio.incrementVolume();
else if (event.angleDelta.y < 0)
Audio.decrementVolume();
}

StyledSlider {
anchors.left: parent.left
anchors.right: parent.right
implicitHeight: parent.implicitHeight

value: Audio.volume
onMoved: Audio.setVolume(value)

Behavior on value {
NumberAnimation {
duration: Appearance.anim.durations.fast
}
}
}
}

StyledText {
Layout.preferredWidth: 60
text: Audio.muted ? qsTr("Muted") : `${Math.round(Audio.volume * 100)}%`
font.weight: 600
font.pointSize: Appearance.font.size.large
horizontalAlignment: Text.AlignRight
}
}
}
}

// Input Volume Section
StyledText {
Layout.topMargin: Appearance.spacing.large
text: qsTr("Input volume")
font.pointSize: Appearance.font.size.larger
font.weight: 500
}

StyledText {
text: qsTr("Control microphone volume and mute")
color: Colours.palette.m3outline
}

StyledRect {
Layout.fillWidth: true
implicitHeight: inputVolume.implicitHeight + Appearance.padding.large * 2

radius: Appearance.rounding.normal
color: Colours.tPalette.m3surfaceContainer

ColumnLayout {
id: inputVolume

anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.margins: Appearance.padding.large

spacing: Appearance.spacing.larger

RowLayout {
Layout.fillWidth: true
spacing: Appearance.spacing.normal

MaterialIcon {
text: Audio.sourceMuted ? "mic_off" : "mic"
font.pointSize: Appearance.font.size.extraLarge
color: Colours.palette.m3primary

StateLayer {
function onClicked(): void {
if (Audio.source?.audio)
Audio.source.audio.muted = !Audio.source.audio.muted;
}
}
}

CustomMouseArea {
Layout.fillWidth: true
implicitHeight: Appearance.padding.normal * 3

onWheel: event => {
if (event.angleDelta.y > 0)
Audio.incrementSourceVolume();
else if (event.angleDelta.y < 0)
Audio.decrementSourceVolume();
}

StyledSlider {
anchors.left: parent.left
anchors.right: parent.right
implicitHeight: parent.implicitHeight

value: Audio.sourceVolume
onMoved: Audio.setSourceVolume(value)

Behavior on value {
NumberAnimation {
duration: Appearance.anim.durations.fast
}
}
}
}

StyledText {
Layout.preferredWidth: 60
text: Audio.sourceMuted ? qsTr("Muted") : `${Math.round(Audio.sourceVolume * 100)}%`
font.weight: 600
font.pointSize: Appearance.font.size.large
horizontalAlignment: Text.AlignRight
}
}
}
}

// Device Information
StyledText {
Layout.topMargin: Appearance.spacing.large
text: qsTr("Device information")
font.pointSize: Appearance.font.size.larger
font.weight: 500
}

StyledText {
text: qsTr("Current audio devices")
color: Colours.palette.m3outline
}

StyledRect {
Layout.fillWidth: true
implicitHeight: deviceInfo.implicitHeight + Appearance.padding.large * 2

radius: Appearance.rounding.normal
color: Colours.tPalette.m3surfaceContainer

ColumnLayout {
id: deviceInfo

anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.margins: Appearance.padding.large

spacing: Appearance.spacing.small / 2

StyledText {
text: qsTr("Output device")
}

StyledText {
text: Audio.sink?.description || Audio.sink?.name || qsTr("Unknown")
color: Colours.palette.m3outline
font.pointSize: Appearance.font.size.small
}

StyledText {
Layout.topMargin: Appearance.spacing.normal
text: qsTr("Input device")
}

StyledText {
text: Audio.source?.description || Audio.source?.name || qsTr("Unknown")
color: Colours.palette.m3outline
font.pointSize: Appearance.font.size.small
}
}
}
}
Loading