Updated copyright year
[harmattan/cameraplus] / qml / main.qml
index fb484fb..c34841d 100644 (file)
@@ -3,7 +3,7 @@
 /*!
  * This file is part of CameraPlus.
  *
- * Copyright (C) 2012 Mohammed Sameer <msameer@foolab.org>
+ * Copyright (C) 2012-2013 Mohammed Sameer <msameer@foolab.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -25,20 +25,9 @@ import com.nokia.meego 1.1
 import com.nokia.extras 1.1
 import QtCamera 1.0
 import CameraPlus 1.0
-import QtMobility.systeminfo 1.2
 import QtMobility.location 1.2
 
-// TODO: postcapture
-// TODO: flash not ready
-// TODO: focus, caf, ...
-// TODO: portrait/landscape
-// TODO: stop viewfinder in settings pages ?
-// TODO: grid lines, face tracking, ambr
-// TODO: complete settings pages
-// TODO: select primary/secondary camera.
-// TODO: disable debug builds.
-// TODO: a way to get buffers to the application
-// TODO: fcam like functionality (precise control over capture parameters).
+// TODO: flash not ready (battery low or flash not ready message)
 
 PageStackWindow {
         id: root
@@ -114,8 +103,9 @@ PageStackWindow {
                 active: cam.running && settings.useGps && settings.useGeotags
         }
 
-        CameraResources {
-                id: resourcePolicy
+        PipelineManager {
+                id: pipelineManager
+                camera: cam
         }
 
         DeviceInfo {
@@ -145,17 +135,55 @@ PageStackWindow {
                 path: fileNaming.path
         }
 
+        BatteryInfo {
+                id: batteryMonitor
+                active: cam.running
+
+                function check() {
+                        if (!checkBattery()) {
+                                pageStack.currentPage.batteryLow();
+                        }
+                }
+
+                onChargingChanged: {
+                        batteryMonitor.check();
+                }
+
+                onCriticalChanged: {
+                        batteryMonitor.check();
+                }
+        }
+
         function replacePage(file) {
-                pageStack.replace(Qt.resolvedUrl(file), {cam: cam}, true);
+                pageStack.replace(Qt.resolvedUrl(file), {cam: cam, dimmer: root.dimmer}, true);
         }
 
         function openFile(file) {
-                pageStack.push(Qt.resolvedUrl(file), {cam: cam});
+                pageStack.push(Qt.resolvedUrl(file), {cam: cam, dimmer: root.dimmer});
+        }
+
+        function openFileNow(file) {
+                pageStack.push(Qt.resolvedUrl(file), {cam: cam, dimmer: root.dimmer}, true);
+        }
+
+        function checkBattery() {
+                // We are fine if we are connected to the charger:
+                if (batteryMonitor.charging) {
+                        return true;
+                }
+
+                // If we have enough battery then we are fine:
+                if (!batteryMonitor.critical) {
+                        return true;
+                }
+
+                return false;
         }
 
         platformStyle: PageStackWindowStyle {
-                // TODO: Hack
-                background: " "
+                cornersVisible: false
+                background: ""
+                backgroundColor: "transparent"
         }
 
         ImageSettings {
@@ -208,23 +236,43 @@ PageStackWindow {
         }
 
         Camera {
-/*
-                onDeviceIdChanged: {
-                        // TODO: is this needed ?
-                        if (platformWindow.active) {
-                                cam.start();
-                        }
-                }
-*/
                 id: cam
                 anchors.fill: parent
 
+                onRoiChanged: roi.normalize = false;
+
+                GridLines {
+                        x: cam.renderArea.x
+                        y: cam.renderArea.y
+                        width: cam.renderArea.width
+                        height: cam.renderArea.height
+                        visible: settings.gridEnabled
+                }
+
+                FocusReticle {
+                        id: focusReticle
+                        cam: cam
+                        visible: pageStack.currentPage && pageStack.currentPage.controlsVisible && pageStack.currentPage.focusReticleVisible && cam && cam.autoFocus.canFocus(cam.scene.value);
+                        cafStatus: cam ? cam.autoFocus.cafStatus : -1
+                        status: cam ? cam.autoFocus.status : -1
+                }
+
                 onError: {
+                        if (pipelineManager.error) {
+                                // Ignore any subsequent errors.
+                                // Killing pulseaudio while recording will lead to an
+                                // infinite supply of errors which will break the UI
+                                // if we show a banner for each.
+                                return;
+                        }
+
+                        pipelineManager.error = true;
+                        pageStack.currentPage.cameraError();
                         console.log("Camera error (" + code + "): " + message + " " + debug);
                         showError(qsTr("Camera error. Please restart the application."));
-                        cam.stop();
-                        resourcePolicy.acquire(CameraResources.None);
-                        mountProtector.unlock();
+
+                        // We cannot stop camera here. Seems there is a race condition somewhere
+                        // which leads to a freeze if we do so.
                 }
 
                 onRunningChanged: {
@@ -235,15 +283,19 @@ PageStackWindow {
 
                 Component.onDestruction: cam.stop();
 
-                // TODO: Hack
+                // We need to show viewfinder below pages.
                 z: -1
 
                 Rectangle {
+                        property bool dimmed: false
                         id: camDimmer
                         z: 1
                         anchors.fill: parent
-                        opacity: 0
+                        opacity: dimmed ? 1.0 : 0.0
                         color: "black"
+                        Behavior on opacity {
+                                PropertyAnimation { duration: 150 }
+                        }
                 }
 
                 notifications: Sounds {
@@ -351,6 +403,26 @@ PageStackWindow {
                 value: cam.iso.value
         }
 
+        Binding {
+                target: cam.videoMute
+                property: "enabled"
+                value: settings.videoMuted
+        }
+
+        Binding {
+                target: cam.roi
+                property: "enabled"
+                value: settings.faceDetectionEnabled && !focusReticle.pressed && !focusReticle.touchMode && cam.mode == Camera.ImageMode
+        }
+
+
+        TrackerStore {
+                id: trackerStore
+                active: cam.running
+                manufacturer: deviceInfo.manufacturer
+                model: deviceInfo.model
+        }
+
         ModeController {
                 id: cameraMode
                 cam: cam
@@ -368,4 +440,14 @@ PageStackWindow {
                         }
                 }
         }
+
+        Standby {
+                policyLost: pipelineManager.state == "policyLost"
+                show: !pageStack.currentPage || (pageStack.currentPage.standbyVisible && pageStack.currentPage.status == PageStatus.Active && pipelineManager.showStandBy)
+        }
+
+        DeviceKeys {
+                id: keys
+                active: Qt.application.active && pipelineManager.scaleAcquired
+        }
 }