QTabletEvent manual test: show buttons, pressure, eraser

- Show which button was pressed or released
- Render an ellipse proportional to pressure for each point drawn
- Different color for the eraser
- More complete output for each event
- Don't show mouse events by default, just as most tablet applications
  can now ignore mouse events on the drawing canvas.  But for the
  purpose of testing interleaving of tablet and mouse events,
  one can give the argument --mouse when starting this program
  to show them too, as before.

Task-number: QTBUG-39458
Change-Id: I5e03f1aa748be39d524bd6984ff5d66579787cf9
Reviewed-by: Frederik Gladhorn <frederik.gladhorn@digia.com>
This commit is contained in:
Shawn Rutledge 2014-06-06 09:43:00 +02:00
parent 6c1a12c558
commit da9e02eb83
4 changed files with 127 additions and 39 deletions

View File

@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal ** Contact: http://www.qt-project.org/legal
** **
** This file is part of the test suite of the Qt Toolkit. ** This file is part of the test suite of the Qt Toolkit.
@ -40,11 +40,21 @@
****************************************************************************/ ****************************************************************************/
#include <QApplication> #include <QApplication>
#include <QDebug>
#include "tabletwidget.h" #include "tabletwidget.h"
int main(int argc, char **argv) { int main(int argc, char **argv) {
QApplication app(argc, argv); QApplication app(argc, argv);
TabletWidget tabletWidget; bool mouseToo = false;
tabletWidget.showMaximized(); if (app.arguments().contains(QLatin1String("--nomouse")) || app.arguments().contains(QLatin1String("-nomouse")))
return app.exec(); mouseToo = false;
else if (app.arguments().contains(QLatin1String("--mouse")) || app.arguments().contains(QLatin1String("-mouse")))
mouseToo = true;
if (mouseToo)
qDebug() << "will show mouse events coming from the tablet as well as QTabletEvents";
else
qDebug() << "will not show mouse events from the tablet; use the --mouse option to enable";
TabletWidget tabletWidget(mouseToo);
tabletWidget.showMaximized();
return app.exec();
} }

View File

