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