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