|  | Home · All Classes · All Functions · Overviews

# tabletcanvas.cpp Example File
widgets/tablet/tabletcanvas.cpp

     /****************************************************************************
     **
     ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     ** All rights reserved.
     ** Contact: Nokia Corporation (qt-info@nokia.com)
     **
     ** This file is part of the examples of the Qt Toolkit.
     **
     ** $QT_BEGIN_LICENSE:LGPL$
     ** Commercial Usage
     ** Licensees holding valid Qt Commercial licenses may use this file in
     ** accordance with the Qt Commercial License Agreement provided with the
     ** Software or, alternatively, in accordance with the terms contained in
     ** a written agreement between you and Nokia.
     **
     ** GNU Lesser General Public License Usage
     ** Alternatively, this file may be used under the terms of the GNU Lesser
     ** General Public License version 2.1 as published by the Free Software
     ** Foundation and appearing in the file LICENSE.LGPL included in the
     ** packaging of this file.  Please review the following information to
     ** ensure the GNU Lesser General Public License version 2.1 requirements
     ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
     **
     ** In addition, as a special exception, Nokia gives you certain additional
     ** rights.  These rights are described in the Nokia Qt LGPL Exception
     ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
     **
     ** GNU General Public License Usage
     ** Alternatively, this file may be used under the terms of the GNU
     ** General Public License version 3.0 as published by the Free Software
     ** Foundation and appearing in the file LICENSE.GPL included in the
     ** packaging of this file.  Please review the following information to
     ** ensure the GNU General Public License version 3.0 requirements will be
     ** met: http://www.gnu.org/copyleft/gpl.html.
     **
     ** If you have questions regarding the use of this file, please contact
     ** Nokia at qt-info@nokia.com.
     ** $QT_END_LICENSE$
     **
     ****************************************************************************/

     #include <QtGui>
     #include <math.h>

     #include "tabletcanvas.h"

     TabletCanvas::TabletCanvas()
     {
         resize(500, 500);
         myBrush = QBrush();
         myPen = QPen();
         initPixmap();
         setAutoFillBackground(true);
         deviceDown = false;
         myColor = Qt::red;
         myTabletDevice = QTabletEvent::Stylus;
         alphaChannelType = NoAlpha;
         colorSaturationType = NoSaturation;
         lineWidthType = LineWidthPressure;
     }

     void TabletCanvas::initPixmap()
     {
         QPixmap newPixmap = QPixmap(width(), height());
         newPixmap.fill(Qt::white);
         QPainter painter(&newPixmap);
         if (!pixmap.isNull())
             painter.drawPixmap(0, 0, pixmap);
         painter.end();
         pixmap = newPixmap;
     }

     bool TabletCanvas::saveImage(const QString &file)
     {
         return pixmap.save(file);
     }

     bool TabletCanvas::loadImage(const QString &file)
     {
         bool success = pixmap.load(file);

         if (success) {
             update();
             return true;
         }
         return false;
     }

     void TabletCanvas::tabletEvent(QTabletEvent *event)
     {

         switch (event->type()) {
             case QEvent::TabletPress:
                 if (!deviceDown) {
                     deviceDown = true;
                     polyLine[0] = polyLine[1] = polyLine[2] = event->pos();
                 }
                 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);
                 }
                 break;
             default:
                 break;
         }
         update();
     }

     void TabletCanvas::paintEvent(QPaintEvent *)
     {
         QPainter painter(this);
         painter.drawPixmap(0, 0, pixmap);
     }

     void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event)
     {
         QPoint brushAdjust(10, 10);

         switch (myTabletDevice) {
             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));
                 }
                 break;
             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
                     QStatusTipEvent status(error);
                     QApplication::sendEvent(this, &status);
     #else
                     qWarning() << error;
     #endif
                 }
                 break;
             default:
                 {
                     const QString error(tr("Unknown tablet device - treating as stylus"));
     #ifndef QT_NO_STATUSTIP
                     QStatusTipEvent status(error);
                     QApplication::sendEvent(this, &status);
     #else
                     qWarning() << error;
     #endif
                 }
                 // FALL-THROUGH
             case QTabletEvent::Stylus:
                 painter.setBrush(myBrush);
                 painter.setPen(myPen);
                 painter.drawLine(polyLine[1], event->pos());
                 break;
         }
     }

     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;
         }
     }

     void TabletCanvas::updateBrush(QTabletEvent *event)
     {
         int hue, saturation, value, alpha;
         myColor.getHsv(&hue, &saturation, &value, &alpha);

         int vValue = int(((event->yTilt() + 60.0) / 120.0) * 255);
         int hValue = int(((event->xTilt() + 60.0) / 120.0) * 255);

         switch (alphaChannelType) {
             case AlphaPressure:
                 myColor.setAlpha(int(event->pressure() * 255.0));
                 break;
             case AlphaTilt:
                 myColor.setAlpha(maximum(abs(vValue - 127), abs(hValue - 127)));
                 break;
             default:
                 myColor.setAlpha(255);
         }

         switch (colorSaturationType) {
             case SaturationVTilt:
                 myColor.setHsv(hue, vValue, value, alpha);
                 break;
             case SaturationHTilt:
                 myColor.setHsv(hue, hValue, value, alpha);
                 break;
             case SaturationPressure:
                 myColor.setHsv(hue, int(event->pressure() * 255.0), value, alpha);
                 break;
             default:
                 ;
         }

         switch (lineWidthType) {
             case LineWidthPressure:
                 myPen.setWidthF(event->pressure() * 10 + 1);
                 break;
             case LineWidthTilt:
                 myPen.setWidthF(maximum(abs(vValue - 127), abs(hValue - 127)) / 12);
                 break;
             default:
                 myPen.setWidthF(1);
         }

         if (event->pointerType() == QTabletEvent::Eraser) {
             myBrush.setColor(Qt::white);
             myPen.setColor(Qt::white);
             myPen.setWidthF(event->pressure() * 10 + 1);
         } else {
             myBrush.setColor(myColor);
             myPen.setColor(myColor);
         }
     }

     void TabletCanvas::resizeEvent(QResizeEvent *)
     {
         initPixmap();
         polyLine[0] = polyLine[1] = polyLine[2] = QPoint();
     }