source: trunk/examples/widgets/tablet/tabletcanvas.cpp@ 1147

Last change on this file since 1147 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 7.7 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the examples of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:BSD$
10** You may use this file under the terms of the BSD license as follows:
11**
12** "Redistribution and use in source and binary forms, with or without
13** modification, are permitted provided that the following conditions are
14** met:
15** * Redistributions of source code must retain the above copyright
16** notice, this list of conditions and the following disclaimer.
17** * Redistributions in binary form must reproduce the above copyright
18** notice, this list of conditions and the following disclaimer in
19** the documentation and/or other materials provided with the
20** distribution.
21** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22** the names of its contributors may be used to endorse or promote
23** products derived from this software without specific prior written
24** permission.
25**
26** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#include <QtGui>
42#include <math.h>
43
44#include "tabletcanvas.h"
45
46//! [0]
47TabletCanvas::TabletCanvas()
48{
49 resize(500, 500);
50 myBrush = QBrush();
51 myPen = QPen();
52 initPixmap();
53 setAutoFillBackground(true);
54 deviceDown = false;
55 myColor = Qt::red;
56 myTabletDevice = QTabletEvent::Stylus;
57 alphaChannelType = NoAlpha;
58 colorSaturationType = NoSaturation;
59 lineWidthType = LineWidthPressure;
60}
61
62void TabletCanvas::initPixmap()
63{
64 QPixmap newPixmap = QPixmap(width(), height());
65 newPixmap.fill(Qt::white);
66 QPainter painter(&newPixmap);
67 if (!pixmap.isNull())
68 painter.drawPixmap(0, 0, pixmap);
69 painter.end();
70 pixmap = newPixmap;
71}
72//! [0]
73
74//! [1]
75bool TabletCanvas::saveImage(const QString &file)
76{
77 return pixmap.save(file);
78}
79//! [1]
80
81//! [2]
82bool TabletCanvas::loadImage(const QString &file)
83{
84 bool success = pixmap.load(file);
85
86 if (success) {
87 update();
88 return true;
89 }
90 return false;
91}
92//! [2]
93
94//! [3]
95void TabletCanvas::tabletEvent(QTabletEvent *event)
96{
97
98 switch (event->type()) {
99 case QEvent::TabletPress:
100 if (!deviceDown) {
101 deviceDown = true;
102 polyLine[0] = polyLine[1] = polyLine[2] = event->pos();
103 }
104 break;
105 case QEvent::TabletRelease:
106 if (deviceDown)
107 deviceDown = false;
108 break;
109 case QEvent::TabletMove:
110 polyLine[2] = polyLine[1];
111 polyLine[1] = polyLine[0];
112 polyLine[0] = event->pos();
113
114 if (deviceDown) {
115 updateBrush(event);
116 QPainter painter(&pixmap);
117 paintPixmap(painter, event);
118 }
119 break;
120 default:
121 break;
122 }
123 update();
124}
125//! [3]
126
127//! [4]
128void TabletCanvas::paintEvent(QPaintEvent *)
129{
130 QPainter painter(this);
131 painter.drawPixmap(0, 0, pixmap);
132}
133//! [4]
134
135//! [5]
136void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event)
137{
138 QPoint brushAdjust(10, 10);
139
140 switch (myTabletDevice) {
141 case QTabletEvent::Airbrush:
142 myBrush.setColor(myColor);
143 myBrush.setStyle(brushPattern(event->pressure()));
144 painter.setPen(Qt::NoPen);
145 painter.setBrush(myBrush);
146
147 for (int i = 0; i < 3; ++i) {
148 painter.drawEllipse(QRect(polyLine[i] - brushAdjust,
149 polyLine[i] + brushAdjust));
150 }
151 break;
152 case QTabletEvent::Puck:
153 case QTabletEvent::FourDMouse:
154 case QTabletEvent::RotationStylus:
155 {
156 const QString error(tr("This input device is not supported by the example."));
157#ifndef QT_NO_STATUSTIP
158 QStatusTipEvent status(error);
159 QApplication::sendEvent(this, &status);
160#else
161 qWarning() << error;
162#endif
163 }
164 break;
165 default:
166 {
167 const QString error(tr("Unknown tablet device - treating as stylus"));
168#ifndef QT_NO_STATUSTIP
169 QStatusTipEvent status(error);
170 QApplication::sendEvent(this, &status);
171#else
172 qWarning() << error;
173#endif
174 }
175 // FALL-THROUGH
176 case QTabletEvent::Stylus:
177 painter.setBrush(myBrush);
178 painter.setPen(myPen);
179 painter.drawLine(polyLine[1], event->pos());
180 break;
181 }
182}
183//! [5]
184
185//! [6]
186Qt::BrushStyle TabletCanvas::brushPattern(qreal value)
187{
188 int pattern = int((value) * 100.0) % 7;
189
190 switch (pattern) {
191 case 0:
192 return Qt::SolidPattern;
193 case 1:
194 return Qt::Dense1Pattern;
195 case 2:
196 return Qt::Dense2Pattern;
197 case 3:
198 return Qt::Dense3Pattern;
199 case 4:
200 return Qt::Dense4Pattern;
201 case 5:
202 return Qt::Dense5Pattern;
203 case 6:
204 return Qt::Dense6Pattern;
205 default:
206 return Qt::Dense7Pattern;
207 }
208}
209//! [6]
210
211//! [7]
212void TabletCanvas::updateBrush(QTabletEvent *event)
213{
214 int hue, saturation, value, alpha;
215 myColor.getHsv(&hue, &saturation, &value, &alpha);
216
217 int vValue = int(((event->yTilt() + 60.0) / 120.0) * 255);
218 int hValue = int(((event->xTilt() + 60.0) / 120.0) * 255);
219//! [7] //! [8]
220
221 switch (alphaChannelType) {
222 case AlphaPressure:
223 myColor.setAlpha(int(event->pressure() * 255.0));
224 break;
225 case AlphaTilt:
226 myColor.setAlpha(maximum(abs(vValue - 127), abs(hValue - 127)));
227 break;
228 default:
229 myColor.setAlpha(255);
230 }
231
232//! [8] //! [9]
233 switch (colorSaturationType) {
234 case SaturationVTilt:
235 myColor.setHsv(hue, vValue, value, alpha);
236 break;
237 case SaturationHTilt:
238 myColor.setHsv(hue, hValue, value, alpha);
239 break;
240 case SaturationPressure:
241 myColor.setHsv(hue, int(event->pressure() * 255.0), value, alpha);
242 break;
243 default:
244 ;
245 }
246
247//! [9] //! [10]
248 switch (lineWidthType) {
249 case LineWidthPressure:
250 myPen.setWidthF(event->pressure() * 10 + 1);
251 break;
252 case LineWidthTilt:
253 myPen.setWidthF(maximum(abs(vValue - 127), abs(hValue - 127)) / 12);
254 break;
255 default:
256 myPen.setWidthF(1);
257 }
258
259//! [10] //! [11]
260 if (event->pointerType() == QTabletEvent::Eraser) {
261 myBrush.setColor(Qt::white);
262 myPen.setColor(Qt::white);
263 myPen.setWidthF(event->pressure() * 10 + 1);
264 } else {
265 myBrush.setColor(myColor);
266 myPen.setColor(myColor);
267 }
268}
269//! [11]
270
271void TabletCanvas::resizeEvent(QResizeEvent *)
272{
273 initPixmap();
274 polyLine[0] = polyLine[1] = polyLine[2] = QPoint();
275}
Note: See TracBrowser for help on using the repository browser.