summaryrefslogtreecommitdiffstats
path: root/demos
diff options
context:
space:
mode:
authorBenjamin Poulain <benjamin.poulain@nokia.com>2009-10-02 19:11:55 +0200
committerBenjamin Poulain <benjamin.poulain@nokia.com>2009-10-02 19:20:34 +0200
commit31cddefea97be65cdcc0970c237418b5b8a8e1d5 (patch)
treea969bf0e24d05f31f53a9d9652969b8e5b083424 /demos
parente3fa7e2f0fd8f69d3de96af9ba0b868bd3ccc07c (diff)
Add multitouch capabilities to the shared classes of the demo
Add multitouch feature to the HoverPoints and the ArthurWidget. Multitouch is enabled by default for widgets using HoverPoints. The ArthurWidget propagate the TouchEvents in order to have them handled by a parent if a parent accept the touch events. Reviewed-by: Denis Dzyubenko Reviewed-by: Pierre Rossi
Diffstat (limited to 'demos')
-rw-r--r--demos/shared/arthurwidgets.h21
-rw-r--r--demos/shared/hoverpoints.cpp82
-rw-r--r--demos/shared/hoverpoints.h2
3 files changed, 104 insertions, 1 deletions
diff --git a/demos/shared/arthurwidgets.h b/demos/shared/arthurwidgets.h
index aa70002427..7b02bcd5c3 100644
--- a/demos/shared/arthurwidgets.h
+++ b/demos/shared/arthurwidgets.h
@@ -49,13 +49,32 @@
#if defined(QT_OPENGL_SUPPORT)
#include <QGLWidget>
+#include <QEvent>
class GLWidget : public QGLWidget
{
public:
GLWidget(QWidget *parent)
- : QGLWidget(QGLFormat(QGL::SampleBuffers), parent) {}
+ : QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
+ {
+ setAttribute(Qt::WA_AcceptTouchEvents);
+ }
void disableAutoBufferSwap() { setAutoBufferSwap(false); }
void paintEvent(QPaintEvent *) { parentWidget()->update(); }
+protected:
+ bool event(QEvent *event)
+ {
+ switch (event->type()) {
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ event->ignore();
+ return false;
+ break;
+ default:
+ break;
+ }
+ return QGLWidget::event(event);
+ }
};
#endif
diff --git a/demos/shared/hoverpoints.cpp b/demos/shared/hoverpoints.cpp
index 182f4d8893..84f58150d6 100644
--- a/demos/shared/hoverpoints.cpp
+++ b/demos/shared/hoverpoints.cpp
@@ -53,6 +53,7 @@ HoverPoints::HoverPoints(QWidget *widget, PointShape shape)
{
m_widget = widget;
widget->installEventFilter(this);
+ widget->setAttribute(Qt::WA_AcceptTouchEvents);
m_connectionType = CurveConnection;
m_sortType = NoSort;
@@ -86,6 +87,8 @@ bool HoverPoints::eventFilter(QObject *object, QEvent *event)
case QEvent::MouseButtonPress:
{
+ if (!m_fingerPointMapping.isEmpty())
+ return true;
QMouseEvent *me = (QMouseEvent *) event;
QPointF clickPos = me->pos();
@@ -147,13 +150,90 @@ bool HoverPoints::eventFilter(QObject *object, QEvent *event)
break;
case QEvent::MouseButtonRelease:
+ if (!m_fingerPointMapping.isEmpty())
+ return true;
m_currentIndex = -1;
break;
case QEvent::MouseMove:
+ if (!m_fingerPointMapping.isEmpty())
+ return true;
if (m_currentIndex >= 0)
movePoint(m_currentIndex, ((QMouseEvent *)event)->pos());
break;
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ {
+ const QTouchEvent *const touchEvent = static_cast<const QTouchEvent*>(event);
+ const QList<QTouchEvent::TouchPoint> points = touchEvent->touchPoints();
+ const qreal pointSize = qMax(m_pointSize.width(), m_pointSize.height());
+ foreach (const QTouchEvent::TouchPoint &touchPoint, points) {
+ const int id = touchPoint.id();
+ switch (touchPoint.state()) {
+ case Qt::TouchPointPressed:
+ {
+ // find the point, move it
+ QSet<int> activePoints = QSet<int>::fromList(m_fingerPointMapping.values());
+ int activePoint = -1;
+ qreal distance = -1;
+ const int pointsCount = m_points.size();
+ const int activePointCount = activePoints.size();
+ if (pointsCount == 2 && activePointCount == 1) { // only two points
+ activePoint = activePoints.contains(0) ? 1 : 0;
+ } else {
+ for (int i=0; i<pointsCount; ++i) {
+ if (activePoints.contains(i))
+ continue;
+
+ qreal d = QLineF(touchPoint.pos(), m_points.at(i)).length();
+ if ((distance < 0 && d < 12 * pointSize) || d < distance) {
+ distance = d;
+ activePoint = i;
+ }
+
+ }
+ }
+ if (activePoint != -1) {
+ m_fingerPointMapping.insert(touchPoint.id(), activePoint);
+ movePoint(activePoint, touchPoint.pos());
+ }
+ }
+ break;
+ case Qt::TouchPointReleased:
+ {
+ // move the point and release
+ QHash<int,int>::iterator it = m_fingerPointMapping.find(id);
+ movePoint(it.value(), touchPoint.pos());
+ m_fingerPointMapping.erase(it);
+ }
+ break;
+ case Qt::TouchPointMoved:
+ {
+ // move the point
+ const int pointIdx = m_fingerPointMapping.value(id, -1);
+ if (pointIdx >= 0) // do we track this point?
+ movePoint(pointIdx, touchPoint.pos());
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (m_fingerPointMapping.isEmpty()) {
+ event->ignore();
+ return false;
+ } else {
+ return true;
+ }
+ }
+ break;
+ case QEvent::TouchEnd:
+ if (m_fingerPointMapping.isEmpty()) {
+ event->ignore();
+ return false;
+ }
+ return true;
+ break;
case QEvent::Resize:
{
@@ -262,6 +342,8 @@ static QPointF bound_point(const QPointF &point, const QRectF &bounds, int lock)
void HoverPoints::setPoints(const QPolygonF &points)
{
+ if (points.size() != m_points.size())
+ m_fingerPointMapping.clear();
m_points.clear();
for (int i=0; i<points.size(); ++i)
m_points << bound_point(points.at(i), boundingRect(), 0);
diff --git a/demos/shared/hoverpoints.h b/demos/shared/hoverpoints.h
index 8f6e1b8f1d..23ac8c1e1c 100644
--- a/demos/shared/hoverpoints.h
+++ b/demos/shared/hoverpoints.h
@@ -133,6 +133,8 @@ private:
bool m_editable;
bool m_enabled;
+ QHash<int, int> m_fingerPointMapping;
+
QPen m_pointPen;
QBrush m_pointBrush;
QPen m_connectionPen;