Don't anchor the tool bar menu button.
[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     property bool inCaptureMode: mainView.currentIndex == 1
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         onImageAspectRatioChanged: {
102             if (!root.deviceChangeInProgress) {
103                 imageSettings.setImageResolution()
104             }
105         }
106
107         onImageResolutionChanged: {
108             if (!root.deviceChangeInProgress) {
109                 imageSettings.setImageResolution()
110             }
111         }
112
113         onVideoResolutionChanged: {
114             if (!root.deviceChangeInProgress) {
115                 videoSettings.setVideoResolution()
116             }
117         }
118
119         onVideoAspectRatioChanged: {
120             if (!root.deviceChangeInProgress) {
121                 videoSettings.setVideoResolution()
122             }
123         }
124     }
125
126     PipelineManager {
127         id: pipelineManager
128         camera: viewfinder.camera
129         currentItem: mainView.currentItem
130     }
131
132     function resetCamera(deviceId, mode) {
133         if (!viewfinder.camera.reset(deviceId, mode)) {
134             showError(qsTr("Failed to set camera device and mode. Please restart the application."))
135             return false
136         }
137
138         if (mode == Camera.ImageMode) {
139             imageSettings.setImageResolution()
140         }
141         else if (mode == Camera.VideoMode) {
142             videoSettings.setVideoResolution()
143         }
144
145         return true
146     }
147
148     function showError(msg) {
149         error.text = msg
150         error.show()
151     }
152
153     property alias dimmer: camDimmer
154
155     PlatformQuirks {
156         id: platformQuirks
157     }
158
159     DisplayState {
160         id: displayState
161         inhibitDim: mainView.currentItem != null ? mainView.currentItem.inhibitDim : false
162     }
163
164     CameraPositionSource {
165         id: positionSource
166         active: (viewfinder.camera.running || platformQuirks.forceOn) && settings.useGps && displayState.isOn
167         onPositionChanged: geocode.search(position.coordinate.longitude, position.coordinate.latitude)
168     }
169
170     MetaData {
171         id: metaData
172         camera: viewfinder.camera
173         manufacturer: deviceInfo.manufacturer
174         model: deviceInfo.model
175         country: geocode.country
176         city: geocode.city
177         suburb: geocode.suburb
178         longitude: positionSource.longitude
179         longitudeValid: positionSource.longitudeValid && settings.useGps
180         latitude: positionSource.latitude
181         latitudeValid: positionSource.latitudeValid && settings.useGps
182         elevation: positionSource.altitude
183         elevationValid: positionSource.altitudeValid && settings.useGps
184         orientation: orientation.orientation
185         artist: settings.creatorName
186         captureDirection: compass.direction
187         captureDirectionValid: compass.directionValid
188         horizontalError: positionSource.horizontalAccuracy
189         horizontalErrorValid: positionSource.horizontalAccuracyValid && settings.useGps
190         dateTimeEnabled: true
191     }
192
193     CameraOrientation {
194         id: orientation
195         active: viewfinder.camera.running || (mainView.currentIndex == 2 && Qt.application.active)
196     }
197
198     CameraCompass {
199         id: compass
200         active: viewfinder.camera.running
201     }
202
203     ReverseGeocode {
204         id: geocode
205         active: (viewfinder.camera.running || platformQuirks.forceOn) && settings.useGps && settings.useGeotags && displayState.isOn
206     }
207
208     DeviceInfo {
209         id: deviceInfo
210     }
211
212     FSMonitor {
213         id: fileSystem
214     }
215
216     CameraInfoBanner {
217         id: error
218     }
219
220     FileNaming {
221         id: fileNaming
222         imageSuffix: viewfinder.camera.imageSuffix
223         videoSuffix: viewfinder.camera.videoSuffix
224         imagePath: platformSettings.imagePath
225         videoPath: platformSettings.videoPath
226         temporaryVideoPath: platformSettings.temporaryVideoPath
227         settings: settings
228     }
229
230     MountProtector {
231         id: mountProtector
232     }
233
234     TrackerStore {
235         id: trackerStore
236         active: viewfinder.camera.running
237         manufacturer: deviceInfo.manufacturer
238         model: deviceInfo.model
239     }
240
241     ImageSettings {
242         id: imageSettings
243         camera: viewfinder.camera
244
245         function setImageResolution() {
246             if (!imageSettings.setResolution(settings.imageAspectRatio, settings.imageResolution)) {
247                 showError(qsTr("Failed to set required resolution"))
248             }
249         }
250     }
251
252     VideoSettings {
253         id: videoSettings
254         camera: viewfinder.camera
255
256         function setVideoResolution() {
257             if (!videoSettings.setResolution(settings.videoAspectRatio, settings.videoResolution)) {
258                 showError(qsTr("Failed to set required resolution"))
259             }
260         }
261     }
262
263     ModeController {
264         id: cameraMode
265         cam: viewfinder.camera
266         dimmer: root.dimmer
267     }
268
269     Rectangle {
270         property bool dimmed: false
271         id: camDimmer
272         z: 1
273         anchors.fill: parent
274         opacity: dimmed ? 1.0 : 0.0
275         color: "black"
276         Behavior on opacity {
277             PropertyAnimation { duration: 150 }
278         }
279     }
280
281     DeviceKeys {
282         id: keys
283         active: Qt.application.active && pipelineManager.scaleAcquired && root.inCaptureMode && !mainView.moving
284         repeat: !settings.zoomAsShutter
285     }
286
287     Timer {
288         id: proximityTimer
289         running: proximitySensor.close
290         repeat: false
291         interval: 500
292         onTriggered: {
293             if (proximitySensor.close) {
294                 proximitySensor.sensorClosed = true
295             }
296         }
297     }
298
299     CameraProximitySensor {
300         id: proximitySensor
301         property bool sensorClosed: false
302
303         active: Qt.application.active && viewfinder.camera.running && settings.proximityAsShutter && root.inCaptureMode && !mainView.moving
304         onCloseChanged: {
305             if (!close) {
306                 sensorClosed = false
307             }
308         }
309     }
310
311     Standby {
312         policyLost: pipelineManager.state == "policyLost"
313         show: !Qt.application.active || pipelineManager.showStandBy ||
314             (inCaptureMode && !viewfinder.camera.running)
315     }
316 }