set window background to empty string and backgroundColor to transparent so viewfinde...
[harmattan/cameraplus] / qml / main.qml
1 // -*- qml -*-
2
3 /*!
4  * This file is part of CameraPlus.
5  *
6  * Copyright (C) 2012 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 1.1
24 import com.nokia.meego 1.1
25 import com.nokia.extras 1.1
26 import QtCamera 1.0
27 import CameraPlus 1.0
28 import QtMobility.systeminfo 1.2
29 import QtMobility.location 1.2
30
31 // TODO: postcapture
32 // TODO: flash not ready (battery low or flash not ready message)
33 // TODO: portrait/landscape
34 // TODO: stop viewfinder in settings pages ?
35 // TODO: grid lines, face tracking, ambr
36 // TODO: select primary/secondary camera.
37 // TODO: disable debug builds.
38 // TODO: a way to get buffers to the application
39 // TODO: fcam like functionality (precise control over capture parameters).
40 // TODO: mute video sound
41
42 PageStackWindow {
43         id: root
44
45         property alias dimmer: camDimmer
46
47         showStatusBar: false
48
49         Component.onCompleted: {
50                 theme.inverted = true;
51                 // TODO: hardcoding device id
52                 root.resetCamera(0, settings.mode);
53         }
54
55         function showError(msg) {
56                 error.text = msg;
57                 error.show();
58         }
59
60         function resetCamera(deviceId, mode) {
61                 if (!cam.reset(deviceId, mode)) {
62                         showError(qsTr("Failed to set camera device and mode. Please restart the application."));
63                 }
64         }
65
66         PositionSource {
67                 // NOTE: The source will not reset the position when we lose the signal.
68                 // This shouldn't be a big problem as we are course enough.
69                 // If we ever need street level updates then this will be an issue.
70                 id: positionSource
71                 active: settings.useGps
72                 // TODO: we cannot bind to cam.running because camera will stop
73                 // when the connection dialog pops up and we end up with an infinite loop
74                 // active: cam.running && settings.useGps
75                 onPositionChanged: geocode.search(position.coordinate.longitude, position.coordinate.latitude);
76         }
77
78         MetaData {
79                 id: metaData
80                 camera: cam
81                 manufacturer: deviceInfo.manufacturer
82                 model: deviceInfo.model
83                 country: geocode.country
84                 city: geocode.city
85                 suburb: geocode.suburb
86                 longitude: positionSource.position.coordinate.longitude
87                 longitudeValid: positionSource.position.longitudeValid && settings.useGps
88                 latitude: positionSource.position.coordinate.latitude
89                 latitudeValid: positionSource.position.latitudeValid && settings.useGps
90                 elevation: positionSource.position.coordinate.altitude
91                 elevationValid: positionSource.position.altitudeValid && settings.useGps
92                 orientation: orientation.orientation
93                 artist: settings.creatorName
94                 captureDirection: compass.direction
95                 captureDirectionValid: compass.directionValid
96                 horizontalError: positionSource.position.horizontalAccuracy
97                 horizontalErrorValid: positionSource.position.horizontalAccuracyValid && settings.useGps
98                 dateTimeEnabled: true
99         }
100
101         Orientation {
102                 id: orientation
103                 active: cam.running
104         }
105
106         Compass {
107                 id: compass
108                 active: cam.running
109         }
110
111         ReverseGeocode {
112                 id: geocode
113                 active: cam.running && settings.useGps && settings.useGeotags
114         }
115
116         PipelineManager {
117                 id: pipelineManager
118                 camera: cam
119         }
120
121         DeviceInfo {
122                 id: deviceInfo
123         }
124
125         FSMonitor {
126                 id: fileSystem
127         }
128
129         InfoBanner {
130                 id: error
131         }
132
133         Settings {
134                 id: settings
135         }
136
137         FileNaming {
138                 id: fileNaming
139                 imageSuffix: cam.imageSuffix
140                 videoSuffix: cam.videoSuffix
141         }
142
143         MountProtector {
144                 id: mountProtector
145                 path: fileNaming.path
146         }
147
148         function replacePage(file) {
149                 pageStack.replace(Qt.resolvedUrl(file), {cam: cam}, true);
150         }
151
152         function openFile(file) {
153                 pageStack.push(Qt.resolvedUrl(file), {cam: cam});
154         }
155
156         function openFileNow(file) {
157                 pageStack.push(Qt.resolvedUrl(file), {cam: cam}, true);
158         }
159
160         platformStyle: PageStackWindowStyle {
161                 cornersVisible: false
162                 background: ""
163                 backgroundColor: "transparent"
164         }
165
166         ImageSettings {
167                 id: imageSettings
168                 camera: cam
169                 function setImageResolution() {
170                         if (!imageSettings.setResolution(settings.imageAspectRatio, settings.imageResolution)) {
171                                 showError(qsTr("Failed to set required resolution"));
172                         }
173                 }
174
175                 onReadyChanged: {
176                         if (ready) {
177                                 imageSettings.setImageResolution();
178                         }
179                 }
180         }
181
182         VideoSettings {
183                 id: videoSettings
184                 camera: cam
185
186                 function setVideoResolution() {
187                         if (!videoSettings.setResolution(settings.videoAspectRatio, settings.videoResolution)) {
188                                 showError(qsTr("Failed to set required resolution"));
189                         }
190                 }
191
192                 onReadyChanged: {
193                         if (ready) {
194                                 videoSettings.setVideoResolution();
195                         }
196                 }
197         }
198
199         Connections {
200                 target: settings
201
202                 onImageAspectRatioChanged: {
203                         imageSettings.setImageResolution();
204                 }
205
206                 onImageResolutionChanged: {
207                         imageSettings.setImageResolution();
208                 }
209
210                 onVideoResolutionChanged: {
211                         videoSettings.setVideoResolution();
212                 }
213         }
214
215         Camera {
216                 id: cam
217                 anchors.fill: parent
218
219                 FocusReticle {
220                         id: focusReticle
221                         cam: cam
222                         visible: pageStack.currentPage && pageStack.currentPage.controlsVisible && pageStack.currentPage.focusReticleVisible && cam && cam.autoFocus.canFocus(cam.scene.value);
223                         cafStatus: cam ? cam.autoFocus.cafStatus : -1
224                         status: cam ? cam.autoFocus.status : -1
225         }
226
227 /*
228                 onDeviceIdChanged: {
229                         // TODO: is this needed ?
230                         if (platformWindow.active) {
231                                 cam.start();
232                         }
233                 }
234 */
235                 onError: {
236                         console.log("Camera error (" + code + "): " + message + " " + debug);
237                         showError(qsTr("Camera error. Please restart the application."));
238                         cam.stop();
239                         mountProtector.unlock();
240                 }
241
242                 onRunningChanged: {
243                         if (!cam.running) {
244                                 mountProtector.unlock();
245                         }
246                 }
247
248                 Component.onDestruction: cam.stop();
249
250                 // We need to show viewfinder below pages.
251                 z: -1
252
253                 Rectangle {
254                         id: camDimmer
255                         z: 1
256                         anchors.fill: parent
257                         opacity: 0
258                         color: "black"
259                 }
260
261                 notifications: Sounds {
262                         id: sounds
263                         mute: !settings.soundEnabled
264                 }
265
266         }
267
268         Binding {
269                 target: cam.flash
270                 property: "value"
271                 when: cam.mode == Camera.ImageMode
272                 value: settings.imageFlashMode
273         }
274
275         Binding {
276                 target: settings
277                 property: "imageFlashMode"
278                 when: cam.mode == Camera.ImageMode
279                 value: cam.flash.value
280         }
281
282         Binding {
283                 target: cam.scene
284                 property: "value"
285                 when: cam.mode == Camera.VideoMode
286                 value: settings.videoSceneMode
287         }
288
289         Binding {
290                 target: cam.scene
291                 property: "value"
292                 when: cam.mode == Camera.ImageMode
293                 value: settings.imageSceneMode
294         }
295
296         Binding {
297                 target: cam.evComp
298                 property: "value"
299                 when: cam.mode == Camera.ImageMode
300                 value: settings.imageEvComp
301         }
302
303         Binding {
304                 target: cam.evComp
305                 property: "value"
306                 when: cam.mode == Camera.VideoMode
307                 value: settings.videoEvComp
308         }
309
310         Binding {
311                 target: settings
312                 property: "imageEvComp"
313                 when: cam.mode == Camera.ImageMode
314                 value: cam.evComp.value
315         }
316
317         Binding {
318                 target: settings
319                 property: "videoEvComp"
320                 when: cam.mode == Camera.VideoMode
321                 value: cam.evComp.value
322         }
323
324         Binding {
325                 target: cam.whiteBalance
326                 property: "value"
327                 when: cam.mode == Camera.ImageMode
328                 value: settings.imageWhiteBalance
329         }
330
331         Binding {
332                 target: cam.whiteBalance
333                 property: "value"
334                 when: cam.mode == Camera.VideoMode
335                 value: settings.videoWhiteBalance
336         }
337
338         Binding {
339                 target: cam.colorTone
340                 property: "value"
341                 when: cam.mode == Camera.ImageMode
342                 value: settings.imageColorFilter
343         }
344
345         Binding {
346                 target: cam.colorTone
347                 property: "value"
348                 when: cam.mode == Camera.VideoMode
349                 value: settings.videoColorFilter
350         }
351
352         Binding {
353                 target: cam.iso
354                 property: "value"
355                 when: cam.mode == Camera.ImageMode
356                 value: settings.imageIso
357         }
358
359         Binding {
360                 target: settings
361                 property: "imageIso"
362                 when: cam.mode == Camera.ImageMode
363                 value: cam.iso.value
364         }
365
366         TrackerStore {
367                 id: trackerStore
368                 active: cam.running
369                 manufacturer: deviceInfo.manufacturer
370                 model: deviceInfo.model
371         }
372
373         ModeController {
374                 id: cameraMode
375                 cam: cam
376                 dimmer: root.dimmer
377         }
378
379         Connections {
380                 target: cam
381                 onModeChanged: {
382                         if (cam.mode == Camera.VideoMode) {
383                                 replacePage("VideoPage.qml");
384                         }
385                         else {
386                                 replacePage("ImagePage.qml");
387                         }
388                 }
389         }
390 }