85c14cfb0edf8e1783c20fc9da6cc60d368bec40
[harmattan/cameraplus] / qml / VideoPage.qml
1 // -*- qml -*-
2
3 /*!
4  * This file is part of CameraPlus.
5  *
6  * Copyright (C) 2012 Mohammed Sameer <msameer@foolab.org>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  */
22
23 import QtQuick 1.1
24 import com.nokia.meego 1.1
25 import QtCamera 1.0
26 import CameraPlus 1.0
27 import "data.js" as Data
28
29 CameraPage {
30         id: page
31
32         policyMode: CameraResources.Video
33
34         controlsVisible: videoControlsVisible && !videoMode.recording
35         property bool videoControlsVisible: recording.visible && cam.running && !standbyWidget.visible
36
37         orientationLock: PageOrientation.LockLandscape
38
39         DisplayState {
40                 inhibitDim: videoMode.recording
41         }
42
43         onBatteryLow: {
44                 if (!videoMode.recording) {
45                         return;
46                 }
47
48                 if (!checkBattery()) {
49                         videoMode.stopRecording();
50                         showError(qsTr("Not enough battery to record video."));
51                 }
52         }
53
54         Button {
55                 id: recording
56                 anchors.right: parent.right
57                 anchors.rightMargin: 20
58                 anchors.verticalCenter: parent.verticalCenter
59                 iconSource: "image://theme/icon-m-camera-video-record"
60                 width: 75
61                 height: 75
62                 opacity: 0.5
63
64                 onClicked: buttonClicked();
65
66                 function buttonClicked() {
67                         if (!fileSystem.available) {
68                                 showError(qsTr("Camera cannot record videos in mass storage mode."));
69                                 return;
70                         }
71
72                         // We only toggle the mode to video recording so
73                         // policy can acquire the needed resources
74
75                         if (policyMode == CameraResources.Video) {
76                                 if (!checkBattery()) {
77                                         showError(qsTr("Not enough battery to record video."));
78                                         return;
79                                 }
80
81                                 if (!checkDiskSpace()) {
82                                         showError(qsTr("Not enough space to record video."));
83                                         return;
84                                 }
85
86                                 policyMode = CameraResources.Recording;
87                         }
88                         else if (videoMode.recording) {
89                                 // We just ask to stop video.
90                                 videoMode.stopRecording();
91                         }
92                 }
93
94                 Connections {
95                         target: videoMode
96                         onRecordingChanged: {
97                                 if (!videoMode.recording) {
98                                         policyMode = CameraResources.Video;
99                                 }
100                         }
101                 }
102
103                 Connections {
104                         target: resourcePolicy
105                         onAcquiredChanged: {
106                                 if (resourcePolicy.acquired && policyMode == CameraResources.Recording) {
107                                         metaData.setMetaData();
108
109                                         if (!mountProtector.lock()) {
110                                                 showError(qsTr("Failed to lock images directory."));
111                                                 policyMode = CameraResources.Video
112                                                 return;
113                                         }
114
115
116                                         if (!videoMode.startRecording(fileNaming.videoFileName(),
117                                              fileNaming.temporaryVideoFileName())) {
118                                                 showError(qsTr("Failed to record video. Please restart the camera."));
119                                                 policyMode = CameraResources.Video
120 }
121                                 }
122                         }
123                 }
124
125                 visible: (videoMode.recording || videoMode.canCapture) && !cameraMode.animationRunning && !previewAnimationRunning && !standbyWidget.visible
126         }
127
128         Connections {
129                 target: Qt.application
130                 onActiveChanged: {
131                         if (!Qt.application.active && videoMode.recording) {
132                                 videoMode.stopRecording();
133                         }
134                 }
135         }
136
137         VideoMode {
138                 id: videoMode
139                 camera: cam
140                 onPreviewAvailable: {
141                         if (!standbyWidget.visible) {
142                                 page.setPreview(preview);
143                         }
144                 }
145
146                 onSaved: mountProtector.unlock();
147         }
148
149         VideoTorchButton {
150                 id: torch
151                 camera: cam
152                 visible: videoControlsVisible
153                 anchors.top: parent.top
154                 anchors.left: parent.left
155                 anchors.topMargin: 20
156                 anchors.leftMargin: 20
157                 opacity: 0.5
158         }
159
160         VideoSceneButton {
161                 id: scene
162                 visible: controlsVisible
163                 anchors.top: torch.bottom
164                 anchors.left: parent.left
165                 anchors.topMargin: 10
166                 anchors.leftMargin: 20
167         }
168
169         VideoEvCompButton {
170                 id: evComp
171                 visible: videoControlsVisible
172                 anchors.top: scene.bottom
173                 anchors.left: parent.left
174                 anchors.topMargin: 10
175                 anchors.leftMargin: 20
176         }
177
178         MouseArea {
179                 id: indicators
180                 anchors.bottom: parent.bottom
181                 anchors.bottomMargin: 20
182                 anchors.left: parent.left
183                 anchors.leftMargin: 20
184                 width: 48
185                 height: col.height
186                 onClicked: openFile("VideoSettingsPage.qml");
187                 visible: controlsVisible
188
189                 BorderImage {
190                         id: image
191                         anchors.fill: parent
192                         smooth: true
193                         source: indicators.pressed ? "image://theme/meegotouch-camera-settings-indicators-background-pressed" : "image://theme/meegotouch-camera-settings-indicators-background"
194                 }
195
196                 Column {
197                         id: col
198                         width: parent.width
199                         spacing: 5
200
201                         Indicator {
202                                 id: resolutionIndicator
203                                 source: "image://theme/" + Data.videoIcon(settings.videoResolution);
204                         }
205
206                         Indicator {
207                                 id: wbIndicator
208                                 source: "image://theme/" + Data.wbIcon(settings.videoWhiteBalance) + "-screen"
209                                 visible: settings.videoWhiteBalance != WhiteBalance.Auto
210                         }
211
212                         Indicator {
213                                 id: cfIndicator
214                                 source: "image://theme/" + Data.cfIcon(settings.videoColorFilter) + "-screen"
215                                 visible: settings.videoColorFilter != ColorTone.Normal
216                         }
217
218                         Indicator {
219                                 id: gpsIndicator
220                                 visible: settings.useGps
221                                 source: "image://theme/icon-m-camera-location"
222
223                                 PropertyAnimation on opacity  {
224                                         easing.type: Easing.OutSine
225                                         loops: Animation.Infinite
226                                         from: 0.2
227                                         to: 1.0
228                                         duration: 1000
229                                         running: settings.useGps && !positionSource.position.longitudeValid
230                                         alwaysRunToEnd: true
231                                 }
232                         }
233                 }
234         }
235
236         Button {
237                 id: cameraRoll
238                 anchors.top: parent.top
239                 anchors.right: parent.right
240                 anchors.topMargin: 20
241                 anchors.rightMargin: 20
242                 width: 56
243                 height: 56
244
245                 opacity: 0.5
246                 iconSource: "image://theme/icon-m-camera-roll"
247                 onClicked: openFile("PostCapturePage.qml");
248                 visible: controlsVisible && !videoMode.recording
249         }
250
251         Rectangle {
252                 anchors.left: parent.left
253                 anchors.bottom: parent.bottom
254                 anchors.leftMargin: 20
255                 anchors.bottomMargin: 20
256
257                 visible: videoControlsVisible && videoMode.recording
258
259                 color: "black"
260                 opacity: 0.5
261                 width: 100
262                 height: 30
263
264                 Timer {
265                         id: recordingDuration
266
267                         property int duration: 0
268
269                         running: cam.running && videoMode.recording
270                         triggeredOnStart: true
271                         interval: 1000
272                         repeat: true
273
274                         onTriggered: {
275                                 duration = duration + 1;
276                                 if (duration == 3600) {
277                                         videoMode.stopRecording();
278                                         showError(qsTr("Maximum recording time reached."));
279                                 }
280                                 else if (!checkDiskSpace()) {
281                                         videoMode.stopRecording();
282                                         showError(qsTr("Not enough space to continue recording."));
283                                 }
284                         }
285
286                         onRunningChanged: {
287                                 if (!running) {
288                                         duration = 0;
289                                 }
290                         }
291                 }
292
293                 Image {
294                         id: recordingIcon
295                         source: "image://theme/icon-m-camera-ongoing-recording"
296                         width: 20
297                         height: 20
298                         anchors.verticalCenter: parent.verticalCenter
299                         anchors.left: parent.left
300                         anchors.leftMargin: 5
301                         sourceSize.width: 20
302                         sourceSize.height: 20
303                 }
304
305                 Label {
306                         function formatDuration(dur) {
307                                 var secs = parseInt(dur);
308                                 var mins = Math.floor(secs / 60);
309                                 var seconds = secs - (mins * 60);
310
311                                 if (mins < 10) {
312                                         mins = "0" + mins;
313                                 }
314
315                                 if (seconds < 10) {
316                                         seconds = "0" + seconds;
317                                 }
318
319                                 return mins + ":" + seconds;
320                         }
321
322                         id: durationLabel
323                         text: formatDuration(recordingDuration.duration);
324                         anchors.left: recordingIcon.right
325                         anchors.leftMargin: 5
326                 }
327         }
328 }