Camera doesn't need to subclass QDeclarativeItem
authorMohammed Sameer <msameer@foolab.org>
Sat, 27 Jul 2013 01:25:21 +0000 (04:25 +0300)
committerMohammed Sameer <msameer@foolab.org>
Sat, 27 Jul 2013 01:25:21 +0000 (04:25 +0300)
declarative/camera.cpp
declarative/camera.h
qml/CameraView.qml
qml/ImageResolutionSettings.qml
qml/ImageSettings.qml
qml/PipelineManager.qml
qml/SettingsView.qml
qml/VideoResolutionSettings.qml
qml/VideoSettings.qml
qml/main.qml

index 0058c13..c04741b 100644 (file)
@@ -50,8 +50,8 @@
 #include "videotorch.h"
 #include "cameraconfig.h"
 
-Camera::Camera(QDeclarativeItem *parent) :
-  QDeclarativeItem(parent),
+Camera::Camera(QObject *parent) :
+  QObject(parent),
   m_cam(new QtCamera(this)),
   m_dev(0),
   m_mode(Camera::UnknownMode),
@@ -106,12 +106,6 @@ Camera::~Camera() {
   delete m_videoTorch;
 }
 
-void Camera::componentComplete() {
-  QDeclarativeItem::componentComplete();
-
-  emit deviceCountChanged();
-}
-
 int Camera::deviceCount() const {
   return m_cam ? m_cam->devices().size() : 0;
 }
@@ -130,11 +124,6 @@ bool Camera::reset(const QVariant& deviceId, const CameraMode& mode) {
     return false;
   }
 
-  if (!isComponentComplete()) {
-    qmlInfo(this) << "Component is still not ready";
-    return false;
-  }
-
   QVariant oldId = m_id;
   Camera::CameraMode oldMode = m_mode;
 
index 2b97247..f6bb59e 100644 (file)
@@ -23,7 +23,7 @@
 #ifndef CAMERA_H
 #define CAMERA_H
 
-#include <QDeclarativeItem>
+#include <QObject>
 #include <QVariant>
 #include <QPointer>
 
@@ -49,7 +49,7 @@ class VideoMute;
 class VideoTorch;
 class CameraConfig;
 
