From: Mohammed Sameer Date: Wed, 19 Dec 2012 20:56:23 +0000 (+0200) Subject: Added touch focus X-Git-Url: http://cgit.sxemacs.org/?a=commitdiff_plain;ds=sidebyside;h=a699e984fa7e256c2781257be6b39c9d55504db8;p=harmattan%2Fcameraplus Added touch focus --- diff --git a/imports/autofocus.cpp b/imports/autofocus.cpp index ed08771..2bfb6ea 100644 --- a/imports/autofocus.cpp +++ b/imports/autofocus.cpp @@ -52,3 +52,7 @@ bool AutoFocus::stopAutoFocus() { bool AutoFocus::canFocus(int sceneMode) { return m_af->canFocus((QtCamScene::SceneMode)sceneMode); } + +void AutoFocus::setRegionOfInterest(const QRectF& roi) { + return m_af->setRegionOfInterest(roi); +} diff --git a/imports/autofocus.h b/imports/autofocus.h index 14b20f7..0aecb79 100644 --- a/imports/autofocus.h +++ b/imports/autofocus.h @@ -52,6 +52,9 @@ public: Status status(); Status cafStatus(); +public slots: + void setRegionOfInterest(const QRectF& roi); + signals: void valueChanged(); void cafValueChanged(); diff --git a/imports/camera.cpp b/imports/camera.cpp index 1b36d73..03bf053 100644 --- a/imports/camera.cpp +++ b/imports/camera.cpp @@ -72,6 +72,7 @@ Camera::Camera(QDeclarativeItem *parent) : m_videoTorch(0) { QObject::connect(m_vf, SIGNAL(renderAreaChanged()), this, SIGNAL(renderAreaChanged())); + QObject::connect(m_vf, SIGNAL(videoResolutionChanged()), this, SIGNAL(videoResolutionChanged())); } Camera::~Camera() { @@ -286,6 +287,10 @@ QRectF Camera::renderArea() const { return m_vf->renderArea(); } +QSizeF Camera::videoResolution() const { + return m_vf->videoResolution(); +} + void Camera::resetCapabilities() { QtCamDevice *dev = device(); diff --git a/imports/camera.h b/imports/camera.h index 60333f7..a826828 100644 --- a/imports/camera.h +++ b/imports/camera.h @@ -61,6 +61,7 @@ class Camera : public QDeclarativeItem { Q_PROPERTY(Notifications *notifications READ notifications WRITE setNotifications NOTIFY notificationsChanged); Q_PROPERTY(QRectF renderArea READ renderArea NOTIFY renderAreaChanged); + Q_PROPERTY(QSizeF videoResolution READ videoResolution NOTIFY videoResolutionChanged); Q_PROPERTY(Zoom *zoom READ zoom NOTIFY zoomChanged); Q_PROPERTY(Flash *flash READ flash NOTIFY flashChanged); @@ -135,6 +136,7 @@ public: VideoTorch *videoTorch() const; QRectF renderArea() const; + QSizeF videoResolution() const; signals: void deviceCountChanged(); @@ -146,6 +148,7 @@ signals: void error(const QString& message, int code, const QString& debug); void notificationsChanged(); void renderAreaChanged(); + void videoResolutionChanged(); void zoomChanged(); void flashChanged(); diff --git a/qml/CameraPage.qml b/qml/CameraPage.qml index b496f71..b9d5780 100644 --- a/qml/CameraPage.qml +++ b/qml/CameraPage.qml @@ -53,6 +53,12 @@ Page { } } + onStatusChanged: { + if (status == PageStatus.Active) { + focusReticle.setRegionOfInterest(); + } + } + FocusReticle { visible: controlsVisible && focusReticleVisible && cam.autoFocus.canFocus(cam.scene.value); id: focusReticle diff --git a/qml/FocusReticle.qml b/qml/FocusReticle.qml index 02e2d90..e932d44 100644 --- a/qml/FocusReticle.qml +++ b/qml/FocusReticle.qml @@ -24,14 +24,10 @@ import QtQuick 1.1 import QtCamera 1.0 import CameraPlus 1.0 -// TODO: keep reticle within bounds -// TODO: move reticle within bounds if resolution changes - +// TODO: I've seen the reticle color changing to red while dragging it but failed to reproduce :( MouseArea { property int cafStatus: AutoFocus.None property int status: AutoFocus.None - property variant topLeft: mapFromItem(cam, cam.renderArea.x, cam.renderArea.y) - property variant bottomRight: mapFromItem(cam, cam.renderArea.x + cam.renderArea.width, cam.renderArea.y + cam.renderArea.height) id: mouse // A 100x100 central "rectangle" @@ -39,10 +35,37 @@ MouseArea { property alias touchMode: reticle.touchMode - x: topLeft.x - y: topLeft.y - width: bottomRight.x - topLeft.x - height: bottomRight.y - topLeft.y + x: cam.renderArea.x + y: cam.renderArea.y + width: cam.renderArea.width + height: cam.renderArea.height + + // Changing mode (which implies changing pages) will not reset ROI thus we do it here + Component.onCompleted: cam.autoFocus.setRegionOfInterest(Qt.rect(0, 0, 0, 0)); + +/* + // This is for debugging + Rectangle { + color: "blue" + opacity: 0.2 + anchors.fill: parent + } + + Rectangle { + color: "red" + opacity: 0.4 + x: centerRect.x + y: centerRect.y + width: centerRect.width + height: centerRect.height + } +*/ + drag.target: reticle + drag.axis: Drag.XandYAxis + drag.minimumX: 0 - (0.1 * reticle.width) + drag.minimumY: 0 - (0.1 * reticle.height) + drag.maximumX: width - reticle.width + (0.1 * reticle.width) + drag.maximumY: height - reticle.height + (0.1 * reticle.height) onStatusChanged: { if (status != AutoFocus.Running) { @@ -68,13 +91,13 @@ MouseArea { } } - function moveRect(x, y) { - // TODO: don't put reticle outside area - x = x - (reticle.width / 2) - y = y - (reticle.height / 2) - - reticle.x = x; - reticle.y = y; + function moveReticle(x, y) { + var xPos = x - ((reticle.width * 1) / 2); + var yPos = y - ((reticle.height * 1) / 2); + x = Math.min(Math.max(xPos, drag.minimumX), drag.maximumX); + y = Math.min(Math.max(yPos, drag.minimumY), drag.maximumY); + reticle.x = xPos; + reticle.y = yPos; } function moveToCenterIfNeeded(x, y) { @@ -86,14 +109,41 @@ MouseArea { } } - onPressed: moveRect(mouse.x, mouse.y); - onPositionChanged: moveRect(mouse.x, mouse.y); + function setRegionOfInterest() { + if (!reticle.touchMode) { + cam.autoFocus.setRegionOfInterest(Qt.rect(0, 0, 0, 0)); + return; + } + + // take into account scale: + var x = reticle.x + (reticle.width * 0.1); + var y = reticle.y + (reticle.height * 0.1); - onReleased: moveToCenterIfNeeded(mouse.x, mouse.y); + var width = reticle.width * 0.8; + var height = reticle.height * 0.8; - onXChanged: { - // TODO: -// moveRect(reticle.x, reticle.y); + // in terms of video resolution: + x = (cam.videoResolution.width * x) / mouse.width; + width = (cam.videoResolution.width * width) / mouse.width; + y = (cam.videoResolution.height * y) / mouse.height; + height = (cam.videoResolution.height * height) / mouse.height; + + // Translate to normalized coordinates (1x1 square) as expected by our C++ backend + x = x / cam.videoResolution.width; + width = width / cam.videoResolution.width; + y = y / cam.videoResolution.height; + height = height / cam.videoResolution.height; + + cam.autoFocus.setRegionOfInterest(Qt.rect(x, y, width, height)); + } + + onReleased: { + moveToCenterIfNeeded(mouse.x, mouse.y); + setRegionOfInterest(); + } + + onPressed: { + moveReticle(mouse.x, mouse.y); } FocusRectangle { @@ -101,7 +151,7 @@ MouseArea { property variant center: Qt.point((mouse.width - width) / 2, (mouse.height - height) / 2); property bool touchMode: !(reticle.x == center.x && reticle.y == center.y) - scale: mouse.pressed ? 0.6 : touchMode ? 0.8 : 1.0 + scale: mouse.pressed ? 0.6 : touchMode ? 0.8 : 1.0 width: 250 height: 150 @@ -109,15 +159,6 @@ MouseArea { y: center.y color: predictColor(cafStatus, status); - - onXChanged: { - if (mouse.pressed) { - return; - } - -// console.log(x); -// console.log(x); - } } Timer { diff --git a/qml/RecordingPage.qml b/qml/RecordingPage.qml index a7e233f..9bd1e8c 100644 --- a/qml/RecordingPage.qml +++ b/qml/RecordingPage.qml @@ -30,6 +30,7 @@ import "data.js" as Data // TODO: resources lost? // TODO: closing camera in the middle of recording will hang camera // TODO: optional resources? +// TODO: get touch focus settings from VideoPage CameraPage { id: page