diff options
author | Benjamin Poulain <benjamin.poulain@nokia.com> | 2009-10-02 17:11:55 (GMT) |
---|---|---|
committer | Benjamin Poulain <benjamin.poulain@nokia.com> | 2009-10-02 17:20:34 (GMT) |
commit | 31cddefea97be65cdcc0970c237418b5b8a8e1d5 (patch) | |
tree | a969bf0e24d05f31f53a9d9652969b8e5b083424 /demos/shared | |
parent | e3fa7e2f0fd8f69d3de96af9ba0b868bd3ccc07c (diff) | |
download | Qt-31cddefea97be65cdcc0970c237418b5b8a8e1d5.zip Qt-31cddefea97be65cdcc0970c237418b5b8a8e1d5.tar.gz Qt-31cddefea97be65cdcc0970c237418b5b8a8e1d5.tar.bz2 |
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/shared')
-rw-r--r-- | demos/shared/arthurwidgets.h | 21 | ||||
-rw-r--r-- | demos/shared/hoverpoints.cpp | 82 | ||||
-rw-r--r-- | demos/shared/hoverpoints.h | 2 |
3 files changed, 104 insertions, 1 deletions
diff --git a/demos/shared/arthurwidgets.h b/demos/shared/arthurwidgets.h index aa70002..7b02bcd 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 182f4d8..84f5815 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 8f6e1b8..23ac8c1 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; |