Initial ui reimplementation. Still in its early phase.
[harmattan/cameraplus] / qml / main.qml
index 7b836eb..6693eb5 100644 (file)
 // -*- qml -*-
+
+/*!
+ * This file is part of CameraPlus.
+ *
+ * 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
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
 import QtQuick 1.1
 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
-
-// TODO: metadata creator name, gps, geotags
-// TODO: resolutions and aspect ratios
-// TODO: postcapture
-// TODO: battery low state
-// TODO: disk space
-// TODO: flash not ready
-// TODO: focus, caf, ...
-// TODO: indicators
-// TODO: portrait/landscape
-// TODO: record video in a hidden directory and then copy the video to avoid tracker indexing it.
-// TODO: stop viewfinder in postcapture and settings pages ?
-// TODO: resource policy
-// TODO: prevent going to mass storage while recording and capturing
-// TODO: sounds
-// TODO: grid lines, face tracking
-// TODO: complete settings pages
-// TODO: stop camera properly when we get closed.
-// TODO: select primary/secondary camera.
-// TODO: disable debug builds.
-// TODO: seems start gets called when we are shutting down
-// TODO: seems start gets called twice when we are starting up if screen is locked or dimmed ?!
-
-PageStackWindow {
+import QtMobility.location 1.2
+//import QtCamera 1.0
+// TODO: flash not ready (battery low or flash not ready message)
+
+Window {
         id: root
+        property alias camera: cam
+//        property bool cameraVisible: mainView.currentIndex == 1
 
-        property alias dimmer: camDimmer
+        VisualItemModel {
+            id: mainModel
 
-        showStatusBar: false
+            SettingsView {
+                width: mainView.width
+                height: mainView.height
+            }
+
+            CameraView {
+                id: cam
+                width: mainView.width
+                height: mainView.height
+            }
+
+            PostCaptureView {
+                width: mainView.width
+                height: mainView.height
+            }
+        }
+
+        ListView {
+            id: mainView
+            LayoutMirroring.enabled: false
+            anchors.fill: parent
+            orientation: ListView.Horizontal
+            model: mainModel
+            snapMode: ListView.SnapOneItem
+            highlightRangeMode: ListView.StrictlyEnforceRange
+            boundsBehavior: Flickable.StopAtBounds
+            currentIndex: 1
+            interactive: !currentItem.pressed
+        }
 
         Component.onCompleted: {
-                theme.inverted = true;
-                if (settings.mode == 0) {
-                        openFile("ImagePage.qml");
-                }
-                else {
-                        openFile("VideoPage.qml");
-                }
+            screen.setAllowedOrientations(Screen.Landscape)
+            theme.inverted = true
+            platformSettings.init()        
+            // TODO: hardcoding device id
+            root.resetCamera(0, settings.mode)
+        }
+
+        PlatformSettings {
+            id: platformSettings
+        }
+
+        Settings {
+            id: settings
+        }
+
+        PipelineManager {
+            id: pipelineManager
+            camera: cam
+            currentItem: mainView.currentItem
+        }
+
+        function resetCamera(deviceId, mode) {
+            if (!cam.reset(deviceId, mode)) {
+                showError(qsTr("Failed to set camera device and mode. Please restart the application."))
+            }
         }
 
         function showError(msg) {
-                error.text = msg;
-                error.show();
-        }
-
-        CameraResources {
-                id: resourcePolicy
-                onAcquiredChanged: {
-                        if (resourcePolicy.acquired) {
-                                // TODO:
-                        }
-                        else {
-                                // TODO: We need a way to force a stop.
-                        }
-                }
+            error.text = msg
+            error.show()
+        }
+
+        property alias dimmer: camDimmer
+
+        PageStack {
+            id: pageStack
+            anchors.fill: parent
+        }
+
+        MouseArea {
+            anchors.fill: parent
+            enabled: pageStack.busy
+        }
+
+        PositionSource {
+            // NOTE: The source will not reset the position when we lose the signal.
+            // This shouldn't be a big problem as we are course enough.
+            // If we ever need street level updates then this will be an issue.
+            id: positionSource
+            active: settings.useGps
+            // TODO: we cannot bind to cam.running because camera will stop
+            // when the connection dialog pops up and we end up with an infinite loop
+            // active: cam.running && settings.useGps
+            onPositionChanged: geocode.search(position.coordinate.longitude, position.coordinate.latitude)
+        }
+
+        MetaData {
+            id: metaData
+            camera: cam
+            manufacturer: deviceInfo.manufacturer
+            model: deviceInfo.model
+            country: geocode.country
+            city: geocode.city
+            suburb: geocode.suburb
+            longitude: positionSource.position.coordinate.longitude
+            longitudeValid: positionSource.position.longitudeValid && settings.useGps
+            latitude: positionSource.position.coordinate.latitude
+            latitudeValid: positionSource.position.latitudeValid && settings.useGps
+            elevation: positionSource.position.coordinate.altitude
+            elevationValid: positionSource.position.altitudeValid && settings.useGps
+            orientation: orientation.orientation
+            artist: settings.creatorName
+            captureDirection: compass.direction
+            captureDirectionValid: compass.directionValid
+            horizontalError: positionSource.position.horizontalAccuracy
+            horizontalErrorValid: positionSource.position.horizontalAccuracyValid && settings.useGps
+            dateTimeEnabled: true
+        }
+
+        Orientation {
+            id: orientation
+            active: cam.running
+        }
+
+        Compass {
+            id: compass
+            active: cam.running
+        }
+
+        ReverseGeocode {
+            id: geocode
+            active: cam.running && settings.useGps && settings.useGeotags
         }
 
         DeviceInfo {
-                id: deviceInfo
+            id: deviceInfo
         }
 
         FSMonitor {
-                id: fileSystem
+            id: fileSystem
         }
 
         InfoBanner {
-                id: error
-        }
-
-        Settings {
-                id: settings
+            id: error
         }
 
         FileNaming {
-                id: fileNaming
-                imageSuffix: cam.imageSuffix
-                videoSuffix: cam.videoSuffix
+            id: fileNaming
+            imageSuffix: cam.imageSuffix
+            videoSuffix: cam.videoSuffix
         }
 
-        // Stolen from https://qt.gitorious.org/qt-components/qt-components/blobs/master/examples/meego/QmlComponentGallery/qml/ListPage.qml
-        function replacePage(file) {
-                var component = Qt.createComponent(file)
+        MountProtector {
+            id: mountProtector
+            path: fileNaming.path
+        }
 
-                if (component.status == Component.Ready) {
-                        pageStack.replace(component, {cam: cam}, true);
-                }
-                else {
-                        console.log("Error loading component:", component.errorString());
-                }
+        TrackerStore {
+            id: trackerStore
+            active: cam.running
+            manufacturer: deviceInfo.manufacturer
+            model: deviceInfo.model
         }
 
-        function openFile(file) {
-                var component = Qt.createComponent(file)
+        function checkDiskSpace() {
+            return fileSystem.hasFreeSpace(fileNaming.path)
+        }
 
-                if (component.status == Component.Ready) {
-                        pageStack.push(component, {cam: cam});
+        ImageSettings {
+            id: imageSettings
+            camera: cam
+            function setImageResolution() {
+                if (!imageSettings.setResolution(settings.imageAspectRatio, settings.imageResolution)) {
+                    showError(qsTr("Failed to set required resolution"))
                 }
-                else {
-                        console.log("Error loading component:", component.errorString());
+            }
+
+            onReadyChanged: {
+                if (ready) {
+                    imageSettings.setImageResolution()
                 }
+            }
         }
 
-        platformStyle: PageStackWindowStyle {
-                // TODO: Hack
-                background: " "
-        }
+        VideoSettings {
+            id: videoSettings
+            camera: cam
 
-        Camera {
-/*
-                onDeviceIdChanged: {
-                        // TODO: is this needed ?
-                        if (platformWindow.active) {
-                                cam.start();
-                        }
+            function setVideoResolution() {
+                if (!videoSettings.setResolution(settings.videoAspectRatio, settings.videoResolution)) {
+                    showError(qsTr("Failed to set required resolution"))
                 }
-*/
-                id: cam
-                anchors.fill: parent
-
-                // TODO: hardcoding device id
-                Component.onCompleted: { cam.deviceId = 0; mode = settings.mode; }
+            }
 