@ -42,8 +42,11 @@
#include "tabletwidget.h" #include "tabletwidget.h"
#include <QPainter> #include <QPainter>
#include <QApplication> #include <QApplication>
#include <QDebug>
#include <QMetaObject>
#include <QMetaEnum>
TabletWidget::TabletWidget() TabletWidget::TabletWidget(bool mouseToo) : mMouseToo(mouseToo)
{ {
QPalette newPalette = palette(); QPalette newPalette = palette();
newPalette.setColor(QPalette::Window, Qt::white); newPalette.setColor(QPalette::Window, Qt::white);
@ -76,12 +79,14 @@ bool TabletWidget::eventFilter(QObject *, QEvent *ev)
mPress = event->pressure(); mPress = event->pressure();
mTangential = event->tangentialPressure(); mTangential = event->tangentialPressure();
mRot = event->rotation(); mRot = event->rotation();
mButton = event->button();
mButtons = event->buttons();
if (isVisible()) if (isVisible())
update(); update();
break; break;
} }
case QEvent::MouseMove: case QEvent::MouseMove:
{ if (mMouseToo) {
resetAttributes(); resetAttributes();
QMouseEvent *event = static_cast<QMouseEvent*>(ev); QMouseEvent *event = static_cast<QMouseEvent*>(ev);
mType = event->type(); mType = event->type();
@ -129,7 +134,7 @@ void TabletWidget::paintEvent(QPaintEvent *)
|| mType == QEvent::TabletMove || mType == QEvent::TabletPress || mType == QEvent::TabletMove || mType == QEvent::TabletPress
|| mType == QEvent::TabletRelease) { || mType == QEvent::TabletRelease) {
eventInfo << QString("Hight res global position: %1 %2").arg(QString::number(mHiResGlobalPos.x()), QString::number(mHiResGlobalPos.y())); eventInfo << QString("High res global position: %1 %2").arg(QString::number(mHiResGlobalPos.x()), QString::number(mHiResGlobalPos.y()));
QString pointerType("Pointer type: "); QString pointerType("Pointer type: ");
switch (mPointerType) { switch (mPointerType) {
@ -148,7 +153,6 @@ void TabletWidget::paintEvent(QPaintEvent *)
} }
eventInfo << pointerType; eventInfo << pointerType;
QString deviceString = "Device type: "; QString deviceString = "Device type: ";
switch (mDev) { switch (mDev) {
case QTabletEvent::NoDevice: case QTabletEvent::NoDevice:
@ -172,6 +176,8 @@ void TabletWidget::paintEvent(QPaintEvent *)
} }
eventInfo << deviceString; eventInfo << deviceString;
eventInfo << QString("Button: %1 (0x%2)").arg(buttonToString(mButton)).arg(mButton, 0, 16);
eventInfo << QString("Buttons currently pressed: %1 (0x%2)").arg(buttonsToString(mButtons)).arg(mButtons, 0, 16);
eventInfo << QString("Pressure: %1").arg(QString::number(mPress)); eventInfo << QString("Pressure: %1").arg(QString::number(mPress));
eventInfo << QString("Tangential pressure: %1").arg(QString::number(mTangential)); eventInfo << QString("Tangential pressure: %1").arg(QString::number(mTangential));
eventInfo << QString("Rotation: %1").arg(QString::number(mRot)); eventInfo << QString("Rotation: %1").arg(QString::number(mRot));
@ -182,7 +188,25 @@ void TabletWidget::paintEvent(QPaintEvent *)
eventInfo << QString("Unique Id: %1").arg(QString::number(mUnique)); eventInfo << QString("Unique Id: %1").arg(QString::number(mUnique));
} }
painter.drawText(rect(), eventInfo.join("\n")); QString text = eventInfo.join("\n");
painter.drawText(rect(), text);
}
const char *TabletWidget::buttonToString(Qt::MouseButton b)
{
static int enumIdx = QObject::staticQtMetaObject.indexOfEnumerator("MouseButtons");
return QObject::staticQtMetaObject.enumerator(enumIdx).valueToKey(b);
}
QString TabletWidget::buttonsToString(Qt::MouseButtons bs)
{
QStringList ret;
for (int i = 0; (uint)(1 << i) <= Qt::MaxMouseButton; ++i) {
Qt::MouseButton b = static_cast<Qt::MouseButton>(1 << i);
if (bs.testFlag(b))
ret << buttonToString(b);
}
return ret.join("|");
} }
void TabletWidget::tabletEvent(QTabletEvent *event) void TabletWidget::tabletEvent(QTabletEvent *event)

View File

