b8a415faea92f1a6595bf53978ea5a335c809447
[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 // TODO: Sounds
29 // TODO: N950 conf
30
31 CameraPage {
32     id: root
33
34     property bool deviceChangeInProgress: false
35     property bool inCaptureMode: mainView.currentIndex == 1
36     property Item dimmer: camDimmer
37
38     CameraTheme {
39         id: cameraTheme
40     }
41
42     VisualItemModel {
43         id: mainModel
44
45         Loader {
46             id: settingsLoader
47             width: mainView.width
48             height: mainView.height
49
50             property bool pressed: false
51             property bool inhibitDim: false
52             property int policyMode: settings.mode == Camera.VideoMode ? CameraResources.Video : CameraResources.Image
53         }
54
55         CameraView {
56             id: viewfinder
57             width: mainView.width
58             height: mainView.height
59         }
60
61         Loader {
62             id: postCaptureLoader
63             property bool pressed: item ? item.pressed : false
64             property bool inhibitDim: item ? item.inhibitDim : false
65             property int policyMode: item ? item.policyMode : settings.mode == Camera.VideoMode ? CameraResources.Video : CameraResources.Image
66
67             width: mainView.width
68             height: mainView.height
69         }
70     }
71
72     ListView {
73         id: mainView
74         LayoutMirroring.enabled: false
75         anchors.fill: parent
76         orientation: ListView.Horizontal
77         model: mainModel
78         snapMode: ListView.SnapOneItem
79         highlightRangeMode: ListView.StrictlyEnforceRange
80         boundsBehavior: Flickable.StopAtBounds
81         currentIndex: 1
82         interactive: !currentItem.pressed
83         onContentXChanged: {
84             if (contentX == 0) {
85                 settingsLoader.source = Qt.resolvedUrl("SettingsView.qml")
86             } else if (contentX == width) {
87                 settingsLoader.source = ""
88                 postCaptureLoader.source = ""
89             } else if (contentX == width * 2) {
90                 postCaptureLoader.source = Qt.resolvedUrl("PostCaptureView.qml")
91             }
92         }
93     }
94
95     Component.onCompleted: {
96         platformSettings.init()        
97         root.resetCamera(settings.device, settings.mode)
98     }
99
100     PlatformSettings {
101         id: platformSettings
102     }
103
104     Settings {
105         id: settings
106         onDeviceAboutToChange: {
107             root.deviceChangeInProgress = true
108         }
109
110         onDeviceChanged: {
111             viewfinder.cameraDeviceChanged()
112
113             // Reset pipeline manager error
114             pipelineManager.error = false
115
116             if (root.resetCamera(settings.device, settings.mode)) {
117                 root.deviceChangeInProgress = false
118                 pipelineManager.startCamera()
119             }
120         }
121
122         onImageAspectRatioChanged: {
123             if (!root.deviceChangeInProgress) {
124                 imageSettings.setImageResolution()
125             }
126         }
127
128         onImageResolutionChanged: {
129             if (!root.deviceChangeInProgress) {
130                 imageSettings.setImageResolution()
131             }
132         }
133
134         onVideoResolutionChanged: {
135             if (!root.deviceChangeInProgress) {
136                 videoSettings.setVideoResolution()
137             }
138         }
139
140         onVideoAspectRatioChanged: {
141             if (!root.deviceChangeInProgress) {
142                 videoSettings.setVideoResolution()
143             }
144         }
145     }
146
147     PipelineManager {
148         id: pipelineManager
149         camera: viewfinder.camera
150         currentItem: mainView.currentItem
151     }
152
153     function resetCamera(deviceId, mode) {
154         if (!viewfinder.camera.reset(deviceId, mode)) {
155             showError(qsTr("Failed to set camera device and mode. Please restart the application."))
156             return false
157         }
158
159         if (mode == Camera.ImageMode) {
160             imageSettings.setImageResolution()
161         }
162         else if (mode == Camera.VideoMode) {
163             videoSettings.setVideoResolution()
164         }
165
166         return true
167     }
168
169     function showError(msg) {
170         error.text = msg
171         error.show()
172     }
173
174     PlatformQuirks {
175         id: platformQuirks
176     }
177
178     DisplayState {
179         id: displayState
180         inhibitDim: mainView.currentItem != null ? mainView.currentItem.inhibitDim : false
181     }
182
183     CameraPositionSource {
184         id: positionSource
185         active: (viewfinder.camera.running || platformQuirks.forceOn) && settings.useGps && displayState.isOn
186         onPositionChanged: geocode.search(position.coordinate.longitude, position.coordinate.latitude)
187     }
188
189     MetaData {
190         id: metaData
191         camera: viewfinder.camera
192         manufacturer: deviceInfo.manufacturer
193         model: deviceInfo.model
194         country: geocode.country
195         city: geocode.city
196         suburb: geocode.suburb
197         longitude: positionSource.longitude
198         longitudeValid: positionSource.longitudeValid && settings.useGps
199         latitude: positionSource.latitude
200         latitudeValid: positionSource.latitudeValid && settings.useGps
201         elevation: positionSource.altitude
202         elevationValid: positionSource.altitudeValid && settings.useGps
203         orientation: orientation.orientation
204         artist: settings.creatorName
205         captureDirection: compass.direction
206         captureDirectionValid: compass.directionValid
207         horizontalError: positionSource.horizontalAccuracy
208         horizontalErrorValid: positionSource.horizontalAccuracyValid && settings.useGps
209         dateTimeEnabled: true
210     }
211
212     CameraOrientation {
213         id: orientation
214         active: viewfinder.camera.running || (mainView.currentIndex == 2 && Qt.application.active)
215     }
216
217     CameraCompass {
218         id: compass
219         active: viewfinder.camera.running
220     }
221
222     ReverseGeocode {
223         id: geocode
224         active: (viewfinder.camera.running || platformQuirks.forceOn) && settings.useGps && settings.useGeotags && displayState.isOn
225     }
226
227     DeviceInfo {
228         id: deviceInfo
229     }
230
231     FSMonitor {
232         id: fileSystem
233     }
234
235     CameraInfoBanner {
236         id: error
237     }
238
239     FileNaming {
240         id: fileNaming
241         imageSuffix: viewfinder.camera.imageSuffix
242         videoSuffix: viewfinder.camera.videoSuffix
243         imagePath: platformSettings.imagePath
244         videoPath: platformSettings.videoPath
245         temporaryVideoPath: platformSettings.temporaryVideoPath
246         settings: settings
247     }
248
249     MountProtector {
250         id: mountProtector
251     }
252
253     TrackerStore {
254         id: trackerStore
255         active: viewfinder.camera.running
256         manufacturer: deviceInfo.manufacturer
257         model: deviceInfo.model
258     }
259
260     ImageSettings {
261         id: imageSettings
262         camera: viewfinder.camera
263
264         function setImageResolution() {
265             if (!imageSettings.setResolution(settings.imageAspectRatio, settings.imageResolution)) {
266                 showError(qsTr("Failed to set required resolution"))
267             }
268         }
269     }
270
271     VideoSettings {
272         id: videoSettings
273         camera: viewfinder.camera
274
275         function setVideoResolution() {
276             if (!videoSettings.setResolution(settings.videoAspectRatio, settings.videoResolution)) {
277                 showError(qsTr("Failed to set required resolution"))
278             }
279         }
280     }
281
282     ModeController {
283         id: cameraMode
284         cam: viewfinder.camera
285         dimmer: root.dimmer
286     }
287
288     Rectangle {
289         property bool dimmed: false
290         id: camDimmer
291         z: 1
292         anchors.fill: parent
293         opacity: dimmed ? 1.0 : 0.0
294         color: "black"
295         Behavior on opacity {
296             PropertyAnimation { duration: 150 }
297         }
298     }
299
300     DeviceKeys {
301         id: keys
302         active: Qt.application.active && pipelineManager.scaleAcquired && root.inCaptureMode && !mainView.moving
303         repeat: !settings.zoomAsShutter
304     }
305
306     Timer {
307         id: proximityTimer
308         running: proximitySensor.close
309         repeat: false
310         interval: 500
311         onTriggered: {
312             if (proximitySensor.close) {
313                 proximitySensor.sensorClosed = true
314             }
315         }
316     }
317
318     CameraProximitySensor {
319         id: proximitySensor
320         property bool sensorClosed: false
321
322         active: Qt.application.active && viewfinder.camera.running && settings.proximityAsShutter && root.inCaptureMode && !mainView.moving
323         onCloseChanged: {
324             if (!close) {
325                 sensorClosed = false
326             }
327         }
328     }
329
330     Standby {
331         policyLost: pipelineManager.state == "policyLost"
332         show: !Qt.application.active || pipelineManager.showStandBy ||
333             (inCaptureMode && !viewfinder.camera.running)
334     }
335 }