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