summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZeno Albisser <zeno.albisser@nokia.com>2011-01-06 16:19:29 +0100
committerZeno Albisser <zeno.albisser@nokia.com>2011-01-06 16:24:55 +0100
commit263bd4640cf4a4b02dc672991dfa10832fe66906 (patch)
tree50026d3489d887b2ef6a56f64bbaeace3ccb1748
added source code for TouchArea
-rw-r--r--TouchArea/TouchArea.pro24
-rw-r--r--TouchArea/qdeclarativetoucharea.cpp166
-rw-r--r--TouchArea/qdeclarativetoucharea.h165
-rw-r--r--TouchArea/qmldir1
-rw-r--r--TouchArea/touchareaplugin.cpp12
-rw-r--r--TouchArea/touchareaplugin.h15
6 files changed, 383 insertions, 0 deletions
diff --git a/TouchArea/TouchArea.pro b/TouchArea/TouchArea.pro
new file mode 100644
index 0000000..0a38537
--- /dev/null
+++ b/TouchArea/TouchArea.pro
@@ -0,0 +1,24 @@
+TEMPLATE = lib
+CONFIG += qt plugin
+QT += declarative
+TARGET = $$qtLibraryTarget(qmltouchareaplugin)
+
+TARGETPATH = Qt/labs/toucharea
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH
+else:DESTDIR = imports/$$TARGETPATH
+target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
+
+qmldir.files += $$PWD/qmldir
+qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
+
+HEADERS += \
+ touchareaplugin.h \
+ qdeclarativetoucharea.h
+
+SOURCES += \
+ touchareaplugin.cpp \
+ qdeclarativetoucharea.cpp
+
+QMAKE_POST_LINK=$(COPY_FILE) $$PWD/qmldir $$DESTDIR
+
+INSTALLS += target qmldir
diff --git a/TouchArea/qdeclarativetoucharea.cpp b/TouchArea/qdeclarativetoucharea.cpp
new file mode 100644
index 0000000..470fead
--- /dev/null
+++ b/TouchArea/qdeclarativetoucharea.cpp
@@ -0,0 +1,166 @@
+
+#include "qdeclarativetoucharea.h"
+#include "qevent.h"
+#include "qsharedpointer.h"
+#include <math.h>
+
+int QDeclarativeTouchArea::_globalTouchActive = 0;
+
+QDeclarativeTouchArea::QDeclarativeTouchArea(QDeclarativeItem *parent)
+ : QDeclarativeItem(parent),
+ _minimumTouches(0),
+ _maximumTouches(INT_MAX),
+ _scaleFactor(1.0),
+ _rotationAngle(0.0),
+ _topTouchArea(this),
+ _active(false)
+{
+ setAcceptTouchEvents(true);
+ setAcceptedMouseButtons(Qt::LeftButton);
+ setFiltersChildEvents(true);
+}
+
+void QDeclarativeTouchArea::updateTopTouchArea() {
+ for (QDeclarativeItem* pItem = parentItem(); pItem != 0; pItem = pItem->parentItem()) {
+ if (QDeclarativeTouchArea* ta = qobject_cast<QDeclarativeTouchArea*>(pItem)) {
+ _topTouchArea = ta;
+ }
+ }
+}
+
+QDeclarativeTouchArea::~QDeclarativeTouchArea() {
+}
+
+bool QDeclarativeTouchArea::sceneEvent(QEvent *event) {
+ switch (event->type()) {
+ case QEvent::TouchBegin:
+ updateTopTouchArea();
+ if (_globalTouchActive == 0 || _topTouchArea->_active) {
+ _topTouchArea->_active = true;
+ updateTouchData(event);
+ _globalTouchActive++;
+ return true;
+ }
+ break;
+ case QEvent::TouchUpdate:
+ updateTouchData(event);
+ return true;
+ case QEvent::TouchEnd: {
+ updateTouchData(event);
+ _globalTouchActive--;
+ if (_globalTouchActive == 0)
+ _topTouchArea->_active = false;
+ return true;
+ }
+ default:
+ break;
+ }
+ return QDeclarativeItem::sceneEvent(event);
+}
+
+void QDeclarativeTouchArea::updateTouchData(QEvent *event) {
+ bool ended = false;
+ bool moved = false;
+ bool started = false;
+
+ QTouchEvent *e = static_cast<QTouchEvent*>(event);
+ clearChangedAndReleasedTouches();
+
+ QList<QTouchEvent::TouchPoint> touchPoints = e->touchPoints();
+ int numTouchPoints = touchPoints.count();
+ if (numTouchPoints >= _minimumTouches && numTouchPoints <= _maximumTouches) {
+ foreach (QTouchEvent::TouchPoint p, touchPoints) {
+ Qt::TouchPointState touchPointState = p.state();
+ int id = p.id();
+ if (touchPointState & Qt::TouchPointReleased) {
+ QDeclarativeTouchPoint* dtp = static_cast<QDeclarativeTouchPoint*>(_touches[id]);
+ _changedTouches.insert(id,dtp);
+ _releasedTouches.append(dtp);
+ _touches.remove(id);
+ ended = true;
+ } else if (touchPointState & Qt::TouchPointMoved) {
+ updateTouchPoint(static_cast<QDeclarativeTouchPoint*>(_touches[id]),&p);
+ updatePinch(&touchPoints);
+ moved = true;
+ } else if (!_touches.contains(id)) {
+ addTouchPoint(&p);
+ started = true;
+ }
+ }
+ if (ended) emit(touchEnd());
+ if (moved) emit(touchMove());
+ if (started) emit(touchStart());
+ }
+ event->accept();
+}
+
+void QDeclarativeTouchArea::clearChangedAndReleasedTouches() {
+ foreach (QObject *p, _releasedTouches) {
+ QDeclarativeTouchPoint* dtp = static_cast<QDeclarativeTouchPoint*>(p);
+ if (!dtp->isQmlReferenced())
+ delete dtp;
+ else
+ dtp->setValid(false);
+ }
+ _changedTouches.clear();
+ _releasedTouches.clear();
+}
+
+void QDeclarativeTouchArea::addTouchPoint(const QTouchEvent::TouchPoint *p) {
+ QDeclarativeTouchPoint *dtp = 0;
+ foreach (QObject* proto, _touchPrototypes) {
+ QDeclarativeTouchPoint* tp = static_cast<QDeclarativeTouchPoint*>(proto);
+ if (!tp->isValid()) {
+ tp->setValid(true);
+ dtp = tp;
+ break;
+ }
+ }
+
+ if (dtp == 0)
+ dtp = new QDeclarativeTouchPoint(false);
+ dtp->setId(p->id());
+ updateTouchPoint(dtp,p);
+ _touches.insert(p->id(),dtp);
+}
+
+void QDeclarativeTouchArea::addTouchPrototype(QDeclarativeTouchPoint *prototype) {
+ int id = _touchPrototypes.count();
+ prototype->setId(id);
+ _touchPrototypes.insert(id, prototype);
+}
+
+void QDeclarativeTouchArea::updateTouchPoint(QDeclarativeTouchPoint *dtp, const QTouchEvent::TouchPoint *p) {
+ dtp->setX(p->pos().x());
+ dtp->setY(p->pos().y());
+ dtp->setSceneX(p->scenePos().x());
+ dtp->setSceneY(p->scenePos().y());
+ _changedTouches.insert(dtp->id(),dtp);
+}
+
+void QDeclarativeTouchArea::updatePinch(QList<QTouchEvent::TouchPoint> *touchPoints) {
+ if (touchPoints->count()==2) {
+ QTouchEvent::TouchPoint tp1 = touchPoints->at(0);
+ QTouchEvent::TouchPoint tp2 = touchPoints->at(1);
+
+ QPointF tp1LastPos = tp1.lastPos();
+ QPointF tp2LastPos = tp2.lastPos();
+ QPointF tp1Pos = tp1.pos();
+ QPointF tp2Pos = tp2.pos();
+
+ QPointF deltaA = tp1LastPos - tp2LastPos;
+ QPointF deltaB = tp1Pos - tp2Pos;
+
+ qreal distanceA = sqrt(pow(deltaA.x(),2.0)+pow(deltaA.y(),2.0));
+ qreal distanceB = sqrt(pow(deltaB.x(),2.0)+pow(deltaB.y(),2.0));
+ _scaleFactor*=(distanceB/distanceA);
+ emit(scaleFactorChanged());
+
+ QLineF lineA(tp1LastPos, tp2LastPos);
+ QLineF lineB(tp1Pos,tp2Pos);
+ _rotationAngle-=lineA.angleTo(lineB);
+ emit(rotationAngleChanged());
+ }
+
+}
+
diff --git a/TouchArea/qdeclarativetoucharea.h b/TouchArea/qdeclarativetoucharea.h
new file mode 100644
index 0000000..58ed399
--- /dev/null
+++ b/TouchArea/qdeclarativetoucharea.h
@@ -0,0 +1,165 @@
+#ifndef QDECLARATIVETOUCHAREA_H
+#define QDECLARATIVETOUCHAREA_H
+
+#include "qdeclarativeitem.h"
+#include "qevent.h"
+
+#include <QMap>
+#include <QList>
+
+class QDeclarativeTouchPoint : public QObject {
+ Q_OBJECT
+ Q_PROPERTY(int id READ id)
+ Q_PROPERTY(qreal x READ x NOTIFY xChanged)
+ Q_PROPERTY(qreal y READ y NOTIFY yChanged)
+ Q_PROPERTY(qreal sceneX READ sceneX NOTIFY sceneXChanged)
+ Q_PROPERTY(qreal sceneY READ sceneY NOTIFY sceneYChanged)
+ Q_PROPERTY(bool valid READ isValid NOTIFY validityChanged)
+public:
+ QDeclarativeTouchPoint(bool qmlReference = true)
+ : _id(0),
+ _x(0.0),
+ _y(0.0),
+ _sceneX(0.0),
+ _sceneY(0.0),
+ _qmlReferenced(qmlReference),
+ _valid(!qmlReference)
+ {}
+
+ int id() const { return _id; }
+ void setId(int id) { _id = id; }
+
+ qreal x() const { return _x; }
+ void setX(qreal x) {
+ _x = x;
+ emit(xChanged());
+ }
+
+ qreal y() const { return _y; }
+ void setY(qreal y) {
+ _y = y;
+ emit(yChanged());
+ }
+
+ qreal sceneX() const { return _sceneX; }
+ void setSceneX(qreal sceneX) {
+ _sceneX = sceneX;
+ emit(sceneXChanged());
+ }
+
+ qreal sceneY() const { return _sceneY; }
+ void setSceneY(qreal sceneY) {
+ _sceneY = sceneY;
+ emit(sceneYChanged());
+ }
+
+ bool isQmlReferenced() { return _qmlReferenced; }
+
+ bool isValid() { return _valid; }
+ void setValid(bool valid) {
+ _valid = valid;
+ emit(validityChanged());
+ }
+
+Q_SIGNALS:
+ void xChanged();
+ void yChanged();
+ void sceneXChanged();
+ void sceneYChanged();
+ void validityChanged();
+
+private:
+ int _id;
+ qreal _x;
+ qreal _y;
+ qreal _sceneX;
+ qreal _sceneY;
+ bool _qmlReferenced;
+ bool _valid;
+};
+
+
+
+class QDeclarativeTouchArea : public QDeclarativeItem
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QList<QObject*> touches READ touches)
+ Q_PROPERTY(QList<QObject*> changedTouches READ changedTouches)
+ Q_PROPERTY(QDeclarativeListProperty<QDeclarativeTouchPoint> touchPoints READ touchPoints NOTIFY touchPointsChanged)
+ Q_PROPERTY(int minimumTouches READ minimumTouches WRITE setMinimumTouches)
+ Q_PROPERTY(int maximumTouches READ maximumTouches WRITE setMaximumTouches)
+ Q_PROPERTY(qreal scaleFactor READ scaleFactor NOTIFY scaleFactorChanged)
+ Q_PROPERTY(qreal rotationAngle READ rotationAngle NOTIFY rotationAngleChanged)
+
+public:
+ QDeclarativeTouchArea(QDeclarativeItem *parent=0);
+ ~QDeclarativeTouchArea();
+
+ int minimumTouches() const { return _minimumTouches; }
+ void setMinimumTouches(int num) { _minimumTouches = num; }
+ int maximumTouches() const { return _maximumTouches; }
+ void setMaximumTouches(int num) { _maximumTouches = num; }
+
+ qreal scaleFactor() const { return _scaleFactor; }
+ qreal rotationAngle() const { return _rotationAngle; }
+
+ QList<QObject*> touches() { return _touches.values(); }
+ QList<QObject*> changedTouches() { return _changedTouches.values(); }
+
+ QDeclarativeListProperty<QDeclarativeTouchPoint> touchPoints() {
+ return QDeclarativeListProperty<QDeclarativeTouchPoint>(this, 0, QDeclarativeTouchArea::touchPoint_append, QDeclarativeTouchArea::touchPoint_count, QDeclarativeTouchArea::touchPoint_at, 0);
+ }
+
+ static void touchPoint_append(QDeclarativeListProperty<QDeclarativeTouchPoint> *list, QDeclarativeTouchPoint* touch) {
+ QDeclarativeTouchArea *q = static_cast<QDeclarativeTouchArea*>(list->object);
+ q->addTouchPrototype(touch);
+ }
+
+ static int touchPoint_count(QDeclarativeListProperty<QDeclarativeTouchPoint> *list) {
+ QDeclarativeTouchArea *q = static_cast<QDeclarativeTouchArea*>(list->object);
+ return q->_touchPrototypes.count();
+ }
+
+ static QDeclarativeTouchPoint* touchPoint_at(QDeclarativeListProperty<QDeclarativeTouchPoint> *list, int index) {
+ QDeclarativeTouchArea *q = static_cast<QDeclarativeTouchArea*>(list->object);
+ return static_cast<QDeclarativeTouchPoint*>(q->_touchPrototypes[index]);
+ }
+
+
+Q_SIGNALS:
+ void touchStart();
+ void touchMove();
+ void touchEnd();
+ void touchPointsChanged();
+ void scaleFactorChanged();
+ void rotationAngleChanged();
+
+protected:
+ bool sceneEvent(QEvent *);
+ void updateTouchPoint(QDeclarativeTouchPoint*, const QTouchEvent::TouchPoint*);
+ void updatePinch(QList<QTouchEvent::TouchPoint> *touchPoints);
+ void addTouchPrototype(QDeclarativeTouchPoint* prototype);
+ void addTouchPoint(const QTouchEvent::TouchPoint *p);
+ void clearChangedAndReleasedTouches();
+ void updateTopTouchArea();
+ void updateTouchData(QEvent*);
+
+private:
+ QMap<int,QObject*> _touchPrototypes;
+ QMap<int,QObject*> _touches;
+ QMap<int,QObject*> _changedTouches;
+ QList<QObject*> _releasedTouches;
+ int _minimumTouches;
+ int _maximumTouches;
+ qreal _scaleFactor;
+ qreal _rotationAngle;
+ QDeclarativeTouchArea* _topTouchArea;
+ bool _active;
+ static int _globalTouchActive;
+
+};
+
+QML_DECLARE_TYPE(QDeclarativeTouchPoint)
+
+#endif // QDECLARATIVETOUCHAREA_H
diff --git a/TouchArea/qmldir b/TouchArea/qmldir
new file mode 100644
index 0000000..43db22b
--- /dev/null
+++ b/TouchArea/qmldir
@@ -0,0 +1 @@
+plugin qmltouchareaplugin
diff --git a/TouchArea/touchareaplugin.cpp b/TouchArea/touchareaplugin.cpp
new file mode 100644
index 0000000..337442d
--- /dev/null
+++ b/TouchArea/touchareaplugin.cpp
@@ -0,0 +1,12 @@
+#include "qdeclarativetoucharea.h"
+#include "touchareaplugin.h"
+#include <qdeclarative.h>
+
+void TouchAreaPlugin::registerTypes(const char *uri)
+{
+ qmlRegisterType<QDeclarativeTouchArea>(uri,1,0,"TouchArea");
+ qmlRegisterType<QDeclarativeTouchPoint>(uri,1,0,"TouchPoint");
+}
+
+Q_EXPORT_PLUGIN2(qmltouchareaplugin, TouchAreaPlugin);
+
diff --git a/TouchArea/touchareaplugin.h b/TouchArea/touchareaplugin.h
new file mode 100644
index 0000000..63a6a83
--- /dev/null
+++ b/TouchArea/touchareaplugin.h
@@ -0,0 +1,15 @@
+#ifndef TOUCHAREAPLUGIN_H
+#define TOUCHAREAPLUGIN_H
+
+#include <QDeclarativeExtensionPlugin>
+
+class TouchAreaPlugin : public QDeclarativeExtensionPlugin
+{
+ Q_OBJECT
+public:
+ void registerTypes(const char *uri);
+};
+
+
+
+#endif // TOUCHAREAPLUGIN_H