93bb5160667758ff55fd43033011b2d39590a6c8
[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: rotate post capture image
29 // TODO: hide items for CameraToolBar
30 // TODO: front camera
31
32 CameraPage {
33     id: root
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         // TODO: hardcoding device id
77         root.resetCamera(0, settings.mode)
78     }
79
80     PlatformSettings {
81         id: platformSettings
82     }
83
84     Settings {
85         id: settings
86     }
87
88     PipelineManager {
89         id: pipelineManager
90         camera: viewfinder.camera
91         currentItem: mainView.currentItem
92     }
93
94     function resetCamera(deviceId, mode) {
95         if (!viewfinder.camera.reset(deviceId, mode)) {
96             showError(qsTr("Failed to set camera device and mode. Please restart the application."))
97         }
98     }
99
100     function showError(msg) {
101         error.text = msg
102         error.show()
103     }
104
105     property alias dimmer: camDimmer
106     CameraPositionSource {
107         id: positionSource
108         active: settings.useGps
109         // TODO: we cannot bind to cam.running because camera will stop
110         // when the connection dialog pops up and we end up with an infinite loop
111         // active: cam.running && settings.useGps
112         onPositionChanged: geocode.search(position.coordinate.longitude, position.coordinate.latitude)
113     }
114
115     MetaData {
116         id: metaData
117         camera: viewfinder.camera
118         manufacturer: deviceInfo.manufacturer
119         model: deviceInfo.model
120         country: geocode.country
121         city: geocode.city
122         suburb: geocode.suburb
123         longitude: positionSource.longitude
124         longitudeValid: positionSource.longitudeValid && settings.useGps
125         latitude: positionSource.latitude
126         latitudeValid: positionSource.latitudeValid && settings.useGps
127         elevation: positionSource.altitude
128         elevationValid: positionSource.altitudeValid && settings.useGps
129         orientation: orientation.orientation
130         artist: settings.creatorName
131         captureDirection: compass.direction
132         captureDirectionValid: compass.directionValid
133         horizontalError: positionSource.horizontalAccuracy
134         horizontalErrorValid: positionSource.horizontalAccuracyValid && settings.useGps
135         dateTimeEnabled: true
136     }
137
138     CameraOrientation {
139         id: orientation
140         active: viewfinder.camera.running || (mainView.currentIndex == 2 && Qt.application.active)
141     }
142
143     CameraCompass {
144         id: compass
145         active: viewfinder.camera.running
146     }
147
148     ReverseGeocode {
149         id: geocode
150         active: viewfinder.camera.running && settings.useGps && settings.useGeotags
151     }
152
153     DeviceInfo {
154         id: deviceInfo
155     }
156
157     FSMonitor {
158         id: fileSystem
159     }
160
161     CameraInfoBanner {
162         id: error
163     }
164
165     FileNaming {
166         id: fileNaming
167         imageSuffix: viewfinder.camera.imageSuffix
168         videoSuffix: viewfinder.camera.videoSuffix
169     }
170
171     MountProtector {
172         id: mountProtector
173         path: fileNaming.path
174     }
175
176     TrackerStore {
177         id: trackerStore
178         active: viewfinder.camera.running
179         manufacturer: deviceInfo.manufacturer
180         model: deviceInfo.model
181     }
182
183     function checkDiskSpace() {
184         return fileSystem.hasFreeSpace(fileNaming.path)
185     }
186
187     ImageSettings {
188         id: imageSettings
189         camera: viewfinder.camera
190
191         function setImageResolution() {
192             if (!imageSettings.setResolution(settings.imageAspectRatio, settings.imageResolution)) {
193                 showError(qsTr("Failed to set required resolution"))
194             }
195         }
196
197         onReadyChanged: {
198             if (ready) {
199                 imageSettings.setImageResolution()
200             }
201         }
202     }
203
204     VideoSettings {
205         id: videoSettings
206         camera: viewfinder.camera
207
208         function setVideoResolution() {
209             if (!videoSettings.setResolution(settings.videoAspectRatio, settings.videoResolution)) {
210                 showError(qsTr("Failed to set required resolution"))
211             }
212         }
213
214         onReadyChanged: {
215             if (ready) {
216                 videoSettings.setVideoResolution()
217             }
218         }
219     }
220
221     Connections {
222         target: settings
223
224         onImageAspectRatioChanged: {
225             imageSettings.setImageResolution()
226         }
227
228         onImageResolutionChanged: {
229             imageSettings.setImageResolution()
230         }
231
232         onVideoResolutionChanged: {
233             videoSettings.setVideoResolution()
234         }
235     }
236
237     ModeController {
238         id: cameraMode
239         cam: viewfinder.camera
240         dimmer: root.dimmer
241     }
242
243     Rectangle {
244         property bool dimmed: false
245         id: camDimmer
246         z: 1
247         anchors.fill: parent
248         opacity: dimmed ? 1.0 : 0.0
249         color: "black"
250         Behavior on opacity {
251             PropertyAnimation { duration: 150 }
252         }
253     }
254
255     DeviceKeys {
256         id: keys
257         active: Qt.application.active && pipelineManager.scaleAcquired
258         repeat: !settings.zoomAsShutter
259     }
260
261     Standby {
262         policyLost: pipelineManager.state == "policyLost"
263         show: !Qt.application.active || pipelineManager.showStandBy ||
264             (mainView.currentIndex == 1 && !viewfinder.camera.running)
265     }
266 }