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 }