Try to revent accidental capture via proximity sensor.
[harmattan/cameraplus] / qml / ImageOverlay.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 Item {
28     id: overlay
29
30     property Camera cam
31     property bool animationRunning: false
32     property int policyMode: CameraResources.Image
33     property bool pressed: capture.pressed || zoomSlider.pressed || modeButton.pressed
34     property bool controlsVisible: imageMode.canCapture && cam.running && !animationRunning
35         && dimmer.opacity == 0.0 && !cameraMode.busy
36     property bool inhibitDim: false
37
38     signal previewAvailable(string uri)
39
40     anchors.fill: parent
41
42     ImageMode {
43         id: imageMode
44         camera: cam
45
46         onCaptureEnded: stopAutoFocus()
47
48         onPreviewAvailable: overlay.previewAvailable(preview)
49
50         onSaved: mountProtector.unlock(fileNaming.imagePath)
51     }
52
53     ZoomSlider {
54         id: zoomSlider
55         camera: cam
56         anchors.top: parent.top
57         anchors.topMargin: 0
58         anchors.horizontalCenter: parent.horizontalCenter
59         visible: controlsVisible
60     }
61
62     ModeButton {
63         id: modeButton
64         anchors.bottom: parent.bottom
65         anchors.right: parent.right
66         anchors.rightMargin: 20
67         anchors.bottomMargin: 20
68         visible: controlsVisible
69     }
70
71     CaptureButton {
72         id: capture
73         anchors.right: parent.right
74         anchors.rightMargin: 20
75         anchors.verticalCenter: parent.verticalCenter
76         iconSource: cameraTheme.captureButtonImageIconId
77         width: 75
78         height: 75
79         opacity: 0.5
80         visible: controlsVisible
81
82         onExited: {
83             if (mouseX <= 0 || mouseY <= 0 || mouseX > width || mouseY > height) {
84                 // Release outside the button:
85                 captureControl.canceled = true
86             }
87         }
88     }
89
90     Timer {
91         id: autoFocusTimer
92         interval: 200
93         running: captureControl.state == "capturing"
94         repeat: false
95         onTriggered: {
96             if (cam.autoFocus.cafStatus != AutoFocus.Success) {
97                 startAutoFocus()
98             }
99         }
100     }
101
102     ZoomCaptureButton {
103         id: zoomCapture
104     }
105
106     CaptureControl {
107         id: captureControl
108         capturePressed: capture.pressed
109         zoomPressed: zoomCapture.zoomPressed
110         proximityClosed: proximitySensor.sensorClosed
111         onStartCapture: captureImage()
112         onCancelCapture: stopAutoFocus()
113     }
114
115     CaptureCancel {
116         anchors.fill: parent
117         enabled: captureControl.showCancelBanner
118         onPressed:  captureControl.canceled = true
119     }
120
121     CameraToolBar {
122         id: toolBar
123         anchors.bottom: parent.bottom
124         anchors.bottomMargin: 20
125         anchors.left: parent.left
126         anchors.leftMargin: 20
127         opacity: 0.5
128         targetWidth: parent.width - (anchors.leftMargin * 2) - (66 * 1.5)
129         visible: controlsVisible
130         expanded: settings.showToolBar
131         onExpandedChanged: settings.showToolBar = expanded
132         tools: CameraToolBarTools {
133             FlashButton {
134                 onClicked: toolBar.push(tools)
135                 visible: !overlay.cam.quirks.hasQuirk(Quirks.NoFlash)
136             }
137
138             ImageSceneButton {
139                 onClicked: toolBar.push(tools)
140             }
141
142             ImageEvCompButton {
143                 onClicked: toolBar.push(tools)
144             }
145
146             ImageWhiteBalanceButton {
147                 onClicked: toolBar.push(tools)
148             }
149
150             ImageColorFilterButton {
151                 onClicked: toolBar.push(tools)
152             }
153
154             ImageIsoButton {
155                 onClicked: toolBar.push(tools)
156             }
157         }
158     }
159
160     Rectangle {
161         id: indicators
162         anchors.top: parent.top
163         anchors.topMargin: 20
164         anchors.left: parent.left
165         anchors.leftMargin: 20
166         width: 48
167         height: col.height
168         color: "black"
169         border.color: "gray"
170         radius: 20
171         opacity: 0.5
172         visible: controlsVisible
173
174         Column {
175             id: col
176             width: parent.width
177             spacing: 5
178
179             Indicator {
180                 id: flashIndicator
181                 visible: !toolBar.expanded && !overlay.cam.quirks.hasQuirk(Quirks.NoFlash)
182                 source: cameraTheme.flashIcon(settings.imageFlashMode)
183             }
184
185             CameraLabel {
186                 anchors.left: parent.left
187                 anchors.right: parent.right
188                 anchors.leftMargin: 5
189                 anchors.rightMargin: 5
190                 anchors.topMargin: 5
191                 anchors.bottomMargin: 5
192                 text: imageSettings.currentResolution ? qsTr("%1M").arg(imageSettings.currentResolution.megaPixels) : qsTr("?M")
193                 font.bold: true
194                 verticalAlignment: Text.AlignVCenter
195                 horizontalAlignment: Text.AlignHCenter
196             }
197
198             Indicator {
199                 id: wbIndicator
200                 source: visible ? cameraTheme.whiteBalanceIcon(settings.imageWhiteBalance) : ""
201                 visible: settings.imageWhiteBalance != WhiteBalance.Auto && !toolBar.expanded
202             }
203
204             Indicator {
205                 id: cfIndicator
206                 source: visible ? cameraTheme.colorFilterIcon(settings.imageColorFilter) : ""
207                 visible: settings.imageColorFilter != ColorTone.Normal && !toolBar.expanded
208             }
209
210             Indicator {
211                 id: isoIndicator
212                 visible: settings.imageIso != 0 && !toolBar.expanded
213                 source: visible ? cameraTheme.isoIcon(settings.imageIso) : ""
214             }
215
216             Indicator {
217                 id: sceneIndicator
218                 visible: settings.imageSceneMode != Scene.Auto && !toolBar.expanded
219                 source: visible ? cameraTheme.imageSceneModeIcon(settings.imageSceneMode) : ""
220             }
221
222             Indicator {
223                 id: gpsIndicator
224                 visible: settings.useGps
225                 source: cameraTheme.gpsIndicatorIcon
226
227                 PropertyAnimation on opacity  {
228                     easing.type: Easing.OutSine
229                     loops: Animation.Infinite
230                     from: 0.2
231                     to: 1.0
232                     duration: 1000
233                     running: settings.useGps && !positionSource.position.longitudeValid
234                     alwaysRunToEnd: true
235                 }
236             }
237
238             Indicator {
239                 id: faceDetectionIndicator
240                 visible: settings.faceDetectionEnabled
241                 source: cameraTheme.faceDetectionIndicatorIcon
242             }
243
244         }
245     }
246
247     function cameraError() {
248         mountProtector.unlock(fileNaming.imagePath)
249     }
250
251     function policyLost() {
252         // Nothing
253     }
254
255     function batteryLow() {
256         // Nothing
257     }
258
259     function captureImage() {
260         if (!imageMode.canCapture) {
261             showError(qsTr("Camera is already capturing an image."))
262             stopAutoFocus()
263         } else if (!checkBattery()) {
264             showError(qsTr("Not enough battery to capture images."))
265             stopAutoFocus()
266         } else if (!fileSystem.available) {
267             showError(qsTr("Camera cannot capture images in mass storage mode."))
268             stopAutoFocus()
269         } else if (!fileSystem.hasFreeSpace(fileNaming.imagePath)) {
270             showError(qsTr("Not enough space to capture images."))
271             stopAutoFocus()
272         } else if (!mountProtector.lock(fileNaming.imagePath)) {
273             showError(qsTr("Failed to lock images directory."))
274             stopAutoFocus()
275         } else {
276             metaData.setMetaData()
277
278             var fileName = fileNaming.imageFileName()
279             if (!imageMode.capture(fileName)) {
280                 showError(qsTr("Failed to capture image. Please restart the camera."))
281                 mountProtector.unlock(fileNaming.imagePath)
282                 stopAutoFocus()
283             } else {
284                 trackerStore.storeImage(fileName)
285             }
286         }
287     }
288
289     function startAutoFocus() {
290         if (!overlay.cam.quirks.hasQuirk(Quirks.NoAutoFocus)) {
291             cam.autoFocus.startAutoFocus()
292         }
293     }
294
295     function stopAutoFocus() {
296         if (!overlay.cam.quirks.hasQuirk(Quirks.NoAutoFocus)) {
297             if (!autoFocusTimer.running) {
298                 cam.autoFocus.stopAutoFocus()
299             }
300         }
301     }
302
303     function resetToolBar() {
304         if (toolBar.depth() > 1) {
305             toolBar.pop()
306         }
307     }
308
309     function cameraDeviceChanged() {
310         resetToolBar()
311     }
312 }