From 4fe9fdd5913fc545857582451d638988dc233fc2 Mon Sep 17 00:00:00 2001 From: Mohammed Sameer Date: Sat, 27 Jul 2013 04:25:21 +0300 Subject: [PATCH] Camera doesn't need to subclass QDeclarativeItem --- declarative/camera.cpp | 15 +-- declarative/camera.h | 8 +- qml/CameraView.qml | 163 ++++++++++++++++---------------- qml/ImageResolutionSettings.qml | 7 +- qml/ImageSettings.qml | 5 + qml/PipelineManager.qml | 2 +- qml/SettingsView.qml | 8 ++ qml/VideoResolutionSettings.qml | 5 +- qml/VideoSettings.qml | 4 + qml/main.qml | 31 +++--- 10 files changed, 127 insertions(+), 121 deletions(-) diff --git a/declarative/camera.cpp b/declarative/camera.cpp index 0058c13..c04741b 100644 --- a/declarative/camera.cpp +++ b/declarative/camera.cpp @@ -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; diff --git a/declarative/camera.h b/declarative/camera.h index 2b97247..f6bb59e 100644 --- a/declarative/camera.h +++ b/declarative/camera.h @@ -23,7 +23,7 @@ #ifndef CAMERA_H #define CAMERA_H -#include +#include #include #include @@ -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; diff --git a/qml/CameraView.qml b/qml/CameraView.qml index 7eaf88b..82481d1 100644 --- a/qml/CameraView.qml +++ b/qml/CameraView.qml @@ -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 + } } diff --git a/qml/ImageResolutionSettings.qml b/qml/ImageResolutionSettings.qml index 63ce485..e287394 100644 --- a/qml/ImageResolutionSettings.qml +++ b/qml/ImageResolutionSettings.qml @@ -21,8 +21,11 @@ */ 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 { diff --git a/qml/ImageSettings.qml b/qml/ImageSettings.qml index 3fb37ed..dfb039e 100644 --- a/qml/ImageSettings.qml +++ b/qml/ImageSettings.qml @@ -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 } diff --git a/qml/PipelineManager.qml b/qml/PipelineManager.qml index f6b82d9..0ef0a68 100644 --- a/qml/PipelineManager.qml +++ b/qml/PipelineManager.qml @@ -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") diff --git a/qml/SettingsView.qml b/qml/SettingsView.qml index 0176027..8965fd5 100644 --- a/qml/SettingsView.qml +++ b/qml/SettingsView.qml @@ -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 + } } diff --git a/qml/VideoResolutionSettings.qml b/qml/VideoResolutionSettings.qml index 5100116..26d4eac 100644 --- a/qml/VideoResolutionSettings.qml +++ b/qml/VideoResolutionSettings.qml @@ -21,8 +21,11 @@ */ 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 { diff --git a/qml/VideoSettings.qml b/qml/VideoSettings.qml index 7b740e3..99a0c62 100644 --- a/qml/VideoSettings.qml +++ b/qml/VideoSettings.qml @@ -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 } diff --git a/qml/main.qml b/qml/main.qml index 47cc439..a01489b 100644 --- a/qml/main.qml +++ b/qml/main.qml @@ -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) } } -- 2.34.1