Warning, /utilities/krecorder/src/contents/ui/components/Visualization.qml is written in an unsupported language. File is not indexed.

0001 // SPDX-FileCopyrightText: 2020 Jonah BrĂ¼chert <jbb@kaidan.im>
0002 // SPDX-FileCopyrightText: 2020-2022 Devin Lin <espidev@gmail.com>
0003 // SPDX-License-Identifier: GPL-3.0-or-later
0004 
0005 import QtQuick
0006 import QtQuick.Layouts
0007 import QtQuick.Controls as Controls
0008 import org.kde.kirigami as Kirigami
0009 
0010 import KRecorder
0011 
0012 Item {
0013     id: visualization
0014     
0015     property var prober
0016     
0017     property int maxBarHeight
0018     property int animationIndex // which index rectangle is being expanded
0019     property var volumes: []
0020     property bool showLine
0021     property bool showBarsFromMiddle
0022     
0023     property int reservedBarWidth: Math.round(Kirigami.Units.gridUnit * 0.4)
0024     
0025     property var simpleAudioFormatSetting: SettingsModel.simpleAudioFormat
0026     
0027     // maximum volume to base off volume bar height
0028     property int maxVolumeData: 1000
0029     
0030     // TODO: We need a more sophisticated algorithm to create the visualizer bars (probably using FFT)
0031     // currently we just see how much data is in a sample, which is really random and doesn't deal with spikes very well
0032     
0033     function processVolume(volume) {
0034         // vorbis for some reason has its volume data upside-down
0035         if (simpleAudioFormatSetting == SettingsModel.VORBIS) {
0036             volume = Math.max(0, 17000 - volume);
0037         }
0038         return volume;
0039     }
0040     
0041     Component.onCompleted: {
0042         visualization.prober.maxVolumes = (showBarsFromMiddle ? width / 2 : width) / reservedBarWidth;
0043     }
0044     onWidthChanged: {
0045         visualization.prober.maxVolumes = (showBarsFromMiddle ? width / 2 : width) / reservedBarWidth;
0046     }
0047     
0048     Connections {
0049         target: visualization.prober
0050         function onVolumesListCleared() {
0051             visualization.maxVolumeData = 1000; // reset max
0052         }
0053         function onVolumesListAdded(volume) {
0054             visualization.maxVolumeData = Math.max(visualization.maxVolumeData, processVolume(volume));
0055         }
0056     }
0057     
0058     // central line
0059     Rectangle {
0060         id: verticalBar
0061         visible: showLine
0062         z: 1
0063         anchors.top: list.top
0064         anchors.bottom: list.bottom
0065         anchors.horizontalCenter: parent.horizontalCenter
0066         width: Math.round(Kirigami.Units.gridUnit * 0.1)
0067         color: Kirigami.Theme.negativeTextColor
0068     }
0069     
0070     ListView {
0071         id: list
0072         model: visualization.volumes
0073         orientation: Qt.Horizontal
0074         
0075         interactive: false
0076         height: maxBarHeight
0077         anchors.verticalCenter: parent.verticalCenter
0078         anchors.left: parent.left
0079         anchors.leftMargin: showBarsFromMiddle ? Math.max(0, parent.width / 2 - list.count * reservedBarWidth) : 0 // gradually expand list
0080         anchors.right: showBarsFromMiddle ? verticalBar.left : parent.right
0081         spacing: 0
0082         
0083         delegate: Item {
0084             width: reservedBarWidth
0085             height: list.height
0086         
0087             Rectangle {
0088                 color: Kirigami.Theme.disabledTextColor
0089                 width: Math.round(Kirigami.Units.gridUnit * 0.12)
0090                 radius: Math.round(width / 2)
0091                 height: Math.max(Math.round(Kirigami.Units.gridUnit * 0.15), maxBarHeight * processVolume(modelData) / visualization.maxVolumeData)
0092                 antialiasing: true
0093                 anchors.verticalCenter: parent.verticalCenter
0094             }
0095         }
0096     }
0097 }