-                // TODO: Hack
-                z: -1
-
-                Rectangle {
-                        id: camDimmer
-                        z: 1
-                        anchors.fill: parent
-                        opacity: 0
-                        color: "black"
+            onReadyChanged: {
+                if (ready) {
+                    videoSettings.setVideoResolution()
                 }
+            }
         }
 
-        Scene {
-                id: sceneController
-                camera: cam
-                value: ready ? camera.mode == Camera.VideoMode ? settings.videoSceneMode : settings.imageSceneMode : 0
-        }
+        Connections {
+            target: settings
 
-        ColorTone {
-                id: colorToneController
-                camera: cam
-                value: ready ? camera.mode == Camera.VideoMode ? settings.videoColorFilter : settings.imageColorFilter : 0
-        }
+            onImageAspectRatioChanged: {
+                imageSettings.setImageResolution()
+            }
+
+            onImageResolutionChanged: {
+                imageSettings.setImageResolution()
+            }
 
-        WhiteBalance {
-                id: whiteBalanceController
-                camera: cam
-                value: ready ? camera.mode == Camera.VideoMode ? settings.videoWhiteBalance : settings.imageWhiteBalance : 0
+            onVideoResolutionChanged: {
+                videoSettings.setVideoResolution()
+            }
         }
 
         ModeController {
-                id: cameraMode
-                cam: cam
-                dimmer: root.dimmer
+            id: cameraMode
+            cam: cam
+            dimmer: root.dimmer
         }
 
-        Connections {
-                target: cam
-                onModeChanged: {
-                        if (cam.mode == Camera.VideoMode) {
-                                replacePage("VideoPage.qml");
-                        }
-                        else {
-                                replacePage("ImagePage.qml");
-                        }
-                }
+        Rectangle {
+            property bool dimmed: false
+            id: camDimmer
+            z: 1
+            anchors.fill: parent
+            opacity: dimmed ? 1.0 : 0.0
+            color: "black"
+            Behavior on opacity {
+                PropertyAnimation { duration: 150 }
+            }
         }
+
+        DeviceKeys {
+            id: keys
+            active: Qt.application.active && pipelineManager.scaleAcquired
+            repeat: !settings.zoomAsShutter
+        }
+
+//        Standby {
+//            policyLost: pipelineManager.state == "policyLost"
+// TODO:
+//            show: !pageStack.currentPage || (pageStack.currentPage.activationData.standbyVisible && pageStack.currentPage.status == PageStatus.Active && pipelineManager.showStandBy)
+//        }
 }