Subnavigation

Mouse gestures in Qt apps, to be or not to be.

Thinking of what are the hottest buzz-words in last years "touch screen" and "gestures" come up in mind and many companies work on supporting them in their products. Let's look at "Gestures" - Microsoft has support for touch-screen based gestures in upcoming Windows 7, Opera has mouse gestures for a long time and might have face gestures in future (or not ;) )

Anyway it sounds like Qt should also benefit from having an cross-platform and extensible Gestures API allowing us to use both native (aka "system-generated") gestures (Zoom gesture on Windows and Pinch gesture on Macs) and custom gestures that are defined by the application developer.

We are talking about mouse- and finger-based gestures, i.e. strokes that are drawn with a mouse pointer or with a finger on a touch screen/touchpad (which are translated to mouse events) - from simple double-tapping on a screen (which can also be considered a gesture) to multi-touch gestures (i.e. that are made using several input points - with two fingers).

I've written some mockup code showing how gestures could be used:

void ImageViewWidget::gestureEvent(QGestureEvent *event)
{
if (event->gesture(Qt::TapGesture)) {
// we were tapped!
} else if (const QGesture *g = event->gesture(Qt::DoubleTapGesture)) {
scaleTo(3.0, 3.0);
update()
} else if (const QGesture *g = event->gesture(Qt::PanGesture)) {
if (g->state() == Qt::GestureStarted)
setCursor(Qt::SizeAllCursor);
else
setCursor(Qt::ArrowCursor);
panByOffset(g->pos() - g->lastPos());
update();
} else if (const QSlideGesture *g = static_cast<QSlideGesture*>(event->gesture(Qt::SlideGesture))) {
// converted from base class QGesture to QSlide gesture that
// contains extended info about this particular gesture.
if (g->state() == Qt::GestureFinished) {
if (g->direction() == Qt::RightDirection)
loadNextImage();
else if (g->direction() == Qt::LeftDirection)
loadPreviousImage();
update();
}
} else if (const QGesture *g = event->gesture(Qt::TapAndHoldGesture)) {
if (g->state() == Qt::GestureFinished) {
QMenu menu;
menu.addAction(loadNextImageAction);
menu.addAction(loadPreviousImageAction);
menu.addAction(toggleZoomAction);
menu.exec(mapToGlobal(g->hotSpot()));
}
}
event->accept();
}

However there are a lot of unanswered questions - could it be useful? What are the use cases for gestures? What kind of gestures should work out of the box? (ok, ok, I suppose finger scrolling should work where appropriate).

And more technical ones - how should gestures behave regarding mouse/touch input - consider a Tablet PC with a touch screen where the user taps and moves a finger - should mouse events delivery be delayed until we decide whether it is a gesture, or should we deliver mouse down event, several mouse move events and then switch to delivering gesture events instead? What about ambiguous gestures - what should we do if we are not sure whether it is a Tap or Panning gesture, or we should wait until DoubleTap gesture is finished.

Do you have any other interesting use cases?


Blog Topics:

Comments