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