Made sure we pass the property correctly
[harmattan/cameraplus] / qml / VideoOverlay.qml
1 // -*- qml -*-
2
3 /*!
4  * This file is part of CameraPlus.
5  *
6  * Copyright (C) 2012-2013 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 2.0
24 import QtCamera 1.0
25 import CameraPlus 1.0
26
27 Item {
28     id: overlay
29     property bool recording: false
30
31     property Camera cam
32     property bool animationRunning: false
33     property int policyMode: recording == true ? CameraResources.Recording : CameraResources.Video
34     property bool controlsVisible: !animationRunning && cam != null && cam.running
35         && dimmer.opacity == 0.0 && !cameraMode.busy
36     property bool pressed: overlay.recording || capture.pressed ||
37         zoomSlider.pressed || modeButton.pressed
38
39     signal previewAvailable(string uri)
40
41     anchors.fill: parent
42
43     VideoMode {
44         id: videoMode
45         camera: cam
46         onPreviewAvailable: overlay.previewAvailable(preview)
47     }
48
49     ZoomSlider {
50         id: zoomSlider
51         camera: cam
52         anchors.top: parent.top
53         anchors.topMargin: 0
54         anchors.horizontalCenter: parent.horizontalCenter
55         visible: controlsVisible
56     }
57
58     ModeButton {
59         id: modeButton
60         anchors.bottom: parent.bottom
61         anchors.right: parent.right
62         anchors.rightMargin: 20
63         anchors.bottomMargin: 20
64         visible: controlsVisible && !overlay.recording
65     }
66
67     ZoomCaptureButton {
68         id: zoomCapture
69         onReleased: overlay.toggleRecording()
70     }
71
72     ZoomCaptureCancel {
73         anchors.fill: parent
74         zoomCapture: zoomCapture
75     }
76
77     CaptureButton {
78         id: capture
79         anchors.right: parent.right
80         anchors.rightMargin: 20
81         anchors.verticalCenter: parent.verticalCenter
82         iconId: overlay.recording ? cameraTheme.captureButtonRecordingIconId : cameraTheme.captureButtonVideoIconId
83         width: 75
84         height: 75
85         opacity: 0.5
86
87         onClicked: overlay.toggleRecording()
88
89         visible: controlsVisible && (!settings.zoomAsShutter && keys.active)
90     }
91
92     CameraToolBar {
93         id: toolBar
94         anchors.bottom: parent.bottom
95         anchors.bottomMargin: 20
96         anchors.left: parent.left
97         anchors.leftMargin: 20
98         opacity: 0.5
99         targetWidth: parent.width - (anchors.leftMargin * 2) - (66 * 1.5)
100         visible: controlsVisible
101         expanded: settings.showToolBar
102         onExpandedChanged: settings.showToolBar = expanded;
103
104         tools: CameraToolBarTools {
105             VideoTorchButton {
106                 camera: cam
107             }
108
109             VideoSceneButton {
110                 visible: !overlay.recording
111                 onClicked: toolBar.push(tools)
112             }
113
114             VideoEvCompButton {
115                 onClicked: toolBar.push(tools)
116             }
117
118             VideoWhiteBalanceButton {
119                 onClicked: toolBar.push(tools)
120             }
121
122             VideoColorFilterButton {
123                 onClicked: toolBar.push(tools)
124             }
125
126             VideoMuteButton {
127             }
128         }
129     }
130
131     Rectangle {
132         anchors.top: parent.top
133         anchors.topMargin: 20
134         anchors.left: parent.left
135         anchors.leftMargin: 20
136         width: 48
137         height: col.height
138         color: "black"
139         border.color: "gray"
140         radius: 20
141         opacity: 0.5
142         visible: controlsVisible
143
144         Column {
145             id: col
146             width: parent.width
147             spacing: 5
148
149             Indicator {
150                 id: resolutionIndicator
151                 property string videoResolution: settings.device == 1 ? settings.secondaryVideoResolution : settings.primaryVideoResolution
152                 property string videoRatio: settings.device == 1 ? settings.secondaryVideoAspectRatio : settings.primaryVideoAspectRatio
153                 source: "image://theme/" + cameraTheme.videoIcon(videoRatio, videoResolution, settings.device)
154             }
155
156             Indicator {
157                 id: wbIndicator
158                 source: visible ? "image://theme/" + cameraTheme.whiteBalanceIndicatorIcon(settings.videoWhiteBalance) : ""
159                 visible: settings.videoWhiteBalance != WhiteBalance.Auto
160             }
161
162             Indicator {
163                 id: cfIndicator
164                 source: visible ? "image://theme/" + cameraTheme.colorFilterIndicatorIcon(settings.videoColorFilter) : ""
165                 visible: settings.videoColorFilter != ColorTone.Normal
166             }
167
168             Indicator {
169                 id: gpsIndicator
170                 visible: settings.useGps
171                 source: cameraTheme.gpsIndicatorIcon
172
173                 PropertyAnimation on opacity  {
174                     easing.type: Easing.OutSine
175                     loops: Animation.Infinite
176                     from: 0.2
177                     to: 1.0
178                     duration: 1000
179                     running: settings.useGps && !positionSource.position.longitudeValid
180                     alwaysRunToEnd: true
181                 }
182             }
183         }
184     }
185
186     DisplayState {
187         inhibitDim: overlay.recording
188     }
189
190     Connections {
191         target: Qt.application
192         onActiveChanged: {
193             if (!Qt.application.active && overlay.recording) {
194                 overlay.stopRecording()
195             }
196         }
197     }
198
199     Timer {
200         id: recordingDuration
201         property int duration: 0
202         running: overlay.recording
203         interval: 1000
204         repeat: true
205
206         onTriggered: {
207             duration = duration + 1
208
209             if (duration == 3600) {
210                 overlay.stopRecording()
211                 showError(qsTr("Maximum recording time reached."))
212             } else if (!checkDiskSpace()) {
213                 page.stopRecording()
214                 showError(qsTr("Not enough space to continue recording."))
215             }
216
217         }
218     }
219
220     RecordingDurationLabel {
221         visible: overlay.recording
222         duration: recordingDuration.duration
223     }
224
225     function doStartRecording() {
226         if (!overlay.recording) {
227             return
228         }
229
230         if (!pipelineManager.acquired || pipelineManager.hijacked) {
231             showError(qsTr("Failed to acquire needed resources."))
232             overlay.recording = false
233             return
234         }
235
236         metaData.setMetaData()
237
238         if (!mountProtector.lock()) {
239             showError(qsTr("Failed to lock images directory."))
240             overlay.recording = false
241             return
242         }
243
244         var file = fileNaming.videoFileName()
245         var tmpFile = fileNaming.temporaryVideoFileName()
246
247         if (!videoMode.startRecording(file, tmpFile)) {
248             showError(qsTr("Failed to record video. Please restart the camera."))
249             mountProtector.unlock()
250             overlay.recording = false
251             return
252         }
253
254         trackerStore.storeVideo(file);
255     }
256
257     function startRecording() {
258         if (!fileSystem.available) {
259             showError(qsTr("Camera cannot record videos in mass storage mode."))
260         } else if (!checkBattery()) {
261             showError(qsTr("Not enough battery to record video."))
262         } else if (!checkDiskSpace()) {
263             showError(qsTr("Not enough space to record video."))
264         } else {
265             recordingDuration.duration = 0
266             overlay.recording = true
267             doStartRecording()
268         }
269     }
270
271     function stopRecording() {
272         videoMode.stopRecording(true)
273         mountProtector.unlock()
274         overlay.recording = false
275     }
276
277     function toggleRecording() {
278         if (overlay.recording) {
279             overlay.stopRecording()
280         } else {
281             overlay.startRecording()
282         }
283     }
284
285     function cameraError() {
286         overlay.stopRecording()
287     }
288
289     function policyLost() {
290         overlay.stopRecording()
291     }
292
293     function batteryLow() {
294         if (!overlay.recording) {
295             return
296         }
297
298         if (!checkBattery()) {
299             overlay.stopRecording()
300             showError(qsTr("Not enough battery to record video."))
301         }
302     }
303
304 }