Mega Code Archive

 
Categories / C++ / Qt
 

Tablet widget

/**************************************************************************** ** ** Copyright (C) 2009 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$ ** ****************************************************************************/ #ifndef TABLETCANVAS_H #define TABLETCANVAS_H #include <QWidget> #include <QImage> #include <QPoint> #include <QTabletEvent> #include <QColor> #include <QBrush> #include <QPen> #include <QPoint> QT_BEGIN_NAMESPACE class QPaintEvent; class QString; QT_END_NAMESPACE class TabletCanvas : public QWidget {     Q_OBJECT public:     enum AlphaChannelType { AlphaPressure, AlphaTilt, NoAlpha };     enum ColorSaturationType { SaturationVTilt, SaturationHTilt,                                SaturationPressure, NoSaturation };     enum LineWidthType { LineWidthPressure, LineWidthTilt, NoLineWidth };     TabletCanvas();     bool saveImage(const QString &file);     bool loadImage(const QString &file);     void setAlphaChannelType(AlphaChannelType type)         { alphaChannelType = type; }     void setColorSaturationType(ColorSaturationType type)         { colorSaturationType = type; }     void setLineWidthType(LineWidthType type)         { lineWidthType = type; }     void setColor(const QColor &color)         { myColor = color; }     QColor color() const         { return myColor; }     void setTabletDevice(QTabletEvent::TabletDevice device)         { myTabletDevice = device; }     int maximum(int a, int b)         { return a > b ? a : b; } protected:     void tabletEvent(QTabletEvent *event);     void paintEvent(QPaintEvent *event);     void resizeEvent(QResizeEvent *event); private:     void initImage();     void paintImage(QPainter &painter, QTabletEvent *event);     Qt::BrushStyle brushPattern(qreal value);     void updateBrush(QTabletEvent *event);     AlphaChannelType alphaChannelType;     ColorSaturationType colorSaturationType;     LineWidthType lineWidthType;     QTabletEvent::PointerType pointerType;     QTabletEvent::TabletDevice myTabletDevice;     QColor myColor;     QImage image;     QBrush myBrush;     QPen myPen;     bool deviceDown;     QPoint polyLine[3]; }; #endif #include <QtGui> #include <math.h> #include "tabletcanvas.h" TabletCanvas::TabletCanvas() {     resize(500, 500);     myBrush = QBrush();     myPen = QPen();     initImage();     setAutoFillBackground(true);     deviceDown = false;     myColor = Qt::red;     myTabletDevice = QTabletEvent::Stylus;     alphaChannelType = NoAlpha;     colorSaturationType = NoSaturation;     lineWidthType = LineWidthPressure; } void TabletCanvas::initImage() {     QImage newImage = QImage(width(), height(), QImage::Format_ARGB32);     QPainter painter(&newImage);     painter.fillRect(0, 0, newImage.width(), newImage.height(), Qt::white);     if (!image.isNull())         painter.drawImage(0, 0, image);     painter.end();     image = newImage; } bool TabletCanvas::saveImage(const QString &file) {     return image.save(file); } bool TabletCanvas::loadImage(const QString &file) {     bool success = image.load(file);     if (success) {         update();         return true;     }     return false; } void TabletCanvas::tabletEvent(QTabletEvent *event) {     switch (event->type()) {         case QEvent::TabletPress:             if (!deviceDown)                 deviceDown = true;             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(&image);                 paintImage(painter, event);             }             break;         default:             break;     }     update(); } void TabletCanvas::paintEvent(QPaintEvent *) {     QPainter painter(this);     painter.drawImage(QPoint(0, 0), image); } void TabletCanvas::paintImage(QPainter &painter, QTabletEvent *event) {     QPoint brushAdjust(10, 10);     switch (myTabletDevice) {         case QTabletEvent::Stylus:             painter.setBrush(myBrush);             painter.setPen(myPen);             painter.drawLine(polyLine[1], event->pos());             break;         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:             qWarning("This input device is not supported by the example.");             break;         default:             qWarning("Unknown tablet device.");     } } 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 *event) {     initImage();     polyLine[0] = polyLine[1] = polyLine[2] = QPoint(); } #ifndef TABLETAPPLICATION_H #define TABLETAPPLICATION_H #include <QApplication> #include "tabletcanvas.h" class TabletApplication : public QApplication {     Q_OBJECT public:     TabletApplication(int &argv, char **args)     : QApplication(argv, args) {}     bool event(QEvent *event);     void setCanvas(TabletCanvas *canvas)         { myCanvas = canvas; } private:     TabletCanvas *myCanvas; }; #endif #include <QtGui> #include "tabletapplication.h" bool TabletApplication::event(QEvent *event) {     if (event->type() == QEvent::TabletEnterProximity ||         event->type() == QEvent::TabletLeaveProximity) {         myCanvas->setTabletDevice(             static_cast<QTabletEvent *>(event)->device());         return true;     }     return QApplication::event(event); } #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> QT_BEGIN_NAMESPACE class QAction; class QActionGroup; class QMenu; class QStatusBar; QT_END_NAMESPACE class TabletCanvas; class MainWindow : public QMainWindow {     Q_OBJECT public:     MainWindow(TabletCanvas *canvas); private slots:     void brushColorAct();     void alphaActionTriggered(QAction *action);     void lineWidthActionTriggered(QAction *action);     void saturationActionTriggered(QAction *action);     void saveAct();     void loadAct();     void aboutAct(); private:     void createActions();     void createMenus();     TabletCanvas *myCanvas;     QAction *brushColorAction;     QActionGroup *brushActionGroup;     QActionGroup *alphaChannelGroup;     QAction *alphaChannelPressureAction;     QAction *alphaChannelTiltAction;     QAction *noAlphaChannelAction;     QActionGroup *colorSaturationGroup;     QAction *colorSaturationVTiltAction;     QAction *colorSaturationHTiltAction;     QAction *colorSaturationPressureAction;     QAction *noColorSaturationAction;     QActionGroup *lineWidthGroup;     QAction *lineWidthPressureAction;     QAction *lineWidthTiltAction;     QAction *lineWidthFixedAction;     QAction *exitAction;     QAction *saveAction;     QAction *loadAction;     QAction *aboutAction;     QAction *aboutQtAction;     QMenu *fileMenu;     QMenu *brushMenu;     QMenu *tabletMenu;     QMenu *helpMenu;     QMenu *colorSaturationMenu;     QMenu *lineWidthMenu;     QMenu *alphaChannelMenu; }; #endif #include <QtGui> #include "mainwindow.h" #include "tabletcanvas.h" MainWindow::MainWindow(TabletCanvas *canvas) {     myCanvas = canvas;     createActions();     createMenus();     myCanvas->setColor(Qt::red);     myCanvas->setLineWidthType(TabletCanvas::LineWidthPressure);     myCanvas->setAlphaChannelType(TabletCanvas::NoAlpha);     myCanvas->setColorSaturationType(TabletCanvas::NoSaturation);     setWindowTitle(tr("Tablet Example"));     setCentralWidget(myCanvas); } void MainWindow::brushColorAct() {     QColor color = QColorDialog::getColor(myCanvas->color());     if (color.isValid())         myCanvas->setColor(color); } void MainWindow::alphaActionTriggered(QAction *action) {     if (action == alphaChannelPressureAction) {         myCanvas->setAlphaChannelType(TabletCanvas::AlphaPressure);     } else if (action == alphaChannelTiltAction) {         myCanvas->setAlphaChannelType(TabletCanvas::AlphaTilt);     } else {         myCanvas->setAlphaChannelType(TabletCanvas::NoAlpha);     } } void MainWindow::lineWidthActionTriggered(QAction *action) {     if (action == lineWidthPressureAction) {         myCanvas->setLineWidthType(TabletCanvas::LineWidthPressure);     } else if (action == lineWidthTiltAction) {         myCanvas->setLineWidthType(TabletCanvas::LineWidthTilt);     } else {         myCanvas->setLineWidthType(TabletCanvas::NoLineWidth);     } } void MainWindow::saturationActionTriggered(QAction *action) {     if (action == colorSaturationVTiltAction) {         myCanvas->setColorSaturationType(TabletCanvas::SaturationVTilt);     } else if (action == colorSaturationHTiltAction) {         myCanvas->setColorSaturationType(TabletCanvas::SaturationHTilt);     } else if (action == colorSaturationPressureAction) {         myCanvas->setColorSaturationType(TabletCanvas::SaturationPressure);     } else {         myCanvas->setColorSaturationType(TabletCanvas::NoSaturation);     } } void MainWindow::saveAct() {     QString path = QDir::currentPath() + "/untitled.png";     QString fileName = QFileDialog::getSaveFileName(this, tr("Save Picture"),                              path);     if (!myCanvas->saveImage(fileName))         QMessageBox::information(this, "Error Saving Picture",                                  "Could not save the image"); } void MainWindow::loadAct() {     QString fileName = QFileDialog::getOpenFileName(this, tr("Open Picture"),                                                     QDir::currentPath());     if (!myCanvas->loadImage(fileName))         QMessageBox::information(this, "Error Opening Picture",                                  "Could not open picture"); } void MainWindow::aboutAct() {     QMessageBox::about(this, tr("About Tablet Example"),                        tr("This example shows use of a Wacom tablet in Qt")); } void MainWindow::createActions() {     brushColorAction = new QAction(tr("&Brush Color..."), this);     brushColorAction->setShortcut(tr("Ctrl+C"));     connect(brushColorAction, SIGNAL(triggered()),             this, SLOT(brushColorAct()));     alphaChannelPressureAction = new QAction(tr("&Pressure"), this);     alphaChannelPressureAction->setCheckable(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(alphaChannelTiltAction);     alphaChannelGroup->addAction(noAlphaChannelAction);     connect(alphaChannelGroup, SIGNAL(triggered(QAction *)),             this, SLOT(alphaActionTriggered(QAction *)));     colorSaturationVTiltAction = new QAction(tr("&Vertical Tilt"), this);     colorSaturationVTiltAction->setCheckable(true);     colorSaturationHTiltAction = new QAction(tr("&Horizontal Tilt"), this);     colorSaturationHTiltAction->setCheckable(true);     colorSaturationPressureAction = new QAction(tr("&Pressure"), this);     colorSaturationPressureAction->setCheckable(true);     noColorSaturationAction = new QAction(tr("&No Color Saturation"), this);     noColorSaturationAction->setCheckable(true);     noColorSaturationAction->setChecked(true);     colorSaturationGroup = new QActionGroup(this);     colorSaturationGroup->addAction(colorSaturationVTiltAction);     colorSaturationGroup->addAction(colorSaturationHTiltAction);     colorSaturationGroup->addAction(colorSaturationPressureAction);     colorSaturationGroup->addAction(noColorSaturationAction);     connect(colorSaturationGroup, SIGNAL(triggered(QAction *)),             this, SLOT(saturationActionTriggered(QAction *)));     lineWidthPressureAction = new QAction(tr("&Pressure"), this);     lineWidthPressureAction->setCheckable(true);     lineWidthPressureAction->setChecked(true);     lineWidthTiltAction = new QAction(tr("&Tilt"), this);     lineWidthTiltAction->setCheckable(true);     lineWidthFixedAction = new QAction(tr("&Fixed"), this);     lineWidthFixedAction->setCheckable(true);     lineWidthGroup = new QActionGroup(this);     lineWidthGroup->addAction(lineWidthPressureAction);     lineWidthGroup->addAction(lineWidthTiltAction);     lineWidthGroup->addAction(lineWidthFixedAction);     connect(lineWidthGroup, SIGNAL(triggered(QAction *)),             this, SLOT(lineWidthActionTriggered(QAction *)));     exitAction = new QAction(tr("E&xit"), this);     exitAction->setShortcut(tr("Ctrl+X"));     connect(exitAction, SIGNAL(triggered()),             this, SLOT(close()));     loadAction = new QAction(tr("&Open..."), this);     loadAction->setShortcut(tr("Ctrl+O"));     connect(loadAction, SIGNAL(triggered()),             this, SLOT(loadAct()));     saveAction = new QAction(tr("&Save As..."), this);     saveAction->setShortcut(tr("Ctrl+S"));     connect(saveAction, SIGNAL(triggered()),             this, SLOT(saveAct()));     aboutAction = new QAction(tr("A&bout"), this);     aboutAction->setShortcut(tr("Ctrl+B"));     connect(aboutAction, SIGNAL(triggered()),             this, SLOT(aboutAct()));     aboutQtAction = new QAction(tr("About &Qt"), this);     aboutQtAction->setShortcut(tr("Ctrl+Q"));     connect(aboutQtAction, SIGNAL(triggered()),             qApp, SLOT(aboutQt())); } void MainWindow::createMenus() {     fileMenu = menuBar()->addMenu(tr("&File"));     fileMenu->addAction(loadAction);     fileMenu->addAction(saveAction);     fileMenu->addSeparator();     fileMenu->addAction(exitAction);     brushMenu = menuBar()->addMenu(tr("&Brush"));     brushMenu->addAction(brushColorAction);     tabletMenu = menuBar()->addMenu(tr("&Tablet"));     lineWidthMenu = tabletMenu->addMenu(tr("&Line Width"));     lineWidthMenu->addAction(lineWidthPressureAction);     lineWidthMenu->addAction(lineWidthTiltAction);     lineWidthMenu->addAction(lineWidthFixedAction);     alphaChannelMenu = tabletMenu->addMenu(tr("&Alpha Channel"));     alphaChannelMenu->addAction(alphaChannelPressureAction);     alphaChannelMenu->addAction(alphaChannelTiltAction);     alphaChannelMenu->addAction(noAlphaChannelAction);     colorSaturationMenu = tabletMenu->addMenu(tr("&Color Saturation"));     colorSaturationMenu->addAction(colorSaturationVTiltAction);     colorSaturationMenu->addAction(colorSaturationHTiltAction);     colorSaturationMenu->addAction(noColorSaturationAction);     helpMenu = menuBar()->addMenu("&Help");     helpMenu->addAction(aboutAction);     helpMenu->addAction(aboutQtAction); } #include <QtGui> #include "mainwindow.h" #include "tabletapplication.h" #include "tabletcanvas.h" int main(int argv, char *args[]) {     TabletApplication app(argv, args);     TabletCanvas *canvas = new TabletCanvas;     app.setCanvas(canvas);     MainWindow mainWindow(canvas);     mainWindow.resize(500, 500);     mainWindow.show();     return app.exec(); }