1
<?xml version="1.0" encoding="iso-8859-1"?>
3
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
4
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
6
<title>Qt 4.0: pathdeform.cpp Example File (demos/deform/pathdeform.cpp)</title>
7
<style>h3.fn,span.fn { margin-left: 1cm; text-indent: -1cm; }
8
a:link { color: #004faf; text-decoration: none }
9
a:visited { color: #672967; text-decoration: none }
10
td.postheader { font-family: sans-serif }
11
tr.address { font-family: sans-serif }
12
body { background: #ffffff; color: black; }</style>
15
<table border="0" cellpadding="0" cellspacing="0" width="100%">
17
<td align="left" valign="top" width="32"><img src="images/qt-logo.png" align="left" width="32" height="32" border="0" /></td>
18
<td width="1"> </td><td class="postheader" valign="center"><a href="index.html"><font color="#004faf">Home</font></a> · <a href="classes.html"><font color="#004faf">All Classes</font></a> · <a href="mainclasses.html"><font color="#004faf">Main Classes</font></a> · <a href="annotated.html"><font color="#004faf">Annotated</font></a> · <a href="groups.html"><font color="#004faf">Grouped Classes</font></a> · <a href="functions.html"><font color="#004faf">Functions</font></a></td>
19
<td align="right" valign="top" width="230"><img src="images/trolltech-logo.png" align="right" width="203" height="32" border="0" /></td></tr></table><h1 align="center">pathdeform.cpp Example File<br /><small><small>demos/deform/pathdeform.cpp</small></small></h1>
20
<pre> #include "pathdeform.h"
22
#include <qapplication.h>
23
#include <qdebug.h>
24
#include <qlayout.h>
25
#include <qlineedit.h>
26
#include <qevent.h>
28
#include <math.h>
30
PathDeformWidget::PathDeformWidget(QWidget *parent)
33
setWindowTitle("Vector Deformation");
35
m_renderer = new PathDeformRenderer(this);
36
m_renderer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
38
ArthurGroupBox *mainGroup = new ArthurGroupBox(this);
39
mainGroup->setTitle("Vector Deformation");
41
ArthurGroupBox *radiusGroup = new ArthurGroupBox(mainGroup);
42
radiusGroup->setAttribute(Qt::WA_ContentsPropagated);
43
radiusGroup->setTitle("Lens radius");
44
QSlider *radiusSlider = new QSlider(Qt::Horizontal, radiusGroup);
45
radiusSlider->setRange(50, 150);
46
radiusSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
48
ArthurGroupBox *deformGroup = new ArthurGroupBox(mainGroup);
49
deformGroup->setAttribute(Qt::WA_ContentsPropagated);
50
deformGroup->setTitle("Deformation");
51
QSlider *deformSlider = new QSlider(Qt::Horizontal, deformGroup);
52
deformSlider->setRange(-100, 100);
53
deformSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
55
ArthurGroupBox *fontSizeGroup = new ArthurGroupBox(mainGroup);
56
fontSizeGroup->setAttribute(Qt::WA_ContentsPropagated);
57
fontSizeGroup->setTitle("Font Size");
58
QSlider *fontSizeSlider = new QSlider(Qt::Horizontal, fontSizeGroup);
59
fontSizeSlider->setRange(16, 200);
60
fontSizeSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
62
ArthurGroupBox *textGroup = new ArthurGroupBox(mainGroup);
63
textGroup->setAttribute(Qt::WA_ContentsPropagated);
64
textGroup->setTitle("Text");
65
QLineEdit *textInput = new QLineEdit(textGroup);
67
QPushButton *animateButton = new QPushButton(mainGroup);
68
animateButton->setText("Animated");
69
animateButton->setCheckable(true);
71
QPushButton *showSourceButton = new QPushButton(mainGroup);
72
showSourceButton->setText("Show Source");
73
// showSourceButton->setCheckable(true);
75
QPushButton *whatsThisButton = new QPushButton(mainGroup);
76
whatsThisButton->setText("What's This?");
77
whatsThisButton->setCheckable(true);
80
QHBoxLayout *mainLayout = new QHBoxLayout(this);
81
mainLayout->addWidget(m_renderer);
82
mainLayout->addWidget(mainGroup);
83
mainGroup->setFixedWidth(180);
85
QVBoxLayout *mainGroupLayout = new QVBoxLayout(mainGroup);
86
mainGroupLayout->addWidget(radiusGroup);
87
mainGroupLayout->addWidget(deformGroup);
88
mainGroupLayout->addWidget(fontSizeGroup);
89
mainGroupLayout->addWidget(textGroup);
90
mainGroupLayout->addWidget(animateButton);
91
mainGroupLayout->addStretch(1);
92
mainGroupLayout->addWidget(showSourceButton);
93
mainGroupLayout->addWidget(whatsThisButton);
95
QVBoxLayout *radiusGroupLayout = new QVBoxLayout(radiusGroup);
96
radiusGroupLayout->addWidget(radiusSlider);
98
QVBoxLayout *deformGroupLayout = new QVBoxLayout(deformGroup);
99
deformGroupLayout->addWidget(deformSlider);
101
QVBoxLayout *fontSizeGroupLayout = new QVBoxLayout(fontSizeGroup);
102
fontSizeGroupLayout->addWidget(fontSizeSlider);
104
QVBoxLayout *textGroupLayout = new QVBoxLayout(textGroup);
105
textGroupLayout->addWidget(textInput);
107
connect(textInput, SIGNAL(textChanged(QString)), m_renderer, SLOT(setText(QString)));
108
connect(radiusSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setRadius(int)));
109
connect(deformSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setIntensity(int)));
110
connect(fontSizeSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setFontSize(int)));
111
connect(animateButton, SIGNAL(clicked(bool)), m_renderer, SLOT(setAnimated(bool)));
112
connect(whatsThisButton, SIGNAL(clicked(bool)), m_renderer, SLOT(setDescriptionEnabled(bool)));
113
connect(showSourceButton, SIGNAL(clicked()), m_renderer, SLOT(showSource()));
114
connect(m_renderer, SIGNAL(descriptionEnabledChanged(bool)),
115
whatsThisButton, SLOT(setChecked(bool)));
117
animateButton->animateClick();
118
deformSlider->setValue(80);
119
radiusSlider->setValue(100);
120
fontSizeSlider->setValue(120);
121
textInput->setText("Qt");
123
m_renderer->loadSourceFile(":res/pathdeform.cpp");
124
m_renderer->loadDescription(":res/pathdeform.html");
125
m_renderer->setDescriptionEnabled(false);
128
static inline QRect circle_bounds(const QPointF &center, double radius, double compensation)
130
return QRect(qRound(center.x() - radius - compensation),
131
qRound(center.y() - radius - compensation),
132
qRound((radius + compensation) * 2),
133
qRound((radius + compensation) * 2));
137
const int LENS_EXTENT = 10;
139
PathDeformRenderer::PathDeformRenderer(QWidget *widget)
140
: ArthurFrame(widget)
143
m_pos = QPointF(m_radius, m_radius);
144
m_direction = QPointF(1, 1);
147
m_repaintTimer.start(25, this);
148
m_repaintTracker.start();
151
// m_fpsTimer.start(1000, this);
154
generateLensPixmap();
157
void PathDeformRenderer::setText(const QString &text)
161
QFont f("times new roman,utopia");
162
f.setStyleStrategy(QFont::ForceOutline);
163
f.setPointSize(m_fontSize);
164
f.setStyleHint(QFont::Times);
169
m_pathBounds = QRect();
171
QPointF advance(0, 0);
173
bool do_quick = true;
174
for (int i=0; i<text.size(); ++i) {
175
if (text.at(i).unicode() >= 0x4ff && text.at(i).unicode() <= 0x1e00) {
182
for (int i=0; i<text.size(); ++i) {
184
path.addText(advance, f, text.mid(i, 1));
185
m_pathBounds |= path.boundingRect();
186
m_paths << path;
187
advance += QPointF(fm.width(text.mid(i, 1)), 0);
191
path.addText(advance, f, text);
192
m_pathBounds |= path.boundingRect();
193
m_paths << path;
196
for (int i=0; i<m_paths.size(); ++i)
197
m_paths[i] = m_paths[i] * QMatrix(1, 0, 0, 1, -m_pathBounds.x(), -m_pathBounds.y());
202
void PathDeformRenderer::generateLensPixmap()
204
double rad = m_radius + LENS_EXTENT;
206
QRect bounds = circle_bounds(QPointF(), rad, 0);
211
m_lens_image = QImage(bounds.size(), QImage::Format_ARGB32_Premultiplied);
212
m_lens_image.fill(0);
213
painter.begin(&m_lens_image);
215
m_lens_pixmap = QPixmap(bounds.size());
216
m_lens_pixmap.fill(QColor(0, 0, 0, 0));
217
painter.begin(&m_lens_pixmap);
220
QRadialGradient gr(rad, rad, rad, 3 * rad / 5, 3 * rad / 5);
221
gr.setColorAt(0.0, QColor(255, 255, 255, 191));
222
gr.setColorAt(0.2, QColor(255, 255, 127, 191));
223
gr.setColorAt(0.9, QColor(150, 150, 200, 63));
224
gr.setColorAt(0.95, QColor(0, 0, 0, 127));
225
gr.setColorAt(1, QColor(0, 0, 0, 0));
226
painter.setRenderHint(QPainter::Antialiasing);
227
painter.setBrush(gr);
228
painter.setPen(Qt::NoPen);
229
painter.drawEllipse(0, 0, bounds.width(), bounds.height());
232
void PathDeformRenderer::setAnimated(bool animated)
234
m_animated = animated;
237
// m_fpsTimer.start(1000, this);
239
m_repaintTimer.start(25, this);
240
m_repaintTracker.start();
242
// m_fpsTimer.stop();
243
m_repaintTimer.stop();
247
void PathDeformRenderer::timerEvent(QTimerEvent *e)
250
if (e->timerId() == m_repaintTimer.timerId()) {
252
if (QLineF(QPointF(0,0), m_direction).length() > 1)
253
m_direction *= 0.995;
254
double time = m_repaintTracker.restart();
256
QRect rectBefore = circle_bounds(m_pos, m_radius, m_fontSize);
258
double dx = m_direction.x();
259
double dy = m_direction.y();
265
m_pos += QPointF(dx, dy);
267
if (m_pos.x() - m_radius < 0) {
268
m_direction.setX(-m_direction.x());
269
m_pos.setX(m_radius);
270
} else if (m_pos.x() + m_radius > width()) {
271
m_direction.setX(-m_direction.x());
272
m_pos.setX(width() - m_radius);
275
if (m_pos.y() - m_radius < 0) {
276
m_direction.setY(-m_direction.y());
277
m_pos.setY(m_radius);
278
} else if (m_pos.y() + m_radius > height()) {
279
m_direction.setY(-m_direction.y());
280
m_pos.setY(height() - m_radius);
283
QRect rectAfter = circle_bounds(m_pos, m_radius, m_fontSize);
284
update(QRect(rectBefore | rectAfter));
285
QApplication::syncX();
287
// else if (e->timerId() == m_fpsTimer.timerId()) {
288
// printf("fps: %d\n", m_fpsCounter);
289
// emit frameRate(m_fpsCounter);
295
void PathDeformRenderer::mousePressEvent(QMouseEvent *e)
297
setDescriptionEnabled(false);
299
m_repaintTimer.stop();
300
m_offset = QPointF();
301
if (QLineF(m_pos, e->pos()).length() <= m_radius)
302
m_offset = m_pos - e->pos();
307
void PathDeformRenderer::mouseReleaseEvent(QMouseEvent *e)
309
if (e->buttons() == Qt::NoButton && m_animated) {
310
m_repaintTimer.start(10, this);
311
m_repaintTracker.start();
315
void PathDeformRenderer::mouseMoveEvent(QMouseEvent *e)
317
QRect rectBefore = circle_bounds(m_pos, m_radius, m_fontSize);
318
if (e->type() == QEvent::MouseMove) {
319
QLineF line(m_pos, e->pos() + m_offset);
320
line.setLength(line.length() * .1);
321
QPointF dir(line.dx(), line.dy());
322
m_direction = (m_direction + dir) / 2;
324
m_pos = e->pos() + m_offset;
325
QRect rectAfter = circle_bounds(m_pos, m_radius, m_fontSize);
326
update(rectBefore | rectAfter);
329
QPainterPath PathDeformRenderer::lensDeform(const QPainterPath &source, const QPointF &offset)
332
path.addPath(source);
334
double flip = m_intensity;
336
for (int i=0; i<path.elementCount(); ++i) {
337
QPainterPath::Element &e = const_cast<QPainterPath::Element &>(path.elementAt(i));
339
double x = e.x + offset.x();
340
double y = e.y + offset.y();
342
double dx = x - m_pos.x();
343
double dy = y - m_pos.y();
344
double len = m_radius - sqrt(dx * dx + dy * dy);
347
e.x = x + flip * dx * len / m_radius;
348
e.y = y + flip * dy * len / m_radius;
359
void PathDeformRenderer::paint(QPainter *painter)
364
int skip_x = qRound(m_pathBounds.width() + pad_x + m_fontSize/2);
365
int skip_y = qRound(m_pathBounds.height() + pad_y);
367
painter->setPen(Qt::NoPen);
368
painter->setBrush(Qt::black);
370
QRectF clip(painter->clipPath().boundingRect());
372
int overlap = pad_x / 2;
374
for (int start_y=0; start_y < height(); start_y += skip_y) {
376
if (start_y > clip.bottom())
379
int start_x = -overlap;
380
for (; start_x < width(); start_x += skip_x) {
382
if (start_y + skip_y >= clip.top() &&
383
start_x + skip_x >= clip.left() &&
384
start_x <= clip.right()) {
385
for (int i=0; i<m_paths.size(); ++i) {
386
QPainterPath path = lensDeform(m_paths[i], QPointF(start_x, start_y));
387
painter->drawPath(path);
391
overlap = skip_x - (start_x - width());
396
painter->drawImage(m_pos - QPointF(m_radius + LENS_EXTENT, m_radius + LENS_EXTENT),
399
painter->drawPixmap(m_pos - QPointF(m_radius + LENS_EXTENT, m_radius + LENS_EXTENT),
404
void PathDeformRenderer::setRadius(int radius)
406
double max = qMax(m_radius, (double)radius);
408
generateLensPixmap();
409
if (!m_animated || m_radius < max)
410
update(circle_bounds(m_pos, max, m_fontSize));
413
void PathDeformRenderer::setIntensity(int intensity)
415
m_intensity = intensity / 100.0;
417
update(circle_bounds(m_pos, m_radius, m_fontSize));
419
<p /><address><hr /><div align="center">
420
<table width="100%" cellspacing="0" border="0"><tr class="address">
421
<td width="30%">Copyright © 2005 <a href="trolltech.html">Trolltech</a></td>
422
<td width="40%" align="center"><a href="trademarks.html">Trademarks</a></td>
423
<td width="30%" align="right"><div align="right">Qt 4.0.0</div></td>
424
</tr></table></div></address></body>