-class Camera : public QDeclarativeItem {
+class Camera : public QObject {
   Q_OBJECT
 
   Q_PROPERTY(int deviceCount READ deviceCount NOTIFY deviceCountChanged)
@@ -91,11 +91,9 @@ public:
     VideoMode
   } CameraMode;
 
-  Camera(QDeclarativeItem *parent = 0);
+  Camera(QObject *parent = 0);
   ~Camera();
 
-  virtual void componentComplete();
-
   int deviceCount() const;
   Q_INVOKABLE QString deviceName(int index) const;
   Q_INVOKABLE QVariant deviceId(int index) const;
index 7eaf88b..82481d1 100644 (file)
@@ -25,76 +25,73 @@ import QtCamera 1.0
 import CameraPlus 1.0
 
 // TODO: reset reticle and roi when we stop camera or change mode
-Camera {
-    id: cam
 
+Viewfinder {
+    id: viewfinder
     property bool pressed: focusReticle.locked || (loader.item ? loader.item.pressed : false)
     property int policyMode: loader.item ? loader.item.policyMode : CameraResources.None
 
-    Viewfinder {
-        id: viewfinder
-        width: cam.width
-        height: cam.height
-        x: 0
-        y: 0
+    camera: cam
+    cameraConfig: cam.cameraConfig
+    renderingEnabled: mainView.currentItem == viewfinder
 
-        camera: cam
-        cameraConfig: cam.cameraConfig
-
-        renderingEnabled: mainView.currentItem == cam
+    Component.onDestruction: cam.stop()
 
-        GridLines {
-            x: viewfinder.renderArea.x
-            y: viewfinder.renderArea.y
-            width: viewfinder.renderArea.width
-            height: viewfinder.renderArea.height
-            visible: settings.gridEnabled
-        }
+    GridLines {
+        x: viewfinder.renderArea.x
+        y: viewfinder.renderArea.y
+        width: viewfinder.renderArea.width
+        height: viewfinder.renderArea.height
+        visible: settings.gridEnabled
     }
 
-    function policyLost() {
-        if (loader.item) {
-            loader.item.policyLost()
+    Camera {
+        id: cam
+        sounds: Sounds {
+            id: sounds
+            mute: !settings.soundEnabled
+            volume: volumeControl.fullVolume ? Sounds.VolumeHigh : Sounds.VolumeLow
+            imageCaptureStart: platformSettings.imageCaptureStartedSound
+            imageCaptureEnd: platformSettings.imageCaptureEndedSound
+            videoRecordingStart: platformSettings.videoRecordingStartedSound
+            videoRecordingEnd: platformSettings.videoRecordingEndedSound
+            autoFocusAcquired: platformSettings.autoFocusAcquiredSound
         }
-    }
 
-    function checkBattery() {
-        // We are fine if we are connected to the charger:
-        if (batteryMonitor.charging) {
-            return true
-        }
+        onRoiChanged: roi.normalize = false
 
-        // If we have enough battery then we are fine:
-        if (!batteryMonitor.critical) {
-            return true
+        onRunningChanged: {
+            if (!cam.running) {
+                mountProtector.unlock()
+            }
         }
 
-        return false
-    }
+        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
+            }
 
-    Component.onDestruction: cam.stop()
+            pipelineManager.error = true
+            if (loader.item) {
+                loader.item.cameraError()
+            }
 
-    onRunningChanged: {
-        if (!cam.running) {
-            mountProtector.unlock()
+            console.log("Camera error (" + code + "): " + message + " " + debug)
+            showError(qsTr("Camera error. Please restart the application."))
+            // We cannot stop camera here. Seems there is a race condition somewhere
+            // which leads to a freeze if we do so.
         }
+
     }
 
     SoundVolumeControl {
         id: volumeControl
     }
 
-    sounds: Sounds {
-        id: sounds
-        mute: !settings.soundEnabled
-        volume: volumeControl.fullVolume ? Sounds.VolumeHigh : Sounds.VolumeLow
-        imageCaptureStart: platformSettings.imageCaptureStartedSound
-        imageCaptureEnd: platformSettings.imageCaptureEndedSound
-        videoRecordingStart: platformSettings.videoRecordingStartedSound
-        videoRecordingEnd: platformSettings.videoRecordingEndedSound
-        autoFocusAcquired: platformSettings.autoFocusAcquiredSound
-    }
-
     BatteryInfo {
         id: batteryMonitor
         active: cam.running
@@ -114,10 +111,29 @@ Camera {
         }
     }
 
+    FocusReticle {
+        id: focusReticle
+        cam: cam
+        videoResolution: viewfinder.videoResolution
+        renderArea: viewfinder.renderArea
+
+        visible: loader.item != null && loader.item.controlsVisible &&
+            cam.autoFocus.canFocus(cam.scene.value)
+        cafStatus: cam ? cam.autoFocus.cafStatus : -1
+        status: cam ? cam.autoFocus.status : -1
+    }
+
     PreviewImage {
         id: preview
     }
 
+    Loader {
+        id: loader
+        property string src: cam.mode == Camera.VideoMode ? "VideoOverlay.qml" : "ImageOverlay.qml"
+        anchors.fill: parent
+        source: Qt.resolvedUrl(src)
+    }
+
     Connections {
         target: loader.item
         onPreviewAvailable: preview.setPreview(uri)
@@ -137,27 +153,7 @@ Camera {
         when: loader.item != null
     }
 
-    onRoiChanged: roi.normalize = false
-
-    FocusReticle {
-        id: focusReticle
-        cam: cam
-        videoResolution: viewfinder.videoResolution
-        renderArea: viewfinder.renderArea
-
-        visible: loader.item != null && loader.item.controlsVisible &&
-            cam.autoFocus.canFocus(cam.scene.value)
-        cafStatus: cam ? cam.autoFocus.cafStatus : -1
-        status: cam ? cam.autoFocus.status : -1
-    }
-
-    Loader {
-        id: loader
-        property string src: mode == Camera.VideoMode ? "VideoOverlay.qml" : "ImageOverlay.qml"
-        anchors.fill: parent
-        source: Qt.resolvedUrl(src)
-    }
-
+    /* Camera bindings */
     Binding {
         target: cam.flash
         property: "value"
@@ -268,24 +264,23 @@ Camera {
         value: settings.faceDetectionEnabled && !focusReticle.pressed && !focusReticle.touchMode && cam.mode == Camera.ImageMode
     }
 
-    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
+    function policyLost() {
+        if (loader.item) {
+            loader.item.policyLost()
         }
+    }
 
-        pipelineManager.error = true
-        if (loader.item) {
-            loader.item.cameraError()
+    function checkBattery() {
+        // We are fine if we are connected to the charger:
+        if (batteryMonitor.charging) {
+            return true
         }
 
-        console.log("Camera error (" + code + "): " + message + " " + debug)
-        showError(qsTr("Camera error. Please restart the application."))
-        // We cannot stop camera here. Seems there is a race condition somewhere
-        // which leads to a freeze if we do so.
-    }
+        // If we have enough battery then we are fine:
+        if (!batteryMonitor.critical) {
+            return true
+        }
 
+        return false
+    }
 }
index 63ce485..e287394 100644 (file)
  */
 
 import QtQuick 2.0
+import QtCamera 1.0
 
 Column {
+    property Camera camera: null
+
     spacing: 10
 
     SectionHeader {
@@ -32,7 +35,7 @@ Column {
     CameraButtonRow {
         id: aspectRatioRow
         width: parent.width
-        enabled: cam.idle
+        enabled: camera ? camera.idle : false
         exclusive: false
 
         Repeater {
@@ -52,7 +55,7 @@ Column {
     CameraButtonRow {
         id: resolutionsRow
         width: parent.width
-        enabled: cam.idle
+        enabled: camera ? camera.idle : false
         exclusive: false
 
         Binding {
index 3fb37ed..dfb039e 100644 (file)
@@ -24,6 +24,10 @@ import QtQuick 2.0
 import QtCamera 1.0
 
 Flickable {
+    property Camera camera: null
+
+    id: flick
+
     contentHeight: col.height
     anchors.fill: parent
     anchors.margins: 10
@@ -39,6 +43,7 @@ Flickable {
         }
 
         ImageResolutionSettings {
+            camera: flick.camera
             width: parent.width
         }
 
index f6b82d9..0ef0a68 100644 (file)
@@ -60,7 +60,7 @@ Item {
     function startCamera() {
         if (error) {
             return
-        } else if ((currentPolicyMode == currentItem.policyMode) && cam.running) {
+        } else if ((currentPolicyMode == currentItem.policyMode) && camera.running) {
             return
         } else if (!policy.acquire(currentItem.policyMode)) {
             console.log("Failed to acquire policy resources")
index 0176027..8965fd5 100644 (file)
@@ -25,6 +25,7 @@ import QtCamera 1.0
 import CameraPlus 1.0
 
 Item {
+    property Camera camera: null
     property int policyMode: settings.mode == Camera.VideoMode ? CameraResources.Video
         : CameraResources.Image
 
@@ -33,4 +34,11 @@ Item {
         anchors.fill: parent
         source: settings.mode == Camera.VideoMode ? Qt.resolvedUrl("VideoSettings.qml") : Qt.resolvedUrl("ImageSettings.qml")
     }
+
+    Binding {
+        target: loader.item
+        property: "camera"
+        value: camera
+        when: loader.item != null
+    }
 }
index 5100116..26d4eac 100644 (file)
  */
 
 import QtQuick 2.0
+import QtCamera 1.0
 
 Column {
+    property Camera camera: null
+
     spacing: 10
 
     SectionHeader {
@@ -31,7 +34,7 @@ Column {
 
     CameraButtonRow {
         width: parent.width
-        enabled: cam.idle
+        enabled: camera ? camera.idle : false
         exclusive: false
 
         Repeater {
index 7b740e3..99a0c62 100644 (file)
@@ -24,6 +24,9 @@ import QtQuick 2.0
 import QtCamera 1.0
 
 Flickable {
+    property Camera camera: null
+    id: flick
+
     contentHeight: col.height
     anchors.fill: parent
     anchors.margins: 10
@@ -39,6 +42,7 @@ Flickable {
         }
 
         VideoResolutionSettings {
+            camera: flick.camera
             width: parent.width
         }
 
index 47cc439..a01489b 100644 (file)
@@ -29,18 +29,18 @@ import QtMobility.location 1.2
 
 CameraWindow {
     id: root
-    property alias camera: cam
 
     VisualItemModel {
         id: mainModel
 
         SettingsView {
+            camera: viewfinder.camera
             width: mainView.width
             height: mainView.height
         }
 
         CameraView {
-            id: cam
+            id: viewfinder
             width: mainView.width
             height: mainView.height
         }
@@ -80,12 +80,12 @@ CameraWindow {
 
     PipelineManager {
         id: pipelineManager
-        camera: cam
+        camera: viewfinder.camera
         currentItem: mainView.currentItem
     }
 
     function resetCamera(deviceId, mode) {
-        if (!cam.reset(deviceId, mode)) {
+        if (!viewfinder.camera.reset(deviceId, mode)) {
             showError(qsTr("Failed to set camera device and mode. Please restart the application."))
         }
     }
@@ -111,7 +111,7 @@ CameraWindow {
 
     MetaData {
         id: metaData
-        camera: cam
+        camera: viewfinder.camera
         manufacturer: deviceInfo.manufacturer
         model: deviceInfo.model
         country: geocode.country
@@ -134,17 +134,17 @@ CameraWindow {
 
     Orientation {
         id: orientation
-        active: cam.running || (mainView.currentIndex == 2 && Qt.application.active)
+        active: viewfinder.camera.running || (mainView.currentIndex == 2 && Qt.application.active)
     }
 
     Compass {
         id: compass
-        active: cam.running
+        active: viewfinder.camera.running
     }
 
     ReverseGeocode {
         id: geocode
-        active: cam.running && settings.useGps && settings.useGeotags
+        active: viewfinder.camera.running && settings.useGps && settings.useGeotags
     }
 
     DeviceInfo {
@@ -161,8 +161,8 @@ CameraWindow {
 
     FileNaming {
         id: fileNaming
-        imageSuffix: cam.imageSuffix
-        videoSuffix: cam.videoSuffix
+        imageSuffix: viewfinder.camera.imageSuffix
+        videoSuffix: viewfinder.camera.videoSuffix
     }
 
     MountProtector {
@@ -172,7 +172,7 @@ CameraWindow {
 
     TrackerStore {
         id: trackerStore
-        active: cam.running
+        active: viewfinder.camera.running
         manufacturer: deviceInfo.manufacturer
         model: deviceInfo.model
     }
@@ -183,7 +183,8 @@ CameraWindow {
 
     ImageSettings {
         id: imageSettings
-        camera: cam
+        camera: viewfinder.camera
+
         function setImageResolution() {
             if (!imageSettings.setResolution(settings.imageAspectRatio, settings.imageResolution)) {
                 showError(qsTr("Failed to set required resolution"))
@@ -199,7 +200,7 @@ CameraWindow {
 
     VideoSettings {
         id: videoSettings
-        camera: cam
+        camera: viewfinder.camera
 
         function setVideoResolution() {
             if (!videoSettings.setResolution(settings.videoAspectRatio, settings.videoResolution)) {
@@ -232,7 +233,7 @@ CameraWindow {
 
     ModeController {
         id: cameraMode
-        cam: cam
+        cam: viewfinder.camera
         dimmer: root.dimmer
     }
 
@@ -257,6 +258,6 @@ CameraWindow {
     Standby {
         policyLost: pipelineManager.state == "policyLost"
         show: !Qt.application.active || pipelineManager.showStandBy ||
-            (mainView.currentIndex == 1 && !camera.running)
+            (mainView.currentIndex == 1 && !viewfinder.camera.running)
     }
 }