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