Add missing capability.cpp
[harmattan/cameraplus] / qml / CameraView.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 // TODO: reset reticle and roi when we stop camera or change mode
28
29 Viewfinder {
30     id: viewfinder
31     property bool pressed: focusReticle.locked || preview.animationRunning
32         || (loader.item ? loader.item.pressed : false)
33     property int policyMode: loader.item ? loader.item.policyMode : CameraResources.None
34
35     camera: cam
36     cameraConfig: cam.cameraConfig
37     renderingEnabled: mainView.currentItem == viewfinder
38
39     Component.onDestruction: cam.stop()
40
41     GridLines {
42         x: viewfinder.renderArea.x
43         y: viewfinder.renderArea.y
44         width: viewfinder.renderArea.width
45         height: viewfinder.renderArea.height
46         visible: settings.gridEnabled
47     }
48
49     Camera {
50         id: cam
51         sounds: Sounds {
52             id: sounds
53             mute: !settings.soundEnabled
54             volume: volumeControl.fullVolume ? Sounds.VolumeHigh : Sounds.VolumeLow
55             imageCaptureStart: platformSettings.imageCaptureStartedSound
56             imageCaptureEnd: platformSettings.imageCaptureEndedSound
57             videoRecordingStart: platformSettings.videoRecordingStartedSound
58             videoRecordingEnd: platformSettings.videoRecordingEndedSound
59             autoFocusAcquired: platformSettings.autoFocusAcquiredSound
60         }
61
62         onRoiChanged: roi.normalize = false
63
64         onRunningChanged: {
65             if (!cam.running) {
66                 mountProtector.unlock()
67             }
68         }
69
70         onError: {
71             if (pipelineManager.error) {
72                 // Ignore any subsequent errors.
73                 // Killing pulseaudio while recording will lead to an
74                 // infinite supply of errors which will break the UI
75                 // if we show a banner for each.
76                 return
77             }
78
79             pipelineManager.error = true
80             if (loader.item) {
81                 loader.item.cameraError()
82             }
83
84             console.log("Camera error (" + code + "): " + message + " " + debug)
85             showError(qsTr("Camera error. Please restart the application."))
86             // We cannot stop camera here. Seems there is a race condition somewhere
87             // which leads to a freeze if we do so.
88         }
89
90     }
91
92     SoundVolumeControl {
93         id: volumeControl
94     }
95
96     BatteryInfo {
97         id: batteryMonitor
98         active: cam.running
99
100         function check() {
101             if (!checkBattery()) {
102                 loader.item.batteryLow()
103             }
104         }
105
106         onChargingChanged: {
107             batteryMonitor.check()
108         }
109
110         onCriticalChanged: {
111             batteryMonitor.check()
112         }
113     }
114
115     PreviewImage {
116         id: preview
117     }
118
119     FocusReticle {
120         id: focusReticle
121         cam: cam
122         videoResolution: viewfinder.videoResolution
123         renderArea: viewfinder.renderArea
124
125         visible: loader.item != null && loader.item.controlsVisible &&
126             cam.autoFocus.canFocus(cam.scene.value)
127         cafStatus: cam ? cam.autoFocus.cafStatus : -1
128         status: cam ? cam.autoFocus.status : -1
129     }
130
131     Loader {
132         id: loader
133         property string src: cam.mode == Camera.VideoMode ? "VideoOverlay.qml" : "ImageOverlay.qml"
134         anchors.fill: parent
135         source: Qt.resolvedUrl(src)
136     }
137
138     Connections {
139         target: loader.item
140         onPreviewAvailable: preview.setPreview(uri)
141     }
142
143     Binding {
144         target: loader.item
145         property: "cam"
146         value: cam
147         when: loader.item != null
148     }
149
150     Binding {
151         target: loader.item
152         property: "animationRunning"
153         value: preview.animationRunning
154         when: loader.item != null
155     }
156
157     /* Camera bindings */
158     Binding {
159         target: cam.flash
160         property: "value"
161         when: cam.mode == Camera.ImageMode
162         value: settings.imageFlashMode
163     }
164
165     Binding {
166         target: settings
167         property: "imageFlashMode"
168         when: cam.mode == Camera.ImageMode
169         value: cam.flash.value
170     }
171
172     Binding {
173         target: cam.scene
174         property: "value"
175         when: cam.mode == Camera.VideoMode
176         value: settings.videoSceneMode
177     }
178
179     Binding {
180         target: cam.scene
181         property: "value"
182         when: cam.mode == Camera.ImageMode
183         value: settings.imageSceneMode
184     }
185
186     Binding {
187         target: cam.evComp
188         property: "value"
189         when: cam.mode == Camera.ImageMode
190         value: settings.imageEvComp
191     }
192
193     Binding {
194         target: cam.evComp
195         property: "value"
196         when: cam.mode == Camera.VideoMode
197         value: settings.videoEvComp
198     }
199
200     Binding {
201         target: settings
202         property: "imageEvComp"
203         when: cam.mode == Camera.ImageMode
204         value: cam.evComp.value
205     }
206
207     Binding {
208         target: settings
209         property: "videoEvComp"
210         when: cam.mode == Camera.VideoMode
211         value: cam.evComp.value
212     }
213
214     Binding {
215         target: cam.whiteBalance
216         property: "value"
217         when: cam.mode == Camera.ImageMode
218         value: settings.imageWhiteBalance
219     }
220
221     Binding {
222         target: cam.whiteBalance
223         property: "value"
224         when: cam.mode == Camera.VideoMode
225         value: settings.videoWhiteBalance
226     }
227
228     Binding {
229         target: cam.colorTone
230         property: "value"
231         when: cam.mode == Camera.ImageMode
232         value: settings.imageColorFilter
233     }
234
235     Binding {
236         target: cam.colorTone
237         property: "value"
238         when: cam.mode == Camera.VideoMode
239         value: settings.videoColorFilter
240     }
241
242     Binding {
243         target: cam.iso
244         property: "value"
245         when: cam.mode == Camera.ImageMode
246         value: settings.imageIso
247     }
248
249     Binding {
250         target: settings
251         property: "imageIso"
252         when: cam.mode == Camera.ImageMode
253         value: cam.iso.value
254     }
255
256     Binding {
257         target: cam.videoMute
258         property: "enabled"
259         value: settings.videoMuted
260     }
261
262     Binding {
263         target: cam.roi
264         property: "enabled"
265         value: settings.faceDetectionEnabled && !focusReticle.pressed && !focusReticle.touchMode && cam.mode == Camera.ImageMode
266     }
267
268     function policyLost() {
269         if (loader.item) {
270             loader.item.policyLost()
271         }
272     }
273
274     function checkBattery() {
275         // We are fine if we are connected to the charger:
276         if (batteryMonitor.charging) {
277             return true
278         }
279
280         // If we have enough battery then we are fine:
281         if (!batteryMonitor.critical) {
282             return true
283         }
284
285         return false
286     }
287 }