diff options
author | Benjamin Poulain <benjamin.poulain@nokia.com> | 2009-10-02 17:18:12 (GMT) |
---|---|---|
committer | Benjamin Poulain <benjamin.poulain@nokia.com> | 2009-10-02 17:20:34 (GMT) |
commit | 3babdba3a64d48bf9f948cfb69b3536f0795f343 (patch) | |
tree | 3babfdc352467dd01cb83ca75571f26c3d189c49 | |
parent | 31cddefea97be65cdcc0970c237418b5b8a8e1d5 (diff) | |
download | Qt-3babdba3a64d48bf9f948cfb69b3536f0795f343.zip Qt-3babdba3a64d48bf9f948cfb69b3536f0795f343.tar.gz Qt-3babdba3a64d48bf9f948cfb69b3536f0795f343.tar.bz2 |
Add multitouch to the PathStroke demo
Add multitouch to the position of the path, and enable multitouch on
the controls of the demo.
Reviewed-by: Denis Dzyubenko
Reviewed-by: Pierre Rossi
-rw-r--r-- | demos/pathstroke/main.cpp | 4 | ||||
-rw-r--r-- | demos/pathstroke/pathstroke.cpp | 95 | ||||
-rw-r--r-- | demos/pathstroke/pathstroke.h | 3 |
3 files changed, 97 insertions, 5 deletions
diff --git a/demos/pathstroke/main.cpp b/demos/pathstroke/main.cpp index 60520f1..67f4639 100644 --- a/demos/pathstroke/main.cpp +++ b/demos/pathstroke/main.cpp @@ -57,8 +57,10 @@ int main(int argc, char **argv) QStyle *arthurStyle = new ArthurStyle(); pathStrokeWidget.setStyle(arthurStyle); QList<QWidget *> widgets = qFindChildren<QWidget *>(&pathStrokeWidget); - foreach (QWidget *w, widgets) + foreach (QWidget *w, widgets) { w->setStyle(arthurStyle); + w->setAttribute(Qt::WA_AcceptTouchEvents); + } if (smallScreen) pathStrokeWidget.showFullScreen(); diff --git a/demos/pathstroke/pathstroke.cpp b/demos/pathstroke/pathstroke.cpp index fdc7480..e072f0a 100644 --- a/demos/pathstroke/pathstroke.cpp +++ b/demos/pathstroke/pathstroke.cpp @@ -402,6 +402,7 @@ PathStrokeRenderer::PathStrokeRenderer(QWidget *parent, bool smallScreen) m_penStyle = Qt::SolidLine; m_wasAnimated = true; setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + setAttribute(Qt::WA_AcceptTouchEvents); } void PathStrokeRenderer::paint(QPainter *painter) @@ -510,10 +511,6 @@ void PathStrokeRenderer::updatePoints() Q_ASSERT(m_points.size() == m_vectors.size()); for (int i=0; i<m_points.size(); ++i) { - - if (i == m_activePoint) - continue; - QPointF pos = m_points.at(i); QPointF vec = m_vectors.at(i); pos += vec; @@ -532,6 +529,8 @@ void PathStrokeRenderer::updatePoints() void PathStrokeRenderer::mousePressEvent(QMouseEvent *e) { + if (!m_fingerPointMapping.isEmpty()) + return; setDescriptionEnabled(false); m_activePoint = -1; qreal distance = -1; @@ -556,6 +555,8 @@ void PathStrokeRenderer::mousePressEvent(QMouseEvent *e) void PathStrokeRenderer::mouseMoveEvent(QMouseEvent *e) { + if (!m_fingerPointMapping.isEmpty()) + return; // If we've moved more then 25 pixels, assume user is dragging if (!m_mouseDrag && QPoint(m_mousePress - e->pos()).manhattanLength() > 25) m_mouseDrag = true; @@ -568,6 +569,8 @@ void PathStrokeRenderer::mouseMoveEvent(QMouseEvent *e) void PathStrokeRenderer::mouseReleaseEvent(QMouseEvent *) { + if (!m_fingerPointMapping.isEmpty()) + return; m_activePoint = -1; setAnimation(m_wasAnimated); @@ -586,6 +589,90 @@ void PathStrokeRenderer::timerEvent(QTimerEvent *e) // } } +bool PathStrokeRenderer::event(QEvent *e) +{ + bool touchBegin = false; + switch (e->type()) { + case QEvent::TouchBegin: + touchBegin = true; + case QEvent::TouchUpdate: + { + const QTouchEvent *const event = static_cast<const QTouchEvent*>(e); + const QList<QTouchEvent::TouchPoint> points = event->touchPoints(); + 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(); + 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 * m_pointSize) || d < distance) { + distance = d; + activePoint = i; + } + } + if (activePoint != -1) { + m_fingerPointMapping.insert(touchPoint.id(), activePoint); + m_points[activePoint] = touchPoint.pos(); + } + } + break; + case Qt::TouchPointReleased: + { + // move the point and release + QHash<int,int>::iterator it = m_fingerPointMapping.find(id); + m_points[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) + m_points[pointIdx] = touchPoint.pos(); + } + break; + default: + break; + } + } + if (m_fingerPointMapping.isEmpty()) { + e->ignore(); + return false; + } else { + if (touchBegin) { + m_wasAnimated = m_timer.isActive(); + setAnimation(false); + } + update(); + return true; + } + } + break; + case QEvent::TouchEnd: + if (m_fingerPointMapping.isEmpty()) { + e->ignore(); + return false; + } + m_fingerPointMapping.clear(); + setAnimation(m_wasAnimated); + return true; + break; + default: + break; + } + return QWidget::event(e); +} + void PathStrokeRenderer::setAnimation(bool animation) { m_timer.stop(); diff --git a/demos/pathstroke/pathstroke.h b/demos/pathstroke/pathstroke.h index 3ff2c55..e869515 100644 --- a/demos/pathstroke/pathstroke.h +++ b/demos/pathstroke/pathstroke.h @@ -60,6 +60,7 @@ public: void mouseMoveEvent(QMouseEvent *e); void mouseReleaseEvent(QMouseEvent *e); void timerEvent(QTimerEvent *e); + bool event(QEvent *e); QSize sizeHint() const { return QSize(500, 500); } @@ -118,6 +119,8 @@ private: bool m_smallScreen; QPoint m_mousePress; bool m_mouseDrag; + + QHash<int, int> m_fingerPointMapping; }; class PathStrokeControls : public QWidget |