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 }