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