Warning, /plasma/plasma-mobile/components/mobileshell/qml/dataproviders/AudioInfo.qml is written in an unsupported language. File is not indexed.
0001 // SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org>
0002 // SPDX-License-Identifier: GPL-2.0-or-later
0003
0004 pragma Singleton
0005
0006 import QtQuick
0007
0008 import org.kde.plasma.private.volume
0009
0010 QtObject {
0011 id: root
0012
0013 property var config: GlobalConfig {}
0014
0015 property SinkModel paSinkModel: SinkModel {}
0016
0017 // whether the audio icon should be visible in the status bar
0018 readonly property bool isVisible: paSinkModel.preferredSink
0019
0020 // the icon that should be displayed in the status bar
0021 readonly property string icon: paSinkModel.preferredSink && !isDummyOutput(paSinkModel.preferredSink)
0022 ? iconName(paSinkModel.preferredSink.volume, paSinkModel.preferredSink.muted)
0023 : iconName(0, true)
0024
0025 // the name of the audio device when it isn't valid
0026 readonly property string dummyOutputName: "auto_null"
0027
0028 // the maximum volume amount (percentage)
0029 readonly property int maxVolumePercent: config.raiseMaximumVolume ? 150 : 100
0030
0031 // the maximum volume amount
0032 readonly property int maxVolumeValue: maxVolumePercent * PulseAudio.NormalVolume / 100
0033
0034 // step that increments when adjusting the volume
0035 readonly property int volumeStep: Math.round(5 * PulseAudio.NormalVolume / 100.0)
0036
0037 // The current audio volume (updated by connecting to sinks)
0038 property int volumeValue
0039
0040 function isDummyOutput(output) {
0041 return output && output.name === dummyOutputName;
0042 }
0043
0044 function boundVolume(volume) {
0045 return Math.max(PulseAudio.MinimalVolume, Math.min(volume, maxVolumeValue));
0046 }
0047
0048 function volumePercent(volume, max){
0049 if (!max) {
0050 max = PulseAudio.NormalVolume;
0051 }
0052 return Math.round(volume / max * maxVolumePercent);
0053 }
0054
0055 function increaseVolume() {
0056 if (!paSinkModel.preferredSink || isDummyOutput(paSinkModel.preferredSink)) {
0057 return;
0058 }
0059
0060 var volume = boundVolume(paSinkModel.preferredSink.volume + volumeStep);
0061 var percent = volumePercent(volume, maxVolumeValue);
0062 paSinkModel.preferredSink.muted = percent == 0;
0063 paSinkModel.preferredSink.volume = volume;
0064 }
0065
0066 function decreaseVolume() {
0067 if (!paSinkModel.preferredSink || isDummyOutput(paSinkModel.preferredSink)) {
0068 return;
0069 }
0070
0071 var volume = boundVolume(paSinkModel.preferredSink.volume - volumeStep);
0072 var percent = volumePercent(volume, maxVolumeValue);
0073 paSinkModel.preferredSink.muted = percent == 0;
0074 paSinkModel.preferredSink.volume = volume;
0075 }
0076
0077 function muteVolume() {
0078 if (!paSinkModel.preferredSink || isDummyOutput(paSinkModel.preferredSink)) {
0079 return;
0080 }
0081
0082 paSinkModel.preferredSink.muted = !paSinkModel.preferredSink.muted;
0083 }
0084
0085 function iconName(volume, muted, prefix) {
0086 if (!prefix) {
0087 prefix = "audio-volume";
0088 }
0089 var icon = null;
0090 var percent = volume / maxVolumeValue;
0091 if (percent <= 0.0 || muted) {
0092 icon = prefix + "-muted";
0093 } else if (percent <= 0.25) {
0094 icon = prefix + "-low";
0095 } else if (percent <= 0.75) {
0096 icon = prefix + "-medium";
0097 } else {
0098 icon = prefix + "-high";
0099 }
0100 return icon;
0101 }
0102
0103 // emitted when the volume changed, but not due to sink switching
0104 signal volumeChanged()
0105
0106 property var updateVolume: Connections {
0107 target: root.paSinkModel ? (root.paSinkModel.preferredSink ? root.paSinkModel.preferredSink : null) : null
0108 enabled: target !== null
0109
0110 function onVolumeChanged() {
0111 root.volumeValue = root.volumePercent(root.paSinkModel.preferredSink.volume, root.maxVolumeValue);
0112 root.volumeChanged();
0113 }
0114
0115 function onMutedChanged() {
0116 root.volumeValue = root.paSinkModel.preferredSink.muted ? 0 : root.volumePercent(root.paSinkModel.preferredSink.volume, root.maxVolumeValue);
0117 root.volumeChanged();
0118 }
0119 }
0120
0121 property var updateVolumeOnSinkChange: Connections {
0122 target: root.paSinkModel ? root.paSinkModel : null
0123 enabled: target !== null
0124
0125 function onPreferredSinkChanged() {
0126 if (root.paSinkModel.preferredSink) {
0127 root.volumeValue = root.volumePercent(root.paSinkModel.preferredSink.volume, root.maxVolumeValue);
0128 }
0129 }
0130 }
0131 }