Added an option to enable using proximity sensor to capture
[harmattan/cameraplus] / qml / MainPage.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: flash not ready (battery low or flash not ready message)
28
29 CameraPage {
30     id: root
31
32     property bool deviceChangeInProgress: false
33
34     CameraTheme {
35         id: cameraTheme
36     }
37
38     VisualItemModel {
39         id: mainModel
40
41         SettingsView {
42             camera: viewfinder.camera
43             width: mainView.width
44             height: mainView.height
45         }
46
47         CameraView {
48             id: viewfinder
49             width: mainView.width
50             height: mainView.height
51         }
52
53         PostCaptureView {
54             camera: viewfinder.camera
55             width: mainView.width
56             height: mainView.height
57         }
58     }
59
60     ListView {
61         id: mainView
62         LayoutMirroring.enabled: false
63         anchors.fill: parent
64         orientation: ListView.Horizontal
65         model: mainModel
66         snapMode: ListView.SnapOneItem
67         highlightRangeMode: ListView.StrictlyEnforceRange
68         boundsBehavior: Flickable.StopAtBounds
69         currentIndex: 1
70         interactive: !currentItem.pressed
71     }
72
73     Component.onCompleted: {
74         platformSettings.init()        
75         root.resetCamera(settings.device, settings.mode)
76     }
77
78     PlatformSettings {
79         id: platformSettings
80     }
81
82     Settings {
83         id: settings
84         onDeviceAboutToChange: {
85             root.deviceChangeInProgress = true
86         }
87
88         onDeviceChanged: {
89             viewfinder.cameraDeviceChanged()
90
91             // Reset pipeline manager error
92             pipelineManager.error = false
93
94             if (root.resetCamera(settings.device, settings.mode)) {
95                 root.deviceChangeInProgress = false
96                 pipelineManager.startCamera()
97             }
98         }
99
100         onImageAspectRatioChanged: {
101             if (!root.deviceChangeInProgress) {
102                 imageSettings.setImageResolution()
103             }
104         }
105
106         onImageResolutionChanged: {
107             if (!root.deviceChangeInProgress) {
108                 imageSettings.setImageResolution()
109             }
110         }
111
112         onVideoResolutionChanged: {
113             if (!root.deviceChangeInProgress) {
114                 videoSettings.setVideoResolution()
115             }
116         }
117
118         onVideoAspectRatioChanged: {
119             if (!root.deviceChangeInProgress) {
120                 videoSettings.setVideoResolution()
121             }
122         }
123     }
124
125     PipelineManager {
126         id: pipelineManager
127         camera: viewfinder.camera
128         currentItem: mainView.currentItem
129     }
130
131     function resetCamera(deviceId, mode) {
132         if (!viewfinder.camera.reset(deviceId, mode)) {
133             showError(qsTr("Failed to set camera device and mode. Please restart the application."))
134             return false
135         }
136
137         if (mode == Camera.ImageMode) {
138             imageSettings.setImageResolution()
139         }
140         else if (mode == Camera.VideoMode) {
141             videoSettings.setVideoResolution()
142         }
143
144         return true
145     }
146
147     function showError(msg) {
148         error.text = msg
149         error.show()
150     }
151
152     property alias dimmer: camDimmer
153     CameraPositionSource {
154         id: positionSource
155         active: settings.useGps
156         // TODO: we cannot bind to cam.running because camera will stop
157         // when the connection dialog pops up and we end up with an infinite loop
158         // active: cam.running && settings.useGps
159         onPositionChanged: geocode.search(position.coordinate.longitude, position.coordinate.latitude)
160     }
161
162     MetaData {
163         id: metaData
164         camera: viewfinder.camera
165         manufacturer: deviceInfo.manufacturer
166         model: deviceInfo.model
167         country: geocode.country
168         city: geocode.city
169         suburb: geocode.suburb
170         longitude: positionSource.longitude
171         longitudeValid: positionSource.longitudeValid && settings.useGps
172         latitude: positionSource.latitude
173         latitudeValid: positionSource.latitudeValid && settings.useGps
174         elevation: positionSource.altitude
175         elevationValid: positionSource.altitudeValid && settings.useGps
176         orientation: orientation.orientation
177         artist: settings.creatorName
178         captureDirection: compass.direction
179         captureDirectionValid: compass.directionValid
180         horizontalError: positionSource.horizontalAccuracy
181         horizontalErrorValid: positionSource.horizontalAccuracyValid && settings.useGps
182         dateTimeEnabled: true
183     }
184
185     CameraOrientation {
186         id: orientation
187         active: viewfinder.camera.running || (mainView.currentIndex == 2 && Qt.application.active)
188     }
189
190     CameraCompass {
191         id: compass
192         active: viewfinder.camera.running
193     }
194
195     ReverseGeocode {
196         id: geocode
197         active: viewfinder.camera.running && settings.useGps && settings.useGeotags
198     }
199
200     DeviceInfo {
201         id: deviceInfo
202     }
203
204     FSMonitor {
205         id: fileSystem
206     }
207
208     CameraInfoBanner {
209         id: error
210     }
211
212     FileNaming {
213         id: fileNaming
214         imageSuffix: viewfinder.camera.imageSuffix
215         videoSuffix: viewfinder.camera.videoSuffix
216         imagePath: platformSettings.imagePath
217         videoPath: platformSettings.videoPath
218         temporaryVideoPath: platformSettings.temporaryVideoPath
219         settings: settings
220     }
221
222     MountProtector {
223         id: mountProtector
224     }
225
226     TrackerStore {
227         id: trackerStore
228         active: viewfinder.camera.running
229         manufacturer: deviceInfo.manufacturer
230         model: deviceInfo.model
231     }
232
233     ImageSettings {
234         id: imageSettings
235         camera: viewfinder.camera
236
237         function setImageResolution() {
238             if (!imageSettings.setResolution(settings.imageAspectRatio, settings.imageResolution)) {
239                 showError(qsTr("Failed to set required resolution"))
240             }
241         }
242     }
243
244     VideoSettings {
245         id: videoSettings
246         camera: viewfinder.camera
247
248         function setVideoResolution() {
249             if (!videoSettings.setResolution(settings.videoAspectRatio, settings.videoResolution)) {
250                 showError(qsTr("Failed to set required resolution"))
251             }
252         }
253     }
254
255     ModeController {
256         id: cameraMode
257         cam: viewfinder.camera
258         dimmer: root.dimmer
259     }
260
261     Rectangle {
262         property bool dimmed: false
263         id: camDimmer
264         z: 1
265         anchors.fill: parent
266         opacity: dimmed ? 1.0 : 0.0
267         color: "black"
268         Behavior on opacity {
269             PropertyAnimation { duration: 150 }
270         }
271     }
272
273     DeviceKeys {
274         id: keys
275         active: Qt.application.active && pipelineManager.scaleAcquired
276         repeat: !settings.zoomAsShutter
277     }
278
279     CameraProximitySensor {
280         id: proximitySensor
281         active: Qt.application.active && viewfinder.camera.running && settings.proximityAsShutter
282     }
283
284     // TODO:
285     Standby {
286         policyLost: pipelineManager.state == "policyLost"
287         show: !Qt.application.active || pipelineManager.showStandBy ||
288             (mainView.currentIndex == 1 && !viewfinder.camera.running)
289     }
290 }