diff options
author | Shawn Rutledge <shawn.rutledge@digia.com> | 2015-07-27 12:02:06 +0200 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@theqtcompany.com> | 2015-07-31 04:33:20 +0000 |
commit | 6a991f9cce9da6057c4a053e52e5956284805eea (patch) | |
tree | dd6b2fb68016c8723728ea9114f05b603196bfe9 /examples/widgets/widgets | |
parent | ad4d25589fcd5efd4faa3074c19928d195f615bb (diff) |
Tablet example: smoother, rotation stylus, better airbrush
The drawing is antialiased and with rounded caps and joins.
Rotation stylus acts like a felt marker.
Airbrush sprays a radial gradient of color, and its alpha can
depend on the tangential pressure if so chosen.
Task-number: QTBUG-46694
Change-Id: I4fb16eb621707e3c56a75aa302dd0d3bf418a745
Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
Reviewed-by: Topi Reiniö <topi.reinio@digia.com>
Diffstat (limited to 'examples/widgets/widgets')
-rw-r--r-- | examples/widgets/widgets/tablet/mainwindow.cpp | 11 | ||||
-rw-r--r-- | examples/widgets/widgets/tablet/mainwindow.h | 1 | ||||
-rw-r--r-- | examples/widgets/widgets/tablet/tabletcanvas.cpp | 107 | ||||
-rw-r--r-- | examples/widgets/widgets/tablet/tabletcanvas.h | 8 |
4 files changed, 68 insertions, 59 deletions
diff --git a/examples/widgets/widgets/tablet/mainwindow.cpp b/examples/widgets/widgets/tablet/mainwindow.cpp index aed84c50df..5e84f5b6a2 100644 --- a/examples/widgets/widgets/tablet/mainwindow.cpp +++ b/examples/widgets/widgets/tablet/mainwindow.cpp @@ -52,7 +52,7 @@ MainWindow::MainWindow(TabletCanvas *canvas) myCanvas->setColor(Qt::red); myCanvas->setLineWidthType(TabletCanvas::LineWidthPressure); - myCanvas->setAlphaChannelType(TabletCanvas::NoAlpha); + myCanvas->setAlphaChannelType(TabletCanvas::AlphaTangentialPressure); myCanvas->setColorSaturationType(TabletCanvas::NoSaturation); setWindowTitle(tr("Tablet Example")); @@ -75,6 +75,8 @@ void MainWindow::alphaActionTriggered(QAction *action) { if (action == alphaChannelPressureAction) { myCanvas->setAlphaChannelType(TabletCanvas::AlphaPressure); + } else if (action == alphaChannelTangentialPressureAction) { + myCanvas->setAlphaChannelType(TabletCanvas::AlphaTangentialPressure); } else if (action == alphaChannelTiltAction) { myCanvas->setAlphaChannelType(TabletCanvas::AlphaTilt); } else { @@ -157,15 +159,19 @@ void MainWindow::createActions() alphaChannelPressureAction = new QAction(tr("&Pressure"), this); alphaChannelPressureAction->setCheckable(true); + alphaChannelTangentialPressureAction = new QAction(tr("T&angential Pressure"), this); + alphaChannelTangentialPressureAction->setCheckable(true); + alphaChannelTangentialPressureAction->setChecked(true); + alphaChannelTiltAction = new QAction(tr("&Tilt"), this); alphaChannelTiltAction->setCheckable(true); noAlphaChannelAction = new QAction(tr("No Alpha Channel"), this); noAlphaChannelAction->setCheckable(true); - noAlphaChannelAction->setChecked(true); alphaChannelGroup = new QActionGroup(this); alphaChannelGroup->addAction(alphaChannelPressureAction); + alphaChannelGroup->addAction(alphaChannelTangentialPressureAction); alphaChannelGroup->addAction(alphaChannelTiltAction); alphaChannelGroup->addAction(noAlphaChannelAction); connect(alphaChannelGroup, SIGNAL(triggered(QAction*)), @@ -259,6 +265,7 @@ void MainWindow::createMenus() alphaChannelMenu = tabletMenu->addMenu(tr("&Alpha Channel")); alphaChannelMenu->addAction(alphaChannelPressureAction); + alphaChannelMenu->addAction(alphaChannelTangentialPressureAction); alphaChannelMenu->addAction(alphaChannelTiltAction); alphaChannelMenu->addAction(noAlphaChannelAction); diff --git a/examples/widgets/widgets/tablet/mainwindow.h b/examples/widgets/widgets/tablet/mainwindow.h index 5e77ea1acf..c6ac2e6026 100644 --- a/examples/widgets/widgets/tablet/mainwindow.h +++ b/examples/widgets/widgets/tablet/mainwindow.h @@ -79,6 +79,7 @@ private: QActionGroup *alphaChannelGroup; QAction *alphaChannelPressureAction; + QAction *alphaChannelTangentialPressureAction; QAction *alphaChannelTiltAction; QAction *noAlphaChannelAction; diff --git a/examples/widgets/widgets/tablet/tabletcanvas.cpp b/examples/widgets/widgets/tablet/tabletcanvas.cpp index 20d6291292..bf98a6d621 100644 --- a/examples/widgets/widgets/tablet/tabletcanvas.cpp +++ b/examples/widgets/widgets/tablet/tabletcanvas.cpp @@ -47,14 +47,13 @@ TabletCanvas::TabletCanvas() { resize(500, 500); - myBrush = QBrush(); - myPen = QPen(); + myColor = Qt::red; + myBrush = QBrush(myColor); + myPen = QPen(myBrush, 1.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); initPixmap(); setAutoFillBackground(true); deviceDown = false; - myColor = Qt::red; - myTabletDevice = QTabletEvent::Stylus; - alphaChannelType = NoAlpha; + alphaChannelType = AlphaTangentialPressure; colorSaturationType = NoSaturation; lineWidthType = LineWidthPressure; } @@ -99,24 +98,23 @@ void TabletCanvas::tabletEvent(QTabletEvent *event) case QEvent::TabletPress: if (!deviceDown) { deviceDown = true; - polyLine[0] = polyLine[1] = polyLine[2] = event->pos(); + lastPoint.pos = event->posF(); + lastPoint.rotation = event->rotation(); } break; - case QEvent::TabletRelease: - if (deviceDown) - deviceDown = false; - break; case QEvent::TabletMove: - polyLine[2] = polyLine[1]; - polyLine[1] = polyLine[0]; - polyLine[0] = event->pos(); - if (deviceDown) { updateBrush(event); QPainter painter(&pixmap); paintPixmap(painter, event); + lastPoint.pos = event->posF(); + lastPoint.rotation = event->rotation(); } break; + case QEvent::TabletRelease: + if (deviceDown && event->buttons() == Qt::NoButton) + deviceDown = false; + break; default: break; } @@ -135,23 +133,44 @@ void TabletCanvas::paintEvent(QPaintEvent *) //! [5] void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event) { - QPoint brushAdjust(10, 10); + painter.setRenderHint(QPainter::Antialiasing); - switch (myTabletDevice) { + switch (event->device()) { +//! [6] case QTabletEvent::Airbrush: - myBrush.setColor(myColor); - myBrush.setStyle(brushPattern(event->pressure())); - painter.setPen(Qt::NoPen); - painter.setBrush(myBrush); - - for (int i = 0; i < 3; ++i) { - painter.drawEllipse(QRect(polyLine[i] - brushAdjust, - polyLine[i] + brushAdjust)); + { + painter.setPen(Qt::NoPen); + QRadialGradient grad(lastPoint.pos, myPen.widthF() * 10.0); + QColor color = myBrush.color(); + color.setAlphaF(color.alphaF() * 0.25); + grad.setColorAt(0, myBrush.color()); + grad.setColorAt(0.5, Qt::transparent); + painter.setBrush(grad); + qreal radius = grad.radius(); + painter.drawEllipse(event->posF(), radius, radius); } break; + case QTabletEvent::RotationStylus: + { + myBrush.setStyle(Qt::SolidPattern); + painter.setPen(Qt::NoPen); + painter.setBrush(myBrush); + QPolygonF poly; + qreal halfWidth = myPen.widthF(); + QPointF brushAdjust(qSin(qDegreesToRadians(lastPoint.rotation)) * halfWidth, + qCos(qDegreesToRadians(lastPoint.rotation)) * halfWidth); + poly << lastPoint.pos + brushAdjust; + poly << lastPoint.pos - brushAdjust; + brushAdjust = QPointF(qSin(qDegreesToRadians(event->rotation())) * halfWidth, + qCos(qDegreesToRadians(event->rotation())) * halfWidth); + poly << event->posF() - brushAdjust; + poly << event->posF() + brushAdjust; + painter.drawConvexPolygon(poly); + } + break; +//! [6] case QTabletEvent::Puck: case QTabletEvent::FourDMouse: - case QTabletEvent::RotationStylus: { const QString error(tr("This input device is not supported by the example.")); #ifndef QT_NO_STATUSTIP @@ -174,40 +193,13 @@ void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event) } // FALL-THROUGH case QTabletEvent::Stylus: - painter.setBrush(myBrush); painter.setPen(myPen); - painter.drawLine(polyLine[1], event->pos()); + painter.drawLine(lastPoint.pos, event->posF()); break; } } //! [5] -//! [6] -Qt::BrushStyle TabletCanvas::brushPattern(qreal value) -{ - int pattern = int((value) * 100.0) % 7; - - switch (pattern) { - case 0: - return Qt::SolidPattern; - case 1: - return Qt::Dense1Pattern; - case 2: - return Qt::Dense2Pattern; - case 3: - return Qt::Dense3Pattern; - case 4: - return Qt::Dense4Pattern; - case 5: - return Qt::Dense5Pattern; - case 6: - return Qt::Dense6Pattern; - default: - return Qt::Dense7Pattern; - } -} -//! [6] - //! [7] void TabletCanvas::updateBrush(QTabletEvent *event) { @@ -220,7 +212,13 @@ void TabletCanvas::updateBrush(QTabletEvent *event) switch (alphaChannelType) { case AlphaPressure: - myColor.setAlpha(int(event->pressure() * 255.0)); + myColor.setAlphaF(event->pressure()); + break; + case AlphaTangentialPressure: + if (event->device() == QTabletEvent::Airbrush) + myColor.setAlphaF(qMax(0.01, (event->tangentialPressure() + 1.0) / 2.0)); + else + myColor.setAlpha(255); break; case AlphaTilt: myColor.setAlpha(maximum(abs(vValue - 127), abs(hValue - 127))); @@ -271,5 +269,4 @@ void TabletCanvas::updateBrush(QTabletEvent *event) void TabletCanvas::resizeEvent(QResizeEvent *) { initPixmap(); - polyLine[0] = polyLine[1] = polyLine[2] = QPoint(); } diff --git a/examples/widgets/widgets/tablet/tabletcanvas.h b/examples/widgets/widgets/tablet/tabletcanvas.h index 873f3a7ab0..06090a9052 100644 --- a/examples/widgets/widgets/tablet/tabletcanvas.h +++ b/examples/widgets/widgets/tablet/tabletcanvas.h @@ -61,7 +61,7 @@ class TabletCanvas : public QWidget Q_OBJECT public: - enum AlphaChannelType { AlphaPressure, AlphaTilt, NoAlpha }; + enum AlphaChannelType { AlphaPressure, AlphaTangentialPressure, AlphaTilt, NoAlpha }; enum ColorSaturationType { SaturationVTilt, SaturationHTilt, SaturationPressure, NoSaturation }; enum LineWidthType { LineWidthPressure, LineWidthTilt, NoLineWidth }; @@ -107,7 +107,11 @@ private: QBrush myBrush; QPen myPen; bool deviceDown; - QPoint polyLine[3]; + + struct Point { + QPointF pos; + qreal rotation; + } lastPoint; }; //! [0] |