From 806dda08d685bc5f9ed71dfe8b61f21848d48066 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 17 Aug 2012 13:23:19 +0200 Subject: Moving .qdoc files under examples/widgets/doc Updated those .qdoc files to refer to the new relative examples emplacement. Images and snippets to be moved later. Also grouped all widgets related examples under widgets. Change-Id: Ib29696e2d8948524537f53e8dda88f9ee26a597f Reviewed-by: J-P Nurmi --- examples/widgets/painting/deform/pathdeform.cpp | 646 ++++++++++++++++++++++++ 1 file changed, 646 insertions(+) create mode 100644 examples/widgets/painting/deform/pathdeform.cpp (limited to 'examples/widgets/painting/deform/pathdeform.cpp') diff --git a/examples/widgets/painting/deform/pathdeform.cpp b/examples/widgets/painting/deform/pathdeform.cpp new file mode 100644 index 0000000000..d5880fb786 --- /dev/null +++ b/examples/widgets/painting/deform/pathdeform.cpp @@ -0,0 +1,646 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "pathdeform.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PathDeformControls::PathDeformControls(QWidget *parent, PathDeformRenderer* renderer, bool smallScreen) + : QWidget(parent) +{ + m_renderer = renderer; + + if (smallScreen) + layoutForSmallScreen(); + else + layoutForDesktop(); +} + + +void PathDeformControls::layoutForDesktop() +{ + QGroupBox* mainGroup = new QGroupBox(this); + mainGroup->setTitle(tr("Controls")); + + QGroupBox *radiusGroup = new QGroupBox(mainGroup); + radiusGroup->setTitle(tr("Lens Radius")); + QSlider *radiusSlider = new QSlider(Qt::Horizontal, radiusGroup); + radiusSlider->setRange(15, 150); + radiusSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + + QGroupBox *deformGroup = new QGroupBox(mainGroup); + deformGroup->setTitle(tr("Deformation")); + QSlider *deformSlider = new QSlider(Qt::Horizontal, deformGroup); + deformSlider->setRange(-100, 100); + deformSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + + QGroupBox *fontSizeGroup = new QGroupBox(mainGroup); + fontSizeGroup->setTitle(tr("Font Size")); + QSlider *fontSizeSlider = new QSlider(Qt::Horizontal, fontSizeGroup); + fontSizeSlider->setRange(16, 200); + fontSizeSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + + QGroupBox *textGroup = new QGroupBox(mainGroup); + textGroup->setTitle(tr("Text")); + QLineEdit *textInput = new QLineEdit(textGroup); + + QPushButton *animateButton = new QPushButton(mainGroup); + animateButton->setText(tr("Animated")); + animateButton->setCheckable(true); + + QPushButton *showSourceButton = new QPushButton(mainGroup); + showSourceButton->setText(tr("Show Source")); + +#ifdef QT_OPENGL_SUPPORT + QPushButton *enableOpenGLButton = new QPushButton(mainGroup); + enableOpenGLButton->setText(tr("Use OpenGL")); + enableOpenGLButton->setCheckable(true); + enableOpenGLButton->setChecked(m_renderer->usesOpenGL()); + if (!QGLFormat::hasOpenGL()) + enableOpenGLButton->hide(); +#endif + + QPushButton *whatsThisButton = new QPushButton(mainGroup); + whatsThisButton->setText(tr("What's This?")); + whatsThisButton->setCheckable(true); + + + mainGroup->setFixedWidth(180); + + QVBoxLayout *mainGroupLayout = new QVBoxLayout(mainGroup); + mainGroupLayout->addWidget(radiusGroup); + mainGroupLayout->addWidget(deformGroup); + mainGroupLayout->addWidget(fontSizeGroup); + mainGroupLayout->addWidget(textGroup); + mainGroupLayout->addWidget(animateButton); + mainGroupLayout->addStretch(1); +#ifdef QT_OPENGL_SUPPORT + mainGroupLayout->addWidget(enableOpenGLButton); +#endif + mainGroupLayout->addWidget(showSourceButton); + mainGroupLayout->addWidget(whatsThisButton); + + QVBoxLayout *radiusGroupLayout = new QVBoxLayout(radiusGroup); + radiusGroupLayout->addWidget(radiusSlider); + + QVBoxLayout *deformGroupLayout = new QVBoxLayout(deformGroup); + deformGroupLayout->addWidget(deformSlider); + + QVBoxLayout *fontSizeGroupLayout = new QVBoxLayout(fontSizeGroup); + fontSizeGroupLayout->addWidget(fontSizeSlider); + + QVBoxLayout *textGroupLayout = new QVBoxLayout(textGroup); + textGroupLayout->addWidget(textInput); + + QVBoxLayout * mainLayout = new QVBoxLayout(this); + mainLayout->addWidget(mainGroup); + mainLayout->setMargin(0); + + connect(radiusSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setRadius(int))); + connect(deformSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setIntensity(int))); + connect(fontSizeSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setFontSize(int))); + connect(animateButton, SIGNAL(clicked(bool)), m_renderer, SLOT(setAnimated(bool))); +#ifdef QT_OPENGL_SUPPORT + connect(enableOpenGLButton, SIGNAL(clicked(bool)), m_renderer, SLOT(enableOpenGL(bool))); +#endif + + connect(textInput, SIGNAL(textChanged(QString)), m_renderer, SLOT(setText(QString))); + connect(m_renderer, SIGNAL(descriptionEnabledChanged(bool)), + whatsThisButton, SLOT(setChecked(bool))); + connect(whatsThisButton, SIGNAL(clicked(bool)), m_renderer, SLOT(setDescriptionEnabled(bool))); + connect(showSourceButton, SIGNAL(clicked()), m_renderer, SLOT(showSource())); + + animateButton->animateClick(); + deformSlider->setValue(80); + fontSizeSlider->setValue(120); + radiusSlider->setValue(100); + textInput->setText(tr("Qt")); +} + +void PathDeformControls::layoutForSmallScreen() +{ + QGroupBox* mainGroup = new QGroupBox(this); + mainGroup->setTitle(tr("Controls")); + + QLabel *radiusLabel = new QLabel(mainGroup); + radiusLabel->setText(tr("Lens Radius:")); + QSlider *radiusSlider = new QSlider(Qt::Horizontal, mainGroup); + radiusSlider->setRange(15, 150); + radiusSlider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + + QLabel *deformLabel = new QLabel(mainGroup); + deformLabel->setText(tr("Deformation:")); + QSlider *deformSlider = new QSlider(Qt::Horizontal, mainGroup); + deformSlider->setRange(-100, 100); + deformSlider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + + QLabel *fontSizeLabel = new QLabel(mainGroup); + fontSizeLabel->setText(tr("Font Size:")); + QSlider *fontSizeSlider = new QSlider(Qt::Horizontal, mainGroup); + fontSizeSlider->setRange(16, 200); + fontSizeSlider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + + QPushButton *animateButton = new QPushButton(tr("Animated"), mainGroup); + animateButton->setCheckable(true); + +#ifdef QT_OPENGL_SUPPORT + QPushButton *enableOpenGLButton = new QPushButton(mainGroup); + enableOpenGLButton->setText(tr("Use OpenGL")); + enableOpenGLButton->setCheckable(mainGroup); + enableOpenGLButton->setChecked(m_renderer->usesOpenGL()); + if (!QGLFormat::hasOpenGL()) + enableOpenGLButton->hide(); +#endif + + QPushButton *quitButton = new QPushButton(tr("Quit"), mainGroup); + QPushButton *okButton = new QPushButton(tr("OK"), mainGroup); + + + QGridLayout *mainGroupLayout = new QGridLayout(mainGroup); + mainGroupLayout->setMargin(0); + mainGroupLayout->addWidget(radiusLabel, 0, 0, Qt::AlignRight); + mainGroupLayout->addWidget(radiusSlider, 0, 1); + mainGroupLayout->addWidget(deformLabel, 1, 0, Qt::AlignRight); + mainGroupLayout->addWidget(deformSlider, 1, 1); + mainGroupLayout->addWidget(fontSizeLabel, 2, 0, Qt::AlignRight); + mainGroupLayout->addWidget(fontSizeSlider, 2, 1); + mainGroupLayout->addWidget(animateButton, 3,0, 1,2); +#ifdef QT_OPENGL_SUPPORT + mainGroupLayout->addWidget(enableOpenGLButton, 4,0, 1,2); +#endif + + QVBoxLayout *mainLayout = new QVBoxLayout(this); + mainLayout->addWidget(mainGroup); + mainLayout->addStretch(1); + mainLayout->addWidget(okButton); + mainLayout->addWidget(quitButton); + + connect(quitButton, SIGNAL(clicked()), this, SLOT(emitQuitSignal())); + connect(okButton, SIGNAL(clicked()), this, SLOT(emitOkSignal())); + connect(radiusSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setRadius(int))); + connect(deformSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setIntensity(int))); + connect(fontSizeSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setFontSize(int))); + connect(animateButton, SIGNAL(clicked(bool)), m_renderer, SLOT(setAnimated(bool))); +#ifdef QT_OPENGL_SUPPORT + connect(enableOpenGLButton, SIGNAL(clicked(bool)), m_renderer, SLOT(enableOpenGL(bool))); +#endif + + + animateButton->animateClick(); + deformSlider->setValue(80); + fontSizeSlider->setValue(120); + + QRect screen_size = QApplication::desktop()->screenGeometry(); + radiusSlider->setValue(qMin(screen_size.width(), screen_size.height())/5); + + m_renderer->setText(tr("Qt")); +} + + +void PathDeformControls::emitQuitSignal() +{ emit quitPressed(); } + +void PathDeformControls::emitOkSignal() +{ emit okPressed(); } + + +PathDeformWidget::PathDeformWidget(QWidget *parent, bool smallScreen) + : QWidget(parent) +{ + setWindowTitle(tr("Vector Deformation")); + + m_renderer = new PathDeformRenderer(this, smallScreen); + m_renderer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + // Layouts + QHBoxLayout *mainLayout = new QHBoxLayout(this); + mainLayout->addWidget(m_renderer); + + m_controls = new PathDeformControls(0, m_renderer, smallScreen); + m_controls->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); + + if (!smallScreen) + mainLayout->addWidget(m_controls); + + m_renderer->loadSourceFile(":res/deform/pathdeform.cpp"); + m_renderer->loadDescription(":res/deform/pathdeform.html"); + m_renderer->setDescriptionEnabled(false); + + connect(m_renderer, SIGNAL(clicked()), this, SLOT(showControls())); + connect(m_controls, SIGNAL(okPressed()), this, SLOT(hideControls())); + connect(m_controls, SIGNAL(quitPressed()), QApplication::instance(), SLOT(quit())); +} + + +void PathDeformWidget::showControls() +{ + m_controls->showFullScreen(); +} + +void PathDeformWidget::hideControls() +{ + m_controls->hide(); +} + +void PathDeformWidget::setStyle( QStyle * style ) +{ + QWidget::setStyle(style); + if (m_controls != 0) + { + m_controls->setStyle(style); + + QList widgets = m_controls->findChildren(); + foreach (QWidget *w, widgets) + w->setStyle(style); + } +} + +static inline QRect circle_bounds(const QPointF ¢er, qreal radius, qreal compensation) +{ + return QRect(qRound(center.x() - radius - compensation), + qRound(center.y() - radius - compensation), + qRound((radius + compensation) * 2), + qRound((radius + compensation) * 2)); + +} + +const int LENS_EXTENT = 10; + +PathDeformRenderer::PathDeformRenderer(QWidget *widget, bool smallScreen) + : ArthurFrame(widget) +{ + m_radius = 100; + m_pos = QPointF(m_radius, m_radius); + m_direction = QPointF(1, 1); + m_fontSize = 24; + m_animated = true; + m_repaintTimer.start(25, this); + m_repaintTracker.start(); + m_intensity = 100; + m_smallScreen = smallScreen; + +// m_fpsTimer.start(1000, this); +// m_fpsCounter = 0; + + generateLensPixmap(); +} + +void PathDeformRenderer::setText(const QString &text) +{ + m_text = text; + + QFont f("times new roman,utopia"); + f.setStyleStrategy(QFont::ForceOutline); + f.setPointSize(m_fontSize); + f.setStyleHint(QFont::Times); + + QFontMetrics fm(f); + + m_paths.clear(); + m_pathBounds = QRect(); + + QPointF advance(0, 0); + + bool do_quick = true; + for (int i=0; i= 0x4ff && text.at(i).unicode() <= 0x1e00) { + do_quick = false; + break; + } + } + + if (do_quick) { + for (int i=0; itimerId() == m_repaintTimer.timerId()) { + + if (QLineF(QPointF(0,0), m_direction).length() > 1) + m_direction *= 0.995; + qreal time = m_repaintTracker.restart(); + + QRect rectBefore = circle_bounds(m_pos, m_radius, m_fontSize); + + qreal dx = m_direction.x(); + qreal dy = m_direction.y(); + if (time > 0) { + dx = dx * time * .1; + dy = dy * time * .1; + } + + m_pos += QPointF(dx, dy); + + + + if (m_pos.x() - m_radius < 0) { + m_direction.setX(-m_direction.x()); + m_pos.setX(m_radius); + } else if (m_pos.x() + m_radius > width()) { + m_direction.setX(-m_direction.x()); + m_pos.setX(width() - m_radius); + } + + if (m_pos.y() - m_radius < 0) { + m_direction.setY(-m_direction.y()); + m_pos.setY(m_radius); + } else if (m_pos.y() + m_radius > height()) { + m_direction.setY(-m_direction.y()); + m_pos.setY(height() - m_radius); + } + +#ifdef QT_OPENGL_SUPPORT + if (usesOpenGL()) { + update(); + } else +#endif + { + QRect rectAfter = circle_bounds(m_pos, m_radius, m_fontSize); + update(rectAfter | rectBefore); + } + } +// else if (e->timerId() == m_fpsTimer.timerId()) { +// printf("fps: %d\n", m_fpsCounter); +// emit frameRate(m_fpsCounter); +// m_fpsCounter = 0; + +// } +} + +void PathDeformRenderer::mousePressEvent(QMouseEvent *e) +{ + setDescriptionEnabled(false); + + m_repaintTimer.stop(); + m_offset = QPointF(); + if (QLineF(m_pos, e->pos()).length() <= m_radius) + m_offset = m_pos - e->pos(); + + m_mousePress = e->pos(); + + // If we're not running in small screen mode, always assume we're dragging + m_mouseDrag = !m_smallScreen; + + mouseMoveEvent(e); +} + +void PathDeformRenderer::mouseReleaseEvent(QMouseEvent *e) +{ + if (e->buttons() == Qt::NoButton && m_animated) { + m_repaintTimer.start(10, this); + m_repaintTracker.start(); + } + + if (!m_mouseDrag && m_smallScreen) + emit clicked(); +} + +void PathDeformRenderer::mouseMoveEvent(QMouseEvent *e) +{ + if (!m_mouseDrag && (QLineF(m_mousePress, e->pos()).length() > 25.0) ) + m_mouseDrag = true; + + if (m_mouseDrag) { + QRect rectBefore = circle_bounds(m_pos, m_radius, m_fontSize); + if (e->type() == QEvent::MouseMove) { + QLineF line(m_pos, e->pos() + m_offset); + line.setLength(line.length() * .1); + QPointF dir(line.dx(), line.dy()); + m_direction = (m_direction + dir) / 2; + } + m_pos = e->pos() + m_offset; +#ifdef QT_OPENGL_SUPPORT + if (usesOpenGL()) { + update(); + } else +#endif + { + QRect rectAfter = circle_bounds(m_pos, m_radius, m_fontSize); + update(rectBefore | rectAfter); + } + } +} + +QPainterPath PathDeformRenderer::lensDeform(const QPainterPath &source, const QPointF &offset) +{ + QPainterPath path; + path.addPath(source); + + qreal flip = m_intensity / qreal(100); + + for (int i=0; i 0) { + path.setElementPositionAt(i, + x + flip * dx * len / m_radius, + y + flip * dy * len / m_radius); + } else { + path.setElementPositionAt(i, x, y); + } + + } + + return path; +} + + +void PathDeformRenderer::paint(QPainter *painter) +{ + int pad_x = 5; + int pad_y = 5; + + int skip_x = qRound(m_pathBounds.width() + pad_x + m_fontSize/2); + int skip_y = qRound(m_pathBounds.height() + pad_y); + + painter->setPen(Qt::NoPen); + painter->setBrush(Qt::black); + + QRectF clip(painter->clipPath().boundingRect()); + + int overlap = pad_x / 2; + + for (int start_y=0; start_y < height(); start_y += skip_y) { + + if (start_y > clip.bottom()) + break; + + int start_x = -overlap; + for (; start_x < width(); start_x += skip_x) { + + if (start_y + skip_y >= clip.top() && + start_x + skip_x >= clip.left() && + start_x <= clip.right()) { + for (int i=0; idrawPath(path); + } + } + } + overlap = skip_x - (start_x - width()); + + } + + if (preferImage()) { + painter->drawImage(m_pos - QPointF(m_radius + LENS_EXTENT, m_radius + LENS_EXTENT), + m_lens_image); + } else { + painter->drawPixmap(m_pos - QPointF(m_radius + LENS_EXTENT, m_radius + LENS_EXTENT), + m_lens_pixmap); + } +} + + + +void PathDeformRenderer::setRadius(int radius) +{ + qreal max = qMax(m_radius, (qreal)radius); + m_radius = radius; + generateLensPixmap(); + if (!m_animated || m_radius < max) { +#ifdef QT_OPENGL_SUPPORT + if (usesOpenGL()) { + update(); + } else +#endif + { + update(circle_bounds(m_pos, max, m_fontSize)); + } + } +} + +void PathDeformRenderer::setIntensity(int intensity) +{ + m_intensity = intensity; + if (!m_animated) { +#ifdef QT_OPENGL_SUPPORT + if (usesOpenGL()) { + update(); + } else +#endif + { + update(circle_bounds(m_pos, m_radius, m_fontSize)); + } + } +} -- cgit v1.2.3