@ -49,11 +49,13 @@
class TabletWidget : public QWidget class TabletWidget : public QWidget
{ {
public: public:
TabletWidget(); TabletWidget(bool mouseToo);
protected: protected:
bool eventFilter(QObject *obj, QEvent *ev); bool eventFilter(QObject *obj, QEvent *ev);
void tabletEvent(QTabletEvent *event); void tabletEvent(QTabletEvent *event);
void paintEvent(QPaintEvent *event); void paintEvent(QPaintEvent *event);
const char *buttonToString(Qt::MouseButton b);
QString buttonsToString(Qt::MouseButtons bs);
private: private:
void resetAttributes() { void resetAttributes() {
mType = mDev = mPointerType = mXT = mYT = mZ = 0; mType = mDev = mPointerType = mXT = mYT = mZ = 0;
@ -66,8 +68,11 @@ private:
QPoint mPos, mGPos; QPoint mPos, mGPos;
QPointF mHiResGlobalPos; QPointF mHiResGlobalPos;
int mDev, mPointerType, mXT, mYT, mZ; int mDev, mPointerType, mXT, mYT, mZ;
Qt::MouseButton mButton;
Qt::MouseButtons mButtons;
qreal mPress, mTangential, mRot; qreal mPress, mTangential, mRot;
qint64 mUnique; qint64 mUnique;
bool mMouseToo;
}; };
#endif // TABLETWIDGET_H #endif // TABLETWIDGET_H

View File

@ -54,16 +54,20 @@
enum TabletPointType { enum TabletPointType {
TabletButtonPress, TabletButtonPress,
TabletButtonRelease, TabletButtonRelease,
TabletMove, TabletMove
TabletDraw
}; };
struct TabletPoint struct TabletPoint
{ {
TabletPoint(const QPoint &p = QPoint(), TabletPointType t = TabletMove) : pos(p), type(t) {} TabletPoint(const QPointF &p = QPointF(), TabletPointType t = TabletMove,
Qt::MouseButton b = Qt::LeftButton, QTabletEvent::PointerType pt = QTabletEvent::UnknownPointer, qreal prs = 0) :
pos(p), type(t), button(b), ptype(pt), pressure(prs) {}
QPoint pos; QPointF pos;
TabletPointType type; TabletPointType type;
Qt::MouseButton button;
QTabletEvent::PointerType ptype;
qreal pressure;
}; };
class EventReportWidget : public QWidget class EventReportWidget : public QWidget
@ -90,36 +94,47 @@ private:
bool m_lastIsMouseMove; bool m_lastIsMouseMove;
bool m_lastIsTabletMove; bool m_lastIsTabletMove;
Qt::MouseButton m_lastButton;
QVector<TabletPoint> m_points; QVector<TabletPoint> m_points;
}; };
EventReportWidget::EventReportWidget() EventReportWidget::EventReportWidget()
: m_lastIsMouseMove(false) : m_lastIsMouseMove(false)
, m_lastIsTabletMove(false) , m_lastIsTabletMove(false)
, m_lastButton(Qt::NoButton)
{ } { }
void EventReportWidget::paintEvent(QPaintEvent *) void EventReportWidget::paintEvent(QPaintEvent *)
{ {
QPainter p(this); QPainter p(this);
const QRect geom = QRect(QPoint(0, 0), size()); const QRectF geom = QRectF(QPoint(0, 0), size());
p.fillRect(geom, Qt::white); p.fillRect(geom, Qt::white);
p.drawRect(QRect(geom.topLeft(), geom.bottomRight() - QPoint(1,1))); p.drawRect(QRectF(geom.topLeft(), geom.bottomRight() - QPointF(1,1)));
p.setPen(Qt::white);
foreach (const TabletPoint &t, m_points) { foreach (const TabletPoint &t, m_points) {
if (geom.contains(t.pos)) { if (geom.contains(t.pos)) {
QPainterPath pp; QPainterPath pp;
pp.addEllipse(t.pos, 5, 5); pp.addEllipse(t.pos, 8, 8);
QRectF pointBounds(t.pos.x() - 10, t.pos.y() - 10, 20, 20);
switch (t.type) { switch (t.type) {
case TabletButtonPress: case TabletButtonPress:
p.fillPath(pp, Qt::black); p.fillPath(pp, Qt::darkGreen);
if (t.button != Qt::NoButton)
p.drawText(pointBounds, Qt::AlignCenter, QString::number(t.button));
break; break;
case TabletButtonRelease: case TabletButtonRelease:
p.fillPath(pp, Qt::red); p.fillPath(pp, Qt::red);
if (t.button != Qt::NoButton)
p.drawText(pointBounds, Qt::AlignCenter, QString::number(t.button));
break; break;
case TabletMove: case TabletMove:
p.drawPath(pp); if (t.pressure > 0.0) {
break; p.setPen(t.ptype == QTabletEvent::Eraser ? Qt::red : Qt::black);
case TabletDraw: p.drawEllipse(t.pos, t.pressure * 10.0, t.pressure * 10.0);
p.fillPath(pp, Qt::blue); p.setPen(Qt::white);
} else {
p.fillRect(t.pos.x() - 2, t.pos.y() - 2, 4, 4, Qt::black);
}
break; break;
} }
} }
@ -128,37 +143,30 @@ void EventReportWidget::paintEvent(QPaintEvent *)
void EventReportWidget::tabletEvent(QTabletEvent *event) void EventReportWidget::tabletEvent(QTabletEvent *event)
{ {
QWidget::tabletEvent(event);
QWidget::tabletEvent(event);
QString type; QString type;
switch (event->type()) { switch (event->type()) {
case QEvent::TabletEnterProximity: case QEvent::TabletEnterProximity:
m_lastIsTabletMove = false;
type = QString::fromLatin1("TabletEnterProximity"); type = QString::fromLatin1("TabletEnterProximity");
break; break;
case QEvent::TabletLeaveProximity: case QEvent::TabletLeaveProximity:
m_lastIsTabletMove = false;
type = QString::fromLatin1("TabletLeaveProximity"); type = QString::fromLatin1("TabletLeaveProximity");
break; break;
case QEvent::TabletMove: case QEvent::TabletMove:
if (m_lastIsTabletMove)
return;
m_lastIsTabletMove = true;
type = QString::fromLatin1("TabletMove"); type = QString::fromLatin1("TabletMove");
m_points.push_back(TabletPoint(event->pos(), event->pressure() ? TabletDraw : TabletMove)); m_points.push_back(TabletPoint(event->pos(), TabletMove, m_lastButton, event->pointerType(), event->pressure()));
update(); update();
break; break;
case QEvent::TabletPress: case QEvent::TabletPress:
m_lastIsTabletMove = false;
type = QString::fromLatin1("TabletPress"); type = QString::fromLatin1("TabletPress");
m_points.push_back(TabletPoint(event->pos(), TabletButtonPress)); m_points.push_back(TabletPoint(event->pos(), TabletButtonPress, event->button(), event->pointerType()));
m_lastButton = event->button();
update(); update();
break; break;
case QEvent::TabletRelease: case QEvent::TabletRelease:
m_lastIsTabletMove = false;
type = QString::fromLatin1("TabletRelease"); type = QString::fromLatin1("TabletRelease");
m_points.push_back(TabletPoint(event->pos(), TabletButtonRelease)); m_points.push_back(TabletPoint(event->pos(), TabletButtonRelease, event->button(), event->pointerType()));
update(); update();
break; break;
default: default:
@ -166,10 +174,51 @@ void EventReportWidget::tabletEvent(QTabletEvent *event)
break; break;
} }
qDebug() << "Tablet event, type = " << type QString pointerType = "UNKNOWN";
<< " position = " << event->pos() switch (event->pointerType()) {
<< " global position = " << event->globalPos() case QTabletEvent::Pen:
<< " cursor at " << QCursor::pos(); pointerType = "Pen";
break;
case QTabletEvent::Cursor:
pointerType = "Cursor";
break;
case QTabletEvent::Eraser:
pointerType = "Eraser";
break;
default:
break;
}
QString device = "UNKNOWN";
switch (event->device()) {
case QTabletEvent::Puck:
pointerType = "Puck";
break;
case QTabletEvent::Stylus:
pointerType = "Stylus";
break;
case QTabletEvent::Airbrush:
pointerType = "Airbrush";
break;
case QTabletEvent::FourDMouse:
pointerType = "FourDMouse";
break;
case QTabletEvent::RotationStylus:
pointerType = "RotationStylus";
break;
default:
break;
}
if (!m_lastIsTabletMove)
qDebug() << "Tablet event, type = " << type
<< " position = " << event->pos()
<< " global position = " << event->globalPos()
<< " cursor at " << QCursor::pos()
<< " buttons " << event->buttons() << " changed " << event->button()
<< " pointer type " << pointerType << " device " << device;
m_lastIsTabletMove = (event->type() == QEvent::TabletMove);
} }
void EventReportWidget::outputMouseEvent(QMouseEvent *event) void EventReportWidget::outputMouseEvent(QMouseEvent *event)