ec09db0cdf6cf24cf2ec74e261593c42b04412d7
[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                 visible: videoControlsVisible
152                 anchors.top: parent.top
153                 anchors.left: parent.left
154                 anchors.topMargin: 20
155                 anchors.leftMargin: 20
156                 opacity: 0.5
157         }
158
159         VideoSceneButton {
160                 id: scene
161                 visible: controlsVisible
162                 anchors.top: torch.bottom
163                 anchors.left: parent.left
164                 anchors.topMargin: 10
165                 anchors.leftMargin: 20
166         }
167
168         VideoEvCompButton {
169                 id: evComp
170                 visible: videoControlsVisible
171                 anchors.top: scene.bottom
172                 anchors.left: parent.left
173                 anchors.topMargin: 10
174                 anchors.leftMargin: 20
175         }
176
177         MouseArea {
178                 id: indicators
179                 anchors.bottom: parent.bottom
180                 anchors.bottomMargin: 20
181                 anchors.left: parent.left
182                 anchors.leftMargin: 20
183                 width: 48
184                 height: col.height
185                 onClicked: openFile("VideoSettingsPage.qml");
186                 visible: controlsVisible
187
188                 BorderImage {
189                         id: image
190                         anchors.fill: parent
191                         smooth: true
192                         source: indicators.pressed ? "image://theme/meegotouch-camera-settings-indicators-background-pressed" : "image://theme/meegotouch-camera-settings-indicators-background"
193                 }
194
195                 Column {
196                         id: col
197                         width: parent.width
198                         spacing: 5
199
200                         Indicator {
201                                 id: resolutionIndicator
202                                 source: "image://theme/" + Data.videoIcon(settings.videoResolution);
203                         }
204
205                         Indicator {
206                                 id: wbIndicator
207                                 source: "image://theme/" + Data.wbIcon(settings.videoWhiteBalance) + "-screen"
208                                 visible: settings.videoWhiteBalance != WhiteBalance.Auto
209                         }
210
211                         Indicator {
212                                 id: cfIndicator
213                                 source: "image://theme/" + Data.cfIcon(settings.videoColorFilter) + "-screen"
214                                 visible: settings.videoColorFilter != ColorTone.Normal
215                         }
216
217                         Indicator {
218                                 id: gpsIndicator
219                                 visible: settings.useGps
220                                 source: "image://theme/icon-m-camera-location"
221
222                                 PropertyAnimation on opacity  {
223                                         easing.type: Easing.OutSine
224                                         loops: Animation.Infinite
225                                         from: 0.2
226                                         to: 1.0
227                                         duration: 1000
228                                         running: settings.useGps && !positionSource.position.longitudeValid
229                                         alwaysRunToEnd: true
230                                 }
231                         }
232                 }
233         }
234
235         Button {
236                 id: cameraRoll
237                 anchors.top: parent.top
238                 anchors.right: parent.right
239                 anchors.topMargin: 20
240                 anchors.rightMargin: 20
241                 width: 56
242                 height: 56
243
244                 opacity: 0.5
245                 iconSource: "image://theme/icon-m-camera-roll"
246                 onClicked: openFile("PostCapturePage.qml");
247                 visible: controlsVisible && !videoMode.recording
248         }
249
250         Rectangle {
251                 anchors.left: parent.left
252                 anchors.bottom: parent.bottom
253                 anchors.leftMargin: 20
254                 anchors.bottomMargin: 20
255
256                 visible: videoControlsVisible && videoMode.recording
257
258                 color: "black"
259                 opacity: 0.5
260                 width: 100
261                 height: 30
262
263                 Timer {
264                         id: recordingDuration
265
266                         property int duration: 0
267
268                         running: cam.running && videoMode.recording
269                         triggeredOnStart: true
270                         interval: 1000
271                         repeat: true
272
273                         onTriggered: {
274                                 duration = duration + 1;
275                                 if (duration == 3600) {
276                                         videoMode.stopRecording();
277                                         showError(qsTr("Maximum recording time reached."));
278                                 }
279                                 else if (!checkDiskSpace()) {
280                                         videoMode.stopRecording();
281                                         showError(qsTr("Not enough space to continue recording."));
282                                 }
283                         }
284
285                         onRunningChanged: {
286                                 if (!running) {
287                                         duration = 0;
288                                 }
289                         }
290                 }
291
292                 Image {
293                         id: recordingIcon
294                         source: "image://theme/icon-m-camera-ongoing-recording"
295                         width: 20
296                         height: 20
297                         anchors.verticalCenter: parent.verticalCenter
298                         anchors.left: parent.left
299                         anchors.leftMargin: 5
300                         sourceSize.width: 20
301                         sourceSize.height: 20
302                 }
303
304                 Label {
305                         function formatDuration(dur) {
306                                 var secs = parseInt(dur);
307                                 var mins = Math.floor(secs / 60);
308                                 var seconds = secs - (mins * 60);
309
310                                 if (mins < 10) {
311                                         mins = "0" + mins;
312                                 }
313
314                                 if (seconds < 10) {
315                                         seconds = "0" + seconds;
316                                 }
317
318                                 return mins + ":" + seconds;
319                         }
320
321                         id: durationLabel
322                         text: formatDuration(recordingDuration.duration);
323                         anchors.left: recordingIcon.right
324                         anchors.leftMargin: 5
325                 }
326         }
327 }