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