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