a41d838994210af2a4a84a9b7665726bf2694f43
[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 && (!settings.zoomAsShutter && keys.active)
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     ZoomCaptureCancel {
108         anchors.fill: parent
109         zoomCapture: zoomCapture
110         onCanceled: {
111             if (!autoFocusTimer.running) {
112                 stopAutoFocus()
113             }
114         }
115     }
116
117     CameraToolBar {
118         id: toolBar
119         anchors.bottom: parent.bottom
120         anchors.bottomMargin: 20
121         anchors.left: parent.left
122         anchors.leftMargin: 20
123         opacity: 0.5
124         targetWidth: parent.width - (anchors.leftMargin * 2) - (66 * 1.5)
125         visible: controlsVisible
126         expanded: settings.showToolBar
127         onExpandedChanged: settings.showToolBar = expanded
128         tools: CameraToolBarTools {
129             FlashButton {
130                 onClicked: toolBar.push(tools)
131                 visible: cam.device == 0
132             }
133
134             ImageSceneButton {
135                 onClicked: toolBar.push(tools)
136             }
137
138             ImageEvCompButton {
139                 onClicked: toolBar.push(tools)
140             }
141
142             ImageWhiteBalanceButton {
143                 onClicked: toolBar.push(tools)
144             }
145
146             ImageColorFilterButton {
147                 onClicked: toolBar.push(tools)
148             }
149
150             ImageIsoButton {
151                 onClicked: toolBar.push(tools)
152             }
153         }
154     }
155
156     Rectangle {
157         id: indicators
158         anchors.top: parent.top
159         anchors.topMargin: 20
160         anchors.left: parent.left
161         anchors.leftMargin: 20
162         width: 48
163         height: col.height
164         color: "black"
165         border.color: "gray"
166         radius: 20
167         opacity: 0.5
168         visible: controlsVisible
169
170         Column {
171             id: col
172             width: parent.width
173             spacing: 5
174
175             Indicator {
176                 id: flashIndicator
177                 visible: !toolBar.expanded && cam.device == 0
178                 source: cameraTheme.flashIcon(settings.imageFlashMode)
179             }
180
181             CameraLabel {
182                 anchors.left: parent.left
183                 anchors.right: parent.right
184                 anchors.leftMargin: 5
185                 anchors.rightMargin: 5
186                 anchors.topMargin: 5
187                 anchors.bottomMargin: 5
188                 property string mp: imageSettings.currentResolutionMegapixel == "" ? "?" : imageSettings.currentResolutionMegapixel
189                 text: qsTr("%1M").arg(mp)
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 (cam.device == 0) {
288             cam.autoFocus.startAutoFocus()
289         }
290     }
291
292     function stopAutoFocus() {
293         if (cam.device == 0) {
294             cam.autoFocus.stopAutoFocus()
295         }
296     }
297
298 }