1
/****************************************************************************
3
** Copyright (C) 2004-2005 Trolltech AS. All rights reserved.
5
** This file is part of the example classes of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
33
#include "mandelbrotwidget.h"
35
const double DefaultCenterX = -0.637011f;
36
const double DefaultCenterY = -0.0395159f;
37
const double DefaultScale = 0.00403897f;
39
const double ZoomInFactor = 0.8f;
40
const double ZoomOutFactor = 1 / ZoomInFactor;
41
const int ScrollStep = 20;
43
MandelbrotWidget::MandelbrotWidget(QWidget *parent)
46
centerX = DefaultCenterX;
47
centerY = DefaultCenterY;
48
pixmapScale = DefaultScale;
49
curScale = DefaultScale;
51
qRegisterMetaType<QImage>("QImage");
52
connect(&thread, SIGNAL(renderedImage(const QImage &, double)),
53
this, SLOT(updatePixmap(const QImage &, double)));
55
setWindowTitle(tr("Mandelbrot"));
56
setCursor(Qt::CrossCursor);
60
void MandelbrotWidget::paintEvent(QPaintEvent * /* event */)
62
QPainter painter(this);
63
painter.fillRect(rect(), Qt::black);
65
if (pixmap.isNull()) {
66
painter.setPen(Qt::white);
67
painter.drawText(rect(), Qt::AlignCenter,
68
tr("Rendering initial image, please wait..."));
72
if (curScale == pixmapScale) {
73
painter.drawPixmap(pixmapOffset, pixmap);
75
double scaleFactor = pixmapScale / curScale;
76
int newWidth = int(pixmap.width() * scaleFactor);
77
int newHeight = int(pixmap.height() * scaleFactor);
78
int newX = pixmapOffset.x() + (pixmap.width() - newWidth) / 2;
79
int newY = pixmapOffset.y() + (pixmap.height() - newHeight) / 2;
82
painter.translate(newX, newY);
83
painter.scale(scaleFactor, scaleFactor);
84
painter.drawPixmap(0, 0, pixmap);
88
QString text = tr("Use mouse wheel to zoom. "
89
"Press and hold left mouse button to scroll.");
90
QFontMetrics metrics = painter.fontMetrics();
91
int textWidth = metrics.width(text);
93
painter.setPen(Qt::NoPen);
94
painter.setBrush(QColor(0, 0, 0, 127));
95
painter.drawRect((width() - textWidth) / 2 - 5, 0, textWidth + 10,
96
metrics.lineSpacing() + 5);
97
painter.setPen(Qt::white);
98
painter.drawText((width() - textWidth) / 2,
99
metrics.leading() + metrics.ascent(), text);
102
void MandelbrotWidget::resizeEvent(QResizeEvent * /* event */)
104
thread.render(centerX, centerY, curScale, size());
107
void MandelbrotWidget::keyPressEvent(QKeyEvent *event)
109
switch (event->key()) {
117
scroll(-ScrollStep, 0);
120
scroll(+ScrollStep, 0);
123
scroll(0, -ScrollStep);
126
scroll(0, +ScrollStep);
129
QWidget::keyPressEvent(event);
133
void MandelbrotWidget::wheelEvent(QWheelEvent *event)
135
int numDegrees = event->delta() / 8;
136
double numSteps = numDegrees / 15.0f;
137
zoom(pow(ZoomInFactor, numSteps));
140
void MandelbrotWidget::mousePressEvent(QMouseEvent *event)
142
if (event->button() == Qt::LeftButton)
143
lastDragPos = event->pos();
146
void MandelbrotWidget::mouseMoveEvent(QMouseEvent *event)
148
if (event->buttons() & Qt::LeftButton) {
149
pixmapOffset += event->pos() - lastDragPos;
150
lastDragPos = event->pos();
155
void MandelbrotWidget::mouseReleaseEvent(QMouseEvent *event)
157
if (event->button() == Qt::LeftButton) {
158
pixmapOffset += event->pos() - lastDragPos;
159
lastDragPos = QPoint();
161
int deltaX = (width() - pixmap.width()) / 2 - pixmapOffset.x();
162
int deltaY = (height() - pixmap.height()) / 2 - pixmapOffset.y();
163
scroll(deltaX, deltaY);
167
void MandelbrotWidget::updatePixmap(const QImage &image, double scaleFactor)
169
if (!lastDragPos.isNull())
172
pixmap = QPixmap::fromImage(image);
173
pixmapOffset = QPoint();
174
lastDragPos = QPoint();
175
pixmapScale = scaleFactor;
179
void MandelbrotWidget::zoom(double zoomFactor)
181
curScale *= zoomFactor;
183
thread.render(centerX, centerY, curScale, size());
186
void MandelbrotWidget::scroll(int deltaX, int deltaY)
188
centerX += deltaX * curScale;
189
centerY += deltaY * curScale;
191
thread.render(centerX, centerY, curScale, size());