Warning, /utilities/krecorder/src/contents/ui/RecordPage.qml is written in an unsupported language. File is not indexed.
0001 /*
0002 * SPDX-FileCopyrightText: 2020 Jonah BrĂ¼chert <jbb@kaidan.im>
0003 * SPDX-FileCopyrightText: 2020-2022 Devin Lin <espidev@gmail.com>
0004 *
0005 * SPDX-License-Identifier: GPL-3.0-or-later
0006 */
0007
0008 import QtQuick
0009 import QtQuick.Controls as Controls
0010 import QtQuick.Layouts
0011
0012 import org.kde.kirigami as Kirigami
0013
0014 import KRecorder
0015
0016 import "components"
0017
0018 Kirigami.Page {
0019 id: root
0020 visible: false
0021 title: i18n("Record Audio")
0022
0023 property bool isStopped: AudioRecorder.recorderState === AudioRecorder.StoppedState
0024 property bool isPaused: AudioRecorder.recorderState === AudioRecorder.PausedState
0025
0026 onVisibleChanged: {
0027 // if page has been opened, and not in a recording session, start recording
0028 if (visible && (!isStopped && !isPaused)) {
0029 AudioRecorder.record();
0030 }
0031 }
0032
0033 Connections {
0034 target: AudioRecorder
0035 function onErrorChanged() {
0036 console.warn("Error on the recorder", AudioRecorder.errorString)
0037 }
0038 }
0039
0040 ColumnLayout {
0041 id: column
0042 anchors.fill: parent
0043
0044 Controls.Label {
0045 id: timeText
0046 Layout.alignment: Qt.AlignHCenter
0047 Layout.bottomMargin: Kirigami.Units.largeSpacing
0048 text: isStopped ? "00:00:00" : Utils.formatTime(AudioRecorder.duration)
0049 opacity: (root.isStopped || root.isPaused) ? 0.5 : 0.7
0050 font.pointSize: Math.round(Kirigami.Theme.defaultFont.pointSize * 3)
0051 font.weight: Font.DemiBold
0052 }
0053
0054 Item { Layout.fillHeight: true }
0055
0056 // TODO visualization disabled until we port the model to Qt6
0057 // Visualization {
0058 // Layout.fillWidth: true
0059
0060 // prober: AudioRecorder.prober
0061 // showBarsFromMiddle: true
0062 // showLine: true
0063 // height: Kirigami.Units.gridUnit * 10
0064 // maxBarHeight: Kirigami.Units.gridUnit * 5 * 2
0065 // animationIndex: AudioRecorder.prober.animationIndex
0066
0067 // volumes: AudioRecorder.prober.volumesList
0068 // }
0069
0070 // placeholder visualization for now
0071 Item {
0072 id: visualization
0073 height: Kirigami.Units.gridUnit * 10
0074 Layout.fillWidth: true
0075
0076 Rectangle {
0077 color: Kirigami.Theme.highlightColor
0078 anchors.centerIn: parent
0079 height: Kirigami.Units.gridUnit * 12
0080 width: height
0081 radius: height / 2
0082 opacity: 0.5
0083 transformOrigin: Item.Center
0084 scale: stopAnim.min
0085
0086 NumberAnimation on scale {
0087 id: recordingAnim
0088 property real min: (9 / 12)
0089 property real max: 1.0
0090 to: max
0091 running: !root.isStopped && !root.isPaused
0092 easing.type: Easing.OutBack
0093 duration: 2000
0094 onRunningChanged: Easing.OutBack
0095
0096 onFinished: {
0097 to = (to === min) ? max : min;
0098 easing.type = (to === min) ? Easing.InBack : Easing.OutBack;
0099 restart();
0100 }
0101 }
0102
0103 NumberAnimation on scale {
0104 id: stopAnim
0105 to: (7 / 12)
0106 running: root.isStopped || root.isPaused
0107 easing.type: Easing.OutExpo
0108 duration: 2000
0109 }
0110 }
0111
0112 RoundFlatButton {
0113 id: pauseButton
0114 anchors.centerIn: parent
0115 height: Kirigami.Units.gridUnit * 7
0116 width: height
0117 text: (!isStopped && isPaused) ? i18n("Continue") : i18n("Pause")
0118
0119 onClicked: {
0120 if (isPaused) {
0121 AudioRecorder.record();
0122 } else {
0123 AudioRecorder.pause();
0124 }
0125 }
0126 }
0127
0128 ColumnLayout {
0129 anchors.centerIn: parent
0130 Kirigami.Theme.inherit: false
0131 Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
0132
0133 Kirigami.Icon {
0134 source: 'microphone-sensitivity-high'
0135 implicitHeight: Kirigami.Units.iconSizes.huge
0136 implicitWidth: Kirigami.Units.iconSizes.huge
0137 }
0138 Controls.Label {
0139 visible: isStopped || isPaused
0140 Layout.alignment: Qt.AlignCenter
0141 text: i18n('Paused')
0142 font.bold: true
0143 }
0144 }
0145 }
0146
0147 Item { Layout.fillHeight: true }
0148
0149 RowLayout {
0150 spacing: Math.round(Kirigami.Units.gridUnit * 1.5)
0151
0152 Layout.fillWidth: true
0153 Layout.bottomMargin: Kirigami.Units.gridUnit
0154 Layout.topMargin: Kirigami.Units.largeSpacing
0155
0156 Item { Layout.fillWidth: true }
0157
0158 // moved pause button until we port the visualization to Qt6
0159 // ToolTipToolButton {
0160 // implicitWidth: Math.round(Kirigami.Units.gridUnit * 2.5)
0161 // implicitHeight: Math.round(Kirigami.Units.gridUnit * 2.5)
0162 // text: (!isStopped && isPaused) ? i18n("Continue") : i18n("Pause")
0163 // icon.name: (!isStopped && isPaused) ? "media-playback-start" : "media-playback-pause"
0164
0165 // onClicked: {
0166 // if (isPaused) {
0167 // AudioRecorder.record();
0168 // } else {
0169 // AudioRecorder.pause();
0170 // }
0171 // }
0172 // }
0173
0174 RoundFlatButton {
0175 id: stopButton
0176 text: i18n("Save Recording")
0177
0178 icon.name: "checkmark"
0179
0180 onClicked: {
0181 // pop record page off
0182 applicationWindow().pageStack.layers.pop();
0183
0184 // save recording
0185 recordingName.text = RecordingModel.nextDefaultRecordingName();
0186 saveDialog.open();
0187 AudioRecorder.pause();
0188 }
0189 }
0190
0191 ToolTipToolButton {
0192 implicitWidth: Math.round(Kirigami.Units.gridUnit * 2.5)
0193 implicitHeight: Math.round(Kirigami.Units.gridUnit * 2.5)
0194 text: i18n("Delete")
0195 icon.name: "delete"
0196
0197 onClicked: {
0198 // pop record page off
0199 applicationWindow().pageStack.layers.pop();
0200 AudioRecorder.reset();
0201 }
0202 }
0203
0204 Item { Layout.fillWidth: true }
0205 }
0206 }
0207
0208 Kirigami.Dialog {
0209 id: saveDialog
0210 standardButtons: Kirigami.Dialog.NoButton
0211 padding: Kirigami.Units.largeSpacing
0212 bottomPadding: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing
0213
0214 title: i18n("Save recording")
0215
0216 customFooterActions: [
0217 Kirigami.Action {
0218 text: i18n("Save")
0219 icon.name: "document-save"
0220 onTriggered: {
0221 AudioRecorder.setRecordingName(recordingName.text);
0222 AudioRecorder.stop();
0223 pageStack.layers.pop();
0224 recordingName.text = "";
0225
0226 saveDialog.close();
0227 }
0228 },
0229 Kirigami.Action {
0230 text: i18n("Discard")
0231 icon.name: "delete"
0232 onTriggered: {
0233 AudioRecorder.reset()
0234 saveDialog.close();
0235 }
0236 }
0237 ]
0238
0239 Kirigami.FormLayout {
0240 implicitWidth: Kirigami.Units.gridUnit * 20
0241
0242 Controls.TextField {
0243 id: recordingName
0244 Kirigami.FormData.label: i18n("Name:")
0245 placeholderText: i18n("Name (optional)")
0246 }
0247
0248 Controls.Label {
0249 Kirigami.FormData.label: i18n("Storage Folder:")
0250 Layout.fillWidth: true
0251 wrapMode: Text.Wrap
0252 text: AudioRecorder.storageFolder
0253 }
0254 }
0255 }
0256 }