summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Griebl <rgriebl@trolltech.com>2010-04-20 19:42:24 +0200
committerRobert Griebl <rgriebl@trolltech.com>2010-04-20 19:42:24 +0200
commit27ce15ae5c7f47f6a2c456db74c41b5be6d4144f (patch)
tree88eba70b21abec2b29efb32f6e144be02fb365b1
parent12c24346cee853394625eb02277830c081a6a3c5 (diff)
use touch events if possible
-rw-r--r--testapp/qscrollareakineticscroller.cpp2
-rw-r--r--touchy/qscrollareakineticscroller.cpp117
2 files changed, 88 insertions, 31 deletions
diff --git a/testapp/qscrollareakineticscroller.cpp b/testapp/qscrollareakineticscroller.cpp
index a1ed70d..0b37a16 100644
--- a/testapp/qscrollareakineticscroller.cpp
+++ b/testapp/qscrollareakineticscroller.cpp
@@ -94,7 +94,7 @@ public:
: q_ptr(0)
, area(0)
, ignoreEvents(false)
- {}
+ { }
void init()
{
diff --git a/touchy/qscrollareakineticscroller.cpp b/touchy/qscrollareakineticscroller.cpp
index 6702325..ad7a137 100644
--- a/touchy/qscrollareakineticscroller.cpp
+++ b/touchy/qscrollareakineticscroller.cpp
@@ -80,6 +80,7 @@ public:
QAbstractScrollArea *area;
QItemSelection oldSelection; // the selection before the first mouse down
bool ignoreEvents;
+ bool isTouchEnabled;
QPoint lastOvershoot; // don't change the type to QPointF or we might never shoot completely back.
QPointer<QWidget> childWidget; // the widget where the mouse was pressed
QPointF fractionalPosition;
@@ -94,6 +95,7 @@ public:
: q_ptr(0)
, area(0)
, ignoreEvents(false)
+ , isTouchEnabled(false)
{}
void init()
@@ -164,6 +166,7 @@ void QScrollAreaKineticScroller::setWidget(QAbstractScrollArea *widget)
view->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
view->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
}
+ d->isTouchEnabled = d->area->viewport()->testAttribute(Qt::WA_AcceptTouchEvents);
}
}
@@ -177,35 +180,87 @@ bool QScrollAreaKineticScroller::eventFilter(QObject *o, QEvent *e)
bool isMouseDown = false;
if (d->area && (o == d->area->viewport()) &&
- !d->ignoreEvents && d->area->isEnabled() && isEnabled()) {
+ !d->ignoreEvents && d->area->isEnabled() && isEnabled()) {
switch (e->type()) {
- case QEvent::TouchBegin: {
- QTouchEvent *te = static_cast<QTouchEvent *>(e);
- if (te->touchPoints().count() == 1)
- res = handleInput(InputPress, te->touchPoints().at(0).pos() - d->lastOvershoot, timestamp);
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ if (d->isTouchEnabled) {
+ Input type = (e->type() == QEvent::TouchBegin) ? InputPress :
+ ((e->type() == QEvent::TouchEnd) ? InputRelease : InputMove);
+ QTouchEvent *te = static_cast<QTouchEvent *>(e);
+ int idx = (te->deviceType() == QTouchEvent::TouchScreen) ? 0 : 1;
+
+ if (te->touchPoints().count() == (idx + 1))
+ res = handleInput(type, te->touchPoints().at(idx).pos() - d->lastOvershoot, timestamp);
+ }
break;
- }
- case QEvent::TouchUpdate: {
- QTouchEvent *te = static_cast<QTouchEvent *>(e);
- if (te->touchPoints().count() == 1)
- res = handleInput(InputMove, te->touchPoints().at(0).pos() - d->lastOvershoot, timestamp);
+
+ case QEvent::Wheel:
+#ifdef Q_WS_MAC
+ // the two-finger gesture is mapped to wheel events by default
+ res = d->isTouchEnabled;
+#endif
break;
- }
- case QEvent::TouchEnd: {
- QTouchEvent *te = static_cast<QTouchEvent *>(e);
- if (te->touchPoints().count() == 1)
- res = handleInput(InputRelease, te->touchPoints().at(0).pos() - d->lastOvershoot, timestamp);
+
+ case QEvent::MouseButtonPress:
+ if (!d->isTouchEnabled) {
+ // re-install the event filter so that we get the mouse release before all other filters.
+ // this is an evil hack, but hard to work around without prioritized event filters.
+ d->area->viewport()->removeEventFilter(this);
+ d->area->viewport()->installEventFilter(this);
+ }
+ // fall through
+
+ case QEvent::MouseButtonDblClick:
+ isMouseDown = true;
+ // fall through
+
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonRelease:
+ if (!d->isTouchEnabled) {
+ Input type = (e->type() == QEvent::MouseButtonRelease) ? InputRelease :
+ ((e->type() == QEvent::MouseMove) ? InputMove : InputPress);
+ QMouseEvent *me = static_cast<QMouseEvent *>(e);
+ isMouseEvent = true;
+ res = handleInput(type, me->posF() - d->lastOvershoot, timestamp);
+ }
+ break;
+
+ case QEvent::ChildAdded:
+ case QEvent::ChildRemoved: {
+ QChildEvent *ce = static_cast<QChildEvent *>(e);
+ if (ce->child()->isWidgetType()) {
+ static_cast<QWidget *>(ce->child())->setAttribute(Qt::WA_TransparentForMouseEvents, ce->added());
+ if ((e->type() == QEvent::ChildRemoved) && (ce->child() == d->childWidget))
+ d->childWidget = 0;
+ }
break;
}
default:
break;
}
}
-
+
if (res)
e->accept();
res |= QObject::eventFilter(o, e);
+ // all child widgets get the WA_TransparentForMouseEvents attribute, so
+ // we have to find the "real" widget to forward this event to...
+ if (!res && isMouseEvent) {
+ QMouseEvent *me = static_cast<QMouseEvent *>(e);
+
+ if (isMouseDown)
+ d->childWidget = d->mouseTransparentChildAtGlobalPos(d->area->viewport(), me->globalPos());
+
+ if (d->childWidget) {
+ QMouseEvent cme(me->type(), me->pos(),
+ me->globalPos(), me->button(), me->buttons(), me->modifiers());
+ d->sendEvent(d->childWidget, &cme);
+ res = cme.isAccepted();
+ }
+ }
return res;
}
@@ -250,21 +305,23 @@ void QScrollAreaKineticScroller::cancelPress(const QPointF &pressPos)
QPoint pos = pressPos.toPoint();
- /*
- if (QWidget *childWidget = d->mouseTransparentChildAtGlobalPos(d->area->viewport(), d->view->mapToGlobal(pos))) {
- */
if (d->childWidget) {
- // simulate a mouse-move and mouse-release far, far away
- QPoint faraway(-1000, -1000);
- QMouseEvent cmem(QEvent::MouseMove, faraway, d->childWidget->mapToGlobal(faraway),
- Qt::LeftButton, QApplication::mouseButtons() | Qt::LeftButton,
- QApplication::keyboardModifiers());
- d->sendEvent(d->childWidget, &cmem);
-
- QMouseEvent cmer(QEvent::MouseButtonRelease, faraway, d->childWidget->mapToGlobal(faraway),
- Qt::LeftButton, QApplication::mouseButtons() & ~Qt::LeftButton,
- QApplication::keyboardModifiers());
- d->sendEvent(d->childWidget, &cmer);
+ if (d->isTouchEnabled) {
+ //TODO
+ // TouchUpdate + TouchEnd?
+ } else {
+ // simulate a mouse-move and mouse-release far, far away
+ QPoint faraway(-1000, -1000);
+ QMouseEvent cmem(QEvent::MouseMove, faraway, d->childWidget->mapToGlobal(faraway),
+ Qt::LeftButton, QApplication::mouseButtons() | Qt::LeftButton,
+ QApplication::keyboardModifiers());
+ d->sendEvent(d->childWidget, &cmem);
+
+ QMouseEvent cmer(QEvent::MouseButtonRelease, faraway, d->childWidget->mapToGlobal(faraway),
+ Qt::LeftButton, QApplication::mouseButtons() & ~Qt::LeftButton,
+ QApplication::keyboardModifiers());
+ d->sendEvent(d->childWidget, &cmer);
+ }
}
if (QAbstractItemView *view = qobject_cast<QAbstractItemView *>(d->area))