summaryrefslogtreecommitdiffstats
path: root/examples/widgets/painting
diff options
context:
space:
mode:
Diffstat (limited to 'examples/widgets/painting')
-rw-r--r--examples/widgets/painting/README11
-rw-r--r--examples/widgets/painting/affine/affine.pro24
-rw-r--r--examples/widgets/painting/affine/affine.qrc7
-rw-r--r--examples/widgets/painting/affine/bg1.jpgbin0 -> 23771 bytes
-rw-r--r--examples/widgets/painting/affine/main.cpp65
-rw-r--r--examples/widgets/painting/affine/xform.cpp902
-rw-r--r--examples/widgets/painting/affine/xform.h141
-rw-r--r--examples/widgets/painting/affine/xform.html23
-rw-r--r--examples/widgets/painting/basicdrawing/basicdrawing.desktop11
-rw-r--r--examples/widgets/painting/basicdrawing/basicdrawing.pro14
-rw-r--r--examples/widgets/painting/basicdrawing/basicdrawing.qrc6
-rw-r--r--examples/widgets/painting/basicdrawing/images/brick.pngbin0 -> 767 bytes
-rw-r--r--examples/widgets/painting/basicdrawing/images/qt-logo.pngbin0 -> 3696 bytes
-rw-r--r--examples/widgets/painting/basicdrawing/main.cpp53
-rw-r--r--examples/widgets/painting/basicdrawing/renderarea.cpp207
-rw-r--r--examples/widgets/painting/basicdrawing/renderarea.h83
-rw-r--r--examples/widgets/painting/basicdrawing/window.cpp259
-rw-r--r--examples/widgets/painting/basicdrawing/window.h87
-rw-r--r--examples/widgets/painting/composition/composition.cpp522
-rw-r--r--examples/widgets/painting/composition/composition.h187
-rw-r--r--examples/widgets/painting/composition/composition.html23
-rw-r--r--examples/widgets/painting/composition/composition.pro29
-rw-r--r--examples/widgets/painting/composition/composition.qrc8
-rw-r--r--examples/widgets/painting/composition/flower.jpgbin0 -> 49616 bytes
-rw-r--r--examples/widgets/painting/composition/flower_alpha.jpgbin0 -> 67326 bytes
-rw-r--r--examples/widgets/painting/composition/main.cpp65
-rw-r--r--examples/widgets/painting/concentriccircles/circlewidget.cpp124
-rw-r--r--examples/widgets/painting/concentriccircles/circlewidget.h73
-rw-r--r--examples/widgets/painting/concentriccircles/concentriccircles.desktop11
-rw-r--r--examples/widgets/painting/concentriccircles/concentriccircles.pro14
-rw-r--r--examples/widgets/painting/concentriccircles/main.cpp51
-rw-r--r--examples/widgets/painting/concentriccircles/window.cpp93
-rw-r--r--examples/widgets/painting/concentriccircles/window.h70
-rw-r--r--examples/widgets/painting/deform/deform.pro20
-rw-r--r--examples/widgets/painting/deform/deform.qrc6
-rw-r--r--examples/widgets/painting/deform/main.cpp72
-rw-r--r--examples/widgets/painting/deform/pathdeform.cpp646
-rw-r--r--examples/widgets/painting/deform/pathdeform.h153
-rw-r--r--examples/widgets/painting/deform/pathdeform.html24
-rw-r--r--examples/widgets/painting/fontsampler/fontsampler.desktop11
-rw-r--r--examples/widgets/painting/fontsampler/fontsampler.pro13
-rw-r--r--examples/widgets/painting/fontsampler/main.cpp51
-rw-r--r--examples/widgets/painting/fontsampler/mainwindow.cpp380
-rw-r--r--examples/widgets/painting/fontsampler/mainwindow.h87
-rw-r--r--examples/widgets/painting/fontsampler/mainwindowbase.ui142
-rw-r--r--examples/widgets/painting/gradients/gradients.cpp516
-rw-r--r--examples/widgets/painting/gradients/gradients.h170
-rw-r--r--examples/widgets/painting/gradients/gradients.html31
-rw-r--r--examples/widgets/painting/gradients/gradients.pro20
-rw-r--r--examples/widgets/painting/gradients/gradients.qrc6
-rw-r--r--examples/widgets/painting/gradients/main.cpp63
-rw-r--r--examples/widgets/painting/imagecomposition/imagecomposer.cpp211
-rw-r--r--examples/widgets/painting/imagecomposition/imagecomposer.h87
-rw-r--r--examples/widgets/painting/imagecomposition/imagecomposition.desktop11
-rw-r--r--examples/widgets/painting/imagecomposition/imagecomposition.pro13
-rw-r--r--examples/widgets/painting/imagecomposition/imagecomposition.qrc6
-rw-r--r--examples/widgets/painting/imagecomposition/images/background.pngbin0 -> 18579 bytes
-rw-r--r--examples/widgets/painting/imagecomposition/images/blackrectangle.pngbin0 -> 90 bytes
-rw-r--r--examples/widgets/painting/imagecomposition/images/butterfly.pngbin0 -> 36868 bytes
-rw-r--r--examples/widgets/painting/imagecomposition/images/checker.pngbin0 -> 10384 bytes
-rw-r--r--examples/widgets/painting/imagecomposition/main.cpp55
-rw-r--r--examples/widgets/painting/painterpaths/main.cpp51
-rw-r--r--examples/widgets/painting/painterpaths/painterpaths.desktop11
-rw-r--r--examples/widgets/painting/painterpaths/painterpaths.pro15
-rw-r--r--examples/widgets/painting/painterpaths/renderarea.cpp130
-rw-r--r--examples/widgets/painting/painterpaths/renderarea.h80
-rw-r--r--examples/widgets/painting/painterpaths/window.cpp289
-rw-r--r--examples/widgets/painting/painterpaths/window.h90
-rw-r--r--examples/widgets/painting/painting.pro36
-rw-r--r--examples/widgets/painting/pathstroke/main.cpp71
-rw-r--r--examples/widgets/painting/pathstroke/pathstroke.cpp685
-rw-r--r--examples/widgets/painting/pathstroke/pathstroke.h171
-rw-r--r--examples/widgets/painting/pathstroke/pathstroke.html20
-rw-r--r--examples/widgets/painting/pathstroke/pathstroke.pro21
-rw-r--r--examples/widgets/painting/pathstroke/pathstroke.qrc6
-rw-r--r--examples/widgets/painting/shared/arthurstyle.cpp452
-rw-r--r--examples/widgets/painting/shared/arthurstyle.h79
-rw-r--r--examples/widgets/painting/shared/arthurwidgets.cpp355
-rw-r--r--examples/widgets/painting/shared/arthurwidgets.h137
-rw-r--r--examples/widgets/painting/shared/hoverpoints.cpp415
-rw-r--r--examples/widgets/painting/shared/hoverpoints.h162
-rw-r--r--examples/widgets/painting/shared/images/bg_pattern.pngbin0 -> 104 bytes
-rw-r--r--examples/widgets/painting/shared/images/button_normal_cap_left.pngbin0 -> 654 bytes
-rw-r--r--examples/widgets/painting/shared/images/button_normal_cap_right.pngbin0 -> 674 bytes
-rw-r--r--examples/widgets/painting/shared/images/button_normal_stretch.pngbin0 -> 185 bytes
-rw-r--r--examples/widgets/painting/shared/images/button_pressed_cap_left.pngbin0 -> 710 bytes
-rw-r--r--examples/widgets/painting/shared/images/button_pressed_cap_right.pngbin0 -> 785 bytes
-rw-r--r--examples/widgets/painting/shared/images/button_pressed_stretch.pngbin0 -> 217 bytes
-rw-r--r--examples/widgets/painting/shared/images/curve_thing_edit-6.pngbin0 -> 58097 bytes
-rw-r--r--examples/widgets/painting/shared/images/frame_bottom.pngbin0 -> 166 bytes
-rw-r--r--examples/widgets/painting/shared/images/frame_bottomleft.pngbin0 -> 602 bytes
-rw-r--r--examples/widgets/painting/shared/images/frame_bottomright.pngbin0 -> 553 bytes
-rw-r--r--examples/widgets/painting/shared/images/frame_left.pngbin0 -> 182 bytes
-rw-r--r--examples/widgets/painting/shared/images/frame_right.pngbin0 -> 175 bytes
-rw-r--r--examples/widgets/painting/shared/images/frame_top.pngbin0 -> 188 bytes
-rw-r--r--examples/widgets/painting/shared/images/frame_topleft.pngbin0 -> 801 bytes
-rw-r--r--examples/widgets/painting/shared/images/frame_topright.pngbin0 -> 851 bytes
-rw-r--r--examples/widgets/painting/shared/images/groupframe_bottom_left.pngbin0 -> 397 bytes
-rw-r--r--examples/widgets/painting/shared/images/groupframe_bottom_right.pngbin0 -> 383 bytes
-rw-r--r--examples/widgets/painting/shared/images/groupframe_bottom_stretch.pngbin0 -> 141 bytes
-rw-r--r--examples/widgets/painting/shared/images/groupframe_left_stretch.pngbin0 -> 132 bytes
-rw-r--r--examples/widgets/painting/shared/images/groupframe_right_stretch.pngbin0 -> 113 bytes
-rw-r--r--examples/widgets/painting/shared/images/groupframe_top_stretch.pngbin0 -> 115 bytes
-rw-r--r--examples/widgets/painting/shared/images/groupframe_topleft.pngbin0 -> 412 bytes
-rw-r--r--examples/widgets/painting/shared/images/groupframe_topright.pngbin0 -> 449 bytes
-rw-r--r--examples/widgets/painting/shared/images/line_dash_dot.pngbin0 -> 151 bytes
-rw-r--r--examples/widgets/painting/shared/images/line_dash_dot_dot.pngbin0 -> 155 bytes
-rw-r--r--examples/widgets/painting/shared/images/line_dashed.pngbin0 -> 121 bytes
-rw-r--r--examples/widgets/painting/shared/images/line_dotted.pngbin0 -> 116 bytes
-rw-r--r--examples/widgets/painting/shared/images/line_solid.pngbin0 -> 110 bytes
-rw-r--r--examples/widgets/painting/shared/images/radiobutton-off.pngbin0 -> 442 bytes
-rw-r--r--examples/widgets/painting/shared/images/radiobutton-on.pngbin0 -> 474 bytes
-rw-r--r--examples/widgets/painting/shared/images/radiobutton_off.pngbin0 -> 442 bytes
-rw-r--r--examples/widgets/painting/shared/images/radiobutton_on.pngbin0 -> 499 bytes
-rw-r--r--examples/widgets/painting/shared/images/slider_bar.pngbin0 -> 748 bytes
-rw-r--r--examples/widgets/painting/shared/images/slider_thumb_off.pngbin0 -> 823 bytes
-rw-r--r--examples/widgets/painting/shared/images/slider_thumb_on.pngbin0 -> 798 bytes
-rw-r--r--examples/widgets/painting/shared/images/title_cap_left.pngbin0 -> 179 bytes
-rw-r--r--examples/widgets/painting/shared/images/title_cap_right.pngbin0 -> 184 bytes
-rw-r--r--examples/widgets/painting/shared/images/title_stretch.pngbin0 -> 106 bytes
-rw-r--r--examples/widgets/painting/shared/shared.pri20
-rw-r--r--examples/widgets/painting/shared/shared.pro34
-rw-r--r--examples/widgets/painting/shared/shared.qrc39
-rw-r--r--examples/widgets/painting/svggenerator/svggenerator.desktop11
-rw-r--r--examples/widgets/painting/svgviewer/svgviewer.desktop11
-rw-r--r--examples/widgets/painting/transformations/main.cpp51
-rw-r--r--examples/widgets/painting/transformations/renderarea.cpp172
-rw-r--r--examples/widgets/painting/transformations/renderarea.h90
-rw-r--r--examples/widgets/painting/transformations/transformations.desktop11
-rw-r--r--examples/widgets/painting/transformations/transformations.pro13
-rw-r--r--examples/widgets/painting/transformations/window.cpp180
-rw-r--r--examples/widgets/painting/transformations/window.h80
132 files changed, 9945 insertions, 0 deletions
diff --git a/examples/widgets/painting/README b/examples/widgets/painting/README
new file mode 100644
index 0000000000..541c553159
--- /dev/null
+++ b/examples/widgets/painting/README
@@ -0,0 +1,11 @@
+Qt's painting system is able to render vector graphics, images, and outline
+font-based text with sub-pixel accuracy accuracy using anti-aliasing to
+improve rendering quality.
+
+These examples show the most common techniques that are used when painting
+with Qt, from basic concepts such as drawing simple primitives to the use of
+transformations.
+
+
+Documentation for these examples can be found via the Examples
+link in the main Qt documentation.
diff --git a/examples/widgets/painting/affine/affine.pro b/examples/widgets/painting/affine/affine.pro
new file mode 100644
index 0000000000..0977ea1c5b
--- /dev/null
+++ b/examples/widgets/painting/affine/affine.pro
@@ -0,0 +1,24 @@
+SOURCES += main.cpp xform.cpp
+HEADERS += xform.h
+
+contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles2) {
+ DEFINES += QT_OPENGL_SUPPORT
+ QT += opengl
+}
+QT += widgets
+
+SHARED_FOLDER = ../shared
+
+include($$SHARED_FOLDER/shared.pri)
+
+RESOURCES += affine.qrc
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/painting/affine
+sources.files = $$SOURCES $$HEADERS $$RESOURCES *.pro *.html *.jpg
+sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/painting/affine
+INSTALLS += target sources
+
+wince*: {
+ DEPLOYMENT_PLUGIN += qjpeg
+}
diff --git a/examples/widgets/painting/affine/affine.qrc b/examples/widgets/painting/affine/affine.qrc
new file mode 100644
index 0000000000..d8a7ae40cb
--- /dev/null
+++ b/examples/widgets/painting/affine/affine.qrc
@@ -0,0 +1,7 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/res/affine">
+ <file>xform.cpp</file>
+ <file>xform.html</file>
+ <file>bg1.jpg</file>
+</qresource>
+</RCC>
diff --git a/examples/widgets/painting/affine/bg1.jpg b/examples/widgets/painting/affine/bg1.jpg
new file mode 100644
index 0000000000..dfc7cee6ad
--- /dev/null
+++ b/examples/widgets/painting/affine/bg1.jpg
Binary files differ
diff --git a/examples/widgets/painting/affine/main.cpp b/examples/widgets/painting/affine/main.cpp
new file mode 100644
index 0000000000..c27e3331f1
--- /dev/null
+++ b/examples/widgets/painting/affine/main.cpp
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** 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 "xform.h"
+
+#include <QApplication>
+
+int main(int argc, char **argv)
+{
+ Q_INIT_RESOURCE(affine);
+
+ QApplication app(argc, argv);
+
+ XFormWidget xformWidget(0);
+ QStyle *arthurStyle = new ArthurStyle();
+ xformWidget.setStyle(arthurStyle);
+
+ QList<QWidget *> widgets = xformWidget.findChildren<QWidget *>();
+ foreach (QWidget *w, widgets) {
+ w->setStyle(arthurStyle);
+ w->setAttribute(Qt::WA_AcceptTouchEvents);
+ }
+
+ xformWidget.show();
+
+ return app.exec();
+}
diff --git a/examples/widgets/painting/affine/xform.cpp b/examples/widgets/painting/affine/xform.cpp
new file mode 100644
index 0000000000..8c9d37406c
--- /dev/null
+++ b/examples/widgets/painting/affine/xform.cpp
@@ -0,0 +1,902 @@
+/****************************************************************************
+**
+** 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 "xform.h"
+#include "hoverpoints.h"
+
+#include <QLayout>
+#include <QPainter>
+#include <QPainterPath>
+
+const int alpha = 155;
+
+XFormView::XFormView(QWidget *parent)
+ : ArthurFrame(parent)
+{
+ setAttribute(Qt::WA_MouseTracking);
+ m_type = VectorType;
+ m_rotation = 0.0;
+ m_scale = 1.0;
+ m_shear = 0.0;
+
+ m_pixmap = QPixmap(":res/affine/bg1.jpg");
+ pts = new HoverPoints(this, HoverPoints::CircleShape);
+ pts->setConnectionType(HoverPoints::LineConnection);
+ pts->setEditable(false);
+ pts->setPointSize(QSize(15, 15));
+ pts->setShapeBrush(QBrush(QColor(151, 0, 0, alpha)));
+ pts->setShapePen(QPen(QColor(255, 100, 50, alpha)));
+ pts->setConnectionPen(QPen(QColor(151, 0, 0, 50)));
+ pts->setBoundingRect(QRectF(0, 0, 500, 500));
+ ctrlPoints << QPointF(250, 250) << QPointF(350, 250);
+ pts->setPoints(ctrlPoints);
+ connect(pts, SIGNAL(pointsChanged(QPolygonF)),
+ this, SLOT(updateCtrlPoints(QPolygonF)));
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+}
+
+XFormView::XFormType XFormView::type() const
+{
+ return m_type;
+}
+
+QPixmap XFormView::pixmap() const
+{
+ return m_pixmap;
+}
+
+QString XFormView::text() const
+{
+ return m_text;
+}
+
+void XFormView::setText(const QString &t)
+{
+ m_text = t;
+ update();
+}
+
+void XFormView::setPixmap(const QPixmap &p)
+{
+ m_pixmap = p;
+ update();
+}
+
+void XFormView::setType(XFormType t)
+{
+ m_type = t;
+ update();
+}
+
+void XFormView::mousePressEvent(QMouseEvent *)
+{
+ setDescriptionEnabled(false);
+}
+
+void XFormView::resizeEvent(QResizeEvent *e)
+{
+ pts->setBoundingRect(rect());
+ ArthurFrame::resizeEvent(e);
+}
+
+void XFormView::paint(QPainter *p)
+{
+ p->save();
+ p->setRenderHint(QPainter::Antialiasing);
+ p->setRenderHint(QPainter::SmoothPixmapTransform);
+ switch (m_type) {
+ case VectorType:
+ drawVectorType(p);
+ break;
+ case PixmapType:
+ drawPixmapType(p);
+ break;
+ case TextType:
+ drawTextType(p);
+ break;
+ }
+ p->restore();
+}
+
+void XFormView::updateCtrlPoints(const QPolygonF &points)
+{
+ QPointF trans = points.at(0) - ctrlPoints.at(0);
+
+ if (qAbs(points.at(0).x() - points.at(1).x()) < 10
+ && qAbs(points.at(0).y() - points.at(1).y()) < 10)
+ pts->setPoints(ctrlPoints);
+ if (!trans.isNull()) {
+ ctrlPoints[0] = points.at(0);
+ ctrlPoints[1] += trans;
+ pts->setPoints(ctrlPoints);
+ }
+ ctrlPoints = points;
+
+ QLineF line(ctrlPoints.at(0), ctrlPoints.at(1));
+ m_rotation = line.angle(QLineF(0, 0, 1, 0));
+ if (line.dy() < 0)
+ m_rotation = 360 - m_rotation;
+
+ if (trans.isNull())
+ emit rotationChanged(int(m_rotation*10));
+}
+
+void XFormView::setVectorType()
+{
+ m_type = VectorType;
+ update();
+}
+
+void XFormView::setPixmapType()
+{
+ m_type = PixmapType;
+ update();
+}
+
+void XFormView::setTextType()
+{
+ m_type = TextType;
+ update();
+}
+
+void XFormView::setAnimation(bool animate)
+{
+ timer.stop();
+ if (animate)
+ timer.start(25, this);
+}
+
+void XFormView::changeRotation(int r)
+{
+ setRotation(qreal(r) / 10);
+}
+
+void XFormView::changeScale(int s)
+{
+ setScale(qreal(s) / 1000);
+}
+
+void XFormView::changeShear(int s)
+{
+ setShear(qreal(s) / 1000);
+}
+
+void XFormView::setShear(qreal s)
+{
+ m_shear = s;
+ update();
+}
+
+void XFormView::setScale(qreal s)
+{
+ m_scale = s;
+ update();
+}
+
+void XFormView::setRotation(qreal r)
+{
+ qreal old_rot = m_rotation;
+ m_rotation = r;
+
+ QPointF center(pts->points().at(0));
+ QMatrix m;
+ m.translate(center.x(), center.y());
+ m.rotate(m_rotation - old_rot);
+ m.translate(-center.x(), -center.y());
+ pts->setPoints(pts->points() * m);
+
+ update();
+}
+
+void XFormView::timerEvent(QTimerEvent *e)
+{
+ if (e->timerId() == timer.timerId()) {
+ QPointF center(pts->points().at(0));
+ QMatrix m;
+ m.translate(center.x(), center.y());
+ m.rotate(0.2);
+ m.translate(-center.x(), -center.y());
+ pts->setPoints(pts->points() * m);
+
+ setUpdatesEnabled(false);
+ static qreal scale_inc = 0.003;
+ static qreal shear_inc = -0.001;
+ emit scaleChanged(int((m_scale + scale_inc) * 1000));
+ emit shearChanged(int((m_shear + shear_inc) * 1000));
+ if (m_scale >= 4.0 || m_scale <= 0.1)
+ scale_inc = -scale_inc;
+ if (m_shear >= 1.0 || m_shear <= -1.0)
+ shear_inc = -shear_inc;
+ setUpdatesEnabled(true);
+
+ pts->firePointChange();
+ }
+}
+
+void XFormView::wheelEvent(QWheelEvent *e)
+{
+ m_scale += e->delta() / qreal(600);
+ m_scale = qMax(qreal(0.1), qMin(qreal(4), m_scale));
+ emit scaleChanged(int(m_scale*1000));
+}
+
+void XFormView::reset()
+{
+ emit rotationChanged(0);
+ emit scaleChanged(1000);
+ emit shearChanged(0);
+ ctrlPoints = QPolygonF();
+ ctrlPoints << QPointF(250, 250) << QPointF(350, 250);
+ pts->setPoints(ctrlPoints);
+ pts->firePointChange();
+}
+
+void XFormView::drawPixmapType(QPainter *painter)
+{
+ QPointF center(m_pixmap.width() / qreal(2), m_pixmap.height() / qreal(2));
+ painter->translate(ctrlPoints.at(0) - center);
+
+ painter->translate(center);
+ painter->rotate(m_rotation);
+ painter->scale(m_scale, m_scale);
+ painter->shear(0, m_shear);
+ painter->translate(-center);
+
+ painter->drawPixmap(QPointF(0, 0), m_pixmap);
+ painter->setPen(QPen(QColor(255, 0, 0, alpha), 0.25, Qt::SolidLine, Qt::FlatCap, Qt::BevelJoin));
+ painter->setBrush(Qt::NoBrush);
+ painter->drawRect(QRectF(0, 0, m_pixmap.width(), m_pixmap.height()).adjusted(-2, -2, 2, 2));
+}
+
+void XFormView::drawTextType(QPainter *painter)
+{
+ QPainterPath path;
+ QFont f("times new roman,utopia");
+ f.setStyleStrategy(QFont::ForceOutline);
+ f.setPointSize(72);
+ f.setStyleHint(QFont::Times);
+ path.addText(0, 0, f, m_text);
+
+ QFontMetrics fm(f);
+ QRectF br(fm.boundingRect(m_text));
+ QPointF center(br.center());
+ painter->translate(ctrlPoints.at(0) - center);
+
+ painter->translate(center);
+ painter->rotate(m_rotation);
+ painter->scale(m_scale, m_scale);
+ painter->shear(0, m_shear);
+ painter->translate(-center);
+
+ painter->fillPath(path, Qt::black);
+
+ painter->setPen(QPen(QColor(255, 0, 0, alpha), 0.25, Qt::SolidLine, Qt::FlatCap, Qt::BevelJoin));
+ painter->setBrush(Qt::NoBrush);
+ painter->drawRect(br.adjusted(-1, -1, 1, 1));
+}
+
+void XFormView::drawVectorType(QPainter *painter)
+{
+ QPainterPath path;
+ painter->translate(ctrlPoints.at(0) - QPointF(250,250));
+
+ painter->scale(0.77, 0.77);
+ painter->translate(98.9154 + 30 , -217.691 - 20);
+
+ QRect br(-55, 275, 500, 590);
+ QPoint center = br.center();
+ painter->translate(center.x(), center.y());
+ painter->rotate(m_rotation);
+ painter->scale(m_scale, m_scale);
+ painter->shear(0, m_shear);
+ painter->translate(-center.x(), -center.y());
+
+ painter->setPen(Qt::NoPen);
+ path.moveTo(120, 470);
+ path.lineTo(60+245, 470);
+ path.lineTo(60+245, 470+350);
+ path.lineTo(60, 470+350);
+ path.lineTo(60, 470+80);
+
+ painter->setBrush(Qt::white);
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor( 193, 193, 191, 255));
+ path.moveTo(329.336, 727.552);
+ path.cubicTo(QPointF(315.224, 726.328), QPointF(304.136, 715.816), QPointF(303.128, 694.936));
+ path.cubicTo(QPointF(306.368, 639.496), QPointF(309.608, 582.112), QPointF(271.232, 545.104));
+ path.cubicTo(QPointF(265.256, 499.024), QPointF(244.016, 482.104), QPointF(234.008, 452.512));
+ path.lineTo(218.24, 441.208);
+ path.lineTo(237.104, 411.688);
+ path.lineTo(245.168, 411.904);
+ path.lineTo(323.936, 571.168);
+ path.lineTo(340.424, 651.448);
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(136.232, 439.696);
+ path.cubicTo(QPointF(133.856, 455.248), QPointF(132.56, 470.512), QPointF(134.792, 485.272));
+ path.cubicTo(QPointF(118.376, 507.592), QPointF(105.92, 530.128), QPointF(104.48, 553.312));
+ path.cubicTo(QPointF(92.024, 586.504), QPointF(62.432, 614.584), QPointF(67.544, 680.104));
+ path.cubicTo(QPointF(84.176, 697.456), QPointF(107.432, 713.584), QPointF(127.376, 730.36));
+ path.cubicTo(QPointF(152.432, 751.312), QPointF(137.528, 778.96), QPointF(102.248, 772.408));
+ path.cubicTo(QPointF(94.4, 763.768), QPointF(76.616, 709.624), QPointF(42.92, 676.288));
+ path.lineTo(49.544, 632.584);
+ path.lineTo(81.368, 547.408);
+ path.lineTo(120.968, 484.048);
+ path.lineTo(125.36, 456.688);
+ path.lineTo(119.816, 386.776);
+ path.lineTo(124.424, 361.216);
+ path.lineTo(136.232, 439.696);
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(115.64, 341.416);
+ path.cubicTo(QPointF(116.576, 336.376), QPointF(117.8, 331.624), QPointF(119.312, 327.16));
+ path.lineTo(121.688, 342.784);
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(120.968, 500.464);
+ path.cubicTo(QPointF(108.368, 523.792), QPointF(103.976, 546.256), QPointF(132.92, 550.216));
+ path.cubicTo(QPointF(117.008, 553.888), QPointF(97.208, 568.648), QPointF(77.192, 593.488));
+ path.lineTo(77.624, 543.016);
+ path.lineTo(101.456, 503.272);
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(-33.256, 818.488);
+ path.cubicTo(QPointF(10.52, 838.144), QPointF(41.408, 837.064), QPointF(69.272, 850.96));
+ path.cubicTo(QPointF(91.304, 862.552), QPointF(113.552, 861.184), QPointF(126.944, 847.144));
+ path.cubicTo(QPointF(138.32, 832.456), QPointF(146.744, 831.736), QPointF(163.52, 830.224));
+ path.cubicTo(QPointF(190.952, 828.568), QPointF(217.736, 828.28), QPointF(241.928, 830.8));
+ path.lineTo(269.576, 833.032);
+ path.cubicTo(QPointF(269.072, 864.064), QPointF(328.04, 867.88), QPointF(345.392, 844.336));
+ path.cubicTo(QPointF(366.344, 819.424), QPointF(395.144, 808.264), QPointF(419.84, 790.192));
+ path.lineTo(289.304, 725.536);
+ path.cubicTo(QPointF(255.824, 806.464), QPointF(131.048, 827.632), QPointF(113.768, 763.264));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(286.424, 711.568);
+ path.cubicTo(QPointF(273.824, 711.496), QPointF(260.936, 715.6), QPointF(261.944, 732.16));
+ path.lineTo(266.192, 776.44);
+ path.lineTo(304.424, 756.64);
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(0, 0, 0, 255));
+ path.moveTo(-37.36, 821.224);
+ path.cubicTo(QPointF(7.136, 840.88), QPointF(38.6, 839.728), QPointF(66.968, 853.696));
+ path.cubicTo(QPointF(89.36, 865.216), QPointF(111.968, 863.92), QPointF(125.648, 849.808));
+ path.cubicTo(QPointF(137.24, 835.192), QPointF(145.808, 834.472), QPointF(162.872, 832.96));
+ path.cubicTo(QPointF(190.736, 831.232), QPointF(218.024, 831.016), QPointF(242.648, 833.464));
+ path.lineTo(270.728, 835.768);
+ path.cubicTo(QPointF(270.224, 866.8), QPointF(330.272, 870.544), QPointF(347.912, 847));
+ path.cubicTo(QPointF(369.224, 822.088), QPointF(398.528, 811), QPointF(423.656, 792.856));
+ path.lineTo(290.816, 728.272);
+ path.cubicTo(QPointF(256.76, 809.128), QPointF(129.824, 830.296), QPointF(112.256, 766));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(183, 114, 0, 255));
+ path.moveTo(382.328, 691.984);
+ path.cubicTo(QPointF(403.64, 698.968), QPointF(389.888, 720.28), QPointF(400.76, 732.52));
+ path.cubicTo(QPointF(405.44, 742.888), QPointF(415.304, 752.032), QPointF(431.792, 760.528));
+ path.cubicTo(QPointF(459.368, 774.424), QPointF(426.248, 799.336), QPointF(392.768, 812.08));
+ path.cubicTo(QPointF(351.944, 825.616), QPointF(344.024, 862.912), QPointF(299.312, 851.896));
+ path.cubicTo(QPointF(283.112, 846.496), QPointF(278.36, 831.808), QPointF(278.864, 809.128));
+ path.cubicTo(QPointF(284.264, 762.76), QPointF(277.784, 730.432), QPointF(278.792, 698.824));
+ path.cubicTo(QPointF(278.72, 686.152), QPointF(283.544, 684.64), QPointF(307.232, 687.952));
+ path.cubicTo(QPointF(310.04, 726.328), QPointF(352.376, 727.336), QPointF(382.328, 691.984));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(242, 183, 0, 255));
+ path.moveTo(339.632, 826.624);
+ path.cubicTo(QPointF(371.6, 814.312), QPointF(403.856, 798.112), QPointF(429.848, 782.128));
+ path.cubicTo(QPointF(437.84, 777.448), QPointF(438.92, 765.928), QPointF(427.688, 762.328));
+ path.cubicTo(QPointF(403.352, 748.504), QPointF(390.104, 731.224), QPointF(392.912, 708.76));
+ path.cubicTo(QPointF(393.344, 700.912), QPointF(383.696, 692.56), QPointF(381.104, 700.048));
+ path.cubicTo(QPointF(359.864, 771.472), QPointF(291.32, 767.656), QPointF(300.752, 696.952));
+ path.cubicTo(QPointF(301.256, 694.864), QPointF(301.76, 692.776), QPointF(302.264, 690.76));
+ path.cubicTo(QPointF(289.952, 688.24), QPointF(285.2, 690.976), QPointF(285.776, 700.408));
+ path.lineTo(295.28, 806.608);
+ path.cubicTo(QPointF(297.656, 830.8), QPointF(317.312, 836.128), QPointF(339.632, 826.624));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(0, 0, 0, 255));
+ path.moveTo(354.464, 537.544);
+ path.cubicTo(QPointF(379.16, 569.8), QPointF(404.432, 651.088), QPointF(384.416, 691.552));
+ path.cubicTo(QPointF(360.944, 737.776), QPointF(307.808, 743.248), QPointF(305.504, 695.8));
+ path.cubicTo(QPointF(308.816, 639.64), QPointF(311.984, 581.536), QPointF(273.68, 544.096));
+ path.cubicTo(QPointF(267.704, 497.368), QPointF(246.392, 480.232), QPointF(236.384, 450.28));
+ path.lineTo(203.12, 426.088);
+ path.lineTo(133.568, 435.088);
+ path.cubicTo(QPointF(130.76, 452.152), QPointF(129.104, 468.784), QPointF(131.552, 484.912));
+ path.cubicTo(QPointF(115.064, 507.376), QPointF(102.608, 530.056), QPointF(101.168, 553.312));
+ path.cubicTo(QPointF(88.712, 586.648), QPointF(59.12, 614.944), QPointF(64.232, 680.752));
+ path.cubicTo(QPointF(80.864, 698.248), QPointF(104.12, 714.448), QPointF(124.064, 731.296));
+ path.cubicTo(QPointF(149.12, 752.392), QPointF(135.512, 776.296), QPointF(100.232, 769.672));
+ path.cubicTo(QPointF(78.848, 746.056), QPointF(56.744, 722.872), QPointF(35.288, 699.328));
+ path.cubicTo(QPointF(12.392, 683.056), QPointF(3.896, 662.176), QPointF(27.368, 630.496));
+ path.cubicTo(QPointF(43.424, 609.04), QPointF(47.96, 562.456), QPointF(62, 543.664));
+ path.cubicTo(QPointF(74.312, 525.16), QPointF(92.24, 508.6), QPointF(105.272, 490.096));
+ path.cubicTo(QPointF(112.184, 477.928), QPointF(114.344, 468.568), QPointF(113.264, 454.456));
+ path.lineTo(110.312, 369.136);
+ path.cubicTo(QPointF(108.368, 307.216), QPointF(142.424, 274.24), QPointF(189.8, 275.248));
+ path.cubicTo(QPointF(243.512, 275.752), QPointF(287.576, 312.472), QPointF(288.152, 378.28));
+ path.cubicTo(QPointF(292.688, 410.32), QPointF(283.256, 428.68), QPointF(308.672, 474.472));
+ path.cubicTo(QPointF(334.52, 522.712), QPointF(338.552, 520.12), QPointF(354.464, 537.544));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(261.296, 503.632);
+ path.lineTo(263.528, 512.2);
+ path.cubicTo(QPointF(257.696, 501.688), QPointF(250.712, 483.616), QPointF(241.928, 475.696));
+ path.cubicTo(QPointF(239.264, 473.536), QPointF(235.808, 473.608), QPointF(233.72, 475.624));
+ path.cubicTo(QPointF(222.056, 486.928), QPointF(193.112, 510.112), QPointF(169.928, 507.088));
+ path.cubicTo(QPointF(152.072, 505.288), QPointF(134.648, 493.264), QPointF(130.832, 480.232));
+ path.cubicTo(QPointF(128.816, 470.872), QPointF(129.752, 463.168), QPointF(130.976, 455.32));
+ path.lineTo(240.704, 453.52);
+ path.cubicTo(QPointF(238.472, 463.168), QPointF(253.088, 487), QPointF(261.296, 503.632));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(143.144, 363.232);
+ path.cubicTo(QPointF(154.088, 363.232), QPointF(163.88, 376.84), QPointF(163.808, 395.632));
+ path.cubicTo(QPointF(163.736, 408.232), QPointF(155.528, 411.472), QPointF(149.336, 417.016));
+ path.cubicTo(QPointF(146.6, 419.536), QPointF(145.952, 433.144), QPointF(142.568, 433.144));
+ path.cubicTo(QPointF(131.696, 433.144), QPointF(123.488, 413.776), QPointF(123.488, 395.632));
+ path.cubicTo(QPointF(123.488, 377.56), QPointF(132.272, 363.232), QPointF(143.144, 363.232));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(255, 255, 255, 255));
+ path.moveTo(144.368, 375.04);
+ path.cubicTo(QPointF(154.088, 375.04), QPointF(160.856, 379.936), QPointF(161.648, 391.312));
+ path.cubicTo(QPointF(162.224, 399.16), QPointF(160.136, 411.76), QPointF(154.664, 414.424));
+ path.cubicTo(QPointF(152.144, 415.648), QPointF(143.432, 426.664), QPointF(140.408, 426.52));
+ path.cubicTo(QPointF(128.096, 425.944), QPointF(125, 402.112), QPointF(125.936, 390.736));
+ path.cubicTo(QPointF(126.8, 379.36), QPointF(134.72, 375.04), QPointF(144.368, 375.04));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(0, 0, 0, 255));
+ path.moveTo(141.848, 382.672);
+ path.cubicTo(QPointF(148.544, 382.096), QPointF(154.736, 389.728), QPointF(155.6, 399.664));
+ path.cubicTo(QPointF(156.464, 409.6), QPointF(151.64, 418.24), QPointF(144.944, 418.816));
+ path.cubicTo(QPointF(138.248, 419.392), QPointF(132.056, 411.76), QPointF(131.192, 401.752));
+ path.cubicTo(QPointF(130.328, 391.816), QPointF(135.152, 383.248), QPointF(141.848, 382.672));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(151.064, 397.288);
+ path.cubicTo(QPointF(151.424, 399.088), QPointF(149.408, 400.024), QPointF(148.832, 398.224));
+ path.cubicTo(QPointF(148.256, 395.992), QPointF(146.888, 393.328), QPointF(145.088, 391.168));
+ path.cubicTo(QPointF(143.936, 389.872), QPointF(145.088, 388.432), QPointF(146.528, 389.44));
+ path.cubicTo(QPointF(149.048, 391.528), QPointF(150.488, 394.12), QPointF(151.064, 397.288));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(216.944, 360.712);
+ path.cubicTo(QPointF(232.712, 360.712), QPointF(245.6, 377.416), QPointF(245.6, 397.792));
+ path.cubicTo(QPointF(245.6, 418.24), QPointF(232.712, 434.872), QPointF(216.944, 434.872));
+ path.cubicTo(QPointF(201.176, 434.872), QPointF(188.432, 418.24), QPointF(188.432, 397.792));
+ path.cubicTo(QPointF(188.432, 377.416), QPointF(201.176, 360.712), QPointF(216.944, 360.712));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(255, 255, 255, 255));
+ path.moveTo(224.792, 374.968);
+ path.cubicTo(QPointF(235.664, 378.856), QPointF(241.928, 387.424), QPointF(242.72, 396.568));
+ path.cubicTo(QPointF(243.656, 407.08), QPointF(239.408, 418.96), QPointF(230.264, 425.944));
+ path.cubicTo(QPointF(227.672, 427.888), QPointF(197.72, 416.08), QPointF(195.992, 411.616));
+ path.cubicTo(QPointF(193.4, 405.208), QPointF(191.816, 392.896), QPointF(193.76, 385.624));
+ path.cubicTo(QPointF(194.552, 382.744), QPointF(197.216, 378.568), QPointF(201.176, 376.336));
+ path.cubicTo(QPointF(207.44, 372.808), QPointF(216.656, 372.088), QPointF(224.792, 374.968));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(0, 0, 0, 255));
+ path.moveTo(216.872, 380.944);
+ path.cubicTo(QPointF(225.584, 380.944), QPointF(232.712, 389.296), QPointF(232.712, 399.448));
+ path.cubicTo(QPointF(232.712, 409.672), QPointF(225.584, 418.024), QPointF(216.872, 418.024));
+ path.cubicTo(QPointF(208.16, 418.024), QPointF(201.032, 409.672), QPointF(201.032, 399.448));
+ path.cubicTo(QPointF(201.032, 389.296), QPointF(208.16, 380.944), QPointF(216.872, 380.944));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(227.096, 392.392);
+ path.cubicTo(QPointF(228.104, 394.048), QPointF(226.448, 395.776), QPointF(225.224, 394.12));
+ path.cubicTo(QPointF(223.784, 392.104), QPointF(221.408, 389.944), QPointF(218.888, 388.432));
+ path.cubicTo(QPointF(217.232, 387.568), QPointF(217.808, 385.624), QPointF(219.68, 386.2));
+ path.cubicTo(QPointF(222.92, 387.28), QPointF(225.368, 389.368), QPointF(227.096, 392.392));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(183, 114, 0, 255));
+ path.moveTo(164.96, 404.488);
+ path.cubicTo(QPointF(172.376, 402.328), QPointF(184.112, 403.048), QPointF(192.248, 404.632));
+ path.cubicTo(QPointF(200.384, 406.792), QPointF(222.056, 418.24), QPointF(245.024, 430.696));
+ path.cubicTo(QPointF(247.976, 432.208), QPointF(248.84, 437.104), QPointF(245.024, 438.688));
+ path.cubicTo(QPointF(239.12, 439.12), QPointF(249.272, 453.664), QPointF(238.904, 458.848));
+ path.cubicTo(QPointF(223.352, 462.88), QPointF(198.44, 485.992), QPointF(186.128, 487.864));
+ path.cubicTo(QPointF(179.288, 489.376), QPointF(172.232, 489.592), QPointF(164.6, 487.864));
+ path.cubicTo(QPointF(140.552, 482.968), QPointF(134.216, 455.608), QPointF(122.912, 450.064));
+ path.cubicTo(QPointF(119.816, 446.824), QPointF(121.4, 441.208), QPointF(122.408, 440.056));
+ path.cubicTo(QPointF(123.632, 434.224), QPointF(149.696, 406.216), QPointF(164.96, 404.488));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(242, 183, 0, 255));
+ path.moveTo(185.408, 405.856);
+ path.cubicTo(QPointF(198.44, 407.296), QPointF(226.088, 423.928), QPointF(239.408, 430.624));
+ path.cubicTo(QPointF(242.72, 432.424), QPointF(242.504, 437.824), QPointF(239.552, 438.688));
+ path.cubicTo(QPointF(236.384, 440.488), QPointF(235.448, 438.256), QPointF(232.928, 437.896));
+ path.cubicTo(QPointF(228.896, 435.736), QPointF(222.272, 440.92), QPointF(217.016, 444.88));
+ path.cubicTo(QPointF(186.704, 467.776), QPointF(180.656, 465.256), QPointF(156.176, 462.664));
+ path.cubicTo(QPointF(147.68, 460.576), QPointF(142.136, 457.984), QPointF(139.688, 455.968));
+ path.cubicTo(QPointF(141.488, 445.888), QPointF(160.496, 407.656), QPointF(166.76, 406.792));
+ path.cubicTo(QPointF(168.344, 404.704), QPointF(179.936, 404.632), QPointF(185.408, 405.856));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(183, 114, 0, 255));
+ path.moveTo(190.664, 412.048);
+ path.lineTo(193.76, 413.416);
+ path.cubicTo(QPointF(196.064, 414.712), QPointF(193.256, 418.168), QPointF(190.736, 417.088));
+ path.lineTo(186.2, 415.504);
+ path.cubicTo(QPointF(183.536, 413.272), QPointF(186.704, 410.104), QPointF(190.664, 412.048));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(268.568, 452.368);
+ path.cubicTo(QPointF(273.032, 454.384), QPointF(279.224, 457.192), QPointF(282.536, 460.144));
+ path.cubicTo(QPointF(285.488, 464.104), QPointF(286.784, 468.064), QPointF(286.424, 472.024));
+ path.cubicTo(QPointF(285.776, 474.544), QPointF(284.12, 476.344), QPointF(281.24, 477.424));
+ path.cubicTo(QPointF(277.856, 478.216), QPointF(273.68, 477.424), QPointF(271.376, 474.112));
+ path.cubicTo(QPointF(269.864, 471.448), QPointF(265.256, 462.16), QPointF(263.96, 460.576));
+ path.cubicTo(QPointF(262.232, 457.12), QPointF(261.944, 454.456), QPointF(262.88, 452.368));
+ path.cubicTo(QPointF(264.032, 451.288), QPointF(266.048, 451), QPointF(268.568, 452.368));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(255, 255, 255, 255));
+ path.moveTo(273.752, 461.584);
+ path.cubicTo(QPointF(275.48, 462.376), QPointF(277.928, 463.456), QPointF(279.224, 464.68));
+ path.cubicTo(QPointF(280.376, 466.264), QPointF(280.88, 467.776), QPointF(280.736, 469.36));
+ path.cubicTo(QPointF(280.52, 470.296), QPointF(279.8, 471.016), QPointF(278.72, 471.448));
+ path.cubicTo(QPointF(277.352, 471.808), QPointF(275.768, 471.448), QPointF(274.832, 470.152));
+ path.cubicTo(QPointF(274.256, 469.144), QPointF(272.456, 465.472), QPointF(271.952, 464.824));
+ path.cubicTo(QPointF(271.232, 463.456), QPointF(271.088, 462.448), QPointF(271.448, 461.584));
+ path.cubicTo(QPointF(271.952, 461.152), QPointF(272.744, 461.08), QPointF(273.752, 461.584));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(238.616, 358.552);
+ path.cubicTo(QPointF(239.048, 359.2), QPointF(238.976, 359.776), QPointF(238.4, 360.28));
+ path.cubicTo(QPointF(237.896, 360.784), QPointF(237.176, 360.712), QPointF(236.24, 360.208));
+ path.lineTo(231.632, 356.248);
+ path.cubicTo(QPointF(231.056, 355.744), QPointF(230.912, 354.952), QPointF(231.272, 354.088));
+ path.cubicTo(QPointF(232.28, 353.44), QPointF(233.144, 353.44), QPointF(233.936, 354.088));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(235.592, 305.992);
+ path.cubicTo(QPointF(239.624, 308.224), QPointF(240.848, 313.912), QPointF(238.184, 318.592));
+ path.cubicTo(QPointF(235.592, 323.2), QPointF(230.12, 325.144), QPointF(226.016, 322.84));
+ path.cubicTo(QPointF(221.984, 320.536), QPointF(220.76, 314.92), QPointF(223.424, 310.24));
+ path.cubicTo(QPointF(226.016, 305.56), QPointF(231.488, 303.688), QPointF(235.592, 305.992));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(374.912, 680.536);
+ path.cubicTo(QPointF(378.296, 683.128), QPointF(373.256, 687.376), QPointF(371.024, 686.296));
+ path.cubicTo(QPointF(369.152, 685.648), QPointF(367.784, 683.488), QPointF(366.92, 682.408));
+ path.cubicTo(QPointF(366.128, 681.184), QPointF(366.2, 679.168), QPointF(366.92, 678.448));
+ path.cubicTo(QPointF(367.712, 677.44), QPointF(369.728, 677.656), QPointF(371.024, 678.52));
+ path.cubicTo(QPointF(372.32, 679.168), QPointF(373.616, 679.888), QPointF(374.912, 680.536));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(297.44, 551.512);
+ path.cubicTo(QPointF(338.984, 572.896), QPointF(350, 611.56), QPointF(332.072, 664.192));
+ path.cubicTo(QPointF(330.992, 666.64), QPointF(334.16, 668.368), QPointF(335.24, 666.064));
+ path.cubicTo(QPointF(354.824, 610.336), QPointF(341.432, 571.312), QPointF(299.024, 548.56));
+ path.cubicTo(QPointF(296.864, 547.552), QPointF(295.28, 550.432), QPointF(297.44, 551.512));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(72.008, 569.512);
+ path.cubicTo(QPointF(38.312, 627.256), QPointF(38.096, 662.68), QPointF(62.504, 681.328));
+ path.cubicTo(QPointF(63.728, 682.264), QPointF(64.448, 680.032), QPointF(63.296, 679.168));
+ path.cubicTo(QPointF(36.296, 655.48), QPointF(48.896, 615.52), QPointF(74.168, 570.88));
+ path.cubicTo(QPointF(74.888, 569.584), QPointF(72.512, 568.432), QPointF(72.008, 569.512));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(289.376, 586.864);
+ path.cubicTo(QPointF(289.232, 589.168), QPointF(288.368, 589.528), QPointF(286.424, 587.368));
+ path.cubicTo(QPointF(279.8, 575.848), QPointF(235.088, 551.44), QPointF(213.344, 548.704));
+ path.cubicTo(QPointF(209.24, 547.264), QPointF(209.456, 545.392), QPointF(213.488, 544.816));
+ path.cubicTo(QPointF(229.184, 544.816), QPointF(241.28, 537.904), QPointF(254.96, 537.904));
+ path.cubicTo(QPointF(258.704, 538.048), QPointF(262.304, 539.488), QPointF(264.392, 541.648));
+ path.cubicTo(QPointF(269.504, 544.96), QPointF(288.08, 570.592), QPointF(289.376, 586.864));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(180.152, 546.832);
+ path.cubicTo(QPointF(180.872, 550.792), QPointF(163.808, 545.68), QPointF(164.744, 556.696));
+ path.cubicTo(QPointF(165.032, 559.72), QPointF(160.496, 561.376), QPointF(160.64, 556.696));
+ path.cubicTo(QPointF(160.64, 548.272), QPointF(161.072, 548.416), QPointF(152.72, 546.832));
+ path.cubicTo(QPointF(151.208, 546.76), QPointF(151.352, 544.528), QPointF(152.72, 544.816));
+ path.lineTo(152.72, 544.816);
+ path.cubicTo(QPointF(158.696, 546.472), QPointF(166.76, 542.872), QPointF(166.4, 538.84));
+ path.cubicTo(QPointF(166.256, 537.472), QPointF(168.56, 537.688), QPointF(168.488, 538.84));
+ path.cubicTo(QPointF(167.984, 545.248), QPointF(181.664, 542.152), QPointF(180.152, 546.832));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(151.568, 705.376);
+ path.cubicTo(QPointF(151.64, 708.328), QPointF(148.76, 707.68), QPointF(148.544, 705.592));
+ path.cubicTo(QPointF(140.192, 680.536), QPointF(143.72, 618.832), QPointF(151.856, 598.96));
+ path.cubicTo(QPointF(152.432, 596.08), QPointF(156.248, 596.944), QPointF(155.744, 598.96));
+ path.cubicTo(QPointF(147.104, 635.464), QPointF(147.248, 673.048), QPointF(151.568, 705.376));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(183, 114, 0, 255));
+ path.moveTo(51.704, 684.424);
+ path.cubicTo(QPointF(75.68, 707.824), QPointF(91.376, 743.248), QPointF(114.632, 775.288));
+ path.cubicTo(QPointF(148.472, 816.04), QPointF(121.472, 858.304), QPointF(66.464, 845.56));
+ path.cubicTo(QPointF(38.888, 835.192), QPointF(-0.784, 836.344), QPointF(-32.68, 825.832));
+ path.cubicTo(QPointF(-55.072, 820.36), QPointF(-55.864, 809.272), QPointF(-44.416, 787.6));
+ path.cubicTo(QPointF(-40.384, 773.776), QPointF(-40.024, 751.312), QPointF(-43.768, 732.592));
+ path.cubicTo(QPointF(-45.784, 718.408), QPointF(-39.232, 710.488), QPointF(-24.112, 708.832));
+ path.lineTo(-24.112, 708.832);
+ path.cubicTo(QPointF(-11.296, 708.688), QPointF(6.56, 713.872), QPointF(16.28, 686.44));
+ path.cubicTo(QPointF(23.552, 673.336), QPointF(40.976, 672.976), QPointF(51.704, 684.424));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(242, 183, 0, 255));
+ path.moveTo(24.632, 699.04);
+ path.cubicTo(QPointF(23.84, 680.968), QPointF(39.32, 677.296), QPointF(49.688, 688.312));
+ path.cubicTo(QPointF(68.192, 710.992), QPointF(85.112, 736.048), QPointF(100.376, 764.992));
+ path.cubicTo(QPointF(124.712, 804.16), QPointF(104.624, 842.68), QPointF(67.904, 828.064));
+ path.cubicTo(QPointF(49.688, 817.84), QPointF(6.128, 813.304), QPointF(-17.344, 809.128));
+ path.cubicTo(QPointF(-33.04, 807.832), QPointF(-35.128, 797.608), QPointF(-29.152, 791.848));
+ path.cubicTo(QPointF(-20.944, 782.416), QPointF(-20.08, 759.808), QPointF(-27.856, 740.512));
+ path.cubicTo(QPointF(-35.56, 728.56), QPointF(-21.088, 715.384), QPointF(-9.712, 720.856));
+ path.cubicTo(QPointF(0.8, 727.048), QPointF(25.64, 713.08), QPointF(24.632, 699.04));
+ path.closeSubpath();
+ painter->drawPath(path);
+
+ painter->setPen(QPen(QColor(255, 0, 0, alpha), 0.25, Qt::SolidLine, Qt::FlatCap, Qt::BevelJoin));
+ painter->setBrush(Qt::NoBrush);
+ painter->drawRect(br.adjusted(-1, -1, 1, 1));
+}
+
+
+XFormWidget::XFormWidget(QWidget *parent)
+ : QWidget(parent), textEditor(new QLineEdit)
+{
+ setWindowTitle(tr("Affine Transformations"));
+
+ view = new XFormView(this);
+ view->setMinimumSize(200, 200);
+
+ QGroupBox *mainGroup = new QGroupBox(this);
+ mainGroup->setFixedWidth(180);
+ mainGroup->setTitle(tr("Affine Transformations"));
+
+ QGroupBox *rotateGroup = new QGroupBox(mainGroup);
+ rotateGroup->setTitle(tr("Rotate"));
+ QSlider *rotateSlider = new QSlider(Qt::Horizontal, rotateGroup);
+ rotateSlider->setRange(0, 3600);
+ rotateSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+
+ QGroupBox *scaleGroup = new QGroupBox(mainGroup);
+ scaleGroup->setTitle(tr("Scale"));
+ QSlider *scaleSlider = new QSlider(Qt::Horizontal, scaleGroup);
+ scaleSlider->setRange(1, 4000);
+ scaleSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+
+ QGroupBox *shearGroup = new QGroupBox(mainGroup);
+ shearGroup->setTitle(tr("Shear"));
+ QSlider *shearSlider = new QSlider(Qt::Horizontal, shearGroup);
+ shearSlider->setRange(-990, 990);
+ shearSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+
+ QGroupBox *typeGroup = new QGroupBox(mainGroup);
+ typeGroup->setTitle(tr("Type"));
+ QRadioButton *vectorType = new QRadioButton(typeGroup);
+ QRadioButton *pixmapType = new QRadioButton(typeGroup);
+ QRadioButton *textType= new QRadioButton(typeGroup);
+ vectorType->setText(tr("Vector Image"));
+ pixmapType->setText(tr("Pixmap"));
+ textType->setText(tr("Text"));
+
+ QPushButton *resetButton = new QPushButton(mainGroup);
+ resetButton->setText(tr("Reset Transform"));
+
+ QPushButton *animateButton = new QPushButton(mainGroup);
+ animateButton->setText(tr("Animate"));
+ 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(view->usesOpenGL());
+ if (!QGLFormat::hasOpenGL())
+ enableOpenGLButton->hide();
+#endif
+ QPushButton *whatsThisButton = new QPushButton(mainGroup);
+ whatsThisButton->setText(tr("What's This?"));
+ whatsThisButton->setCheckable(true);
+
+ QHBoxLayout *viewLayout = new QHBoxLayout(this);
+ viewLayout->addWidget(view);
+ viewLayout->addWidget(mainGroup);
+
+ QVBoxLayout *rotateGroupLayout = new QVBoxLayout(rotateGroup);
+ rotateGroupLayout->addWidget(rotateSlider);
+
+ QVBoxLayout *scaleGroupLayout = new QVBoxLayout(scaleGroup);
+ scaleGroupLayout->addWidget(scaleSlider);
+
+ QVBoxLayout *shearGroupLayout = new QVBoxLayout(shearGroup);
+ shearGroupLayout->addWidget(shearSlider);
+
+ QVBoxLayout *typeGroupLayout = new QVBoxLayout(typeGroup);
+ typeGroupLayout->addWidget(vectorType);
+ typeGroupLayout->addWidget(pixmapType);
+ typeGroupLayout->addWidget(textType);
+ typeGroupLayout->addSpacing(4);
+ typeGroupLayout->addWidget(textEditor);
+
+ QVBoxLayout *mainGroupLayout = new QVBoxLayout(mainGroup);
+ mainGroupLayout->addWidget(rotateGroup);
+ mainGroupLayout->addWidget(scaleGroup);
+ mainGroupLayout->addWidget(shearGroup);
+ mainGroupLayout->addWidget(typeGroup);
+ mainGroupLayout->addStretch(1);
+ mainGroupLayout->addWidget(resetButton);
+ mainGroupLayout->addWidget(animateButton);
+ mainGroupLayout->addWidget(showSourceButton);
+#ifdef QT_OPENGL_SUPPORT
+ mainGroupLayout->addWidget(enableOpenGLButton);
+#endif
+ mainGroupLayout->addWidget(whatsThisButton);
+
+ connect(rotateSlider, SIGNAL(valueChanged(int)), view, SLOT(changeRotation(int)));
+ connect(shearSlider, SIGNAL(valueChanged(int)), view, SLOT(changeShear(int)));
+ connect(scaleSlider, SIGNAL(valueChanged(int)), view, SLOT(changeScale(int)));
+
+ connect(vectorType, SIGNAL(clicked()), view, SLOT(setVectorType()));
+ connect(pixmapType, SIGNAL(clicked()), view, SLOT(setPixmapType()));
+ connect(textType, SIGNAL(clicked()), view, SLOT(setTextType()));
+ connect(textType, SIGNAL(toggled(bool)), textEditor, SLOT(setEnabled(bool)));
+ connect(textEditor, SIGNAL(textChanged(QString)), view, SLOT(setText(QString)));
+
+ connect(view, SIGNAL(rotationChanged(int)), rotateSlider, SLOT(setValue(int)));
+ connect(view, SIGNAL(scaleChanged(int)), scaleSlider, SLOT(setValue(int)));
+ connect(view, SIGNAL(shearChanged(int)), shearSlider, SLOT(setValue(int)));
+
+ connect(resetButton, SIGNAL(clicked()), view, SLOT(reset()));
+ connect(animateButton, SIGNAL(clicked(bool)), view, SLOT(setAnimation(bool)));
+ connect(whatsThisButton, SIGNAL(clicked(bool)), view, SLOT(setDescriptionEnabled(bool)));
+ connect(whatsThisButton, SIGNAL(clicked(bool)), view->hoverPoints(), SLOT(setDisabled(bool)));
+ connect(view, SIGNAL(descriptionEnabledChanged(bool)), view->hoverPoints(), SLOT(setDisabled(bool)));
+ connect(view, SIGNAL(descriptionEnabledChanged(bool)), whatsThisButton, SLOT(setChecked(bool)));
+ connect(showSourceButton, SIGNAL(clicked()), view, SLOT(showSource()));
+#ifdef QT_OPENGL_SUPPORT
+ connect(enableOpenGLButton, SIGNAL(clicked(bool)), view, SLOT(enableOpenGL(bool)));
+#endif
+ view->loadSourceFile(":res/affine/xform.cpp");
+ view->loadDescription(":res/affine/xform.html");
+
+ // defaults
+ view->reset();
+ vectorType->setChecked(true);
+ textEditor->setText("Qt Affine Transformation Example");
+ textEditor->setEnabled(false);
+
+ animateButton->animateClick();
+}
diff --git a/examples/widgets/painting/affine/xform.h b/examples/widgets/painting/affine/xform.h
new file mode 100644
index 0000000000..d710f5175e
--- /dev/null
+++ b/examples/widgets/painting/affine/xform.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef XFORM_H
+#define XFORM_H
+
+#include "arthurwidgets.h"
+
+#include <QBasicTimer>
+#include <QPolygonF>
+
+class HoverPoints;
+QT_FORWARD_DECLARE_CLASS(QLineEdit)
+
+class XFormView : public ArthurFrame
+{
+public:
+ Q_OBJECT
+
+ Q_PROPERTY(XFormType type READ type WRITE setType)
+ Q_PROPERTY(bool animation READ animation WRITE setAnimation)
+ Q_PROPERTY(qreal shear READ shear WRITE setShear)
+ Q_PROPERTY(qreal rotation READ rotation WRITE setRotation)
+ Q_PROPERTY(qreal scale READ scale WRITE setScale)
+ Q_PROPERTY(QString text READ text WRITE setText)
+ Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap)
+ Q_ENUMS(XFormType)
+
+public:
+ enum XFormType { VectorType, PixmapType, TextType };
+
+ XFormView(QWidget *parent);
+ void paint(QPainter *);
+ void drawVectorType(QPainter *painter);
+ void drawPixmapType(QPainter *painter);
+ void drawTextType(QPainter *painter);
+ QSize sizeHint() const { return QSize(500, 500); }
+
+ void mousePressEvent(QMouseEvent *e);
+ void resizeEvent(QResizeEvent *e);
+ HoverPoints *hoverPoints() { return pts; }
+
+ bool animation() const { return timer.isActive(); }
+ qreal shear() const { return m_shear; }
+ qreal scale() const { return m_scale; }
+ qreal rotation() const { return m_rotation; }
+ void setShear(qreal s);
+ void setScale(qreal s);
+ void setRotation(qreal r);
+
+ XFormType type() const;
+ QPixmap pixmap() const;
+ QString text() const;
+
+public slots:
+ void setAnimation(bool animate);
+ void updateCtrlPoints(const QPolygonF &);
+ void changeRotation(int rotation);
+ void changeScale(int scale);
+ void changeShear(int shear);
+
+ void setText(const QString &);
+ void setPixmap(const QPixmap &);
+ void setType(XFormType t);
+
+ void setVectorType();
+ void setPixmapType();
+ void setTextType();
+ void reset();
+
+signals:
+ void rotationChanged(int rotation);
+ void scaleChanged(int scale);
+ void shearChanged(int shear);
+
+protected:
+ void timerEvent(QTimerEvent *e);
+ void wheelEvent(QWheelEvent *);
+
+private:
+ QPolygonF ctrlPoints;
+ HoverPoints *pts;
+ qreal m_rotation;
+ qreal m_scale;
+ qreal m_shear;
+ XFormType m_type;
+ QPixmap m_pixmap;
+ QString m_text;
+ QBasicTimer timer;
+};
+
+class XFormWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ XFormWidget(QWidget *parent);
+
+private:
+ XFormView *view;
+ QLineEdit *textEditor;
+};
+
+#endif // XFORM_H
diff --git a/examples/widgets/painting/affine/xform.html b/examples/widgets/painting/affine/xform.html
new file mode 100644
index 0000000000..17325ac2a0
--- /dev/null
+++ b/examples/widgets/painting/affine/xform.html
@@ -0,0 +1,23 @@
+<html>
+<center>
+<h2>Affine Transformations</h2>
+</center>
+
+<p>In this demo we demonstrate Qt's ability to perform affine transformations
+on painting operations.</p>
+
+<p>Transformations can be performed on any kind of graphics drawn using
+QPainter. The transformations used to display the vector graphics, images,
+and text can be adjusted in the following ways:</p>
+
+<ul>
+ <li>Dragging the red circle in the centre of each drawing moves it to a new
+ position.</li>
+ <li>Dragging the displaced red circle causes the current drawing to be
+ rotated about the central circle. Rotation can also be controlled with
+ the <b>Rotate</b> slider.</li>
+ <li>Scaling is controlled with the <b>Scale</b> slider.</li>
+ <li>Each drawing can be sheared with the <b>Shear</b> slider.</li>
+</ul>
+
+</html>
diff --git a/examples/widgets/painting/basicdrawing/basicdrawing.desktop b/examples/widgets/painting/basicdrawing/basicdrawing.desktop
new file mode 100644
index 0000000000..7f178ec8a7
--- /dev/null
+++ b/examples/widgets/painting/basicdrawing/basicdrawing.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Terminal=false
+Name=Basic Drawing
+Exec=/opt/usr/bin/basicdrawing
+Icon=basicdrawing
+X-Window-Icon=
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
diff --git a/examples/widgets/painting/basicdrawing/basicdrawing.pro b/examples/widgets/painting/basicdrawing/basicdrawing.pro
new file mode 100644
index 0000000000..0e0328e61f
--- /dev/null
+++ b/examples/widgets/painting/basicdrawing/basicdrawing.pro
@@ -0,0 +1,14 @@
+HEADERS = renderarea.h \
+ window.h
+SOURCES = main.cpp \
+ renderarea.cpp \
+ window.cpp
+RESOURCES = basicdrawing.qrc
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/painting/basicdrawing
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS basicdrawing.pro images
+sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/painting/basicdrawing
+INSTALLS += target sources
+
+QT += widgets
diff --git a/examples/widgets/painting/basicdrawing/basicdrawing.qrc b/examples/widgets/painting/basicdrawing/basicdrawing.qrc
new file mode 100644
index 0000000000..9d8a23a1c8
--- /dev/null
+++ b/examples/widgets/painting/basicdrawing/basicdrawing.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>images/brick.png</file>
+ <file>images/qt-logo.png</file>
+</qresource>
+</RCC>
diff --git a/examples/widgets/painting/basicdrawing/images/brick.png b/examples/widgets/painting/basicdrawing/images/brick.png
new file mode 100644
index 0000000000..87e7df5b04
--- /dev/null
+++ b/examples/widgets/painting/basicdrawing/images/brick.png
Binary files differ
diff --git a/examples/widgets/painting/basicdrawing/images/qt-logo.png b/examples/widgets/painting/basicdrawing/images/qt-logo.png
new file mode 100644
index 0000000000..a8b452e07a
--- /dev/null
+++ b/examples/widgets/painting/basicdrawing/images/qt-logo.png
Binary files differ
diff --git a/examples/widgets/painting/basicdrawing/main.cpp b/examples/widgets/painting/basicdrawing/main.cpp
new file mode 100644
index 0000000000..d80c9a2daa
--- /dev/null
+++ b/examples/widgets/painting/basicdrawing/main.cpp
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+
+#include "window.h"
+
+int main(int argc, char *argv[])
+{
+ Q_INIT_RESOURCE(basicdrawing);
+
+ QApplication app(argc, argv);
+ Window window;
+ window.show();
+ return app.exec();
+}
diff --git a/examples/widgets/painting/basicdrawing/renderarea.cpp b/examples/widgets/painting/basicdrawing/renderarea.cpp
new file mode 100644
index 0000000000..9fb4ab589d
--- /dev/null
+++ b/examples/widgets/painting/basicdrawing/renderarea.cpp
@@ -0,0 +1,207 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtWidgets>
+
+#include "renderarea.h"
+
+//! [0]
+RenderArea::RenderArea(QWidget *parent)
+ : QWidget(parent)
+{
+ shape = Polygon;
+ antialiased = false;
+ transformed = false;
+ pixmap.load(":/images/qt-logo.png");
+
+ setBackgroundRole(QPalette::Base);
+ setAutoFillBackground(true);
+}
+//! [0]
+
+//! [1]
+QSize RenderArea::minimumSizeHint() const
+{
+ return QSize(100, 100);
+}
+//! [1]
+
+//! [2]
+QSize RenderArea::sizeHint() const
+{
+ return QSize(400, 200);
+}
+//! [2]
+
+//! [3]
+void RenderArea::setShape(Shape shape)
+{
+ this->shape = shape;
+ update();
+}
+//! [3]
+
+//! [4]
+void RenderArea::setPen(const QPen &pen)
+{
+ this->pen = pen;
+ update();
+}
+//! [4]
+
+//! [5]
+void RenderArea::setBrush(const QBrush &brush)
+{
+ this->brush = brush;
+ update();
+}
+//! [5]
+
+//! [6]
+void RenderArea::setAntialiased(bool antialiased)
+{
+ this->antialiased = antialiased;
+ update();
+}
+//! [6]
+
+//! [7]
+void RenderArea::setTransformed(bool transformed)
+{
+ this->transformed = transformed;
+ update();
+}
+//! [7]
+
+//! [8]
+void RenderArea::paintEvent(QPaintEvent * /* event */)
+{
+ static const QPoint points[4] = {
+ QPoint(10, 80),
+ QPoint(20, 10),
+ QPoint(80, 30),
+ QPoint(90, 70)
+ };
+
+ QRect rect(10, 20, 80, 60);
+
+ QPainterPath path;
+ path.moveTo(20, 80);
+ path.lineTo(20, 30);
+ path.cubicTo(80, 0, 50, 50, 80, 80);
+
+ int startAngle = 20 * 16;
+ int arcLength = 120 * 16;
+//! [8]
+
+//! [9]
+ QPainter painter(this);
+ painter.setPen(pen);
+ painter.setBrush(brush);
+ if (antialiased)
+ painter.setRenderHint(QPainter::Antialiasing, true);
+//! [9]
+
+//! [10]
+ for (int x = 0; x < width(); x += 100) {
+ for (int y = 0; y < height(); y += 100) {
+ painter.save();
+ painter.translate(x, y);
+//! [10] //! [11]
+ if (transformed) {
+ painter.translate(50, 50);
+ painter.rotate(60.0);
+ painter.scale(0.6, 0.9);
+ painter.translate(-50, -50);
+ }
+//! [11]
+
+//! [12]
+ switch (shape) {
+ case Line:
+ painter.drawLine(rect.bottomLeft(), rect.topRight());
+ break;
+ case Points:
+ painter.drawPoints(points, 4);
+ break;
+ case Polyline:
+ painter.drawPolyline(points, 4);
+ break;
+ case Polygon:
+ painter.drawPolygon(points, 4);
+ break;
+ case Rect:
+ painter.drawRect(rect);
+ break;
+ case RoundedRect:
+ painter.drawRoundedRect(rect, 25, 25, Qt::RelativeSize);
+ break;
+ case Ellipse:
+ painter.drawEllipse(rect);
+ break;
+ case Arc:
+ painter.drawArc(rect, startAngle, arcLength);
+ break;
+ case Chord:
+ painter.drawChord(rect, startAngle, arcLength);
+ break;
+ case Pie:
+ painter.drawPie(rect, startAngle, arcLength);
+ break;
+ case Path:
+ painter.drawPath(path);
+ break;
+ case Text:
+ painter.drawText(rect, Qt::AlignCenter, tr("Qt by\nNokia"));
+ break;
+ case Pixmap:
+ painter.drawPixmap(10, 10, pixmap);
+ }
+//! [12] //! [13]
+ painter.restore();
+ }
+ }
+
+ painter.setRenderHint(QPainter::Antialiasing, false);
+ painter.setPen(palette().dark().color());
+ painter.setBrush(Qt::NoBrush);
+ painter.drawRect(QRect(0, 0, width() - 1, height() - 1));
+}
+//! [13]
diff --git a/examples/widgets/painting/basicdrawing/renderarea.h b/examples/widgets/painting/basicdrawing/renderarea.h
new file mode 100644
index 0000000000..3ed9eb6321
--- /dev/null
+++ b/examples/widgets/painting/basicdrawing/renderarea.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RENDERAREA_H
+#define RENDERAREA_H
+
+#include <QBrush>
+#include <QPen>
+#include <QPixmap>
+#include <QWidget>
+
+//! [0]
+class RenderArea : public QWidget
+{
+ Q_OBJECT
+
+public:
+ enum Shape { Line, Points, Polyline, Polygon, Rect, RoundedRect, Ellipse, Arc,
+ Chord, Pie, Path, Text, Pixmap };
+
+ RenderArea(QWidget *parent = 0);
+
+ QSize minimumSizeHint() const;
+ QSize sizeHint() const;
+
+public slots:
+ void setShape(Shape shape);
+ void setPen(const QPen &pen);
+ void setBrush(const QBrush &brush);
+ void setAntialiased(bool antialiased);
+ void setTransformed(bool transformed);
+
+protected:
+ void paintEvent(QPaintEvent *event);
+
+private:
+ Shape shape;
+ QPen pen;
+ QBrush brush;
+ bool antialiased;
+ bool transformed;
+ QPixmap pixmap;
+};
+//! [0]
+
+#endif
diff --git a/examples/widgets/painting/basicdrawing/window.cpp b/examples/widgets/painting/basicdrawing/window.cpp
new file mode 100644
index 0000000000..9579e40ae2
--- /dev/null
+++ b/examples/widgets/painting/basicdrawing/window.cpp
@@ -0,0 +1,259 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtWidgets>
+
+#include "renderarea.h"
+#include "window.h"
+
+//! [0]
+const int IdRole = Qt::UserRole;
+//! [0]
+
+//! [1]
+Window::Window()
+{
+ renderArea = new RenderArea;
+
+ shapeComboBox = new QComboBox;
+ shapeComboBox->addItem(tr("Polygon"), RenderArea::Polygon);
+ shapeComboBox->addItem(tr("Rectangle"), RenderArea::Rect);
+ shapeComboBox->addItem(tr("Rounded Rectangle"), RenderArea::RoundedRect);
+ shapeComboBox->addItem(tr("Ellipse"), RenderArea::Ellipse);
+ shapeComboBox->addItem(tr("Pie"), RenderArea::Pie);
+ shapeComboBox->addItem(tr("Chord"), RenderArea::Chord);
+ shapeComboBox->addItem(tr("Path"), RenderArea::Path);
+ shapeComboBox->addItem(tr("Line"), RenderArea::Line);
+ shapeComboBox->addItem(tr("Polyline"), RenderArea::Polyline);
+ shapeComboBox->addItem(tr("Arc"), RenderArea::Arc);
+ shapeComboBox->addItem(tr("Points"), RenderArea::Points);
+ shapeComboBox->addItem(tr("Text"), RenderArea::Text);
+ shapeComboBox->addItem(tr("Pixmap"), RenderArea::Pixmap);
+
+ shapeLabel = new QLabel(tr("&Shape:"));
+ shapeLabel->setBuddy(shapeComboBox);
+//! [1]
+
+//! [2]
+ penWidthSpinBox = new QSpinBox;
+ penWidthSpinBox->setRange(0, 20);
+ penWidthSpinBox->setSpecialValueText(tr("0 (cosmetic pen)"));
+
+ penWidthLabel = new QLabel(tr("Pen &Width:"));
+ penWidthLabel->setBuddy(penWidthSpinBox);
+//! [2]
+
+//! [3]
+ penStyleComboBox = new QComboBox;
+ penStyleComboBox->addItem(tr("Solid"), Qt::SolidLine);
+ penStyleComboBox->addItem(tr("Dash"), Qt::DashLine);
+ penStyleComboBox->addItem(tr("Dot"), Qt::DotLine);
+ penStyleComboBox->addItem(tr("Dash Dot"), Qt::DashDotLine);
+ penStyleComboBox->addItem(tr("Dash Dot Dot"), Qt::DashDotDotLine);
+ penStyleComboBox->addItem(tr("None"), Qt::NoPen);
+
+ penStyleLabel = new QLabel(tr("&Pen Style:"));
+ penStyleLabel->setBuddy(penStyleComboBox);
+
+ penCapComboBox = new QComboBox;
+ penCapComboBox->addItem(tr("Flat"), Qt::FlatCap);
+ penCapComboBox->addItem(tr("Square"), Qt::SquareCap);
+ penCapComboBox->addItem(tr("Round"), Qt::RoundCap);
+
+ penCapLabel = new QLabel(tr("Pen &Cap:"));
+ penCapLabel->setBuddy(penCapComboBox);
+
+ penJoinComboBox = new QComboBox;
+ penJoinComboBox->addItem(tr("Miter"), Qt::MiterJoin);
+ penJoinComboBox->addItem(tr("Bevel"), Qt::BevelJoin);
+ penJoinComboBox->addItem(tr("Round"), Qt::RoundJoin);
+
+ penJoinLabel = new QLabel(tr("Pen &Join:"));
+ penJoinLabel->setBuddy(penJoinComboBox);
+//! [3]
+
+//! [4]
+ brushStyleComboBox = new QComboBox;
+ brushStyleComboBox->addItem(tr("Linear Gradient"),
+ Qt::LinearGradientPattern);
+ brushStyleComboBox->addItem(tr("Radial Gradient"),
+ Qt::RadialGradientPattern);
+ brushStyleComboBox->addItem(tr("Conical Gradient"),
+ Qt::ConicalGradientPattern);
+ brushStyleComboBox->addItem(tr("Texture"), Qt::TexturePattern);
+ brushStyleComboBox->addItem(tr("Solid"), Qt::SolidPattern);
+ brushStyleComboBox->addItem(tr("Horizontal"), Qt::HorPattern);
+ brushStyleComboBox->addItem(tr("Vertical"), Qt::VerPattern);
+ brushStyleComboBox->addItem(tr("Cross"), Qt::CrossPattern);
+ brushStyleComboBox->addItem(tr("Backward Diagonal"), Qt::BDiagPattern);
+ brushStyleComboBox->addItem(tr("Forward Diagonal"), Qt::FDiagPattern);
+ brushStyleComboBox->addItem(tr("Diagonal Cross"), Qt::DiagCrossPattern);
+ brushStyleComboBox->addItem(tr("Dense 1"), Qt::Dense1Pattern);
+ brushStyleComboBox->addItem(tr("Dense 2"), Qt::Dense2Pattern);
+ brushStyleComboBox->addItem(tr("Dense 3"), Qt::Dense3Pattern);
+ brushStyleComboBox->addItem(tr("Dense 4"), Qt::Dense4Pattern);
+ brushStyleComboBox->addItem(tr("Dense 5"), Qt::Dense5Pattern);
+ brushStyleComboBox->addItem(tr("Dense 6"), Qt::Dense6Pattern);
+ brushStyleComboBox->addItem(tr("Dense 7"), Qt::Dense7Pattern);
+ brushStyleComboBox->addItem(tr("None"), Qt::NoBrush);
+
+ brushStyleLabel = new QLabel(tr("&Brush:"));
+ brushStyleLabel->setBuddy(brushStyleComboBox);
+//! [4]
+
+//! [5]
+ otherOptionsLabel = new QLabel(tr("Options:"));
+//! [5] //! [6]
+ antialiasingCheckBox = new QCheckBox(tr("&Antialiasing"));
+//! [6] //! [7]
+ transformationsCheckBox = new QCheckBox(tr("&Transformations"));
+//! [7]
+
+//! [8]
+ connect(shapeComboBox, SIGNAL(activated(int)),
+ this, SLOT(shapeChanged()));
+ connect(penWidthSpinBox, SIGNAL(valueChanged(int)),
+ this, SLOT(penChanged()));
+ connect(penStyleComboBox, SIGNAL(activated(int)),
+ this, SLOT(penChanged()));
+ connect(penCapComboBox, SIGNAL(activated(int)),
+ this, SLOT(penChanged()));
+ connect(penJoinComboBox, SIGNAL(activated(int)),
+ this, SLOT(penChanged()));
+ connect(brushStyleComboBox, SIGNAL(activated(int)),
+ this, SLOT(brushChanged()));
+ connect(antialiasingCheckBox, SIGNAL(toggled(bool)),
+ renderArea, SLOT(setAntialiased(bool)));
+ connect(transformationsCheckBox, SIGNAL(toggled(bool)),
+ renderArea, SLOT(setTransformed(bool)));
+//! [8]
+
+//! [9]
+ QGridLayout *mainLayout = new QGridLayout;
+//! [9] //! [10]
+ mainLayout->setColumnStretch(0, 1);
+ mainLayout->setColumnStretch(3, 1);
+ mainLayout->addWidget(renderArea, 0, 0, 1, 4);
+ mainLayout->addWidget(shapeLabel, 2, 0, Qt::AlignRight);
+ mainLayout->addWidget(shapeComboBox, 2, 1);
+ mainLayout->addWidget(penWidthLabel, 3, 0, Qt::AlignRight);
+ mainLayout->addWidget(penWidthSpinBox, 3, 1);
+ mainLayout->addWidget(penStyleLabel, 4, 0, Qt::AlignRight);
+ mainLayout->addWidget(penStyleComboBox, 4, 1);
+ mainLayout->addWidget(penCapLabel, 3, 2, Qt::AlignRight);
+ mainLayout->addWidget(penCapComboBox, 3, 3);
+ mainLayout->addWidget(penJoinLabel, 2, 2, Qt::AlignRight);
+ mainLayout->addWidget(penJoinComboBox, 2, 3);
+ mainLayout->addWidget(brushStyleLabel, 4, 2, Qt::AlignRight);
+ mainLayout->addWidget(brushStyleComboBox, 4, 3);
+ mainLayout->addWidget(otherOptionsLabel, 5, 0, Qt::AlignRight);
+ mainLayout->addWidget(antialiasingCheckBox, 5, 1, 1, 1, Qt::AlignRight);
+ mainLayout->addWidget(transformationsCheckBox, 5, 2, 1, 2, Qt::AlignRight);
+ setLayout(mainLayout);
+
+ shapeChanged();
+ penChanged();
+ brushChanged();
+ antialiasingCheckBox->setChecked(true);
+
+ setWindowTitle(tr("Basic Drawing"));
+}
+//! [10]
+
+//! [11]
+void Window::shapeChanged()
+{
+ RenderArea::Shape shape = RenderArea::Shape(shapeComboBox->itemData(
+ shapeComboBox->currentIndex(), IdRole).toInt());
+ renderArea->setShape(shape);
+}
+//! [11]
+
+//! [12]
+void Window::penChanged()
+{
+ int width = penWidthSpinBox->value();
+ Qt::PenStyle style = Qt::PenStyle(penStyleComboBox->itemData(
+ penStyleComboBox->currentIndex(), IdRole).toInt());
+ Qt::PenCapStyle cap = Qt::PenCapStyle(penCapComboBox->itemData(
+ penCapComboBox->currentIndex(), IdRole).toInt());
+ Qt::PenJoinStyle join = Qt::PenJoinStyle(penJoinComboBox->itemData(
+ penJoinComboBox->currentIndex(), IdRole).toInt());
+
+ renderArea->setPen(QPen(Qt::blue, width, style, cap, join));
+}
+//! [12]
+
+//! [13]
+void Window::brushChanged()
+{
+ Qt::BrushStyle style = Qt::BrushStyle(brushStyleComboBox->itemData(
+//! [13]
+ brushStyleComboBox->currentIndex(), IdRole).toInt());
+
+//! [14]
+ if (style == Qt::LinearGradientPattern) {
+ QLinearGradient linearGradient(0, 0, 100, 100);
+ linearGradient.setColorAt(0.0, Qt::white);
+ linearGradient.setColorAt(0.2, Qt::green);
+ linearGradient.setColorAt(1.0, Qt::black);
+ renderArea->setBrush(linearGradient);
+//! [14] //! [15]
+ } else if (style == Qt::RadialGradientPattern) {
+ QRadialGradient radialGradient(50, 50, 50, 70, 70);
+ radialGradient.setColorAt(0.0, Qt::white);
+ radialGradient.setColorAt(0.2, Qt::green);
+ radialGradient.setColorAt(1.0, Qt::black);
+ renderArea->setBrush(radialGradient);
+ } else if (style == Qt::ConicalGradientPattern) {
+ QConicalGradient conicalGradient(50, 50, 150);
+ conicalGradient.setColorAt(0.0, Qt::white);
+ conicalGradient.setColorAt(0.2, Qt::green);
+ conicalGradient.setColorAt(1.0, Qt::black);
+ renderArea->setBrush(conicalGradient);
+//! [15] //! [16]
+ } else if (style == Qt::TexturePattern) {
+ renderArea->setBrush(QBrush(QPixmap(":/images/brick.png")));
+//! [16] //! [17]
+ } else {
+ renderArea->setBrush(QBrush(Qt::green, style));
+ }
+}
+//! [17]
diff --git a/examples/widgets/painting/basicdrawing/window.h b/examples/widgets/painting/basicdrawing/window.h
new file mode 100644
index 0000000000..3f2c8fd561
--- /dev/null
+++ b/examples/widgets/painting/basicdrawing/window.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WINDOW_H
+#define WINDOW_H
+
+#include <QWidget>
+
+QT_BEGIN_NAMESPACE
+class QCheckBox;
+class QComboBox;
+class QLabel;
+class QSpinBox;
+QT_END_NAMESPACE
+class RenderArea;
+
+//! [0]
+class Window : public QWidget
+{
+ Q_OBJECT
+
+public:
+ Window();
+
+private slots:
+ void shapeChanged();
+ void penChanged();
+ void brushChanged();
+
+private:
+ RenderArea *renderArea;
+ QLabel *shapeLabel;
+ QLabel *penWidthLabel;
+ QLabel *penStyleLabel;
+ QLabel *penCapLabel;
+ QLabel *penJoinLabel;
+ QLabel *brushStyleLabel;
+ QLabel *otherOptionsLabel;
+ QComboBox *shapeComboBox;
+ QSpinBox *penWidthSpinBox;
+ QComboBox *penStyleComboBox;
+ QComboBox *penCapComboBox;
+ QComboBox *penJoinComboBox;
+ QComboBox *brushStyleComboBox;
+ QCheckBox *antialiasingCheckBox;
+ QCheckBox *transformationsCheckBox;
+};
+//! [0]
+
+#endif
diff --git a/examples/widgets/painting/composition/composition.cpp b/examples/widgets/painting/composition/composition.cpp
new file mode 100644
index 0000000000..f46a658c17
--- /dev/null
+++ b/examples/widgets/painting/composition/composition.cpp
@@ -0,0 +1,522 @@
+/****************************************************************************
+**
+** 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 "composition.h"
+#include <QBoxLayout>
+#include <QRadioButton>
+#include <QTimer>
+#include <QDateTime>
+#include <QSlider>
+#include <QMouseEvent>
+#include <qmath.h>
+
+const int animationInterval = 15; // update every 16 ms = ~60FPS
+
+CompositionWidget::CompositionWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ CompositionRenderer *view = new CompositionRenderer(this);
+
+ QGroupBox *mainGroup = new QGroupBox(parent);
+ mainGroup->setTitle(tr("Composition Modes"));
+
+ QGroupBox *modesGroup = new QGroupBox(mainGroup);
+ modesGroup->setTitle(tr("Mode"));
+
+ rbClear = new QRadioButton(tr("Clear"), modesGroup);
+ connect(rbClear, SIGNAL(clicked()), view, SLOT(setClearMode()));
+ rbSource = new QRadioButton(tr("Source"), modesGroup);
+ connect(rbSource, SIGNAL(clicked()), view, SLOT(setSourceMode()));
+ rbDest = new QRadioButton(tr("Destination"), modesGroup);
+ connect(rbDest, SIGNAL(clicked()), view, SLOT(setDestMode()));
+ rbSourceOver = new QRadioButton(tr("Source Over"), modesGroup);
+ connect(rbSourceOver, SIGNAL(clicked()), view, SLOT(setSourceOverMode()));
+ rbDestOver = new QRadioButton(tr("Destination Over"), modesGroup);
+ connect(rbDestOver, SIGNAL(clicked()), view, SLOT(setDestOverMode()));
+ rbSourceIn = new QRadioButton(tr("Source In"), modesGroup);
+ connect(rbSourceIn, SIGNAL(clicked()), view, SLOT(setSourceInMode()));
+ rbDestIn = new QRadioButton(tr("Dest In"), modesGroup);
+ connect(rbDestIn, SIGNAL(clicked()), view, SLOT(setDestInMode()));
+ rbSourceOut = new QRadioButton(tr("Source Out"), modesGroup);
+ connect(rbSourceOut, SIGNAL(clicked()), view, SLOT(setSourceOutMode()));
+ rbDestOut = new QRadioButton(tr("Dest Out"), modesGroup);
+ connect(rbDestOut, SIGNAL(clicked()), view, SLOT(setDestOutMode()));
+ rbSourceAtop = new QRadioButton(tr("Source Atop"), modesGroup);
+ connect(rbSourceAtop, SIGNAL(clicked()), view, SLOT(setSourceAtopMode()));
+ rbDestAtop = new QRadioButton(tr("Dest Atop"), modesGroup);
+ connect(rbDestAtop, SIGNAL(clicked()), view, SLOT(setDestAtopMode()));
+ rbXor = new QRadioButton(tr("Xor"), modesGroup);
+ connect(rbXor, SIGNAL(clicked()), view, SLOT(setXorMode()));
+
+ rbPlus = new QRadioButton(tr("Plus"), modesGroup);
+ connect(rbPlus, SIGNAL(clicked()), view, SLOT(setPlusMode()));
+ rbMultiply = new QRadioButton(tr("Multiply"), modesGroup);
+ connect(rbMultiply, SIGNAL(clicked()), view, SLOT(setMultiplyMode()));
+ rbScreen = new QRadioButton(tr("Screen"), modesGroup);
+ connect(rbScreen, SIGNAL(clicked()), view, SLOT(setScreenMode()));
+ rbOverlay = new QRadioButton(tr("Overlay"), modesGroup);
+ connect(rbOverlay, SIGNAL(clicked()), view, SLOT(setOverlayMode()));
+ rbDarken = new QRadioButton(tr("Darken"), modesGroup);
+ connect(rbDarken, SIGNAL(clicked()), view, SLOT(setDarkenMode()));
+ rbLighten = new QRadioButton(tr("Lighten"), modesGroup);
+ connect(rbLighten, SIGNAL(clicked()), view, SLOT(setLightenMode()));
+ rbColorDodge = new QRadioButton(tr("Color Dodge"), modesGroup);
+ connect(rbColorDodge, SIGNAL(clicked()), view, SLOT(setColorDodgeMode()));
+ rbColorBurn = new QRadioButton(tr("Color Burn"), modesGroup);
+ connect(rbColorBurn, SIGNAL(clicked()), view, SLOT(setColorBurnMode()));
+ rbHardLight = new QRadioButton(tr("Hard Light"), modesGroup);
+ connect(rbHardLight, SIGNAL(clicked()), view, SLOT(setHardLightMode()));
+ rbSoftLight = new QRadioButton(tr("Soft Light"), modesGroup);
+ connect(rbSoftLight, SIGNAL(clicked()), view, SLOT(setSoftLightMode()));
+ rbDifference = new QRadioButton(tr("Difference"), modesGroup);
+ connect(rbDifference, SIGNAL(clicked()), view, SLOT(setDifferenceMode()));
+ rbExclusion = new QRadioButton(tr("Exclusion"), modesGroup);
+ connect(rbExclusion, SIGNAL(clicked()), view, SLOT(setExclusionMode()));
+
+ QGroupBox *circleColorGroup = new QGroupBox(mainGroup);
+ circleColorGroup->setTitle(tr("Circle color"));
+ QSlider *circleColorSlider = new QSlider(Qt::Horizontal, circleColorGroup);
+ circleColorSlider->setRange(0, 359);
+ circleColorSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ connect(circleColorSlider, SIGNAL(valueChanged(int)), view, SLOT(setCircleColor(int)));
+
+ QGroupBox *circleAlphaGroup = new QGroupBox(mainGroup);
+ circleAlphaGroup->setTitle(tr("Circle alpha"));
+ QSlider *circleAlphaSlider = new QSlider(Qt::Horizontal, circleAlphaGroup);
+ circleAlphaSlider->setRange(0, 255);
+ circleAlphaSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ connect(circleAlphaSlider, SIGNAL(valueChanged(int)), view, SLOT(setCircleAlpha(int)));
+
+ QPushButton *showSourceButton = new QPushButton(mainGroup);
+ showSourceButton->setText(tr("Show Source"));
+#if defined(QT_OPENGL_SUPPORT) && !defined(QT_OPENGL_ES)
+ QPushButton *enableOpenGLButton = new QPushButton(mainGroup);
+ enableOpenGLButton->setText(tr("Use OpenGL"));
+ enableOpenGLButton->setCheckable(true);
+ enableOpenGLButton->setChecked(view->usesOpenGL());
+
+ if (!QGLFormat::hasOpenGL() || !QGLPixelBuffer::hasOpenGLPbuffers())
+ enableOpenGLButton->hide();
+#endif
+ QPushButton *whatsThisButton = new QPushButton(mainGroup);
+ whatsThisButton->setText(tr("What's This?"));
+ whatsThisButton->setCheckable(true);
+
+ QPushButton *animateButton = new QPushButton(mainGroup);
+ animateButton->setText(tr("Animated"));
+ animateButton->setCheckable(true);
+ animateButton->setChecked(true);
+
+ QHBoxLayout *viewLayout = new QHBoxLayout(this);
+ viewLayout->addWidget(view);
+ viewLayout->addWidget(mainGroup);
+
+ QVBoxLayout *mainGroupLayout = new QVBoxLayout(mainGroup);
+ mainGroupLayout->addWidget(circleColorGroup);
+ mainGroupLayout->addWidget(circleAlphaGroup);
+ mainGroupLayout->addWidget(modesGroup);
+ mainGroupLayout->addStretch();
+ mainGroupLayout->addWidget(animateButton);
+ mainGroupLayout->addWidget(whatsThisButton);
+ mainGroupLayout->addWidget(showSourceButton);
+#if defined(QT_OPENGL_SUPPORT) && !defined(QT_OPENGL_ES)
+ mainGroupLayout->addWidget(enableOpenGLButton);
+#endif
+
+ QGridLayout *modesLayout = new QGridLayout(modesGroup);
+ modesLayout->addWidget(rbClear, 0, 0);
+ modesLayout->addWidget(rbSource, 1, 0);
+ modesLayout->addWidget(rbDest, 2, 0);
+ modesLayout->addWidget(rbSourceOver, 3, 0);
+ modesLayout->addWidget(rbDestOver, 4, 0);
+ modesLayout->addWidget(rbSourceIn, 5, 0);
+ modesLayout->addWidget(rbDestIn, 6, 0);
+ modesLayout->addWidget(rbSourceOut, 7, 0);
+ modesLayout->addWidget(rbDestOut, 8, 0);
+ modesLayout->addWidget(rbSourceAtop, 9, 0);
+ modesLayout->addWidget(rbDestAtop, 10, 0);
+ modesLayout->addWidget(rbXor, 11, 0);
+
+ modesLayout->addWidget(rbPlus, 0, 1);
+ modesLayout->addWidget(rbMultiply, 1, 1);
+ modesLayout->addWidget(rbScreen, 2, 1);
+ modesLayout->addWidget(rbOverlay, 3, 1);
+ modesLayout->addWidget(rbDarken, 4, 1);
+ modesLayout->addWidget(rbLighten, 5, 1);
+ modesLayout->addWidget(rbColorDodge, 6, 1);
+ modesLayout->addWidget(rbColorBurn, 7, 1);
+ modesLayout->addWidget(rbHardLight, 8, 1);
+ modesLayout->addWidget(rbSoftLight, 9, 1);
+ modesLayout->addWidget(rbDifference, 10, 1);
+ modesLayout->addWidget(rbExclusion, 11, 1);
+
+
+ QVBoxLayout *circleColorLayout = new QVBoxLayout(circleColorGroup);
+ circleColorLayout->addWidget(circleColorSlider);
+
+ QVBoxLayout *circleAlphaLayout = new QVBoxLayout(circleAlphaGroup);
+ circleAlphaLayout->addWidget(circleAlphaSlider);
+
+ view->loadDescription(":res/composition/composition.html");
+ view->loadSourceFile(":res/composition/composition.cpp");
+
+ connect(whatsThisButton, SIGNAL(clicked(bool)), view, SLOT(setDescriptionEnabled(bool)));
+ connect(view, SIGNAL(descriptionEnabledChanged(bool)), whatsThisButton, SLOT(setChecked(bool)));
+ connect(showSourceButton, SIGNAL(clicked()), view, SLOT(showSource()));
+#if defined(QT_OPENGL_SUPPORT) && !defined(QT_OPENGL_ES)
+ connect(enableOpenGLButton, SIGNAL(clicked(bool)), view, SLOT(enableOpenGL(bool)));
+#endif
+ connect(animateButton, SIGNAL(toggled(bool)), view, SLOT(setAnimationEnabled(bool)));
+
+ circleColorSlider->setValue(270);
+ circleAlphaSlider->setValue(200);
+ rbSourceOut->animateClick();
+
+ setWindowTitle(tr("Composition Modes"));
+}
+
+
+void CompositionWidget::nextMode()
+{
+ /*
+ if (!m_animation_enabled)
+ return;
+ if (rbClear->isChecked()) rbSource->animateClick();
+ if (rbSource->isChecked()) rbDest->animateClick();
+ if (rbDest->isChecked()) rbSourceOver->animateClick();
+ if (rbSourceOver->isChecked()) rbDestOver->animateClick();
+ if (rbDestOver->isChecked()) rbSourceIn->animateClick();
+ if (rbSourceIn->isChecked()) rbDestIn->animateClick();
+ if (rbDestIn->isChecked()) rbSourceOut->animateClick();
+ if (rbSourceOut->isChecked()) rbDestOut->animateClick();
+ if (rbDestOut->isChecked()) rbSourceAtop->animateClick();
+ if (rbSourceAtop->isChecked()) rbDestAtop->animateClick();
+ if (rbDestAtop->isChecked()) rbXor->animateClick();
+ if (rbXor->isChecked()) rbClear->animateClick();
+ */
+}
+
+CompositionRenderer::CompositionRenderer(QWidget *parent)
+ : ArthurFrame(parent)
+{
+ m_animation_enabled = true;
+ m_animationTimer = startTimer(animationInterval);
+ m_image = QImage(":res/composition/flower.jpg");
+ m_image.setAlphaChannel(QImage(":res/composition/flower_alpha.jpg"));
+ m_circle_alpha = 127;
+ m_circle_hue = 255;
+ m_current_object = NoObject;
+ m_composition_mode = QPainter::CompositionMode_SourceOut;
+
+ m_circle_pos = QPoint(200, 100);
+
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+#ifdef QT_OPENGL_SUPPORT
+ m_pbuffer = 0;
+ m_pbuffer_size = 1024;
+#endif
+}
+
+QRectF rectangle_around(const QPointF &p, const QSizeF &size = QSize(250, 200))
+{
+ QRectF rect(p, size);
+ rect.translate(-size.width()/2, -size.height()/2);
+ return rect;
+}
+
+void CompositionRenderer::setAnimationEnabled(bool enabled)
+{
+ if (m_animation_enabled == enabled)
+ return;
+ m_animation_enabled = enabled;
+ if (enabled) {
+ Q_ASSERT(!m_animationTimer);
+ m_animationTimer = startTimer(animationInterval);
+ } else {
+ killTimer(m_animationTimer);
+ m_animationTimer = 0;
+ }
+}
+
+void CompositionRenderer::updateCirclePos()
+{
+ if (m_current_object != NoObject)
+ return;
+ QDateTime dt = QDateTime::currentDateTime();
+ qreal t = (dt.toTime_t() * 1000 + dt.time().msec()) / 1000.0;
+
+ qreal x = width() / qreal(2) + (qCos(t*8/11) + qSin(-t)) * width() / qreal(4);
+ qreal y = height() / qreal(2) + (qSin(t*6/7) + qCos(t * qreal(1.5))) * height() / qreal(4);
+
+ setCirclePos(QLineF(m_circle_pos, QPointF(x, y)).pointAt(0.02));
+}
+
+void CompositionRenderer::drawBase(QPainter &p)
+{
+ p.setPen(Qt::NoPen);
+
+ QLinearGradient rect_gradient(0, 0, 0, height());
+ rect_gradient.setColorAt(0, Qt::red);
+ rect_gradient.setColorAt(.17, Qt::yellow);
+ rect_gradient.setColorAt(.33, Qt::green);
+ rect_gradient.setColorAt(.50, Qt::cyan);
+ rect_gradient.setColorAt(.66, Qt::blue);
+ rect_gradient.setColorAt(.81, Qt::magenta);
+ rect_gradient.setColorAt(1, Qt::red);
+ p.setBrush(rect_gradient);
+ p.drawRect(width() / 2, 0, width() / 2, height());
+
+ QLinearGradient alpha_gradient(0, 0, width(), 0);
+ alpha_gradient.setColorAt(0, Qt::white);
+ alpha_gradient.setColorAt(0.2, Qt::white);
+ alpha_gradient.setColorAt(0.5, Qt::transparent);
+ alpha_gradient.setColorAt(0.8, Qt::white);
+ alpha_gradient.setColorAt(1, Qt::white);
+
+ p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
+ p.setBrush(alpha_gradient);
+ p.drawRect(0, 0, width(), height());
+
+ p.setCompositionMode(QPainter::CompositionMode_DestinationOver);
+
+ p.setPen(Qt::NoPen);
+ p.setRenderHint(QPainter::SmoothPixmapTransform);
+ p.drawImage(rect(), m_image);
+}
+
+void CompositionRenderer::drawSource(QPainter &p)
+{
+ p.setPen(Qt::NoPen);
+ p.setRenderHint(QPainter::Antialiasing);
+ p.setCompositionMode(m_composition_mode);
+
+ QRectF circle_rect = rectangle_around(m_circle_pos);
+ QColor color = QColor::fromHsvF(m_circle_hue / 360.0, 1, 1, m_circle_alpha / 255.0);
+ QLinearGradient circle_gradient(circle_rect.topLeft(), circle_rect.bottomRight());
+ circle_gradient.setColorAt(0, color.light());
+ circle_gradient.setColorAt(0.5, color);
+ circle_gradient.setColorAt(1, color.dark());
+ p.setBrush(circle_gradient);
+
+ p.drawEllipse(circle_rect);
+}
+
+void CompositionRenderer::paint(QPainter *painter)
+{
+#if defined(QT_OPENGL_SUPPORT) && !defined(QT_OPENGL_ES)
+ if (usesOpenGL()) {
+
+ int new_pbuf_size = m_pbuffer_size;
+ if (size().width() > m_pbuffer_size ||
+ size().height() > m_pbuffer_size)
+ new_pbuf_size *= 2;
+
+ if (size().width() < m_pbuffer_size/2 &&
+ size().height() < m_pbuffer_size/2)
+ new_pbuf_size /= 2;
+
+ if (!m_pbuffer || new_pbuf_size != m_pbuffer_size) {
+ if (m_pbuffer) {
+ m_pbuffer->deleteTexture(m_base_tex);
+ m_pbuffer->deleteTexture(m_compositing_tex);
+ delete m_pbuffer;
+ }
+
+ m_pbuffer = new QGLPixelBuffer(QSize(new_pbuf_size, new_pbuf_size), QGLFormat::defaultFormat(), glWidget());
+ m_pbuffer->makeCurrent();
+ m_base_tex = m_pbuffer->generateDynamicTexture();
+ m_compositing_tex = m_pbuffer->generateDynamicTexture();
+ m_pbuffer_size = new_pbuf_size;
+ }
+
+ if (size() != m_previous_size) {
+ m_previous_size = size();
+ QPainter p(m_pbuffer);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ p.fillRect(QRect(0, 0, m_pbuffer->width(), m_pbuffer->height()), Qt::transparent);
+ drawBase(p);
+ p.end();
+ m_pbuffer->updateDynamicTexture(m_base_tex);
+ }
+
+ qreal x_fraction = width()/float(m_pbuffer->width());
+ qreal y_fraction = height()/float(m_pbuffer->height());
+
+ {
+ QPainter p(m_pbuffer);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ p.fillRect(QRect(0, 0, m_pbuffer->width(), m_pbuffer->height()), Qt::transparent);
+
+ p.save(); // Needed when using the GL1 engine
+ p.beginNativePainting(); // Needed when using the GL2 engine
+
+ glBindTexture(GL_TEXTURE_2D, m_base_tex);
+ glEnable(GL_TEXTURE_2D);
+ glColor4f(1.,1.,1.,1.);
+
+ glBegin(GL_QUADS);
+ {
+ glTexCoord2f(0, 1.0);
+ glVertex2f(0, 0);
+
+ glTexCoord2f(x_fraction, 1.0);
+ glVertex2f(width(), 0);
+
+ glTexCoord2f(x_fraction, 1.0-y_fraction);
+ glVertex2f(width(), height());
+
+ glTexCoord2f(0, 1.0-y_fraction);
+ glVertex2f(0, height());
+ }
+ glEnd();
+
+ glDisable(GL_TEXTURE_2D);
+
+ p.endNativePainting(); // Needed when using the GL2 engine
+ p.restore(); // Needed when using the GL1 engine
+
+ drawSource(p);
+ p.end();
+ m_pbuffer->updateDynamicTexture(m_compositing_tex);
+ }
+
+ painter->beginNativePainting(); // Needed when using the GL2 engine
+ glWidget()->makeCurrent(); // Needed when using the GL1 engine
+ glBindTexture(GL_TEXTURE_2D, m_compositing_tex);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ glColor4f(1.,1.,1.,1.);
+ glBegin(GL_QUADS);
+ {
+ glTexCoord2f(0, 1.0);
+ glVertex2f(0, 0);
+
+ glTexCoord2f(x_fraction, 1.0);
+ glVertex2f(width(), 0);
+
+ glTexCoord2f(x_fraction, 1.0-y_fraction);
+ glVertex2f(width(), height());
+
+ glTexCoord2f(0, 1.0-y_fraction);
+ glVertex2f(0, height());
+ }
+ glEnd();
+ glDisable(GL_TEXTURE_2D);
+ painter->endNativePainting(); // Needed when using the GL2 engine
+ } else
+#endif
+ {
+ // using a QImage
+ if (m_buffer.size() != size()) {
+ m_buffer = QImage(size(), QImage::Format_ARGB32_Premultiplied);
+ m_base_buffer = QImage(size(), QImage::Format_ARGB32_Premultiplied);
+
+ m_base_buffer.fill(0);
+
+ QPainter p(&m_base_buffer);
+
+ drawBase(p);
+ }
+
+ memcpy(m_buffer.bits(), m_base_buffer.bits(), m_buffer.byteCount());
+
+ {
+ QPainter p(&m_buffer);
+ drawSource(p);
+ }
+
+ painter->drawImage(0, 0, m_buffer);
+ }
+}
+
+void CompositionRenderer::mousePressEvent(QMouseEvent *e)
+{
+ setDescriptionEnabled(false);
+
+ QRectF circle = rectangle_around(m_circle_pos);
+
+ if (circle.contains(e->pos())) {
+ m_current_object = Circle;
+ m_offset = circle.center() - e->pos();
+ } else {
+ m_current_object = NoObject;
+ }
+ if (m_animation_enabled) {
+ killTimer(m_animationTimer);
+ m_animationTimer = 0;
+ }
+}
+
+void CompositionRenderer::mouseMoveEvent(QMouseEvent *e)
+{
+ if (m_current_object == Circle) setCirclePos(e->pos() + m_offset);
+}
+
+void CompositionRenderer::mouseReleaseEvent(QMouseEvent *)
+{
+ m_current_object = NoObject;
+
+ if (m_animation_enabled) {
+ Q_ASSERT(!m_animationTimer);
+ m_animationTimer = startTimer(animationInterval);
+ }
+}
+
+void CompositionRenderer::timerEvent(QTimerEvent *event)
+{
+ if (event->timerId() == m_animationTimer)
+ updateCirclePos();
+}
+
+void CompositionRenderer::setCirclePos(const QPointF &pos)
+{
+ const QRect oldRect = rectangle_around(m_circle_pos).toAlignedRect();
+ m_circle_pos = pos;
+ const QRect newRect = rectangle_around(m_circle_pos).toAlignedRect();
+#if defined(QT_OPENGL_SUPPORT) && !defined(QT_OPENGL_ES)
+ if (usesOpenGL())
+ update();
+ else
+#endif
+ update(oldRect | newRect);
+}
+
diff --git a/examples/widgets/painting/composition/composition.h b/examples/widgets/painting/composition/composition.h
new file mode 100644
index 0000000000..ebf278f145
--- /dev/null
+++ b/examples/widgets/painting/composition/composition.h
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef COMPOSITION_H
+#define COMPOSITION_H
+
+#include "arthurwidgets.h"
+
+#include <QPainter>
+#include <QEvent>
+
+QT_FORWARD_DECLARE_CLASS(QPushButton)
+QT_FORWARD_DECLARE_CLASS(QRadioButton)
+
+#ifdef QT_OPENGL_SUPPORT
+#include <QtOpenGL>
+#endif
+
+class CompositionWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ CompositionWidget(QWidget *parent);
+
+public slots:
+void nextMode();
+
+private:
+ bool m_cycle_enabled;
+
+ QRadioButton *rbClear;
+ QRadioButton *rbSource;
+ QRadioButton *rbDest;
+ QRadioButton *rbSourceOver;
+ QRadioButton *rbDestOver;
+ QRadioButton *rbSourceIn;
+ QRadioButton *rbDestIn;
+ QRadioButton *rbSourceOut;
+ QRadioButton *rbDestOut;
+ QRadioButton *rbSourceAtop;
+ QRadioButton *rbDestAtop;
+ QRadioButton *rbXor;
+
+ QRadioButton *rbPlus;
+ QRadioButton *rbMultiply;
+ QRadioButton *rbScreen;
+ QRadioButton *rbOverlay;
+ QRadioButton *rbDarken;
+ QRadioButton *rbLighten;
+ QRadioButton *rbColorDodge;
+ QRadioButton *rbColorBurn;
+ QRadioButton *rbHardLight;
+ QRadioButton *rbSoftLight;
+ QRadioButton *rbDifference;
+ QRadioButton *rbExclusion;
+};
+
+class CompositionRenderer : public ArthurFrame
+{
+ Q_OBJECT
+
+ enum ObjectType { NoObject, Circle, Rectangle, Image };
+
+ Q_PROPERTY(int circleColor READ circleColor WRITE setCircleColor)
+ Q_PROPERTY(int circleAlpha READ circleAlpha WRITE setCircleAlpha)
+ Q_PROPERTY(bool animation READ animationEnabled WRITE setAnimationEnabled)
+
+public:
+ CompositionRenderer(QWidget *parent);
+
+ void paint(QPainter *);
+
+ void setCirclePos(const QPointF &pos);
+
+ QSize sizeHint() const { return QSize(500, 400); }
+
+ bool animationEnabled() const { return m_animation_enabled; }
+ int circleColor() const { return m_circle_hue; }
+ int circleAlpha() const { return m_circle_alpha; }
+
+protected:
+ void mousePressEvent(QMouseEvent *);
+ void mouseMoveEvent(QMouseEvent *);
+ void mouseReleaseEvent(QMouseEvent *);
+ void timerEvent(QTimerEvent *);
+
+public slots:
+ void setClearMode() { m_composition_mode = QPainter::CompositionMode_Clear; update(); }
+ void setSourceMode() { m_composition_mode = QPainter::CompositionMode_Source; update(); }
+ void setDestMode() { m_composition_mode = QPainter::CompositionMode_Destination; update(); }
+ void setSourceOverMode() { m_composition_mode = QPainter::CompositionMode_SourceOver; update(); }
+ void setDestOverMode() { m_composition_mode = QPainter::CompositionMode_DestinationOver; update(); }
+ void setSourceInMode() { m_composition_mode = QPainter::CompositionMode_SourceIn; update(); }
+ void setDestInMode() { m_composition_mode = QPainter::CompositionMode_DestinationIn; update(); }
+ void setSourceOutMode() { m_composition_mode = QPainter::CompositionMode_SourceOut; update(); }
+ void setDestOutMode() { m_composition_mode = QPainter::CompositionMode_DestinationOut; update(); }
+ void setSourceAtopMode() { m_composition_mode = QPainter::CompositionMode_SourceAtop; update(); }
+ void setDestAtopMode() { m_composition_mode = QPainter::CompositionMode_DestinationAtop; update(); }
+ void setXorMode() { m_composition_mode = QPainter::CompositionMode_Xor; update(); }
+
+ void setPlusMode() { m_composition_mode = QPainter::CompositionMode_Plus; update(); }
+ void setMultiplyMode() { m_composition_mode = QPainter::CompositionMode_Multiply; update(); }
+ void setScreenMode() { m_composition_mode = QPainter::CompositionMode_Screen; update(); }
+ void setOverlayMode() { m_composition_mode = QPainter::CompositionMode_Overlay; update(); }
+ void setDarkenMode() { m_composition_mode = QPainter::CompositionMode_Darken; update(); }
+ void setLightenMode() { m_composition_mode = QPainter::CompositionMode_Lighten; update(); }
+ void setColorDodgeMode() { m_composition_mode = QPainter::CompositionMode_ColorDodge; update(); }
+ void setColorBurnMode() { m_composition_mode = QPainter::CompositionMode_ColorBurn; update(); }
+ void setHardLightMode() { m_composition_mode = QPainter::CompositionMode_HardLight; update(); }
+ void setSoftLightMode() { m_composition_mode = QPainter::CompositionMode_SoftLight; update(); }
+ void setDifferenceMode() { m_composition_mode = QPainter::CompositionMode_Difference; update(); }
+ void setExclusionMode() { m_composition_mode = QPainter::CompositionMode_Exclusion; update(); }
+
+ void setCircleAlpha(int alpha) { m_circle_alpha = alpha; update(); }
+ void setCircleColor(int hue) { m_circle_hue = hue; update(); }
+ void setAnimationEnabled(bool enabled);
+
+private:
+ void updateCirclePos();
+ void drawBase(QPainter &p);
+ void drawSource(QPainter &p);
+
+ QPainter::CompositionMode m_composition_mode;
+
+ QImage m_image;
+ QImage m_buffer;
+ QImage m_base_buffer;
+
+ int m_circle_alpha;
+ int m_circle_hue;
+
+ QPointF m_circle_pos;
+ QPointF m_offset;
+
+ ObjectType m_current_object;
+ bool m_animation_enabled;
+ int m_animationTimer;
+
+#ifdef QT_OPENGL_SUPPORT
+ QGLPixelBuffer *m_pbuffer;
+ GLuint m_base_tex;
+ GLuint m_compositing_tex;
+ int m_pbuffer_size; // width==height==size of pbuffer
+ QSize m_previous_size;
+#endif
+};
+
+#endif // COMPOSITION_H
diff --git a/examples/widgets/painting/composition/composition.html b/examples/widgets/painting/composition/composition.html
new file mode 100644
index 0000000000..82b8991e8f
--- /dev/null
+++ b/examples/widgets/painting/composition/composition.html
@@ -0,0 +1,23 @@
+<html>
+
+<h1>Example for composition modes</h1>
+
+<p>
+ This example shows some of the more advanced composition modes supported by Qt.
+</p>
+
+<p>
+ The two most common forms of composition are <b>Source</b> and <b>SourceOver</b>.
+ <b>Source</b> is used to draw opaque objects onto a paint device. In this mode,
+ each pixel in the source replaces the corresponding pixel in the destination.
+ In <b>SourceOver</b> composition mode, the source object is transparent and is
+ drawn on top of the destination.
+</p>
+
+<p>
+ In addition to these standard modes, Qt defines the complete set of composition
+ modes as defined by Thomas Porter and Tom Duff. See the <tt>QPainter</tt> documentation
+ for details.
+</p>
+
+</html>
diff --git a/examples/widgets/painting/composition/composition.pro b/examples/widgets/painting/composition/composition.pro
new file mode 100644
index 0000000000..eb63d0c47a
--- /dev/null
+++ b/examples/widgets/painting/composition/composition.pro
@@ -0,0 +1,29 @@
+SOURCES += main.cpp composition.cpp
+HEADERS += composition.h
+
+SHARED_FOLDER = ../shared
+
+include($$SHARED_FOLDER/shared.pri)
+
+RESOURCES += composition.qrc
+contains(QT_CONFIG, opengl) {
+ DEFINES += QT_OPENGL_SUPPORT
+ QT += opengl
+}
+QT += widgets
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/painting/composition
+sources.files = $$SOURCES $$HEADERS $$RESOURCES *.png *.jpg *.pro *.html
+sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/painting/composition
+INSTALLS += target sources
+
+
+win32-msvc* {
+ QMAKE_CXXFLAGS += /Zm500
+ QMAKE_CFLAGS += /Zm500
+}
+
+wince* {
+ DEPLOYMENT_PLUGIN += qjpeg
+}
diff --git a/examples/widgets/painting/composition/composition.qrc b/examples/widgets/painting/composition/composition.qrc
new file mode 100644
index 0000000000..d02c397ee8
--- /dev/null
+++ b/examples/widgets/painting/composition/composition.qrc
@@ -0,0 +1,8 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/res/composition">
+ <file>composition.cpp</file>
+ <file>composition.html</file>
+ <file>flower.jpg</file>
+ <file>flower_alpha.jpg</file>
+</qresource>
+</RCC>
diff --git a/examples/widgets/painting/composition/flower.jpg b/examples/widgets/painting/composition/flower.jpg
new file mode 100644
index 0000000000..f8e022c98c
--- /dev/null
+++ b/examples/widgets/painting/composition/flower.jpg
Binary files differ
diff --git a/examples/widgets/painting/composition/flower_alpha.jpg b/examples/widgets/painting/composition/flower_alpha.jpg
new file mode 100644
index 0000000000..6a3c2a02ef
--- /dev/null
+++ b/examples/widgets/painting/composition/flower_alpha.jpg
Binary files differ
diff --git a/examples/widgets/painting/composition/main.cpp b/examples/widgets/painting/composition/main.cpp
new file mode 100644
index 0000000000..370069a33a
--- /dev/null
+++ b/examples/widgets/painting/composition/main.cpp
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** 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 "composition.h"
+
+#include <QApplication>
+#ifdef QT_OPENGL_SUPPORT
+#include <QtOpenGL>
+#endif
+
+int main(int argc, char **argv)
+{
+ // Q_INIT_RESOURCE(deform);
+
+ QApplication app(argc, argv);
+
+ CompositionWidget compWidget(0);
+ QStyle *arthurStyle = new ArthurStyle();
+ compWidget.setStyle(arthurStyle);
+
+ QList<QWidget *> widgets = compWidget.findChildren<QWidget *>();
+ foreach (QWidget *w, widgets)
+ w->setStyle(arthurStyle);
+ compWidget.show();
+
+ return app.exec();
+}
diff --git a/examples/widgets/painting/concentriccircles/circlewidget.cpp b/examples/widgets/painting/concentriccircles/circlewidget.cpp
new file mode 100644
index 0000000000..2691f20602
--- /dev/null
+++ b/examples/widgets/painting/concentriccircles/circlewidget.cpp
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtWidgets>
+
+#include "circlewidget.h"
+
+#include <stdlib.h>
+
+//! [0]
+CircleWidget::CircleWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ floatBased = false;
+ antialiased = false;
+ frameNo = 0;
+
+ setBackgroundRole(QPalette::Base);
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+}
+//! [0]
+
+//! [1]
+void CircleWidget::setFloatBased(bool floatBased)
+{
+ this->floatBased = floatBased;
+ update();
+}
+//! [1]
+
+//! [2]
+void CircleWidget::setAntialiased(bool antialiased)
+{
+ this->antialiased = antialiased;
+ update();
+}
+//! [2]
+
+//! [3]
+QSize CircleWidget::minimumSizeHint() const
+{
+ return QSize(50, 50);
+}
+//! [3]
+
+//! [4]
+QSize CircleWidget::sizeHint() const
+{
+ return QSize(180, 180);
+}
+//! [4]
+
+//! [5]
+void CircleWidget::nextAnimationFrame()
+{
+ ++frameNo;
+ update();
+}
+//! [5]
+
+//! [6]
+void CircleWidget::paintEvent(QPaintEvent *)
+{
+ QPainter painter(this);
+ painter.setRenderHint(QPainter::Antialiasing, antialiased);
+ painter.translate(width() / 2, height() / 2);
+//! [6]
+
+//! [7]
+ for (int diameter = 0; diameter < 256; diameter += 9) {
+ int delta = abs((frameNo % 128) - diameter / 2);
+ int alpha = 255 - (delta * delta) / 4 - diameter;
+//! [7] //! [8]
+ if (alpha > 0) {
+ painter.setPen(QPen(QColor(0, diameter / 2, 127, alpha), 3));
+
+ if (floatBased) {
+ painter.drawEllipse(QRectF(-diameter / 2.0, -diameter / 2.0,
+ diameter, diameter));
+ } else {
+ painter.drawEllipse(QRect(-diameter / 2, -diameter / 2,
+ diameter, diameter));
+ }
+ }
+ }
+}
+//! [8]
diff --git a/examples/widgets/painting/concentriccircles/circlewidget.h b/examples/widgets/painting/concentriccircles/circlewidget.h
new file mode 100644
index 0000000000..c2d4de7092
--- /dev/null
+++ b/examples/widgets/painting/concentriccircles/circlewidget.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CIRCLEWIDGET_H
+#define CIRCLEWIDGET_H
+
+#include <QWidget>
+
+//! [0]
+class CircleWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ CircleWidget(QWidget *parent = 0);
+
+ void setFloatBased(bool floatBased);
+ void setAntialiased(bool antialiased);
+
+ QSize minimumSizeHint() const;
+ QSize sizeHint() const;
+
+public slots:
+ void nextAnimationFrame();
+
+protected:
+ void paintEvent(QPaintEvent *event);
+
+private:
+ bool floatBased;
+ bool antialiased;
+ int frameNo;
+};
+//! [0]
+
+#endif
diff --git a/examples/widgets/painting/concentriccircles/concentriccircles.desktop b/examples/widgets/painting/concentriccircles/concentriccircles.desktop
new file mode 100644
index 0000000000..7007f192bc
--- /dev/null
+++ b/examples/widgets/painting/concentriccircles/concentriccircles.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Terminal=false
+Name=Concentric Circles
+Exec=/opt/usr/bin/concentriccircles
+Icon=concentriccircles
+X-Window-Icon=
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
diff --git a/examples/widgets/painting/concentriccircles/concentriccircles.pro b/examples/widgets/painting/concentriccircles/concentriccircles.pro
new file mode 100644
index 0000000000..0f87b991ed
--- /dev/null
+++ b/examples/widgets/painting/concentriccircles/concentriccircles.pro
@@ -0,0 +1,14 @@
+HEADERS = circlewidget.h \
+ window.h
+SOURCES = circlewidget.cpp \
+ main.cpp \
+ window.cpp
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/painting/concentriccircles
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS concentriccircles.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/painting/concentriccircles
+INSTALLS += target sources
+
+QT += widgets
+
diff --git a/examples/widgets/painting/concentriccircles/main.cpp b/examples/widgets/painting/concentriccircles/main.cpp
new file mode 100644
index 0000000000..dcbf1c0449
--- /dev/null
+++ b/examples/widgets/painting/concentriccircles/main.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+
+#include "window.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ Window window;
+ window.show();
+ return app.exec();
+}
diff --git a/examples/widgets/painting/concentriccircles/window.cpp b/examples/widgets/painting/concentriccircles/window.cpp
new file mode 100644
index 0000000000..d946842029
--- /dev/null
+++ b/examples/widgets/painting/concentriccircles/window.cpp
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtWidgets>
+
+#include "circlewidget.h"
+#include "window.h"
+
+//! [0]
+Window::Window()
+{
+ aliasedLabel = createLabel(tr("Aliased"));
+ antialiasedLabel = createLabel(tr("Antialiased"));
+ intLabel = createLabel(tr("Int"));
+ floatLabel = createLabel(tr("Float"));
+
+ QGridLayout *layout = new QGridLayout;
+ layout->addWidget(aliasedLabel, 0, 1);
+ layout->addWidget(antialiasedLabel, 0, 2);
+ layout->addWidget(intLabel, 1, 0);
+ layout->addWidget(floatLabel, 2, 0);
+//! [0]
+
+//! [1]
+ QTimer *timer = new QTimer(this);
+
+ for (int i = 0; i < 2; ++i) {
+ for (int j = 0; j < 2; ++j) {
+ circleWidgets[i][j] = new CircleWidget;
+ circleWidgets[i][j]->setAntialiased(j != 0);
+ circleWidgets[i][j]->setFloatBased(i != 0);
+
+ connect(timer, SIGNAL(timeout()),
+ circleWidgets[i][j], SLOT(nextAnimationFrame()));
+
+ layout->addWidget(circleWidgets[i][j], i + 1, j + 1);
+ }
+ }
+//! [1] //! [2]
+ timer->start(100);
+ setLayout(layout);
+
+ setWindowTitle(tr("Concentric Circles"));
+}
+//! [2]
+
+//! [3]
+QLabel *Window::createLabel(const QString &text)
+{
+ QLabel *label = new QLabel(text);
+ label->setAlignment(Qt::AlignCenter);
+ label->setMargin(2);
+ label->setFrameStyle(QFrame::Box | QFrame::Sunken);
+ return label;
+}
+//! [3]
diff --git a/examples/widgets/painting/concentriccircles/window.h b/examples/widgets/painting/concentriccircles/window.h
new file mode 100644
index 0000000000..a066ddb702
--- /dev/null
+++ b/examples/widgets/painting/concentriccircles/window.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WINDOW_H
+#define WINDOW_H
+
+#include <QWidget>
+
+QT_BEGIN_NAMESPACE
+class QLabel;
+QT_END_NAMESPACE
+class CircleWidget;
+
+//! [0]
+class Window : public QWidget
+{
+ Q_OBJECT
+
+public:
+ Window();
+
+private:
+ QLabel *createLabel(const QString &text);
+
+ QLabel *aliasedLabel;
+ QLabel *antialiasedLabel;
+ QLabel *intLabel;
+ QLabel *floatLabel;
+ CircleWidget *circleWidgets[2][2];
+};
+//! [0]
+
+#endif
diff --git a/examples/widgets/painting/deform/deform.pro b/examples/widgets/painting/deform/deform.pro
new file mode 100644
index 0000000000..527133e7e5
--- /dev/null
+++ b/examples/widgets/painting/deform/deform.pro
@@ -0,0 +1,20 @@
+SOURCES += main.cpp pathdeform.cpp
+HEADERS += pathdeform.h
+
+SHARED_FOLDER = ../shared
+
+include($$SHARED_FOLDER/shared.pri)
+
+RESOURCES += deform.qrc
+
+contains(QT_CONFIG, opengl) {
+ DEFINES += QT_OPENGL_SUPPORT
+ QT += opengl
+}
+QT += widgets
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/painting/deform
+sources.files = $$SOURCES $$HEADERS $$RESOURCES *.pro *.html
+sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/painting/deform
+INSTALLS += target sources
diff --git a/examples/widgets/painting/deform/deform.qrc b/examples/widgets/painting/deform/deform.qrc
new file mode 100644
index 0000000000..2e59ebcfc5
--- /dev/null
+++ b/examples/widgets/painting/deform/deform.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/res/deform">
+ <file>pathdeform.cpp</file>
+ <file>pathdeform.html</file>
+</qresource>
+</RCC>
diff --git a/examples/widgets/painting/deform/main.cpp b/examples/widgets/painting/deform/main.cpp
new file mode 100644
index 0000000000..eeed9b8939
--- /dev/null
+++ b/examples/widgets/painting/deform/main.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** 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 <QApplication>
+#include <QDebug>
+
+int main(int argc, char **argv)
+{
+ Q_INIT_RESOURCE(deform);
+
+ QApplication app(argc, argv);
+
+ bool smallScreen = QApplication::arguments().contains("-small-screen");
+
+ PathDeformWidget deformWidget(0, smallScreen);
+
+ QStyle *arthurStyle = new ArthurStyle();
+ deformWidget.setStyle(arthurStyle);
+ QList<QWidget *> widgets = deformWidget.findChildren<QWidget *>();
+ foreach (QWidget *w, widgets)
+ w->setStyle(arthurStyle);
+
+ if (smallScreen)
+ deformWidget.showFullScreen();
+ else
+ deformWidget.show();
+
+#ifdef QT_KEYPAD_NAVIGATION
+ QApplication::setNavigationMode(Qt::NavigationModeCursorAuto);
+#endif
+ return app.exec();
+}
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 <QApplication>
+#include <QtDebug>
+#include <QMouseEvent>
+#include <QTimerEvent>
+#include <QLayout>
+#include <QLineEdit>
+#include <QPainter>
+#include <QSlider>
+#include <QLabel>
+#include <QDesktopWidget>
+#include <qmath.h>
+
+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<QWidget *> widgets = m_controls->findChildren<QWidget *>();
+ foreach (QWidget *w, widgets)
+ w->setStyle(style);
+ }
+}
+
+static inline QRect circle_bounds(const QPointF &center, 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<text.size(); ++i) {
+ if (text.at(i).unicode() >= 0x4ff && text.at(i).unicode() <= 0x1e00) {
+ do_quick = false;
+ break;
+ }
+ }
+
+ if (do_quick) {
+ for (int i=0; i<text.size(); ++i) {
+ QPainterPath path;
+ path.addText(advance, f, text.mid(i, 1));
+ m_pathBounds |= path.boundingRect();
+ m_paths << path;
+ advance += QPointF(fm.width(text.mid(i, 1)), 0);
+ }
+ } else {
+ QPainterPath path;
+ path.addText(advance, f, text);
+ m_pathBounds |= path.boundingRect();
+ m_paths << path;
+ }
+
+ for (int i=0; i<m_paths.size(); ++i)
+ m_paths[i] = m_paths[i] * QMatrix(1, 0, 0, 1, -m_pathBounds.x(), -m_pathBounds.y());
+
+ update();
+}
+
+
+void PathDeformRenderer::generateLensPixmap()
+{
+ qreal rad = m_radius + LENS_EXTENT;
+
+ QRect bounds = circle_bounds(QPointF(), rad, 0);
+
+ QPainter painter;
+
+ if (preferImage()) {
+ m_lens_image = QImage(bounds.size(), QImage::Format_ARGB32_Premultiplied);
+ m_lens_image.fill(0);
+ painter.begin(&m_lens_image);
+ } else {
+ m_lens_pixmap = QPixmap(bounds.size());
+ m_lens_pixmap.fill(Qt::transparent);
+ painter.begin(&m_lens_pixmap);
+ }
+
+ QRadialGradient gr(rad, rad, rad, 3 * rad / 5, 3 * rad / 5);
+ gr.setColorAt(0.0, QColor(255, 255, 255, 191));
+ gr.setColorAt(0.2, QColor(255, 255, 127, 191));
+ gr.setColorAt(0.9, QColor(150, 150, 200, 63));
+ gr.setColorAt(0.95, QColor(0, 0, 0, 127));
+ gr.setColorAt(1, QColor(0, 0, 0, 0));
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.setBrush(gr);
+ painter.setPen(Qt::NoPen);
+ painter.drawEllipse(0, 0, bounds.width(), bounds.height());
+}
+
+
+void PathDeformRenderer::setAnimated(bool animated)
+{
+ m_animated = animated;
+
+ if (m_animated) {
+// m_fpsTimer.start(1000, this);
+// m_fpsCounter = 0;
+ m_repaintTimer.start(25, this);
+ m_repaintTracker.start();
+ } else {
+// m_fpsTimer.stop();
+ m_repaintTimer.stop();
+ }
+}
+
+void PathDeformRenderer::timerEvent(QTimerEvent *e)
+{
+
+ if (e->timerId() == 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<path.elementCount(); ++i) {
+ const QPainterPath::Element &e = path.elementAt(i);
+
+ qreal x = e.x + offset.x();
+ qreal y = e.y + offset.y();
+
+ qreal dx = x - m_pos.x();
+ qreal dy = y - m_pos.y();
+ qreal len = m_radius - qSqrt(dx * dx + dy * dy);
+
+ if (len > 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; i<m_paths.size(); ++i) {
+ QPainterPath path = lensDeform(m_paths[i], QPointF(start_x, start_y));
+ painter->drawPath(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));
+ }
+ }
+}
diff --git a/examples/widgets/painting/deform/pathdeform.h b/examples/widgets/painting/deform/pathdeform.h
new file mode 100644
index 0000000000..6f0d647f4e
--- /dev/null
+++ b/examples/widgets/painting/deform/pathdeform.h
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef PATHDEFORM_H
+#define PATHDEFORM_H
+
+#include "arthurwidgets.h"
+
+#include <QPainterPath>
+#include <QBasicTimer>
+#include <QDateTime>
+
+class PathDeformRenderer : public ArthurFrame
+{
+ Q_OBJECT
+ Q_PROPERTY(bool animated READ animated WRITE setAnimated)
+ Q_PROPERTY(int radius READ radius WRITE setRadius)
+ Q_PROPERTY(int fontSize READ fontSize WRITE setFontSize)
+ Q_PROPERTY(int intensity READ intensity WRITE setIntensity)
+ Q_PROPERTY(QString text READ text WRITE setText)
+
+public:
+ PathDeformRenderer(QWidget *widget, bool smallScreen = false);
+
+ void paint(QPainter *painter);
+
+ void mousePressEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+ void mouseMoveEvent(QMouseEvent *e);
+ void timerEvent(QTimerEvent *e);
+
+ QSize sizeHint() const { return QSize(600, 500); }
+
+ bool animated() const { return m_animated; }
+ int radius() const { return int(m_radius); }
+ int fontSize() const { return m_fontSize; }
+ int intensity() const { return int(m_intensity); }
+ QString text() const { return m_text; }
+
+public slots:
+ void setRadius(int radius);
+ void setFontSize(int fontSize) { m_fontSize = fontSize; setText(m_text); }
+ void setText(const QString &text);
+ void setIntensity(int intensity);
+
+ void setAnimated(bool animated);
+
+signals:
+ void clicked();
+// void frameRate(double fps);
+
+private:
+ void generateLensPixmap();
+ QPainterPath lensDeform(const QPainterPath &source, const QPointF &offset);
+
+ QBasicTimer m_repaintTimer;
+// QBasicTimer m_fpsTimer;
+// int m_fpsCounter;
+ QTime m_repaintTracker;
+
+ QVector<QPainterPath> m_paths;
+ QVector<QPointF> m_advances;
+ QRectF m_pathBounds;
+ QString m_text;
+
+ QPixmap m_lens_pixmap;
+ QImage m_lens_image;
+
+ int m_fontSize;
+ bool m_animated;
+
+ qreal m_intensity;
+ qreal m_radius;
+ QPointF m_pos;
+ QPointF m_offset;
+ QPointF m_direction;
+ QPointF m_mousePress;
+ bool m_mouseDrag;
+ bool m_smallScreen;
+};
+
+class PathDeformControls : public QWidget
+{
+ Q_OBJECT
+public:
+ PathDeformControls(QWidget *parent, PathDeformRenderer* renderer, bool smallScreen);
+signals:
+ void okPressed();
+ void quitPressed();
+private:
+ PathDeformRenderer* m_renderer;
+ void layoutForDesktop();
+ void layoutForSmallScreen();
+private slots:
+ void emitQuitSignal();
+ void emitOkSignal();
+};
+
+class PathDeformWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ PathDeformWidget(QWidget *parent, bool smallScreen);
+ void setStyle ( QStyle * style );
+
+private:
+ PathDeformRenderer *m_renderer;
+ PathDeformControls *m_controls;
+
+private slots:
+ void showControls();
+ void hideControls();
+};
+
+#endif // PATHDEFORM_H
diff --git a/examples/widgets/painting/deform/pathdeform.html b/examples/widgets/painting/deform/pathdeform.html
new file mode 100644
index 0000000000..b3f63a8e0a
--- /dev/null
+++ b/examples/widgets/painting/deform/pathdeform.html
@@ -0,0 +1,24 @@
+<html>
+<center>
+<h2>Vector deformation</h2>
+</center>
+
+<p>This demo shows how to use advanced vector techniques to draw text
+using a <code>QPainterPath</code>.</p>
+
+<p>We define a vector deformation field in the shape of a lens and apply
+this to all points in a path. This means that what is rendered on
+screen is not pixel manipulation, but modified vector representations of
+the glyphs themselves. This is visible from the high quality of the
+antialiased edges for the deformed glyphs.</p>
+
+<p>To get a fairly complex path we allow the user to type in text and
+convert the text to paths. This is done using the
+<code>QPainterPath::addText()</code> function.</p>
+
+<p>The lens is drawn using a single call to <code>drawEllipse()</code>, using
+a <code>QRadialGradient</code> to fill it with a specialized color table,
+giving the effect of the Sun's reflection and a drop shadow. The lens
+is cached as a pixmap for better performance.</p>
+
+</html>
diff --git a/examples/widgets/painting/fontsampler/fontsampler.desktop b/examples/widgets/painting/fontsampler/fontsampler.desktop
new file mode 100644
index 0000000000..8582891fcf
--- /dev/null
+++ b/examples/widgets/painting/fontsampler/fontsampler.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Terminal=false
+Name=Font Sampler
+Exec=/opt/usr/bin/fontsampler
+Icon=fontsampler
+X-Window-Icon=
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
diff --git a/examples/widgets/painting/fontsampler/fontsampler.pro b/examples/widgets/painting/fontsampler/fontsampler.pro
new file mode 100644
index 0000000000..b918c51837
--- /dev/null
+++ b/examples/widgets/painting/fontsampler/fontsampler.pro
@@ -0,0 +1,13 @@
+FORMS = mainwindowbase.ui
+HEADERS = mainwindow.h
+SOURCES = main.cpp \
+ mainwindow.cpp
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/painting/fontsampler
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS fontsampler.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/painting/fontsampler
+INSTALLS += target sources
+
+QT += widgets
+!isEmpty(QT.printsupport.name): QT += printsupport
diff --git a/examples/widgets/painting/fontsampler/main.cpp b/examples/widgets/painting/fontsampler/main.cpp
new file mode 100644
index 0000000000..09a923477c
--- /dev/null
+++ b/examples/widgets/painting/fontsampler/main.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+
+#include "mainwindow.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ MainWindow window;
+ window.show();
+ return app.exec();
+}
diff --git a/examples/widgets/painting/fontsampler/mainwindow.cpp b/examples/widgets/painting/fontsampler/mainwindow.cpp
new file mode 100644
index 0000000000..ae45613abf
--- /dev/null
+++ b/examples/widgets/painting/fontsampler/mainwindow.cpp
@@ -0,0 +1,380 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtWidgets>
+#ifndef QT_NO_PRINTER
+#include <QPrinter>
+#include <QPrintDialog>
+#include <QPrintPreviewDialog>
+#endif
+
+#include "mainwindow.h"
+
+MainWindow::MainWindow(QWidget *parent)
+ : QMainWindow(parent)
+{
+ setupUi(this);
+
+
+ sampleSizes << 32 << 24 << 16 << 14 << 12 << 8 << 4 << 2 << 1;
+ markedCount = 0;
+ setupFontTree();
+
+ connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
+ connect(fontTree, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
+ this, SLOT(showFont(QTreeWidgetItem*)));
+ connect(fontTree, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
+ this, SLOT(updateStyles(QTreeWidgetItem*,int)));
+
+ fontTree->setItemSelected(fontTree->topLevelItem(0), true);
+ showFont(fontTree->topLevelItem(0));
+}
+
+void MainWindow::setupFontTree()
+{
+ QFontDatabase database;
+ fontTree->setColumnCount(1);
+ fontTree->setHeaderLabels(QStringList() << tr("Font"));
+
+ foreach (QString family, database.families()) {
+ const QStringList styles = database.styles(family);
+ if (styles.isEmpty())
+ continue;
+
+ QTreeWidgetItem *familyItem = new QTreeWidgetItem(fontTree);
+ familyItem->setText(0, family);
+ familyItem->setCheckState(0, Qt::Unchecked);
+
+ foreach (QString style, styles) {
+ QTreeWidgetItem *styleItem = new QTreeWidgetItem(familyItem);
+ styleItem->setText(0, style);
+ styleItem->setCheckState(0, Qt::Unchecked);
+ styleItem->setData(0, Qt::UserRole,
+ QVariant(database.weight(family, style)));
+ styleItem->setData(0, Qt::UserRole + 1,
+ QVariant(database.italic(family, style)));
+ }
+ }
+}
+
+void MainWindow::on_clearAction_triggered()
+{
+ QTreeWidgetItem *currentItem = fontTree->currentItem();
+ foreach (QTreeWidgetItem *item, fontTree->selectedItems())
+ fontTree->setItemSelected(item, false);
+ fontTree->setItemSelected(currentItem, true);
+}
+
+void MainWindow::on_markAction_triggered()
+{
+ markUnmarkFonts(Qt::Checked);
+}
+
+void MainWindow::on_unmarkAction_triggered()
+{
+ markUnmarkFonts(Qt::Unchecked);
+}
+
+void MainWindow::markUnmarkFonts(Qt::CheckState state)
+{
+ QList<QTreeWidgetItem *> items = fontTree->selectedItems();
+ foreach (QTreeWidgetItem *item, items) {
+ if (item->checkState(0) != state)
+ item->setCheckState(0, state);
+ }
+}
+
+void MainWindow::showFont(QTreeWidgetItem *item)
+{
+ if (!item)
+ return;
+
+ QString family;
+ QString style;
+ int weight;
+ bool italic;
+
+ if (item->parent()) {
+ family = item->parent()->text(0);
+ style = item->text(0);
+ weight = item->data(0, Qt::UserRole).toInt();
+ italic = item->data(0, Qt::UserRole + 1).toBool();
+ } else {
+ family = item->text(0);
+ style = item->child(0)->text(0);
+ weight = item->child(0)->data(0, Qt::UserRole).toInt();
+ italic = item->child(0)->data(0, Qt::UserRole + 1).toBool();
+ }
+
+ QString oldText = textEdit->toPlainText().trimmed();
+ bool modified = textEdit->document()->isModified();
+ textEdit->clear();
+ textEdit->document()->setDefaultFont(QFont(family, 32, weight, italic));
+
+ QTextCursor cursor = textEdit->textCursor();
+ QTextBlockFormat blockFormat;
+ blockFormat.setAlignment(Qt::AlignCenter);
+ cursor.insertBlock(blockFormat);
+
+ if (modified)
+ cursor.insertText(QString(oldText));
+ else
+ cursor.insertText(QString("%1 %2").arg(family).arg(style));
+
+ textEdit->document()->setModified(modified);
+}
+
+void MainWindow::updateStyles(QTreeWidgetItem *item, int column)
+{
+ if (!item || column != 0)
+ return;
+
+ Qt::CheckState state = item->checkState(0);
+ QTreeWidgetItem *parent = item->parent();
+
+ if (parent) {
+
+ // Only count style items.
+ if (state == Qt::Checked)
+ ++markedCount;
+ else
+ --markedCount;
+
+ if (state == Qt::Checked &&
+ parent->checkState(0) == Qt::Unchecked) {
+ // Mark parent items when child items are checked.
+ parent->setCheckState(0, Qt::Checked);
+
+ } else if (state == Qt::Unchecked &&
+ parent->checkState(0) == Qt::Checked) {
+
+ bool marked = false;
+ for (int row = 0; row < parent->childCount(); ++row) {
+ if (parent->child(row)->checkState(0) == Qt::Checked) {
+ marked = true;
+ break;
+ }
+ }
+ // Unmark parent items when all child items are unchecked.
+ if (!marked)
+ parent->setCheckState(0, Qt::Unchecked);
+ }
+ } else {
+ int row;
+ int number = 0;
+ for (row = 0; row < item->childCount(); ++row) {
+ if (item->child(row)->checkState(0) == Qt::Checked)
+ ++number;
+ }
+
+ // Mark/unmark all child items when marking/unmarking top-level
+ // items.
+ if (state == Qt::Checked && number == 0) {
+ for (row = 0; row < item->childCount(); ++row) {
+ if (item->child(row)->checkState(0) == Qt::Unchecked)
+ item->child(row)->setCheckState(0, Qt::Checked);
+ }
+ } else if (state == Qt::Unchecked && number > 0) {
+ for (row = 0; row < item->childCount(); ++row) {
+ if (item->child(row)->checkState(0) == Qt::Checked)
+ item->child(row)->setCheckState(0, Qt::Unchecked);
+ }
+ }
+ }
+
+ printAction->setEnabled(markedCount > 0);
+ printPreviewAction->setEnabled(markedCount > 0);
+}
+
+QMap<QString, StyleItems> MainWindow::currentPageMap()
+{
+ QMap<QString, StyleItems> pageMap;
+
+ for (int row = 0; row < fontTree->topLevelItemCount(); ++row) {
+ QTreeWidgetItem *familyItem = fontTree->topLevelItem(row);
+ QString family;
+
+ if (familyItem->checkState(0) == Qt::Checked) {
+ family = familyItem->text(0);
+ pageMap[family] = StyleItems();
+ }
+
+ for (int childRow = 0; childRow < familyItem->childCount(); ++childRow) {
+ QTreeWidgetItem *styleItem = familyItem->child(childRow);
+ if (styleItem->checkState(0) == Qt::Checked)
+ pageMap[family].append(styleItem);
+ }
+ }
+
+ return pageMap;
+}
+
+#ifndef QT_NO_PRINTER
+void MainWindow::on_printAction_triggered()
+{
+ pageMap = currentPageMap();
+
+ if (pageMap.count() == 0)
+ return;
+
+ QPrinter printer(QPrinter::HighResolution);
+ QPrintDialog dialog(&printer, this);
+ if (dialog.exec() != QDialog::Accepted)
+ return;
+
+ int from = printer.fromPage();
+ int to = printer.toPage();
+ if (from <= 0 && to <= 0)
+ printer.setFromTo(1, pageMap.keys().count());
+
+ printDocument(&printer);
+}
+
+void MainWindow::printDocument(QPrinter *printer)
+{
+ printer->setFromTo(1, pageMap.count());
+
+ QProgressDialog progress(tr("Preparing font samples..."), tr("&Cancel"),
+ 0, pageMap.count(), this);
+ progress.setWindowModality(Qt::ApplicationModal);
+ progress.setWindowTitle(tr("Font Sampler"));
+ progress.setMinimum(printer->fromPage() - 1);
+ progress.setMaximum(printer->toPage());
+
+ QPainter painter;
+ painter.begin(printer);
+ bool firstPage = true;
+
+ for (int page = printer->fromPage(); page <= printer->toPage(); ++page) {
+
+ if (!firstPage)
+ printer->newPage();
+
+ qApp->processEvents();
+ if (progress.wasCanceled())
+ break;
+
+ printPage(page - 1, &painter, printer);
+ progress.setValue(page);
+ firstPage = false;
+ }
+
+ painter.end();
+}
+
+void MainWindow::on_printPreviewAction_triggered()
+{
+ pageMap = currentPageMap();
+
+ if (pageMap.count() == 0)
+ return;
+
+ QPrinter printer(QPrinter::HighResolution);
+ QPrintPreviewDialog preview(&printer, this);
+ connect(&preview, SIGNAL(paintRequested(QPrinter*)),
+ this, SLOT(printDocument(QPrinter*)));
+ preview.exec();
+}
+
+void MainWindow::printPage(int index, QPainter *painter, QPrinter *printer)
+{
+ QString family = pageMap.keys()[index];
+ StyleItems items = pageMap[family];
+
+ // Find the dimensions of the text on each page.
+ qreal width = 0.0;
+ qreal height = 0.0;
+ foreach (QTreeWidgetItem *item, items) {
+ QString style = item->text(0);
+ int weight = item->data(0, Qt::UserRole).toInt();
+ bool italic = item->data(0, Qt::UserRole + 1).toBool();
+
+ // Calculate the maximum width and total height of the text.
+ foreach (int size, sampleSizes) {
+ QFont font(family, size, weight, italic);
+ font = QFont(font, painter->device());
+ QFontMetricsF fontMetrics(font);
+ QRectF rect = fontMetrics.boundingRect(
+ QString("%1 %2").arg(family).arg(style));
+ width = qMax(rect.width(), width);
+ height += rect.height();
+ }
+ }
+
+ qreal xScale = printer->pageRect().width() / width;
+ qreal yScale = printer->pageRect().height() / height;
+ qreal scale = qMin(xScale, yScale);
+
+ qreal remainingHeight = printer->pageRect().height()/scale - height;
+ qreal spaceHeight = (remainingHeight/4.0) / (items.count() + 1);
+ qreal interLineHeight = (remainingHeight/4.0) / (sampleSizes.count() * items.count());
+
+ painter->save();
+ painter->translate(printer->pageRect().width()/2.0, printer->pageRect().height()/2.0);
+ painter->scale(scale, scale);
+ painter->setBrush(QBrush(Qt::black));
+
+ qreal x = -width/2.0;
+ qreal y = -height/2.0 - remainingHeight/4.0 + spaceHeight;
+
+ foreach (QTreeWidgetItem *item, items) {
+ QString style = item->text(0);
+ int weight = item->data(0, Qt::UserRole).toInt();
+ bool italic = item->data(0, Qt::UserRole + 1).toBool();
+
+ // Draw each line of text.
+ foreach (int size, sampleSizes) {
+ QFont font(family, size, weight, italic);
+ font = QFont(font, painter->device());
+ QFontMetricsF fontMetrics(font);
+ QRectF rect = fontMetrics.boundingRect(QString("%1 %2").arg(
+ font.family()).arg(style));
+ y += rect.height();
+ painter->setFont(font);
+ painter->drawText(QPointF(x, y),
+ QString("%1 %2").arg(family).arg(style));
+ y += interLineHeight;
+ }
+ y += spaceHeight;
+ }
+
+ painter->restore();
+}
+#endif
diff --git a/examples/widgets/painting/fontsampler/mainwindow.h b/examples/widgets/painting/fontsampler/mainwindow.h
new file mode 100644
index 0000000000..fbb99333db
--- /dev/null
+++ b/examples/widgets/painting/fontsampler/mainwindow.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include "ui_mainwindowbase.h"
+
+QT_BEGIN_NAMESPACE
+class QPrinter;
+class QTextEdit;
+class QTreeWidget;
+class QTreeWidgetItem;
+QT_END_NAMESPACE
+
+typedef QList<QTreeWidgetItem *> StyleItems;
+
+class MainWindow : public QMainWindow, private Ui::MainWindowBase
+{
+ Q_OBJECT
+
+public:
+ MainWindow(QWidget *parent = 0);
+
+public slots:
+ void on_clearAction_triggered();
+ void on_markAction_triggered();
+#ifndef QT_NO_PRINTER
+ void on_printAction_triggered();
+ void on_printPreviewAction_triggered();
+#endif
+ void on_unmarkAction_triggered();
+#ifndef QT_NO_PRINTER
+ void printDocument(QPrinter *printer);
+ void printPage(int index, QPainter *painter, QPrinter *printer);
+#endif
+ void showFont(QTreeWidgetItem *item);
+ void updateStyles(QTreeWidgetItem *item, int column);
+
+private:
+ QMap<QString, StyleItems> currentPageMap();
+ void markUnmarkFonts(Qt::CheckState state);
+ void setupFontTree();
+
+ QList<int> sampleSizes;
+ QMap<QString, StyleItems> pageMap;
+ int markedCount;
+};
+
+#endif
diff --git a/examples/widgets/painting/fontsampler/mainwindowbase.ui b/examples/widgets/painting/fontsampler/mainwindowbase.ui
new file mode 100644
index 0000000000..1a95ebd6d1
--- /dev/null
+++ b/examples/widgets/painting/fontsampler/mainwindowbase.ui
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindowBase</class>
+ <widget class="QMainWindow" name="MainWindowBase">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>800</width>
+ <height>345</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Font Sampler</string>
+ </property>
+ <widget class="QWidget" name="centralwidget">
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>9</number>
+ </property>
+ <item>
+ <widget class="QTextEdit" name="textEdit"/>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menubar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>800</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="menu_Selection">
+ <property name="title">
+ <string>&amp;Selection</string>
+ </property>
+ <addaction name="markAction"/>
+ <addaction name="unmarkAction"/>
+ <addaction name="clearAction"/>
+ </widget>
+ <widget class="QMenu" name="menu_File">
+ <property name="title">
+ <string>&amp;File</string>
+ </property>
+ <addaction name="printPreviewAction"/>
+ <addaction name="printAction"/>
+ <addaction name="quitAction"/>
+ </widget>
+ <addaction name="menu_File"/>
+ <addaction name="menu_Selection"/>
+ </widget>
+ <widget class="QStatusBar" name="statusbar"/>
+ <widget class="QDockWidget" name="dockWidget">
+ <property name="features">
+ <set>QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set>
+ </property>
+ <property name="windowTitle">
+ <string>Available Fonts</string>
+ </property>
+ <attribute name="dockWidgetArea">
+ <number>1</number>
+ </attribute>
+ <widget class="QWidget" name="dockWidgetContents">
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>9</number>
+ </property>
+ <item>
+ <widget class="QTreeWidget" name="fontTree">
+ <property name="selectionMode">
+ <enum>QAbstractItemView::ExtendedSelection</enum>
+ </property>
+ <column>
+ <property name="text">
+ <string notr="true">1</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <action name="printAction">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>&amp;Print...</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+P</string>
+ </property>
+ </action>
+ <action name="quitAction">
+ <property name="text">
+ <string>E&amp;xit</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Q</string>
+ </property>
+ </action>
+ <action name="markAction">
+ <property name="text">
+ <string>&amp;Mark</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+M</string>
+ </property>
+ </action>
+ <action name="unmarkAction">
+ <property name="text">
+ <string>&amp;Unmark</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+U</string>
+ </property>
+ </action>
+ <action name="clearAction">
+ <property name="text">
+ <string>&amp;Clear</string>
+ </property>
+ </action>
+ <action name="printPreviewAction">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Print Preview...</string>
+ </property>
+ </action>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/examples/widgets/painting/gradients/gradients.cpp b/examples/widgets/painting/gradients/gradients.cpp
new file mode 100644
index 0000000000..9dad51a8e4
--- /dev/null
+++ b/examples/widgets/painting/gradients/gradients.cpp
@@ -0,0 +1,516 @@
+/****************************************************************************
+**
+** 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 "gradients.h"
+#include "hoverpoints.h"
+
+ShadeWidget::ShadeWidget(ShadeType type, QWidget *parent)
+ : QWidget(parent), m_shade_type(type), m_alpha_gradient(QLinearGradient(0, 0, 0, 0))
+{
+
+ // Checkers background
+ if (m_shade_type == ARGBShade) {
+ QPixmap pm(20, 20);
+ QPainter pmp(&pm);
+ pmp.fillRect(0, 0, 10, 10, Qt::lightGray);
+ pmp.fillRect(10, 10, 10, 10, Qt::lightGray);
+ pmp.fillRect(0, 10, 10, 10, Qt::darkGray);
+ pmp.fillRect(10, 0, 10, 10, Qt::darkGray);
+ pmp.end();
+ QPalette pal = palette();
+ pal.setBrush(backgroundRole(), QBrush(pm));
+ setAutoFillBackground(true);
+ setPalette(pal);
+
+ } else {
+ setAttribute(Qt::WA_NoBackground);
+
+ }
+
+ QPolygonF points;
+ points << QPointF(0, sizeHint().height())
+ << QPointF(sizeHint().width(), 0);
+
+ m_hoverPoints = new HoverPoints(this, HoverPoints::CircleShape);
+// m_hoverPoints->setConnectionType(HoverPoints::LineConnection);
+ m_hoverPoints->setPoints(points);
+ m_hoverPoints->setPointLock(0, HoverPoints::LockToLeft);
+ m_hoverPoints->setPointLock(1, HoverPoints::LockToRight);
+ m_hoverPoints->setSortType(HoverPoints::XSort);
+
+ setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+
+ connect(m_hoverPoints, SIGNAL(pointsChanged(QPolygonF)), this, SIGNAL(colorsChanged()));
+}
+
+
+QPolygonF ShadeWidget::points() const
+{
+ return m_hoverPoints->points();
+}
+
+
+uint ShadeWidget::colorAt(int x)
+{
+ generateShade();
+
+ QPolygonF pts = m_hoverPoints->points();
+ for (int i=1; i < pts.size(); ++i) {
+ if (pts.at(i-1).x() <= x && pts.at(i).x() >= x) {
+ QLineF l(pts.at(i-1), pts.at(i));
+ l.setLength(l.length() * ((x - l.x1()) / l.dx()));
+ return m_shade.pixel(qRound(qMin(l.x2(), (qreal(m_shade.width() - 1)))),
+ qRound(qMin(l.y2(), qreal(m_shade.height() - 1))));
+ }
+ }
+ return 0;
+}
+
+
+void ShadeWidget::setGradientStops(const QGradientStops &stops)
+{
+ if (m_shade_type == ARGBShade) {
+ m_alpha_gradient = QLinearGradient(0, 0, width(), 0);
+
+ for (int i=0; i<stops.size(); ++i) {
+ QColor c = stops.at(i).second;
+ m_alpha_gradient.setColorAt(stops.at(i).first, QColor(c.red(), c.green(), c.blue()));
+ }
+
+ m_shade = QImage();
+ generateShade();
+ update();
+ }
+}
+
+
+void ShadeWidget::paintEvent(QPaintEvent *)
+{
+ generateShade();
+
+ QPainter p(this);
+ p.drawImage(0, 0, m_shade);
+
+ p.setPen(QColor(146, 146, 146));
+ p.drawRect(0, 0, width() - 1, height() - 1);
+}
+
+
+void ShadeWidget::generateShade()
+{
+ if (m_shade.isNull() || m_shade.size() != size()) {
+
+ if (m_shade_type == ARGBShade) {
+ m_shade = QImage(size(), QImage::Format_ARGB32_Premultiplied);
+ m_shade.fill(0);
+
+ QPainter p(&m_shade);
+ p.fillRect(rect(), m_alpha_gradient);
+
+ p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
+ QLinearGradient fade(0, 0, 0, height());
+ fade.setColorAt(0, QColor(0, 0, 0, 255));
+ fade.setColorAt(1, QColor(0, 0, 0, 0));
+ p.fillRect(rect(), fade);
+
+ } else {
+ m_shade = QImage(size(), QImage::Format_RGB32);
+ QLinearGradient shade(0, 0, 0, height());
+ shade.setColorAt(1, Qt::black);
+
+ if (m_shade_type == RedShade)
+ shade.setColorAt(0, Qt::red);
+ else if (m_shade_type == GreenShade)
+ shade.setColorAt(0, Qt::green);
+ else
+ shade.setColorAt(0, Qt::blue);
+
+ QPainter p(&m_shade);
+ p.fillRect(rect(), shade);
+ }
+ }
+
+
+}
+
+
+GradientEditor::GradientEditor(QWidget *parent)
+ : QWidget(parent)
+{
+ QVBoxLayout *vbox = new QVBoxLayout(this);
+ vbox->setSpacing(1);
+ vbox->setMargin(1);
+
+ m_red_shade = new ShadeWidget(ShadeWidget::RedShade, this);
+ m_green_shade = new ShadeWidget(ShadeWidget::GreenShade, this);
+ m_blue_shade = new ShadeWidget(ShadeWidget::BlueShade, this);
+ m_alpha_shade = new ShadeWidget(ShadeWidget::ARGBShade, this);
+
+ vbox->addWidget(m_red_shade);
+ vbox->addWidget(m_green_shade);
+ vbox->addWidget(m_blue_shade);
+ vbox->addWidget(m_alpha_shade);
+
+ connect(m_red_shade, SIGNAL(colorsChanged()), this, SLOT(pointsUpdated()));
+ connect(m_green_shade, SIGNAL(colorsChanged()), this, SLOT(pointsUpdated()));
+ connect(m_blue_shade, SIGNAL(colorsChanged()), this, SLOT(pointsUpdated()));
+ connect(m_alpha_shade, SIGNAL(colorsChanged()), this, SLOT(pointsUpdated()));
+}
+
+
+inline static bool x_less_than(const QPointF &p1, const QPointF &p2)
+{
+ return p1.x() < p2.x();
+}
+
+
+void GradientEditor::pointsUpdated()
+{
+ qreal w = m_alpha_shade->width();
+
+ QGradientStops stops;
+
+ QPolygonF points;
+
+ points += m_red_shade->points();
+ points += m_green_shade->points();
+ points += m_blue_shade->points();
+ points += m_alpha_shade->points();
+
+ qSort(points.begin(), points.end(), x_less_than);
+
+ for (int i=0; i<points.size(); ++i) {
+ qreal x = int(points.at(i).x());
+ if (i+1 < points.size() && x == points.at(i+1).x())
+ continue;
+ QColor color((0x00ff0000 & m_red_shade->colorAt(int(x))) >> 16,
+ (0x0000ff00 & m_green_shade->colorAt(int(x))) >> 8,
+ (0x000000ff & m_blue_shade->colorAt(int(x))),
+ (0xff000000 & m_alpha_shade->colorAt(int(x))) >> 24);
+
+ if (x / w > 1)
+ return;
+
+ stops << QGradientStop(x / w, color);
+ }
+
+ m_alpha_shade->setGradientStops(stops);
+
+ emit gradientStopsChanged(stops);
+}
+
+
+static void set_shade_points(const QPolygonF &points, ShadeWidget *shade)
+{
+ shade->hoverPoints()->setPoints(points);
+ shade->hoverPoints()->setPointLock(0, HoverPoints::LockToLeft);
+ shade->hoverPoints()->setPointLock(points.size() - 1, HoverPoints::LockToRight);
+ shade->update();
+}
+
+void GradientEditor::setGradientStops(const QGradientStops &stops)
+{
+ QPolygonF pts_red, pts_green, pts_blue, pts_alpha;
+
+ qreal h_red = m_red_shade->height();
+ qreal h_green = m_green_shade->height();
+ qreal h_blue = m_blue_shade->height();
+ qreal h_alpha = m_alpha_shade->height();
+
+ for (int i=0; i<stops.size(); ++i) {
+ qreal pos = stops.at(i).first;
+ QRgb color = stops.at(i).second.rgba();
+ pts_red << QPointF(pos * m_red_shade->width(), h_red - qRed(color) * h_red / 255);
+ pts_green << QPointF(pos * m_green_shade->width(), h_green - qGreen(color) * h_green / 255);
+ pts_blue << QPointF(pos * m_blue_shade->width(), h_blue - qBlue(color) * h_blue / 255);
+ pts_alpha << QPointF(pos * m_alpha_shade->width(), h_alpha - qAlpha(color) * h_alpha / 255);
+ }
+
+ set_shade_points(pts_red, m_red_shade);
+ set_shade_points(pts_green, m_green_shade);
+ set_shade_points(pts_blue, m_blue_shade);
+ set_shade_points(pts_alpha, m_alpha_shade);
+
+}
+
+GradientWidget::GradientWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ setWindowTitle(tr("Gradients"));
+
+ m_renderer = new GradientRenderer(this);
+
+ QGroupBox *mainGroup = new QGroupBox(this);
+ mainGroup->setTitle(tr("Gradients"));
+
+ QGroupBox *editorGroup = new QGroupBox(mainGroup);
+ editorGroup->setTitle(tr("Color Editor"));
+ m_editor = new GradientEditor(editorGroup);
+
+ QGroupBox *typeGroup = new QGroupBox(mainGroup);
+ typeGroup->setTitle(tr("Gradient Type"));
+ m_linearButton = new QRadioButton(tr("Linear Gradient"), typeGroup);
+ m_radialButton = new QRadioButton(tr("Radial Gradient"), typeGroup);
+ m_conicalButton = new QRadioButton(tr("Conical Gradient"), typeGroup);
+
+ QGroupBox *spreadGroup = new QGroupBox(mainGroup);
+ spreadGroup->setTitle(tr("Spread Method"));
+ m_padSpreadButton = new QRadioButton(tr("Pad Spread"), spreadGroup);
+ m_reflectSpreadButton = new QRadioButton(tr("Reflect Spread"), spreadGroup);
+ m_repeatSpreadButton = new QRadioButton(tr("Repeat Spread"), spreadGroup);
+
+ QGroupBox *defaultsGroup = new QGroupBox(mainGroup);
+ defaultsGroup->setTitle(tr("Defaults"));
+ QPushButton *default1Button = new QPushButton(tr("1"), defaultsGroup);
+ QPushButton *default2Button = new QPushButton(tr("2"), defaultsGroup);
+ QPushButton *default3Button = new QPushButton(tr("3"), defaultsGroup);
+ QPushButton *default4Button = new QPushButton(tr("Reset"), editorGroup);
+
+ 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);
+
+ // Layouts
+ QHBoxLayout *mainLayout = new QHBoxLayout(this);
+ mainLayout->addWidget(m_renderer);
+ mainLayout->addWidget(mainGroup);
+
+ mainGroup->setFixedWidth(180);
+ QVBoxLayout *mainGroupLayout = new QVBoxLayout(mainGroup);
+ mainGroupLayout->addWidget(editorGroup);
+ mainGroupLayout->addWidget(typeGroup);
+ mainGroupLayout->addWidget(spreadGroup);
+ mainGroupLayout->addWidget(defaultsGroup);
+ mainGroupLayout->addStretch(1);
+ mainGroupLayout->addWidget(showSourceButton);
+#ifdef QT_OPENGL_SUPPORT
+ mainGroupLayout->addWidget(enableOpenGLButton);
+#endif
+ mainGroupLayout->addWidget(whatsThisButton);
+
+ QVBoxLayout *editorGroupLayout = new QVBoxLayout(editorGroup);
+ editorGroupLayout->addWidget(m_editor);
+
+ QVBoxLayout *typeGroupLayout = new QVBoxLayout(typeGroup);
+ typeGroupLayout->addWidget(m_linearButton);
+ typeGroupLayout->addWidget(m_radialButton);
+ typeGroupLayout->addWidget(m_conicalButton);
+
+ QVBoxLayout *spreadGroupLayout = new QVBoxLayout(spreadGroup);
+ spreadGroupLayout->addWidget(m_padSpreadButton);
+ spreadGroupLayout->addWidget(m_repeatSpreadButton);
+ spreadGroupLayout->addWidget(m_reflectSpreadButton);
+
+ QHBoxLayout *defaultsGroupLayout = new QHBoxLayout(defaultsGroup);
+ defaultsGroupLayout->addWidget(default1Button);
+ defaultsGroupLayout->addWidget(default2Button);
+ defaultsGroupLayout->addWidget(default3Button);
+ editorGroupLayout->addWidget(default4Button);
+
+ connect(m_editor, SIGNAL(gradientStopsChanged(QGradientStops)),
+ m_renderer, SLOT(setGradientStops(QGradientStops)));
+
+ connect(m_linearButton, SIGNAL(clicked()), m_renderer, SLOT(setLinearGradient()));
+ connect(m_radialButton, SIGNAL(clicked()), m_renderer, SLOT(setRadialGradient()));
+ connect(m_conicalButton, SIGNAL(clicked()), m_renderer, SLOT(setConicalGradient()));
+
+ connect(m_padSpreadButton, SIGNAL(clicked()), m_renderer, SLOT(setPadSpread()));
+ connect(m_reflectSpreadButton, SIGNAL(clicked()), m_renderer, SLOT(setReflectSpread()));
+ connect(m_repeatSpreadButton, SIGNAL(clicked()), m_renderer, SLOT(setRepeatSpread()));
+
+ connect(default1Button, SIGNAL(clicked()), this, SLOT(setDefault1()));
+ connect(default2Button, SIGNAL(clicked()), this, SLOT(setDefault2()));
+ connect(default3Button, SIGNAL(clicked()), this, SLOT(setDefault3()));
+ connect(default4Button, SIGNAL(clicked()), this, SLOT(setDefault4()));
+
+ connect(showSourceButton, SIGNAL(clicked()), m_renderer, SLOT(showSource()));
+#ifdef QT_OPENGL_SUPPORT
+ connect(enableOpenGLButton, SIGNAL(clicked(bool)), m_renderer, SLOT(enableOpenGL(bool)));
+#endif
+ connect(whatsThisButton, SIGNAL(clicked(bool)), m_renderer, SLOT(setDescriptionEnabled(bool)));
+ connect(whatsThisButton, SIGNAL(clicked(bool)),
+ m_renderer->hoverPoints(), SLOT(setDisabled(bool)));
+ connect(m_renderer, SIGNAL(descriptionEnabledChanged(bool)),
+ whatsThisButton, SLOT(setChecked(bool)));
+ connect(m_renderer, SIGNAL(descriptionEnabledChanged(bool)),
+ m_renderer->hoverPoints(), SLOT(setDisabled(bool)));
+
+ m_renderer->loadSourceFile(":res/gradients/gradients.cpp");
+ m_renderer->loadDescription(":res/gradients/gradients.html");
+
+ QTimer::singleShot(50, this, SLOT(setDefault1()));
+}
+
+void GradientWidget::setDefault(int config)
+{
+ QGradientStops stops;
+ QPolygonF points;
+ switch (config) {
+ case 1:
+ stops << QGradientStop(0.00, QColor::fromRgba(0));
+ stops << QGradientStop(0.04, QColor::fromRgba(0xff131360));
+ stops << QGradientStop(0.08, QColor::fromRgba(0xff202ccc));
+ stops << QGradientStop(0.42, QColor::fromRgba(0xff93d3f9));
+ stops << QGradientStop(0.51, QColor::fromRgba(0xffb3e6ff));
+ stops << QGradientStop(0.73, QColor::fromRgba(0xffffffec));
+ stops << QGradientStop(0.92, QColor::fromRgba(0xff5353d9));
+ stops << QGradientStop(0.96, QColor::fromRgba(0xff262666));
+ stops << QGradientStop(1.00, QColor::fromRgba(0));
+ m_linearButton->animateClick();
+ m_repeatSpreadButton->animateClick();
+ break;
+
+ case 2:
+ stops << QGradientStop(0.00, QColor::fromRgba(0xffffffff));
+ stops << QGradientStop(0.11, QColor::fromRgba(0xfff9ffa0));
+ stops << QGradientStop(0.13, QColor::fromRgba(0xfff9ff99));
+ stops << QGradientStop(0.14, QColor::fromRgba(0xfff3ff86));
+ stops << QGradientStop(0.49, QColor::fromRgba(0xff93b353));
+ stops << QGradientStop(0.87, QColor::fromRgba(0xff264619));
+ stops << QGradientStop(0.96, QColor::fromRgba(0xff0c1306));
+ stops << QGradientStop(1.00, QColor::fromRgba(0));
+ m_radialButton->animateClick();
+ m_padSpreadButton->animateClick();
+ break;
+
+ case 3:
+ stops << QGradientStop(0.00, QColor::fromRgba(0));
+ stops << QGradientStop(0.10, QColor::fromRgba(0xffe0cc73));
+ stops << QGradientStop(0.17, QColor::fromRgba(0xffc6a006));
+ stops << QGradientStop(0.46, QColor::fromRgba(0xff600659));
+ stops << QGradientStop(0.72, QColor::fromRgba(0xff0680ac));
+ stops << QGradientStop(0.92, QColor::fromRgba(0xffb9d9e6));
+ stops << QGradientStop(1.00, QColor::fromRgba(0));
+ m_conicalButton->animateClick();
+ m_padSpreadButton->animateClick();
+ break;
+
+ case 4:
+ stops << QGradientStop(0.00, QColor::fromRgba(0xff000000));
+ stops << QGradientStop(1.00, QColor::fromRgba(0xffffffff));
+ break;
+
+ default:
+ qWarning("bad default: %d\n", config);
+ break;
+ }
+
+ QPolygonF pts;
+ int h_off = m_renderer->width() / 10;
+ int v_off = m_renderer->height() / 8;
+ pts << QPointF(m_renderer->width() / 2, m_renderer->height() / 2)
+ << QPointF(m_renderer->width() / 2 - h_off, m_renderer->height() / 2 - v_off);
+
+ m_editor->setGradientStops(stops);
+ m_renderer->hoverPoints()->setPoints(pts);
+ m_renderer->setGradientStops(stops);
+}
+
+
+GradientRenderer::GradientRenderer(QWidget *parent)
+ : ArthurFrame(parent)
+{
+ m_hoverPoints = new HoverPoints(this, HoverPoints::CircleShape);
+ m_hoverPoints->setPointSize(QSize(20, 20));
+ m_hoverPoints->setConnectionType(HoverPoints::NoConnection);
+ m_hoverPoints->setEditable(false);
+
+ QVector<QPointF> points;
+ points << QPointF(100, 100) << QPointF(200, 200);
+ m_hoverPoints->setPoints(points);
+
+ m_spread = QGradient::PadSpread;
+ m_gradientType = Qt::LinearGradientPattern;
+}
+
+void GradientRenderer::setGradientStops(const QGradientStops &stops)
+{
+ m_stops = stops;
+ update();
+}
+
+
+void GradientRenderer::mousePressEvent(QMouseEvent *)
+{
+ setDescriptionEnabled(false);
+}
+
+void GradientRenderer::paint(QPainter *p)
+{
+ QPolygonF pts = m_hoverPoints->points();
+
+ QGradient g;
+
+ if (m_gradientType == Qt::LinearGradientPattern) {
+ g = QLinearGradient(pts.at(0), pts.at(1));
+
+ } else if (m_gradientType == Qt::RadialGradientPattern) {
+ g = QRadialGradient(pts.at(0), qMin(width(), height()) / 3.0, pts.at(1));
+
+ } else {
+ QLineF l(pts.at(0), pts.at(1));
+ qreal angle = l.angle(QLineF(0, 0, 1, 0));
+ if (l.dy() > 0)
+ angle = 360 - angle;
+ g = QConicalGradient(pts.at(0), angle);
+ }
+
+ for (int i=0; i<m_stops.size(); ++i)
+ g.setColorAt(m_stops.at(i).first, m_stops.at(i).second);
+
+ g.setSpread(m_spread);
+
+ p->setBrush(g);
+ p->setPen(Qt::NoPen);
+
+ p->drawRect(rect());
+
+}
diff --git a/examples/widgets/painting/gradients/gradients.h b/examples/widgets/painting/gradients/gradients.h
new file mode 100644
index 0000000000..0fed2de82a
--- /dev/null
+++ b/examples/widgets/painting/gradients/gradients.h
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef GRADIENTS_H
+#define GRADIENTS_H
+
+#include "arthurwidgets.h"
+
+#include <QtWidgets>
+
+class HoverPoints;
+
+
+class ShadeWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ enum ShadeType {
+ RedShade,
+ GreenShade,
+ BlueShade,
+ ARGBShade
+ };
+
+ ShadeWidget(ShadeType type, QWidget *parent);
+
+ void setGradientStops(const QGradientStops &stops);
+
+ void paintEvent(QPaintEvent *e);
+
+ QSize sizeHint() const { return QSize(150, 40); }
+ QPolygonF points() const;
+
+ HoverPoints *hoverPoints() const { return m_hoverPoints; }
+
+ uint colorAt(int x);
+
+signals:
+ void colorsChanged();
+
+private:
+ void generateShade();
+
+ ShadeType m_shade_type;
+ QImage m_shade;
+ HoverPoints *m_hoverPoints;
+ QLinearGradient m_alpha_gradient;
+};
+
+class GradientEditor : public QWidget
+{
+ Q_OBJECT
+public:
+ GradientEditor(QWidget *parent);
+
+ void setGradientStops(const QGradientStops &stops);
+
+public slots:
+ void pointsUpdated();
+
+signals:
+ void gradientStopsChanged(const QGradientStops &stops);
+
+private:
+ ShadeWidget *m_red_shade;
+ ShadeWidget *m_green_shade;
+ ShadeWidget *m_blue_shade;
+ ShadeWidget *m_alpha_shade;
+};
+
+
+class GradientRenderer : public ArthurFrame
+{
+ Q_OBJECT
+public:
+ GradientRenderer(QWidget *parent);
+ void paint(QPainter *p);
+
+ QSize sizeHint() const { return QSize(400, 400); }
+
+ HoverPoints *hoverPoints() const { return m_hoverPoints; }
+ void mousePressEvent(QMouseEvent *e);
+
+public slots:
+ void setGradientStops(const QGradientStops &stops);
+
+ void setPadSpread() { m_spread = QGradient::PadSpread; update(); }
+ void setRepeatSpread() { m_spread = QGradient::RepeatSpread; update(); }
+ void setReflectSpread() { m_spread = QGradient::ReflectSpread; update(); }
+
+ void setLinearGradient() { m_gradientType = Qt::LinearGradientPattern; update(); }
+ void setRadialGradient() { m_gradientType = Qt::RadialGradientPattern; update(); }
+ void setConicalGradient() { m_gradientType = Qt::ConicalGradientPattern; update(); }
+
+
+private:
+ QGradientStops m_stops;
+ HoverPoints *m_hoverPoints;
+
+ QGradient::Spread m_spread;
+ Qt::BrushStyle m_gradientType;
+};
+
+
+class GradientWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ GradientWidget(QWidget *parent);
+
+public slots:
+ void setDefault1() { setDefault(1); }
+ void setDefault2() { setDefault(2); }
+ void setDefault3() { setDefault(3); }
+ void setDefault4() { setDefault(4); }
+
+private:
+ void setDefault(int i);
+
+ GradientRenderer *m_renderer;
+ GradientEditor *m_editor;
+
+ QRadioButton *m_linearButton;
+ QRadioButton *m_radialButton;
+ QRadioButton *m_conicalButton;
+ QRadioButton *m_padSpreadButton;
+ QRadioButton *m_reflectSpreadButton;
+ QRadioButton *m_repeatSpreadButton;
+
+};
+
+#endif // GRADIENTS_H
diff --git a/examples/widgets/painting/gradients/gradients.html b/examples/widgets/painting/gradients/gradients.html
new file mode 100644
index 0000000000..1ea2c0ed6c
--- /dev/null
+++ b/examples/widgets/painting/gradients/gradients.html
@@ -0,0 +1,31 @@
+<html>
+<center>
+<h2>Gradients</h2>
+</center>
+
+<p>In this demo we show the various types of gradients that can
+be used in Qt.</p>
+
+<p>There are three types of gradients:
+
+<ul>
+ <li><b>Linear</b> gradients interpolate colors between start and end
+ points.</li>
+ <li><b>Radial</b> gradients interpolate colors between a focal point and the
+ points on a circle surrounding it.</li>
+ <li><b>Conical</b> gradients interpolate colors around a center point.</li>
+</ul>
+
+</p>
+
+<p>The panel on the right contains a color table editor that defines
+the colors in the gradient. The three topmost controls determine the red,
+green and blue components while the last defines the alpha of the
+gradient. You can move points, and add new ones, by clicking with the left
+mouse button, and remove points by clicking with the right button.</p>
+
+<p>There are three default configurations available at the bottom of
+the page that are provided as suggestions on how a color table could be
+configured.</p>
+
+</html>
diff --git a/examples/widgets/painting/gradients/gradients.pro b/examples/widgets/painting/gradients/gradients.pro
new file mode 100644
index 0000000000..4362d283ee
--- /dev/null
+++ b/examples/widgets/painting/gradients/gradients.pro
@@ -0,0 +1,20 @@
+SOURCES += main.cpp gradients.cpp
+HEADERS += gradients.h
+
+SHARED_FOLDER = ../shared
+
+include($$SHARED_FOLDER/shared.pri)
+
+RESOURCES += gradients.qrc
+contains(QT_CONFIG, opengl) {
+ DEFINES += QT_OPENGL_SUPPORT
+ QT += opengl
+}
+QT += widgets
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/painting/gradients
+sources.files = $$SOURCES $$HEADERS $$RESOURCES *.pro *.html
+sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/painting/gradients
+INSTALLS += target sources
+
diff --git a/examples/widgets/painting/gradients/gradients.qrc b/examples/widgets/painting/gradients/gradients.qrc
new file mode 100644
index 0000000000..fb971eb17b
--- /dev/null
+++ b/examples/widgets/painting/gradients/gradients.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/res/gradients">
+ <file>gradients.cpp</file>
+ <file>gradients.html</file>
+</qresource>
+</RCC>
diff --git a/examples/widgets/painting/gradients/main.cpp b/examples/widgets/painting/gradients/main.cpp
new file mode 100644
index 0000000000..eaf8bdc333
--- /dev/null
+++ b/examples/widgets/painting/gradients/main.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** 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 "gradients.h"
+
+#include <QApplication>
+
+int main(int argc, char **argv)
+{
+ Q_INIT_RESOURCE(gradients);
+
+ QApplication app(argc, argv);
+
+ GradientWidget gradientWidget(0);
+ QStyle *arthurStyle = new ArthurStyle();
+ gradientWidget.setStyle(arthurStyle);
+ QList<QWidget *> widgets = gradientWidget.findChildren<QWidget *>();
+ foreach (QWidget *w, widgets) {
+ w->setStyle(arthurStyle);
+ w->setAttribute(Qt::WA_AcceptTouchEvents);
+ }
+ gradientWidget.show();
+
+ return app.exec();
+}
diff --git a/examples/widgets/painting/imagecomposition/imagecomposer.cpp b/examples/widgets/painting/imagecomposition/imagecomposer.cpp
new file mode 100644
index 0000000000..38b04a27b0
--- /dev/null
+++ b/examples/widgets/painting/imagecomposition/imagecomposer.cpp
@@ -0,0 +1,211 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtWidgets>
+
+#include "imagecomposer.h"
+
+//! [0]
+static const QSize resultSize(200, 200);
+//! [0]
+
+//! [1]
+ImageComposer::ImageComposer()
+{
+ sourceButton = new QToolButton;
+ sourceButton->setIconSize(resultSize);
+
+ operatorComboBox = new QComboBox;
+ addOp(QPainter::CompositionMode_SourceOver, tr("SourceOver"));
+ addOp(QPainter::CompositionMode_DestinationOver, tr("DestinationOver"));
+ addOp(QPainter::CompositionMode_Clear, tr("Clear"));
+ addOp(QPainter::CompositionMode_Source, tr("Source"));
+ addOp(QPainter::CompositionMode_Destination, tr("Destination"));
+ addOp(QPainter::CompositionMode_SourceIn, tr("SourceIn"));
+ addOp(QPainter::CompositionMode_DestinationIn, tr("DestinationIn"));
+ addOp(QPainter::CompositionMode_SourceOut, tr("SourceOut"));
+ addOp(QPainter::CompositionMode_DestinationOut, tr("DestinationOut"));
+ addOp(QPainter::CompositionMode_SourceAtop, tr("SourceAtop"));
+ addOp(QPainter::CompositionMode_DestinationAtop, tr("DestinationAtop"));
+ addOp(QPainter::CompositionMode_Xor, tr("Xor"));
+ addOp(QPainter::CompositionMode_Plus, tr("Plus"));
+ addOp(QPainter::CompositionMode_Multiply, tr("Multiply"));
+ addOp(QPainter::CompositionMode_Screen, tr("Screen"));
+ addOp(QPainter::CompositionMode_Overlay, tr("Overlay"));
+ addOp(QPainter::CompositionMode_Darken, tr("Darken"));
+ addOp(QPainter::CompositionMode_Lighten, tr("Lighten"));
+ addOp(QPainter::CompositionMode_ColorDodge, tr("ColorDodge"));
+ addOp(QPainter::CompositionMode_ColorBurn, tr("ColorBurn"));
+ addOp(QPainter::CompositionMode_HardLight, tr("HardLight"));
+ addOp(QPainter::CompositionMode_SoftLight, tr("SoftLight"));
+ addOp(QPainter::CompositionMode_Difference, tr("Difference"));
+ addOp(QPainter::CompositionMode_Exclusion, tr("Exclusion"));
+//! [1]
+
+//! [2]
+ destinationButton = new QToolButton;
+ destinationButton->setIconSize(resultSize);
+
+ equalLabel = new QLabel(tr("="));
+
+ resultLabel = new QLabel;
+ resultLabel->setMinimumWidth(resultSize.width());
+//! [2]
+
+//! [3]
+ connect(sourceButton, SIGNAL(clicked()), this, SLOT(chooseSource()));
+ connect(operatorComboBox, SIGNAL(activated(int)),
+ this, SLOT(recalculateResult()));
+ connect(destinationButton, SIGNAL(clicked()),
+ this, SLOT(chooseDestination()));
+//! [3]
+
+//! [4]
+ QGridLayout *mainLayout = new QGridLayout;
+ mainLayout->addWidget(sourceButton, 0, 0, 3, 1);
+ mainLayout->addWidget(operatorComboBox, 1, 1);
+ mainLayout->addWidget(destinationButton, 0, 2, 3, 1);
+ mainLayout->addWidget(equalLabel, 1, 3);
+ mainLayout->addWidget(resultLabel, 0, 4, 3, 1);
+ mainLayout->setSizeConstraint(QLayout::SetFixedSize);
+ setLayout(mainLayout);
+//! [4]
+
+//! [5]
+ resultImage = QImage(resultSize, QImage::Format_ARGB32_Premultiplied);
+
+ loadImage(":/images/butterfly.png", &sourceImage, sourceButton);
+ loadImage(":/images/checker.png", &destinationImage, destinationButton);
+
+ setWindowTitle(tr("Image Composition"));
+}
+//! [5]
+
+//! [6]
+void ImageComposer::chooseSource()
+{
+ chooseImage(tr("Choose Source Image"), &sourceImage, sourceButton);
+}
+//! [6]
+
+//! [7]
+void ImageComposer::chooseDestination()
+{
+ chooseImage(tr("Choose Destination Image"), &destinationImage,
+ destinationButton);
+}
+//! [7]
+
+//! [8]
+void ImageComposer::recalculateResult()
+{
+ QPainter::CompositionMode mode = currentMode();
+
+ QPainter painter(&resultImage);
+ painter.setCompositionMode(QPainter::CompositionMode_Source);
+ painter.fillRect(resultImage.rect(), Qt::transparent);
+ painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
+ painter.drawImage(0, 0, destinationImage);
+ painter.setCompositionMode(mode);
+ painter.drawImage(0, 0, sourceImage);
+ painter.setCompositionMode(QPainter::CompositionMode_DestinationOver);
+ painter.fillRect(resultImage.rect(), Qt::white);
+ painter.end();
+
+ resultLabel->setPixmap(QPixmap::fromImage(resultImage));
+}
+//! [8]
+
+//! [9]
+void ImageComposer::addOp(QPainter::CompositionMode mode, const QString &name)
+{
+ operatorComboBox->addItem(name, mode);
+}
+//! [9]
+
+//! [10]
+void ImageComposer::chooseImage(const QString &title, QImage *image,
+ QToolButton *button)
+{
+ QString fileName = QFileDialog::getOpenFileName(this, title);
+ if (!fileName.isEmpty())
+ loadImage(fileName, image, button);
+}
+//! [10]
+
+//! [11]
+void ImageComposer::loadImage(const QString &fileName, QImage *image,
+ QToolButton *button)
+{
+ image->load(fileName);
+
+ // Scale the image to given size
+ *image = image->scaled(resultSize, Qt::KeepAspectRatio);
+
+ QImage fixedImage(resultSize, QImage::Format_ARGB32_Premultiplied);
+ QPainter painter(&fixedImage);
+ painter.setCompositionMode(QPainter::CompositionMode_Source);
+ painter.fillRect(fixedImage.rect(), Qt::transparent);
+ painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
+ painter.drawImage(imagePos(*image), *image);
+ painter.end();
+ button->setIcon(QPixmap::fromImage(fixedImage));
+
+ *image = fixedImage;
+
+ recalculateResult();
+}
+//! [11]
+
+//! [12]
+QPainter::CompositionMode ImageComposer::currentMode() const
+{
+ return (QPainter::CompositionMode)
+ operatorComboBox->itemData(operatorComboBox->currentIndex()).toInt();
+}
+//! [12]
+
+//! [13]
+QPoint ImageComposer::imagePos(const QImage &image) const
+{
+ return QPoint((resultSize.width() - image.width()) / 2,
+ (resultSize.height() - image.height()) / 2);
+}
+//! [13]
diff --git a/examples/widgets/painting/imagecomposition/imagecomposer.h b/examples/widgets/painting/imagecomposition/imagecomposer.h
new file mode 100644
index 0000000000..7ec0207e2c
--- /dev/null
+++ b/examples/widgets/painting/imagecomposition/imagecomposer.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef IMAGECOMPOSER_H
+#define IMAGECOMPOSER_H
+
+#include <QPainter>
+#include <QWidget>
+
+QT_BEGIN_NAMESPACE
+class QComboBox;
+class QLabel;
+class QToolButton;
+QT_END_NAMESPACE
+
+//! [0]
+class ImageComposer : public QWidget
+{
+ Q_OBJECT
+
+public:
+ ImageComposer();
+
+private slots:
+ void chooseSource();
+ void chooseDestination();
+ void recalculateResult();
+//! [0]
+
+//! [1]
+private:
+ void addOp(QPainter::CompositionMode mode, const QString &name);
+ void chooseImage(const QString &title, QImage *image, QToolButton *button);
+ void loadImage(const QString &fileName, QImage *image, QToolButton *button);
+ QPainter::CompositionMode currentMode() const;
+ QPoint imagePos(const QImage &image) const;
+
+ QToolButton *sourceButton;
+ QToolButton *destinationButton;
+ QComboBox *operatorComboBox;
+ QLabel *equalLabel;
+ QLabel *resultLabel;
+
+ QImage sourceImage;
+ QImage destinationImage;
+ QImage resultImage;
+};
+//! [1]
+
+#endif
diff --git a/examples/widgets/painting/imagecomposition/imagecomposition.desktop b/examples/widgets/painting/imagecomposition/imagecomposition.desktop
new file mode 100644
index 0000000000..854fc862f0
--- /dev/null
+++ b/examples/widgets/painting/imagecomposition/imagecomposition.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Terminal=false
+Name=Image Composition
+Exec=/opt/usr/bin/imagecomposition
+Icon=imagecomposition
+X-Window-Icon=
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
diff --git a/examples/widgets/painting/imagecomposition/imagecomposition.pro b/examples/widgets/painting/imagecomposition/imagecomposition.pro
new file mode 100644
index 0000000000..edf434f5d2
--- /dev/null
+++ b/examples/widgets/painting/imagecomposition/imagecomposition.pro
@@ -0,0 +1,13 @@
+HEADERS = imagecomposer.h
+SOURCES = imagecomposer.cpp \
+ main.cpp
+RESOURCES = imagecomposition.qrc
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/painting/imagecomposition
+sources.files = $$SOURCES $$HEADERS $$RESOURCES images *.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/painting/imagecomposition
+INSTALLS += target sources
+
+QT += widgets
+
diff --git a/examples/widgets/painting/imagecomposition/imagecomposition.qrc b/examples/widgets/painting/imagecomposition/imagecomposition.qrc
new file mode 100644
index 0000000000..ebba7b2913
--- /dev/null
+++ b/examples/widgets/painting/imagecomposition/imagecomposition.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>images/butterfly.png</file>
+ <file>images/checker.png</file>
+</qresource>
+</RCC>
diff --git a/examples/widgets/painting/imagecomposition/images/background.png b/examples/widgets/painting/imagecomposition/images/background.png
new file mode 100644
index 0000000000..f6ad899823
--- /dev/null
+++ b/examples/widgets/painting/imagecomposition/images/background.png
Binary files differ
diff --git a/examples/widgets/painting/imagecomposition/images/blackrectangle.png b/examples/widgets/painting/imagecomposition/images/blackrectangle.png
new file mode 100644
index 0000000000..5f2ecf8318
--- /dev/null
+++ b/examples/widgets/painting/imagecomposition/images/blackrectangle.png
Binary files differ
diff --git a/examples/widgets/painting/imagecomposition/images/butterfly.png b/examples/widgets/painting/imagecomposition/images/butterfly.png
new file mode 100644
index 0000000000..f3e050eca2
--- /dev/null
+++ b/examples/widgets/painting/imagecomposition/images/butterfly.png
Binary files differ
diff --git a/examples/widgets/painting/imagecomposition/images/checker.png b/examples/widgets/painting/imagecomposition/images/checker.png
new file mode 100644
index 0000000000..546609de3f
--- /dev/null
+++ b/examples/widgets/painting/imagecomposition/images/checker.png
Binary files differ
diff --git a/examples/widgets/painting/imagecomposition/main.cpp b/examples/widgets/painting/imagecomposition/main.cpp
new file mode 100644
index 0000000000..6b17c4d370
--- /dev/null
+++ b/examples/widgets/painting/imagecomposition/main.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+
+#include "imagecomposer.h"
+
+//! [0]
+int main(int argc, char *argv[])
+{
+ Q_INIT_RESOURCE(imagecomposition);
+
+ QApplication app(argc, argv);
+ ImageComposer composer;
+ composer.show();
+ return app.exec();
+}
+//! [0]
diff --git a/examples/widgets/painting/painterpaths/main.cpp b/examples/widgets/painting/painterpaths/main.cpp
new file mode 100644
index 0000000000..dcbf1c0449
--- /dev/null
+++ b/examples/widgets/painting/painterpaths/main.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+
+#include "window.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ Window window;
+ window.show();
+ return app.exec();
+}
diff --git a/examples/widgets/painting/painterpaths/painterpaths.desktop b/examples/widgets/painting/painterpaths/painterpaths.desktop
new file mode 100644
index 0000000000..ae92f2c589
--- /dev/null
+++ b/examples/widgets/painting/painterpaths/painterpaths.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Terminal=false
+Name=Painter Paths
+Exec=/opt/usr/bin/painterpaths
+Icon=painterpaths
+X-Window-Icon=
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
diff --git a/examples/widgets/painting/painterpaths/painterpaths.pro b/examples/widgets/painting/painterpaths/painterpaths.pro
new file mode 100644
index 0000000000..c988ba26e0
--- /dev/null
+++ b/examples/widgets/painting/painterpaths/painterpaths.pro
@@ -0,0 +1,15 @@
+HEADERS = renderarea.h \
+ window.h
+SOURCES = main.cpp \
+ renderarea.cpp \
+ window.cpp
+unix:!mac:!vxworks:!integrity:LIBS += -lm
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/painting/painterpaths
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS painterpaths.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/painting/painterpaths
+INSTALLS += target sources
+
+QT += widgets
+
diff --git a/examples/widgets/painting/painterpaths/renderarea.cpp b/examples/widgets/painting/painterpaths/renderarea.cpp
new file mode 100644
index 0000000000..0b3f1fdc0d
--- /dev/null
+++ b/examples/widgets/painting/painterpaths/renderarea.cpp
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtWidgets>
+
+#include "renderarea.h"
+
+//! [0]
+RenderArea::RenderArea(const QPainterPath &path, QWidget *parent)
+ : QWidget(parent), path(path)
+{
+ penWidth = 1;
+ rotationAngle = 0;
+ setBackgroundRole(QPalette::Base);
+}
+//! [0]
+
+//! [1]
+QSize RenderArea::minimumSizeHint() const
+{
+ return QSize(50, 50);
+}
+//! [1]
+
+//! [2]
+QSize RenderArea::sizeHint() const
+{
+ return QSize(100, 100);
+}
+//! [2]
+
+//! [3]
+void RenderArea::setFillRule(Qt::FillRule rule)
+{
+ path.setFillRule(rule);
+ update();
+}
+//! [3]
+
+//! [4]
+void RenderArea::setFillGradient(const QColor &color1, const QColor &color2)
+{
+ fillColor1 = color1;
+ fillColor2 = color2;
+ update();
+}
+//! [4]
+
+//! [5]
+void RenderArea::setPenWidth(int width)
+{
+ penWidth = width;
+ update();
+}
+//! [5]
+
+//! [6]
+void RenderArea::setPenColor(const QColor &color)
+{
+ penColor = color;
+ update();
+}
+//! [6]
+
+//! [7]
+void RenderArea::setRotationAngle(int degrees)
+{
+ rotationAngle = degrees;
+ update();
+}
+//! [7]
+
+//! [8]
+void RenderArea::paintEvent(QPaintEvent *)
+{
+ QPainter painter(this);
+ painter.setRenderHint(QPainter::Antialiasing);
+//! [8] //! [9]
+ painter.scale(width() / 100.0, height() / 100.0);
+ painter.translate(50.0, 50.0);
+ painter.rotate(-rotationAngle);
+ painter.translate(-50.0, -50.0);
+
+//! [9] //! [10]
+ painter.setPen(QPen(penColor, penWidth, Qt::SolidLine, Qt::RoundCap,
+ Qt::RoundJoin));
+ QLinearGradient gradient(0, 0, 0, 100);
+ gradient.setColorAt(0.0, fillColor1);
+ gradient.setColorAt(1.0, fillColor2);
+ painter.setBrush(gradient);
+ painter.drawPath(path);
+}
+//! [10]
diff --git a/examples/widgets/painting/painterpaths/renderarea.h b/examples/widgets/painting/painterpaths/renderarea.h
new file mode 100644
index 0000000000..5c310fdf62
--- /dev/null
+++ b/examples/widgets/painting/painterpaths/renderarea.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RENDERAREA_H
+#define RENDERAREA_H
+
+#include <QPainterPath>
+#include <QWidget>
+
+//! [0]
+class RenderArea : public QWidget
+{
+ Q_OBJECT
+
+public:
+ RenderArea(const QPainterPath &path, QWidget *parent = 0);
+
+ QSize minimumSizeHint() const;
+ QSize sizeHint() const;
+
+public slots:
+ void setFillRule(Qt::FillRule rule);
+ void setFillGradient(const QColor &color1, const QColor &color2);
+ void setPenWidth(int width);
+ void setPenColor(const QColor &color);
+ void setRotationAngle(int degrees);
+
+protected:
+ void paintEvent(QPaintEvent *event);
+//! [0]
+
+//! [1]
+private:
+ QPainterPath path;
+ QColor fillColor1;
+ QColor fillColor2;
+ int penWidth;
+ QColor penColor;
+ int rotationAngle;
+};
+//! [1]
+
+#endif
diff --git a/examples/widgets/painting/painterpaths/window.cpp b/examples/widgets/painting/painterpaths/window.cpp
new file mode 100644
index 0000000000..3d3eef9d2b
--- /dev/null
+++ b/examples/widgets/painting/painterpaths/window.cpp
@@ -0,0 +1,289 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtWidgets>
+
+#include <math.h>
+
+#include "renderarea.h"
+#include "window.h"
+
+//! [0]
+const float Pi = 3.14159f;
+//! [0]
+
+//! [1]
+Window::Window()
+{
+ QPainterPath rectPath;
+ rectPath.moveTo(20.0, 30.0);
+ rectPath.lineTo(80.0, 30.0);
+ rectPath.lineTo(80.0, 70.0);
+ rectPath.lineTo(20.0, 70.0);
+ rectPath.closeSubpath();
+//! [1]
+
+//! [2]
+ QPainterPath roundRectPath;
+ roundRectPath.moveTo(80.0, 35.0);
+ roundRectPath.arcTo(70.0, 30.0, 10.0, 10.0, 0.0, 90.0);
+ roundRectPath.lineTo(25.0, 30.0);
+ roundRectPath.arcTo(20.0, 30.0, 10.0, 10.0, 90.0, 90.0);
+ roundRectPath.lineTo(20.0, 65.0);
+ roundRectPath.arcTo(20.0, 60.0, 10.0, 10.0, 180.0, 90.0);
+ roundRectPath.lineTo(75.0, 70.0);
+ roundRectPath.arcTo(70.0, 60.0, 10.0, 10.0, 270.0, 90.0);
+ roundRectPath.closeSubpath();
+//! [2]
+
+//! [3]
+ QPainterPath ellipsePath;
+ ellipsePath.moveTo(80.0, 50.0);
+ ellipsePath.arcTo(20.0, 30.0, 60.0, 40.0, 0.0, 360.0);
+//! [3]
+
+//! [4]
+ QPainterPath piePath;
+ piePath.moveTo(50.0, 50.0);
+ piePath.arcTo(20.0, 30.0, 60.0, 40.0, 60.0, 240.0);
+ piePath.closeSubpath();
+//! [4]
+
+//! [5]
+ QPainterPath polygonPath;
+ polygonPath.moveTo(10.0, 80.0);
+ polygonPath.lineTo(20.0, 10.0);
+ polygonPath.lineTo(80.0, 30.0);
+ polygonPath.lineTo(90.0, 70.0);
+ polygonPath.closeSubpath();
+//! [5]
+
+//! [6]
+ QPainterPath groupPath;
+ groupPath.moveTo(60.0, 40.0);
+ groupPath.arcTo(20.0, 20.0, 40.0, 40.0, 0.0, 360.0);
+ groupPath.moveTo(40.0, 40.0);
+ groupPath.lineTo(40.0, 80.0);
+ groupPath.lineTo(80.0, 80.0);
+ groupPath.lineTo(80.0, 40.0);
+ groupPath.closeSubpath();
+//! [6]
+
+//! [7]
+ QPainterPath textPath;
+ QFont timesFont("Times", 50);
+ timesFont.setStyleStrategy(QFont::ForceOutline);
+ textPath.addText(10, 70, timesFont, tr("Qt"));
+//! [7]
+
+//! [8]
+ QPainterPath bezierPath;
+ bezierPath.moveTo(20, 30);
+ bezierPath.cubicTo(80, 0, 50, 50, 80, 80);
+//! [8]
+
+//! [9]
+ QPainterPath starPath;
+ starPath.moveTo(90, 50);
+ for (int i = 1; i < 5; ++i) {
+ starPath.lineTo(50 + 40 * cos(0.8 * i * Pi),
+ 50 + 40 * sin(0.8 * i * Pi));
+ }
+ starPath.closeSubpath();
+//! [9]
+
+//! [10]
+ renderAreas.push_back(new RenderArea(rectPath));
+ renderAreas.push_back(new RenderArea(roundRectPath));
+ renderAreas.push_back(new RenderArea(ellipsePath));
+ renderAreas.push_back(new RenderArea(piePath));
+ renderAreas.push_back(new RenderArea(polygonPath));
+ renderAreas.push_back(new RenderArea(groupPath));
+ renderAreas.push_back(new RenderArea(textPath));
+ renderAreas.push_back(new RenderArea(bezierPath));
+ renderAreas.push_back(new RenderArea(starPath));
+//! [10]
+
+//! [11]
+ fillRuleComboBox = new QComboBox;
+ fillRuleComboBox->addItem(tr("Odd Even"), Qt::OddEvenFill);
+ fillRuleComboBox->addItem(tr("Winding"), Qt::WindingFill);
+
+ fillRuleLabel = new QLabel(tr("Fill &Rule:"));
+ fillRuleLabel->setBuddy(fillRuleComboBox);
+//! [11]
+
+//! [12]
+ fillColor1ComboBox = new QComboBox;
+ populateWithColors(fillColor1ComboBox);
+ fillColor1ComboBox->setCurrentIndex(
+ fillColor1ComboBox->findText("mediumslateblue"));
+
+ fillColor2ComboBox = new QComboBox;
+ populateWithColors(fillColor2ComboBox);
+ fillColor2ComboBox->setCurrentIndex(
+ fillColor2ComboBox->findText("cornsilk"));
+
+ fillGradientLabel = new QLabel(tr("&Fill Gradient:"));
+ fillGradientLabel->setBuddy(fillColor1ComboBox);
+
+ fillToLabel = new QLabel(tr("to"));
+ fillToLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+
+ penWidthSpinBox = new QSpinBox;
+ penWidthSpinBox->setRange(0, 20);
+
+ penWidthLabel = new QLabel(tr("&Pen Width:"));
+ penWidthLabel->setBuddy(penWidthSpinBox);
+
+ penColorComboBox = new QComboBox;
+ populateWithColors(penColorComboBox);
+ penColorComboBox->setCurrentIndex(
+ penColorComboBox->findText("darkslateblue"));
+
+ penColorLabel = new QLabel(tr("Pen &Color:"));
+ penColorLabel->setBuddy(penColorComboBox);
+
+ rotationAngleSpinBox = new QSpinBox;
+ rotationAngleSpinBox->setRange(0, 359);
+ rotationAngleSpinBox->setWrapping(true);
+ rotationAngleSpinBox->setSuffix(QLatin1String("\xB0"));
+
+ rotationAngleLabel = new QLabel(tr("&Rotation Angle:"));
+ rotationAngleLabel->setBuddy(rotationAngleSpinBox);
+//! [12]
+
+//! [16]
+ connect(fillRuleComboBox, SIGNAL(activated(int)),
+ this, SLOT(fillRuleChanged()));
+ connect(fillColor1ComboBox, SIGNAL(activated(int)),
+ this, SLOT(fillGradientChanged()));
+ connect(fillColor2ComboBox, SIGNAL(activated(int)),
+ this, SLOT(fillGradientChanged()));
+ connect(penColorComboBox, SIGNAL(activated(int)),
+ this, SLOT(penColorChanged()));
+
+ for(QList<RenderArea*>::iterator it = renderAreas.begin(); it != renderAreas.end(); it++) {
+ connect(penWidthSpinBox, SIGNAL(valueChanged(int)),
+ *it, SLOT(setPenWidth(int)));
+ connect(rotationAngleSpinBox, SIGNAL(valueChanged(int)),
+ *it, SLOT(setRotationAngle(int)));
+ }
+
+//! [16] //! [17]
+ QGridLayout *topLayout = new QGridLayout;
+
+ int i=0;
+ for(QList<RenderArea*>::iterator it = renderAreas.begin(); it != renderAreas.end(); it++, i++)
+ topLayout->addWidget(*it, i / 3, i % 3);
+
+ QGridLayout *mainLayout = new QGridLayout;
+ mainLayout->addLayout(topLayout, 0, 0, 1, 4);
+ mainLayout->addWidget(fillRuleLabel, 1, 0);
+ mainLayout->addWidget(fillRuleComboBox, 1, 1, 1, 3);
+ mainLayout->addWidget(fillGradientLabel, 2, 0);
+ mainLayout->addWidget(fillColor1ComboBox, 2, 1);
+ mainLayout->addWidget(fillToLabel, 2, 2);
+ mainLayout->addWidget(fillColor2ComboBox, 2, 3);
+ mainLayout->addWidget(penWidthLabel, 3, 0);
+ mainLayout->addWidget(penWidthSpinBox, 3, 1, 1, 3);
+ mainLayout->addWidget(penColorLabel, 4, 0);
+ mainLayout->addWidget(penColorComboBox, 4, 1, 1, 3);
+ mainLayout->addWidget(rotationAngleLabel, 5, 0);
+ mainLayout->addWidget(rotationAngleSpinBox, 5, 1, 1, 3);
+ setLayout(mainLayout);
+//! [17]
+
+//! [18]
+ fillRuleChanged();
+ fillGradientChanged();
+ penColorChanged();
+ penWidthSpinBox->setValue(2);
+
+ setWindowTitle(tr("Painter Paths"));
+}
+//! [18]
+
+//! [19]
+void Window::fillRuleChanged()
+{
+ Qt::FillRule rule = (Qt::FillRule)currentItemData(fillRuleComboBox).toInt();
+
+ for(QList<RenderArea*>::iterator it = renderAreas.begin(); it != renderAreas.end(); it++)
+ (*it)->setFillRule(rule);
+}
+//! [19]
+
+//! [20]
+void Window::fillGradientChanged()
+{
+ QColor color1 = qvariant_cast<QColor>(currentItemData(fillColor1ComboBox));
+ QColor color2 = qvariant_cast<QColor>(currentItemData(fillColor2ComboBox));
+
+ for(QList<RenderArea*>::iterator it = renderAreas.begin(); it != renderAreas.end(); it++)
+ (*it)->setFillGradient(color1, color2);
+}
+//! [20]
+
+//! [21]
+void Window::penColorChanged()
+{
+ QColor color = qvariant_cast<QColor>(currentItemData(penColorComboBox));
+
+ for(QList<RenderArea*>::iterator it = renderAreas.begin(); it != renderAreas.end(); it++)
+ (*it)->setPenColor(color);
+}
+//! [21]
+
+//! [22]
+void Window::populateWithColors(QComboBox *comboBox)
+{
+ QStringList colorNames = QColor::colorNames();
+ foreach (QString name, colorNames)
+ comboBox->addItem(name, QColor(name));
+}
+//! [22]
+
+//! [23]
+QVariant Window::currentItemData(QComboBox *comboBox)
+{
+ return comboBox->itemData(comboBox->currentIndex());
+}
+//! [23]
diff --git a/examples/widgets/painting/painterpaths/window.h b/examples/widgets/painting/painterpaths/window.h
new file mode 100644
index 0000000000..4c01719b16
--- /dev/null
+++ b/examples/widgets/painting/painterpaths/window.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WINDOW_H
+#define WINDOW_H
+
+#include <QWidget>
+
+QT_BEGIN_NAMESPACE
+class QComboBox;
+class QLabel;
+class QSpinBox;
+QT_END_NAMESPACE
+class RenderArea;
+
+//! [0]
+class Window : public QWidget
+{
+ Q_OBJECT
+
+public:
+ Window();
+
+private slots:
+ void fillRuleChanged();
+ void fillGradientChanged();
+ void penColorChanged();
+//! [0]
+
+//! [1]
+private:
+ void populateWithColors(QComboBox *comboBox);
+ QVariant currentItemData(QComboBox *comboBox);
+//! [1]
+
+//! [2]
+ QList<RenderArea*> renderAreas;
+ QLabel *fillRuleLabel;
+ QLabel *fillGradientLabel;
+ QLabel *fillToLabel;
+ QLabel *penWidthLabel;
+ QLabel *penColorLabel;
+ QLabel *rotationAngleLabel;
+ QComboBox *fillRuleComboBox;
+ QComboBox *fillColor1ComboBox;
+ QComboBox *fillColor2ComboBox;
+ QSpinBox *penWidthSpinBox;
+ QComboBox *penColorComboBox;
+ QSpinBox *rotationAngleSpinBox;
+};
+//! [2]
+
+#endif
diff --git a/examples/widgets/painting/painting.pro b/examples/widgets/painting/painting.pro
new file mode 100644
index 0000000000..927d94006b
--- /dev/null
+++ b/examples/widgets/painting/painting.pro
@@ -0,0 +1,36 @@
+TEMPLATE = subdirs
+SUBDIRS = basicdrawing \
+ concentriccircles \
+ examples_affine \
+ examples_composition \
+ examples_deform \
+ examples_gradients \
+ examples_pathstroke \
+ painting_shared \
+ imagecomposition \
+ painterpaths \
+ transformations \
+ fontsampler
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/painting
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS painting.pro README
+sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/painting
+INSTALLS += target sources
+
+QT += widgets
+
+examples_affine.subdir = affine
+examples_composition.subdir = composition
+examples_deform.subdir = deform
+examples_gradients.subdir = gradients
+examples_pathstroke.subdir = pathstroke
+painting_shared.subdir = shared
+
+!ordered {
+ examples_affine.depends = painting_shared
+ examples_deform.depends = painting_shared
+ examples_gradients.depends = painting_shared
+ examples_composition.depends = painting_shared
+ examples_pathstroke.depends = painting_shared
+}
diff --git a/examples/widgets/painting/pathstroke/main.cpp b/examples/widgets/painting/pathstroke/main.cpp
new file mode 100644
index 0000000000..c969d975a3
--- /dev/null
+++ b/examples/widgets/painting/pathstroke/main.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** 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 "pathstroke.h"
+#include <QApplication>
+
+int main(int argc, char **argv)
+{
+ Q_INIT_RESOURCE(pathstroke);
+
+ QApplication app(argc, argv);
+
+ bool smallScreen = QApplication::arguments().contains("-small-screen");
+
+ PathStrokeWidget pathStrokeWidget(smallScreen);
+ QStyle *arthurStyle = new ArthurStyle();
+ pathStrokeWidget.setStyle(arthurStyle);
+ QList<QWidget *> widgets = pathStrokeWidget.findChildren<QWidget *>();
+ foreach (QWidget *w, widgets) {
+ w->setStyle(arthurStyle);
+ w->setAttribute(Qt::WA_AcceptTouchEvents);
+ }
+
+ if (smallScreen)
+ pathStrokeWidget.showFullScreen();
+ else
+ pathStrokeWidget.show();
+
+#ifdef QT_KEYPAD_NAVIGATION
+ QApplication::setNavigationMode(Qt::NavigationModeCursorAuto);
+#endif
+ return app.exec();
+}
diff --git a/examples/widgets/painting/pathstroke/pathstroke.cpp b/examples/widgets/painting/pathstroke/pathstroke.cpp
new file mode 100644
index 0000000000..76495cafea
--- /dev/null
+++ b/examples/widgets/painting/pathstroke/pathstroke.cpp
@@ -0,0 +1,685 @@
+/****************************************************************************
+**
+** 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 "pathstroke.h"
+#include "arthurstyle.h"
+#include "arthurwidgets.h"
+
+#include <stdio.h>
+
+extern void draw_round_rect(QPainter *p, const QRect &bounds, int radius);
+
+
+PathStrokeControls::PathStrokeControls(QWidget* parent, PathStrokeRenderer* renderer, bool smallScreen)
+ : QWidget(parent)
+{
+ m_renderer = renderer;
+
+ if (smallScreen)
+ layoutForSmallScreens();
+ else
+ layoutForDesktop();
+}
+
+void PathStrokeControls::createCommonControls(QWidget* parent)
+{
+ m_capGroup = new QGroupBox(parent);
+ m_capGroup->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
+ QRadioButton *flatCap = new QRadioButton(m_capGroup);
+ QRadioButton *squareCap = new QRadioButton(m_capGroup);
+ QRadioButton *roundCap = new QRadioButton(m_capGroup);
+ m_capGroup->setTitle(tr("Cap Style"));
+ flatCap->setText(tr("Flat"));
+ squareCap->setText(tr("Square"));
+ roundCap->setText(tr("Round"));
+ flatCap->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ squareCap->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ roundCap->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+
+ m_joinGroup = new QGroupBox(parent);
+ m_joinGroup->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
+ QRadioButton *bevelJoin = new QRadioButton(m_joinGroup);
+ QRadioButton *miterJoin = new QRadioButton(m_joinGroup);
+ QRadioButton *roundJoin = new QRadioButton(m_joinGroup);
+ m_joinGroup->setTitle(tr("Join Style"));
+ bevelJoin->setText(tr("Bevel"));
+ miterJoin->setText(tr("Miter"));
+ roundJoin->setText(tr("Round"));
+
+ m_styleGroup = new QGroupBox(parent);
+ m_styleGroup->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
+ QRadioButton *solidLine = new QRadioButton(m_styleGroup);
+ QRadioButton *dashLine = new QRadioButton(m_styleGroup);
+ QRadioButton *dotLine = new QRadioButton(m_styleGroup);
+ QRadioButton *dashDotLine = new QRadioButton(m_styleGroup);
+ QRadioButton *dashDotDotLine = new QRadioButton(m_styleGroup);
+ QRadioButton *customDashLine = new QRadioButton(m_styleGroup);
+ m_styleGroup->setTitle(tr("Pen Style"));
+
+ QPixmap line_solid(":res/images/line_solid.png");
+ solidLine->setIcon(line_solid);
+ solidLine->setIconSize(line_solid.size());
+ QPixmap line_dashed(":res/images/line_dashed.png");
+ dashLine->setIcon(line_dashed);
+ dashLine->setIconSize(line_dashed.size());
+ QPixmap line_dotted(":res/images/line_dotted.png");
+ dotLine->setIcon(line_dotted);
+ dotLine->setIconSize(line_dotted.size());
+ QPixmap line_dash_dot(":res/images/line_dash_dot.png");
+ dashDotLine->setIcon(line_dash_dot);
+ dashDotLine->setIconSize(line_dash_dot.size());
+ QPixmap line_dash_dot_dot(":res/images/line_dash_dot_dot.png");
+ dashDotDotLine->setIcon(line_dash_dot_dot);
+ dashDotDotLine->setIconSize(line_dash_dot_dot.size());
+ customDashLine->setText(tr("Custom"));
+
+ int fixedHeight = bevelJoin->sizeHint().height();
+ solidLine->setFixedHeight(fixedHeight);
+ dashLine->setFixedHeight(fixedHeight);
+ dotLine->setFixedHeight(fixedHeight);
+ dashDotLine->setFixedHeight(fixedHeight);
+ dashDotDotLine->setFixedHeight(fixedHeight);
+
+ m_pathModeGroup = new QGroupBox(parent);
+ m_pathModeGroup->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
+ QRadioButton *curveMode = new QRadioButton(m_pathModeGroup);
+ QRadioButton *lineMode = new QRadioButton(m_pathModeGroup);
+ m_pathModeGroup->setTitle(tr("Line Style"));
+ curveMode->setText(tr("Curves"));
+ lineMode->setText(tr("Lines"));
+
+
+ // Layouts
+ QVBoxLayout *capGroupLayout = new QVBoxLayout(m_capGroup);
+ capGroupLayout->addWidget(flatCap);
+ capGroupLayout->addWidget(squareCap);
+ capGroupLayout->addWidget(roundCap);
+
+ QVBoxLayout *joinGroupLayout = new QVBoxLayout(m_joinGroup);
+ joinGroupLayout->addWidget(bevelJoin);
+ joinGroupLayout->addWidget(miterJoin);
+ joinGroupLayout->addWidget(roundJoin);
+
+ QVBoxLayout *styleGroupLayout = new QVBoxLayout(m_styleGroup);
+ styleGroupLayout->addWidget(solidLine);
+ styleGroupLayout->addWidget(dashLine);
+ styleGroupLayout->addWidget(dotLine);
+ styleGroupLayout->addWidget(dashDotLine);
+ styleGroupLayout->addWidget(dashDotDotLine);
+ styleGroupLayout->addWidget(customDashLine);
+
+ QVBoxLayout *pathModeGroupLayout = new QVBoxLayout(m_pathModeGroup);
+ pathModeGroupLayout->addWidget(curveMode);
+ pathModeGroupLayout->addWidget(lineMode);
+
+
+ // Connections
+ connect(flatCap, SIGNAL(clicked()), m_renderer, SLOT(setFlatCap()));
+ connect(squareCap, SIGNAL(clicked()), m_renderer, SLOT(setSquareCap()));
+ connect(roundCap, SIGNAL(clicked()), m_renderer, SLOT(setRoundCap()));
+
+ connect(bevelJoin, SIGNAL(clicked()), m_renderer, SLOT(setBevelJoin()));
+ connect(miterJoin, SIGNAL(clicked()), m_renderer, SLOT(setMiterJoin()));
+ connect(roundJoin, SIGNAL(clicked()), m_renderer, SLOT(setRoundJoin()));
+
+ connect(curveMode, SIGNAL(clicked()), m_renderer, SLOT(setCurveMode()));
+ connect(lineMode, SIGNAL(clicked()), m_renderer, SLOT(setLineMode()));
+
+ connect(solidLine, SIGNAL(clicked()), m_renderer, SLOT(setSolidLine()));
+ connect(dashLine, SIGNAL(clicked()), m_renderer, SLOT(setDashLine()));
+ connect(dotLine, SIGNAL(clicked()), m_renderer, SLOT(setDotLine()));
+ connect(dashDotLine, SIGNAL(clicked()), m_renderer, SLOT(setDashDotLine()));
+ connect(dashDotDotLine, SIGNAL(clicked()), m_renderer, SLOT(setDashDotDotLine()));
+ connect(customDashLine, SIGNAL(clicked()), m_renderer, SLOT(setCustomDashLine()));
+
+ // Set the defaults:
+ flatCap->setChecked(true);
+ bevelJoin->setChecked(true);
+ curveMode->setChecked(true);
+ solidLine->setChecked(true);
+}
+
+
+void PathStrokeControls::layoutForDesktop()
+{
+ QGroupBox *mainGroup = new QGroupBox(this);
+ mainGroup->setFixedWidth(180);
+ mainGroup->setTitle(tr("Path Stroking"));
+
+ createCommonControls(mainGroup);
+
+ QGroupBox* penWidthGroup = new QGroupBox(mainGroup);
+ QSlider *penWidth = new QSlider(Qt::Horizontal, penWidthGroup);
+ penWidth->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ penWidthGroup->setTitle(tr("Pen Width"));
+ penWidth->setRange(0, 500);
+
+ QPushButton *animated = new QPushButton(mainGroup);
+ animated->setText(tr("Animate"));
+ animated->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);
+
+
+ // Layouts:
+ QVBoxLayout *penWidthLayout = new QVBoxLayout(penWidthGroup);
+ penWidthLayout->addWidget(penWidth);
+
+ QVBoxLayout * mainLayout = new QVBoxLayout(this);
+ mainLayout->setMargin(0);
+ mainLayout->addWidget(mainGroup);
+
+ QVBoxLayout *mainGroupLayout = new QVBoxLayout(mainGroup);
+ mainGroupLayout->setMargin(3);
+ mainGroupLayout->addWidget(m_capGroup);
+ mainGroupLayout->addWidget(m_joinGroup);
+ mainGroupLayout->addWidget(m_styleGroup);
+ mainGroupLayout->addWidget(penWidthGroup);
+ mainGroupLayout->addWidget(m_pathModeGroup);
+ mainGroupLayout->addWidget(animated);
+ mainGroupLayout->addStretch(1);
+ mainGroupLayout->addWidget(showSourceButton);
+#ifdef QT_OPENGL_SUPPORT
+ mainGroupLayout->addWidget(enableOpenGLButton);
+#endif
+ mainGroupLayout->addWidget(whatsThisButton);
+
+
+ // Set up connections
+ connect(animated, SIGNAL(toggled(bool)),
+ m_renderer, SLOT(setAnimation(bool)));
+
+ connect(penWidth, SIGNAL(valueChanged(int)),
+ m_renderer, SLOT(setPenWidth(int)));
+
+ connect(showSourceButton, SIGNAL(clicked()), m_renderer, SLOT(showSource()));
+#ifdef QT_OPENGL_SUPPORT
+ connect(enableOpenGLButton, SIGNAL(clicked(bool)), m_renderer, SLOT(enableOpenGL(bool)));
+#endif
+ connect(whatsThisButton, SIGNAL(clicked(bool)), m_renderer, SLOT(setDescriptionEnabled(bool)));
+ connect(m_renderer, SIGNAL(descriptionEnabledChanged(bool)),
+ whatsThisButton, SLOT(setChecked(bool)));
+
+
+ // Set the defaults
+ animated->setChecked(true);
+ penWidth->setValue(50);
+
+}
+
+void PathStrokeControls::layoutForSmallScreens()
+{
+ createCommonControls(this);
+
+ m_capGroup->layout()->setMargin(0);
+ m_joinGroup->layout()->setMargin(0);
+ m_styleGroup->layout()->setMargin(0);
+ m_pathModeGroup->layout()->setMargin(0);
+
+ QPushButton* okBtn = new QPushButton(tr("OK"), this);
+ okBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ okBtn->setMinimumSize(100,okBtn->minimumSize().height());
+
+ QPushButton* quitBtn = new QPushButton(tr("Quit"), this);
+ quitBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ quitBtn->setMinimumSize(100, okBtn->minimumSize().height());
+
+ QLabel *penWidthLabel = new QLabel(tr(" Width:"));
+ QSlider *penWidth = new QSlider(Qt::Horizontal, this);
+ penWidth->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ penWidth->setRange(0, 500);
+
+#ifdef QT_OPENGL_SUPPORT
+ QPushButton *enableOpenGLButton = new QPushButton(this);
+ enableOpenGLButton->setText(tr("Use OpenGL"));
+ enableOpenGLButton->setCheckable(true);
+ enableOpenGLButton->setChecked(m_renderer->usesOpenGL());
+ if (!QGLFormat::hasOpenGL())
+ enableOpenGLButton->hide();
+#endif
+
+ // Layouts:
+ QHBoxLayout *penWidthLayout = new QHBoxLayout(0);
+ penWidthLayout->addWidget(penWidthLabel, 0, Qt::AlignRight);
+ penWidthLayout->addWidget(penWidth);
+
+ QVBoxLayout *leftLayout = new QVBoxLayout(0);
+ leftLayout->addWidget(m_capGroup);
+ leftLayout->addWidget(m_joinGroup);
+#ifdef QT_OPENGL_SUPPORT
+ leftLayout->addWidget(enableOpenGLButton);
+#endif
+ leftLayout->addLayout(penWidthLayout);
+
+ QVBoxLayout *rightLayout = new QVBoxLayout(0);
+ rightLayout->addWidget(m_styleGroup);
+ rightLayout->addWidget(m_pathModeGroup);
+
+ QGridLayout *mainLayout = new QGridLayout(this);
+ mainLayout->setMargin(0);
+
+ // Add spacers around the form items so we don't look stupid at higher resolutions
+ mainLayout->addItem(new QSpacerItem(0,0), 0, 0, 1, 4);
+ mainLayout->addItem(new QSpacerItem(0,0), 1, 0, 2, 1);
+ mainLayout->addItem(new QSpacerItem(0,0), 1, 3, 2, 1);
+ mainLayout->addItem(new QSpacerItem(0,0), 3, 0, 1, 4);
+
+ mainLayout->addLayout(leftLayout, 1, 1);
+ mainLayout->addLayout(rightLayout, 1, 2);
+ mainLayout->addWidget(quitBtn, 2, 1, Qt::AlignHCenter | Qt::AlignTop);
+ mainLayout->addWidget(okBtn, 2, 2, Qt::AlignHCenter | Qt::AlignTop);
+
+#ifdef QT_OPENGL_SUPPORT
+ connect(enableOpenGLButton, SIGNAL(clicked(bool)), m_renderer, SLOT(enableOpenGL(bool)));
+#endif
+
+ connect(penWidth, SIGNAL(valueChanged(int)), m_renderer, SLOT(setPenWidth(int)));
+ connect(quitBtn, SIGNAL(clicked()), this, SLOT(emitQuitSignal()));
+ connect(okBtn, SIGNAL(clicked()), this, SLOT(emitOkSignal()));
+
+ m_renderer->setAnimation(true);
+ penWidth->setValue(50);
+}
+
+void PathStrokeControls::emitQuitSignal()
+{ emit quitPressed(); }
+
+void PathStrokeControls::emitOkSignal()
+{ emit okPressed(); }
+
+
+PathStrokeWidget::PathStrokeWidget(bool smallScreen)
+{
+ setWindowTitle(tr("Path Stroking"));
+
+ // Widget construction and property setting
+ m_renderer = new PathStrokeRenderer(this, smallScreen);
+
+ m_controls = new PathStrokeControls(0, m_renderer, smallScreen);
+
+ // Layouting
+ QHBoxLayout *viewLayout = new QHBoxLayout(this);
+ viewLayout->addWidget(m_renderer);
+
+ if (!smallScreen)
+ viewLayout->addWidget(m_controls);
+
+ m_renderer->loadSourceFile(":res/pathstroke/pathstroke.cpp");
+ m_renderer->loadDescription(":res/pathstroke/pathstroke.html");
+
+ 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 PathStrokeWidget::showControls()
+{
+ m_controls->showFullScreen();
+}
+
+
+void PathStrokeWidget::hideControls()
+{
+ m_controls->hide();
+}
+
+
+void PathStrokeWidget::setStyle( QStyle * style )
+{
+ QWidget::setStyle(style);
+ if (m_controls != 0)
+ {
+ m_controls->setStyle(style);
+
+ QList<QWidget *> widgets = m_controls->findChildren<QWidget *>();
+ foreach (QWidget *w, widgets)
+ w->setStyle(style);
+ }
+}
+
+
+PathStrokeRenderer::PathStrokeRenderer(QWidget *parent, bool smallScreen)
+ : ArthurFrame(parent)
+{
+ m_smallScreen = smallScreen;
+ m_pointSize = 10;
+ m_activePoint = -1;
+ m_capStyle = Qt::FlatCap;
+ m_joinStyle = Qt::BevelJoin;
+ m_pathMode = CurveMode;
+ m_penWidth = 1;
+ m_penStyle = Qt::SolidLine;
+ m_wasAnimated = true;
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ setAttribute(Qt::WA_AcceptTouchEvents);
+}
+
+void PathStrokeRenderer::paint(QPainter *painter)
+{
+ if (m_points.isEmpty())
+ initializePoints();
+
+ painter->setRenderHint(QPainter::Antialiasing);
+
+ QPalette pal = palette();
+ painter->setPen(Qt::NoPen);
+
+ // Construct the path
+ QPainterPath path;
+ path.moveTo(m_points.at(0));
+
+ if (m_pathMode == LineMode) {
+ for (int i=1; i<m_points.size(); ++i) {
+ path.lineTo(m_points.at(i));
+ }
+ } else {
+ int i=1;
+ while (i + 2 < m_points.size()) {
+ path.cubicTo(m_points.at(i), m_points.at(i+1), m_points.at(i+2));
+ i += 3;
+ }
+ while (i < m_points.size()) {
+ path.lineTo(m_points.at(i));
+ ++i;
+ }
+ }
+
+ // Draw the path
+ {
+ QColor lg = Qt::red;
+
+ // The "custom" pen
+ if (m_penStyle == Qt::NoPen) {
+ QPainterPathStroker stroker;
+ stroker.setWidth(m_penWidth);
+ stroker.setJoinStyle(m_joinStyle);
+ stroker.setCapStyle(m_capStyle);
+
+ QVector<qreal> dashes;
+ qreal space = 4;
+ dashes << 1 << space
+ << 3 << space
+ << 9 << space
+ << 27 << space
+ << 9 << space
+ << 3 << space;
+ stroker.setDashPattern(dashes);
+ QPainterPath stroke = stroker.createStroke(path);
+ painter->fillPath(stroke, lg);
+
+ } else {
+ QPen pen(lg, m_penWidth, m_penStyle, m_capStyle, m_joinStyle);
+ painter->strokePath(path, pen);
+ }
+ }
+
+ if (1) {
+ // Draw the control points
+ painter->setPen(QColor(50, 100, 120, 200));
+ painter->setBrush(QColor(200, 200, 210, 120));
+ for (int i=0; i<m_points.size(); ++i) {
+ QPointF pos = m_points.at(i);
+ painter->drawEllipse(QRectF(pos.x() - m_pointSize,
+ pos.y() - m_pointSize,
+ m_pointSize*2, m_pointSize*2));
+ }
+ painter->setPen(QPen(Qt::lightGray, 0, Qt::SolidLine));
+ painter->setBrush(Qt::NoBrush);
+ painter->drawPolyline(m_points);
+ }
+
+}
+
+void PathStrokeRenderer::initializePoints()
+{
+ const int count = 7;
+ m_points.clear();
+ m_vectors.clear();
+
+ QMatrix m;
+ qreal rot = 360 / count;
+ QPointF center(width() / 2, height() / 2);
+ QMatrix vm;
+ vm.shear(2, -1);
+ vm.scale(3, 3);
+
+ for (int i=0; i<count; ++i) {
+ m_vectors << QPointF(.1f, .25f) * (m * vm);
+ m_points << QPointF(0, 100) * m + center;
+ m.rotate(rot);
+ }
+}
+
+void PathStrokeRenderer::updatePoints()
+{
+ qreal pad = 10;
+ qreal left = pad;
+ qreal right = width() - pad;
+ qreal top = pad;
+ qreal bottom = height() - pad;
+
+ Q_ASSERT(m_points.size() == m_vectors.size());
+ for (int i=0; i<m_points.size(); ++i) {
+ QPointF pos = m_points.at(i);
+ QPointF vec = m_vectors.at(i);
+ pos += vec;
+ if (pos.x() < left || pos.x() > right) {
+ vec.setX(-vec.x());
+ pos.setX(pos.x() < left ? left : right);
+ } if (pos.y() < top || pos.y() > bottom) {
+ vec.setY(-vec.y());
+ pos.setY(pos.y() < top ? top : bottom);
+ }
+ m_points[i] = pos;
+ m_vectors[i] = vec;
+ }
+ update();
+}
+
+void PathStrokeRenderer::mousePressEvent(QMouseEvent *e)
+{
+ if (!m_fingerPointMapping.isEmpty())
+ return;
+ setDescriptionEnabled(false);
+ m_activePoint = -1;
+ qreal distance = -1;
+ for (int i=0; i<m_points.size(); ++i) {
+ qreal d = QLineF(e->pos(), m_points.at(i)).length();
+ if ((distance < 0 && d < 8 * m_pointSize) || d < distance) {
+ distance = d;
+ m_activePoint = i;
+ }
+ }
+
+ if (m_activePoint != -1) {
+ m_wasAnimated = m_timer.isActive();
+ setAnimation(false);
+ mouseMoveEvent(e);
+ }
+
+ // If we're not running in small screen mode, always assume we're dragging
+ m_mouseDrag = !m_smallScreen;
+ m_mousePress = e->pos();
+}
+
+void PathStrokeRenderer::mouseMoveEvent(QMouseEvent *e)
+{
+ if (!m_fingerPointMapping.isEmpty())
+ return;
+ // If we've moved more then 25 pixels, assume user is dragging
+ if (!m_mouseDrag && QPoint(m_mousePress - e->pos()).manhattanLength() > 25)
+ m_mouseDrag = true;
+
+ if (m_mouseDrag && m_activePoint >= 0 && m_activePoint < m_points.size()) {
+ m_points[m_activePoint] = e->pos();
+ update();
+ }
+}
+
+void PathStrokeRenderer::mouseReleaseEvent(QMouseEvent *)
+{
+ if (!m_fingerPointMapping.isEmpty())
+ return;
+ m_activePoint = -1;
+ setAnimation(m_wasAnimated);
+
+ if (!m_mouseDrag && m_smallScreen)
+ emit clicked();
+}
+
+void PathStrokeRenderer::timerEvent(QTimerEvent *e)
+{
+ if (e->timerId() == m_timer.timerId()) {
+ updatePoints();
+ } // else if (e->timerId() == m_fpsTimer.timerId()) {
+// emit frameRate(m_frameCount);
+// m_frameCount = 0;
+// }
+}
+
+bool PathStrokeRenderer::event(QEvent *e)
+{
+ bool touchBegin = false;
+ switch (e->type()) {
+ case QEvent::TouchBegin:
+ touchBegin = true;
+ case QEvent::TouchUpdate:
+ {
+ const QTouchEvent *const event = static_cast<const QTouchEvent*>(e);
+ const QList<QTouchEvent::TouchPoint> points = event->touchPoints();
+ foreach (const QTouchEvent::TouchPoint &touchPoint, points) {
+ const int id = touchPoint.id();
+ switch (touchPoint.state()) {
+ case Qt::TouchPointPressed:
+ {
+ // find the point, move it
+ QSet<int> activePoints = QSet<int>::fromList(m_fingerPointMapping.values());
+ int activePoint = -1;
+ qreal distance = -1;
+ const int pointsCount = m_points.size();
+ for (int i=0; i<pointsCount; ++i) {
+ if (activePoints.contains(i))
+ continue;
+
+ qreal d = QLineF(touchPoint.pos(), m_points.at(i)).length();
+ if ((distance < 0 && d < 12 * m_pointSize) || d < distance) {
+ distance = d;
+ activePoint = i;
+ }
+ }
+ if (activePoint != -1) {
+ m_fingerPointMapping.insert(touchPoint.id(), activePoint);
+ m_points[activePoint] = touchPoint.pos();
+ }
+ }
+ break;
+ case Qt::TouchPointReleased:
+ {
+ // move the point and release
+ QHash<int,int>::iterator it = m_fingerPointMapping.find(id);
+ m_points[it.value()] = touchPoint.pos();
+ m_fingerPointMapping.erase(it);
+ }
+ break;
+ case Qt::TouchPointMoved:
+ {
+ // move the point
+ const int pointIdx = m_fingerPointMapping.value(id, -1);
+ if (pointIdx >= 0)
+ m_points[pointIdx] = touchPoint.pos();
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (m_fingerPointMapping.isEmpty()) {
+ e->ignore();
+ return false;
+ } else {
+ if (touchBegin) {
+ m_wasAnimated = m_timer.isActive();
+ setAnimation(false);
+ }
+ update();
+ return true;
+ }
+ }
+ break;
+ case QEvent::TouchEnd:
+ if (m_fingerPointMapping.isEmpty()) {
+ e->ignore();
+ return false;
+ }
+ m_fingerPointMapping.clear();
+ setAnimation(m_wasAnimated);
+ return true;
+ break;
+ default:
+ break;
+ }
+ return QWidget::event(e);
+}
+
+void PathStrokeRenderer::setAnimation(bool animation)
+{
+ m_timer.stop();
+// m_fpsTimer.stop();
+
+ if (animation) {
+ m_timer.start(25, this);
+// m_fpsTimer.start(1000, this);
+// m_frameCount = 0;
+ }
+}
diff --git a/examples/widgets/painting/pathstroke/pathstroke.h b/examples/widgets/painting/pathstroke/pathstroke.h
new file mode 100644
index 0000000000..743a757b0a
--- /dev/null
+++ b/examples/widgets/painting/pathstroke/pathstroke.h
@@ -0,0 +1,171 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef PATHSTROKE_H
+#define PATHSTROKE_H
+
+#include "arthurwidgets.h"
+#include <QtWidgets>
+
+class PathStrokeRenderer : public ArthurFrame
+{
+ Q_OBJECT
+ Q_PROPERTY(bool animation READ animation WRITE setAnimation)
+ Q_PROPERTY(qreal penWidth READ realPenWidth WRITE setRealPenWidth)
+public:
+ enum PathMode { CurveMode, LineMode };
+
+ PathStrokeRenderer(QWidget *parent, bool smallScreen = false);
+
+ void paint(QPainter *);
+ void mousePressEvent(QMouseEvent *e);
+ void mouseMoveEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+ void timerEvent(QTimerEvent *e);
+ bool event(QEvent *e);
+
+ QSize sizeHint() const { return QSize(500, 500); }
+
+ bool animation() const { return m_timer.isActive(); }
+
+ qreal realPenWidth() const { return m_penWidth; }
+ void setRealPenWidth(qreal penWidth) { m_penWidth = penWidth; update(); }
+
+signals:
+ void clicked();
+
+public slots:
+ void setPenWidth(int penWidth) { m_penWidth = penWidth / 10.0; update(); }
+ void setAnimation(bool animation);
+
+ void setFlatCap() { m_capStyle = Qt::FlatCap; update(); }
+ void setSquareCap() { m_capStyle = Qt::SquareCap; update(); }
+ void setRoundCap() { m_capStyle = Qt::RoundCap; update(); }
+
+ void setBevelJoin() { m_joinStyle = Qt::BevelJoin; update(); }
+ void setMiterJoin() { m_joinStyle = Qt::MiterJoin; update(); }
+ void setRoundJoin() { m_joinStyle = Qt::RoundJoin; update(); }
+
+ void setCurveMode() { m_pathMode = CurveMode; update(); }
+ void setLineMode() { m_pathMode = LineMode; update(); }
+
+ void setSolidLine() { m_penStyle = Qt::SolidLine; update(); }
+ void setDashLine() { m_penStyle = Qt::DashLine; update(); }
+ void setDotLine() { m_penStyle = Qt::DotLine; update(); }
+ void setDashDotLine() { m_penStyle = Qt::DashDotLine; update(); }
+ void setDashDotDotLine() { m_penStyle = Qt::DashDotDotLine; update(); }
+ void setCustomDashLine() { m_penStyle = Qt::NoPen; update(); }
+
+private:
+ void initializePoints();
+ void updatePoints();
+
+ QBasicTimer m_timer;
+
+ PathMode m_pathMode;
+
+ bool m_wasAnimated;
+
+ qreal m_penWidth;
+ int m_pointCount;
+ int m_pointSize;
+ int m_activePoint;
+ QVector<QPointF> m_points;
+ QVector<QPointF> m_vectors;
+
+ Qt::PenJoinStyle m_joinStyle;
+ Qt::PenCapStyle m_capStyle;
+
+ Qt::PenStyle m_penStyle;
+
+ bool m_smallScreen;
+ QPoint m_mousePress;
+ bool m_mouseDrag;
+
+ QHash<int, int> m_fingerPointMapping;
+};
+
+class PathStrokeControls : public QWidget
+{
+ Q_OBJECT
+public:
+ PathStrokeControls(QWidget* parent, PathStrokeRenderer* renderer, bool smallScreen);
+
+signals:
+ void okPressed();
+ void quitPressed();
+
+private:
+ PathStrokeRenderer* m_renderer;
+
+ QGroupBox *m_capGroup;
+ QGroupBox *m_joinGroup;
+ QGroupBox *m_styleGroup;
+ QGroupBox *m_pathModeGroup;
+
+ void createCommonControls(QWidget* parent);
+ void layoutForDesktop();
+ void layoutForSmallScreens();
+
+private slots:
+ void emitQuitSignal();
+ void emitOkSignal();
+
+};
+
+class PathStrokeWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ PathStrokeWidget(bool smallScreen);
+ void setStyle ( QStyle * style );
+
+private:
+ PathStrokeRenderer *m_renderer;
+ PathStrokeControls *m_controls;
+
+private slots:
+ void showControls();
+ void hideControls();
+
+};
+
+#endif // PATHSTROKE_H
diff --git a/examples/widgets/painting/pathstroke/pathstroke.html b/examples/widgets/painting/pathstroke/pathstroke.html
new file mode 100644
index 0000000000..9e7e50de76
--- /dev/null
+++ b/examples/widgets/painting/pathstroke/pathstroke.html
@@ -0,0 +1,20 @@
+<html>
+<center>
+<h2>Primitive Stroking</h2>
+</center>
+
+<p>In this demo we show some of the various types of pens that can be
+used in Qt.</p>
+
+<p>Qt defines cap styles for how the end points are treated and join
+styles for how path segments are joined together. A standard set of
+predefined dash patterns are also included that can be used with
+<code>QPen</code>.</p>
+
+<p>In addition to the predefined patterns available in
+<code>QPen</code> we also demonstrate direct use of the
+<code>QPainterPathStroker</code> class which can be used to define
+custom dash patterns. You can see this by enabling the
+<i>Custom Pattern</i> option.</p>
+
+</html>
diff --git a/examples/widgets/painting/pathstroke/pathstroke.pro b/examples/widgets/painting/pathstroke/pathstroke.pro
new file mode 100644
index 0000000000..916866d1f2
--- /dev/null
+++ b/examples/widgets/painting/pathstroke/pathstroke.pro
@@ -0,0 +1,21 @@
+SOURCES += main.cpp pathstroke.cpp
+HEADERS += pathstroke.h
+
+SHARED_FOLDER = ../shared
+
+include($$SHARED_FOLDER/shared.pri)
+
+RESOURCES += pathstroke.qrc
+
+contains(QT_CONFIG, opengl) {
+ DEFINES += QT_OPENGL_SUPPORT
+ QT += opengl
+}
+QT += widgets
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/painting/pathstroke
+sources.files = $$SOURCES $$HEADERS $$RESOURCES *.pro *.html
+sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/painting/pathstroke
+INSTALLS += target sources
+
diff --git a/examples/widgets/painting/pathstroke/pathstroke.qrc b/examples/widgets/painting/pathstroke/pathstroke.qrc
new file mode 100644
index 0000000000..a9a723409e
--- /dev/null
+++ b/examples/widgets/painting/pathstroke/pathstroke.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/res/pathstroke">
+ <file>pathstroke.cpp</file>
+ <file>pathstroke.html</file>
+</qresource>
+</RCC>
diff --git a/examples/widgets/painting/shared/arthurstyle.cpp b/examples/widgets/painting/shared/arthurstyle.cpp
new file mode 100644
index 0000000000..4bd34464bf
--- /dev/null
+++ b/examples/widgets/painting/shared/arthurstyle.cpp
@@ -0,0 +1,452 @@
+/****************************************************************************
+**
+** 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 "arthurstyle.h"
+#include "arthurwidgets.h"
+#include <QLayout>
+#include <QPainter>
+#include <QPainterPath>
+#include <QPixmapCache>
+#include <QRadioButton>
+#include <QString>
+#include <QStyleOption>
+#include <QtDebug>
+
+QPixmap cached(const QString &img)
+{
+ if (QPixmap *p = QPixmapCache::find(img))
+ return *p;
+
+ QPixmap pm;
+ pm = QPixmap::fromImage(QImage(img), Qt::OrderedDither | Qt::OrderedAlphaDither);
+ if (pm.isNull())
+ return QPixmap();
+
+ QPixmapCache::insert(img, pm);
+ return pm;
+}
+
+
+ArthurStyle::ArthurStyle()
+ : QWindowsStyle()
+{
+ Q_INIT_RESOURCE(shared);
+}
+
+
+void ArthurStyle::drawHoverRect(QPainter *painter, const QRect &r) const
+{
+ qreal h = r.height();
+ qreal h2 = r.height() / qreal(2);
+ QPainterPath path;
+ path.addRect(r.x() + h2, r.y() + 0, r.width() - h2 * 2, r.height());
+ path.addEllipse(r.x(), r.y(), h, h);
+ path.addEllipse(r.x() + r.width() - h, r.y(), h, h);
+ path.setFillRule(Qt::WindingFill);
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(QColor(191, 215, 191));
+ painter->setRenderHint(QPainter::Antialiasing);
+ painter->drawPath(path);
+}
+
+
+void ArthurStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const
+{
+
+ Q_ASSERT(option);
+ switch (element) {
+ case PE_FrameFocusRect:
+ break;
+
+ case PE_IndicatorRadioButton:
+ if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ bool hover = (button->state & State_Enabled) && (button->state & State_MouseOver);
+ painter->save();
+ QPixmap radio;
+ if (hover)
+ drawHoverRect(painter, widget->rect());
+
+ if (button->state & State_Sunken)
+ radio = cached(":res/images/radiobutton-on.png");
+ else if (button->state & State_On)
+ radio = cached(":res/images/radiobutton_on.png");
+ else
+ radio = cached(":res/images/radiobutton_off.png");
+ painter->drawPixmap(button->rect.topLeft(), radio);
+
+ painter->restore();
+ }
+ break;
+
+ case PE_PanelButtonCommand:
+ if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ bool hover = (button->state & State_Enabled) && (button->state & State_MouseOver);
+
+ painter->save();
+ const QPushButton *pushButton = qobject_cast<const QPushButton *>(widget);
+ Q_ASSERT(pushButton);
+ QWidget *parent = pushButton->parentWidget();
+ if (parent && qobject_cast<QGroupBox *>(parent)) {
+ QLinearGradient lg(0, 0, 0, parent->height());
+ lg.setColorAt(0, QColor(224,224,224));
+ lg.setColorAt(1, QColor(255,255,255));
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(lg);
+ painter->setBrushOrigin(-widget->mapToParent(QPoint(0,0)));
+ painter->drawRect(button->rect);
+ painter->setBrushOrigin(0,0);
+ }
+
+ bool down = (button->state & State_Sunken) || (button->state & State_On);
+
+ QPixmap left, right, mid;
+ if (down) {
+ left = cached(":res/images/button_pressed_cap_left.png");
+ right = cached(":res/images/button_pressed_cap_right.png");
+ mid = cached(":res/images/button_pressed_stretch.png");
+ } else {
+ left = cached(":res/images/button_normal_cap_left.png");
+ right = cached(":res/images/button_normal_cap_right.png");
+ mid = cached(":res/images/button_normal_stretch.png");
+ }
+ painter->drawPixmap(button->rect.topLeft(), left);
+ painter->drawTiledPixmap(QRect(button->rect.x() + left.width(),
+ button->rect.y(),
+ button->rect.width() - left.width() - right.width(),
+ left.height()),
+ mid);
+ painter->drawPixmap(button->rect.x() + button->rect.width() - right.width(),
+ button->rect.y(),
+ right);
+ if (hover)
+ painter->fillRect(widget->rect().adjusted(3,5,-3,-5), QColor(31,127,31,63));
+ painter->restore();
+ }
+ break;
+
+ case PE_FrameGroupBox:
+ if (const QStyleOptionFrameV2 *group
+ = qstyleoption_cast<const QStyleOptionFrameV2 *>(option)) {
+ const QRect &r = group->rect;
+
+ painter->save();
+ int radius = 14;
+ int radius2 = radius*2;
+ QPainterPath clipPath;
+ clipPath.moveTo(radius, 0);
+ clipPath.arcTo(r.right() - radius2, 0, radius2, radius2, 90, -90);
+ clipPath.arcTo(r.right() - radius2, r.bottom() - radius2, radius2, radius2, 0, -90);
+ clipPath.arcTo(r.left(), r.bottom() - radius2, radius2, radius2, 270, -90);
+ clipPath.arcTo(r.left(), r.top(), radius2, radius2, 180, -90);
+ painter->setClipPath(clipPath);
+ QPixmap titleStretch = cached(":res/images/title_stretch.png");
+ QPixmap topLeft = cached(":res/images/groupframe_topleft.png");
+ QPixmap topRight = cached(":res/images/groupframe_topright.png");
+ QPixmap bottomLeft = cached(":res/images/groupframe_bottom_left.png");
+ QPixmap bottomRight = cached(":res/images/groupframe_bottom_right.png");
+ QPixmap leftStretch = cached(":res/images/groupframe_left_stretch.png");
+ QPixmap topStretch = cached(":res/images/groupframe_top_stretch.png");
+ QPixmap rightStretch = cached(":res/images/groupframe_right_stretch.png");
+ QPixmap bottomStretch = cached(":res/images/groupframe_bottom_stretch.png");
+ QLinearGradient lg(0, 0, 0, r.height());
+ lg.setColorAt(0, QColor(224,224,224));
+ lg.setColorAt(1, QColor(255,255,255));
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(lg);
+ painter->drawRect(r.adjusted(0, titleStretch.height()/2, 0, 0));
+ painter->setClipping(false);
+
+ int topFrameOffset = titleStretch.height()/2 - 2;
+ painter->drawPixmap(r.topLeft() + QPoint(0, topFrameOffset), topLeft);
+ painter->drawPixmap(r.topRight() - QPoint(topRight.width()-1, 0)
+ + QPoint(0, topFrameOffset), topRight);
+ painter->drawPixmap(r.bottomLeft() - QPoint(0, bottomLeft.height()-1), bottomLeft);
+ painter->drawPixmap(r.bottomRight() - QPoint(bottomRight.width()-1,
+ bottomRight.height()-1), bottomRight);
+
+ QRect left = r;
+ left.setY(r.y() + topLeft.height() + topFrameOffset);
+ left.setWidth(leftStretch.width());
+ left.setHeight(r.height() - topLeft.height() - bottomLeft.height() - topFrameOffset);
+ painter->drawTiledPixmap(left, leftStretch);
+
+ QRect top = r;
+ top.setX(r.x() + topLeft.width());
+ top.setY(r.y() + topFrameOffset);
+ top.setWidth(r.width() - topLeft.width() - topRight.width());
+ top.setHeight(topLeft.height());
+ painter->drawTiledPixmap(top, topStretch);
+
+ QRect right = r;
+ right.setX(r.right() - rightStretch.width()+1);
+ right.setY(r.y() + topRight.height() + topFrameOffset);
+ right.setWidth(rightStretch.width());
+ right.setHeight(r.height() - topRight.height()
+ - bottomRight.height() - topFrameOffset);
+ painter->drawTiledPixmap(right, rightStretch);
+
+ QRect bottom = r;
+ bottom.setX(r.x() + bottomLeft.width());
+ bottom.setY(r.bottom() - bottomStretch.height()+1);
+ bottom.setWidth(r.width() - bottomLeft.width() - bottomRight.width());
+ bottom.setHeight(bottomLeft.height());
+ painter->drawTiledPixmap(bottom, bottomStretch);
+ painter->restore();
+ }
+ break;
+
+ default:
+ QWindowsStyle::drawPrimitive(element, option, painter, widget);
+ break;
+ }
+ return;
+}
+
+
+void ArthurStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const
+{
+ switch (control) {
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ QRect groove = subControlRect(CC_Slider, option, SC_SliderGroove, widget);
+ QRect handle = subControlRect(CC_Slider, option, SC_SliderHandle, widget);
+
+ painter->save();
+
+ bool hover = (slider->state & State_Enabled) && (slider->state & State_MouseOver);
+ if (hover) {
+ QRect moderated = widget->rect().adjusted(0, 4, 0, -4);
+ drawHoverRect(painter, moderated);
+ }
+
+ if ((option->subControls & SC_SliderGroove) && groove.isValid()) {
+ QPixmap grv = cached(":res/images/slider_bar.png");
+ painter->drawPixmap(QRect(groove.x() + 5, groove.y(),
+ groove.width() - 10, grv.height()),
+ grv);
+ }
+ if ((option->subControls & SC_SliderHandle) && handle.isValid()) {
+ QPixmap hndl = cached(":res/images/slider_thumb_on.png");
+ painter->drawPixmap(handle.topLeft(), hndl);
+ }
+
+ painter->restore();
+ }
+ break;
+ case CC_GroupBox:
+ if (const QStyleOptionGroupBox *groupBox
+ = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
+ QStyleOptionGroupBox groupBoxCopy(*groupBox);
+ groupBoxCopy.subControls &= ~SC_GroupBoxLabel;
+ QWindowsStyle::drawComplexControl(control, &groupBoxCopy, painter, widget);
+
+ if (groupBox->subControls & SC_GroupBoxLabel) {
+ const QRect &r = groupBox->rect;
+ QPixmap titleLeft = cached(":res/images/title_cap_left.png");
+ QPixmap titleRight = cached(":res/images/title_cap_right.png");
+ QPixmap titleStretch = cached(":res/images/title_stretch.png");
+ int txt_width = groupBox->fontMetrics.width(groupBox->text) + 20;
+ painter->drawPixmap(r.center().x() - txt_width/2, 0, titleLeft);
+ QRect tileRect = subControlRect(control, groupBox, SC_GroupBoxLabel, widget);
+ painter->drawTiledPixmap(tileRect, titleStretch);
+ painter->drawPixmap(tileRect.x() + tileRect.width(), 0, titleRight);
+ int opacity = 31;
+ painter->setPen(QColor(0, 0, 0, opacity));
+ painter->drawText(tileRect.translated(0, 1),
+ Qt::AlignVCenter | Qt::AlignHCenter, groupBox->text);
+ painter->drawText(tileRect.translated(2, 1),
+ Qt::AlignVCenter | Qt::AlignHCenter, groupBox->text);
+ painter->setPen(QColor(0, 0, 0, opacity * 2));
+ painter->drawText(tileRect.translated(1, 1),
+ Qt::AlignVCenter | Qt::AlignHCenter, groupBox->text);
+ painter->setPen(Qt::white);
+ painter->drawText(tileRect, Qt::AlignVCenter | Qt::AlignHCenter, groupBox->text);
+ }
+ }
+ break;
+ default:
+ QWindowsStyle::drawComplexControl(control, option, painter, widget);
+ break;
+ }
+ return;
+}
+
+QRect ArthurStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option,
+ SubControl subControl, const QWidget *widget) const
+{
+ QRect rect;
+
+ switch (control) {
+ default:
+ rect = QWindowsStyle::subControlRect(control, option, subControl, widget);
+ break;
+ case CC_GroupBox:
+ if (const QStyleOptionGroupBox *group
+ = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
+ switch (subControl) {
+ default:
+ rect = QWindowsStyle::subControlRect(control, option, subControl, widget);
+ break;
+ case SC_GroupBoxContents:
+ rect = QWindowsStyle::subControlRect(control, option, subControl, widget);
+ rect.adjust(0, -8, 0, 0);
+ break;
+ case SC_GroupBoxFrame:
+ rect = group->rect;
+ break;
+ case SC_GroupBoxLabel:
+ QPixmap titleLeft = cached(":res/images/title_cap_left.png");
+ QPixmap titleRight = cached(":res/images/title_cap_right.png");
+ QPixmap titleStretch = cached(":res/images/title_stretch.png");
+ int txt_width = group->fontMetrics.width(group->text) + 20;
+ rect = QRect(group->rect.center().x() - txt_width/2 + titleLeft.width(), 0,
+ txt_width - titleLeft.width() - titleRight.width(),
+ titleStretch.height());
+ break;
+ }
+ }
+ break;
+ }
+
+ if (control == CC_Slider && subControl == SC_SliderHandle) {
+ rect.setWidth(13);
+ rect.setHeight(27);
+ } else if (control == CC_Slider && subControl == SC_SliderGroove) {
+ rect.setHeight(9);
+ rect.moveTop(27/2 - 9/2);
+ }
+ return rect;
+}
+
+QSize ArthurStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const
+{
+ QSize newSize = QWindowsStyle::sizeFromContents(type, option, size, widget);
+
+
+ switch (type) {
+ case CT_RadioButton:
+ newSize += QSize(20, 0);
+ break;
+
+ case CT_PushButton:
+ newSize.setHeight(26);
+ break;
+
+ case CT_Slider:
+ newSize.setHeight(27);
+ break;
+
+ default:
+ break;
+ }
+
+ return newSize;
+}
+
+int ArthurStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QWidget *widget) const
+{
+ if (pm == PM_SliderLength)
+ return 13;
+ return QWindowsStyle::pixelMetric(pm, opt, widget);
+}
+
+void ArthurStyle::polish(QWidget *widget)
+{
+ if (widget->layout() && qobject_cast<QGroupBox *>(widget)) {
+ if (widget->findChildren<QGroupBox *>().size() == 0) {
+ widget->layout()->setSpacing(0);
+ widget->layout()->setMargin(12);
+ } else {
+ widget->layout()->setMargin(13);
+ }
+ }
+
+ if (qobject_cast<QPushButton *>(widget)
+ || qobject_cast<QRadioButton *>(widget)
+ || qobject_cast<QSlider *>(widget)) {
+ widget->setAttribute(Qt::WA_Hover);
+ }
+
+ QPalette pal = widget->palette();
+ if (widget->isWindow()) {
+ pal.setColor(QPalette::Background, QColor(241, 241, 241));
+ widget->setPalette(pal);
+ }
+
+}
+
+void ArthurStyle::unpolish(QWidget *widget)
+{
+ if (qobject_cast<QPushButton *>(widget)
+ || qobject_cast<QRadioButton *>(widget)
+ || qobject_cast<QSlider *>(widget)) {
+ widget->setAttribute(Qt::WA_Hover, false);
+ }
+}
+
+void ArthurStyle::polish(QPalette &palette)
+{
+ palette.setColor(QPalette::Background, QColor(241, 241, 241));
+}
+
+QRect ArthurStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
+{
+ QRect r;
+ switch(element) {
+ case SE_RadioButtonClickRect:
+ r = widget->rect();
+ break;
+ case SE_RadioButtonContents:
+ r = widget->rect().adjusted(20, 0, 0, 0);
+ break;
+ default:
+ r = QWindowsStyle::subElementRect(element, option, widget);
+ break;
+ }
+
+ if (qobject_cast<const QRadioButton*>(widget))
+ r = r.adjusted(5, 0, -5, 0);
+
+ return r;
+}
diff --git a/examples/widgets/painting/shared/arthurstyle.h b/examples/widgets/painting/shared/arthurstyle.h
new file mode 100644
index 0000000000..1d6a573a4e
--- /dev/null
+++ b/examples/widgets/painting/shared/arthurstyle.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef ARTHURSTYLE_H
+#define ARTHURSTYLE_H
+
+#include <QWindowsStyle>
+
+QT_USE_NAMESPACE
+
+class ArthurStyle : public QWindowsStyle
+{
+public:
+ ArthurStyle();
+
+ void drawHoverRect(QPainter *painter, const QRect &rect) const;
+
+ void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget = 0) const;
+// void drawControl(ControlElement element, const QStyleOption *option,
+// QPainter *painter, const QWidget *widget) const;
+ void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const;
+ QSize sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const;
+
+ QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const;
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
+ SubControl sc, const QWidget *widget) const;
+
+// SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+// const QPoint &pos, const QWidget *widget = 0) const;
+
+ int pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const;
+
+ void polish(QPalette &palette);
+ void polish(QWidget *widget);
+ void unpolish(QWidget *widget);
+};
+
+#endif
diff --git a/examples/widgets/painting/shared/arthurwidgets.cpp b/examples/widgets/painting/shared/arthurwidgets.cpp
new file mode 100644
index 0000000000..cf790fea3b
--- /dev/null
+++ b/examples/widgets/painting/shared/arthurwidgets.cpp
@@ -0,0 +1,355 @@
+/****************************************************************************
+**
+** 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 "arthurwidgets.h"
+#include <QApplication>
+#include <QPainter>
+#include <QPainterPath>
+#include <QPixmapCache>
+#include <QtEvents>
+#include <QTextDocument>
+#include <QAbstractTextDocumentLayout>
+#include <QFile>
+#include <QTextBrowser>
+#include <QBoxLayout>
+
+extern QPixmap cached(const QString &img);
+
+ArthurFrame::ArthurFrame(QWidget *parent)
+ : QWidget(parent)
+ , m_prefer_image(false)
+{
+#ifdef QT_OPENGL_SUPPORT
+ glw = 0;
+ m_use_opengl = false;
+ QGLFormat f = QGLFormat::defaultFormat();
+ f.setSampleBuffers(true);
+ f.setStencil(true);
+ f.setAlpha(true);
+ f.setAlphaBufferSize(8);
+ QGLFormat::setDefaultFormat(f);
+#endif
+ m_document = 0;
+ m_show_doc = false;
+
+ m_tile = QPixmap(128, 128);
+ m_tile.fill(Qt::white);
+ QPainter pt(&m_tile);
+ QColor color(230, 230, 230);
+ pt.fillRect(0, 0, 64, 64, color);
+ pt.fillRect(64, 64, 64, 64, color);
+ pt.end();
+
+// QPalette pal = palette();
+// pal.setBrush(backgroundRole(), m_tile);
+// setPalette(pal);
+}
+
+
+#ifdef QT_OPENGL_SUPPORT
+void ArthurFrame::enableOpenGL(bool use_opengl)
+{
+ if (m_use_opengl == use_opengl)
+ return;
+
+ if (!glw && use_opengl) {
+ glw = new GLWidget(this);
+ glw->setAutoFillBackground(false);
+ glw->disableAutoBufferSwap();
+ QApplication::postEvent(this, new QResizeEvent(size(), size()));
+ }
+
+ m_use_opengl = use_opengl;
+ if (use_opengl) {
+ glw->show();
+ } else {
+ if (glw)
+ glw->hide();
+ }
+
+ update();
+}
+#endif
+
+void ArthurFrame::paintEvent(QPaintEvent *e)
+{
+ static QImage *static_image = 0;
+ QPainter painter;
+ if (preferImage()
+#ifdef QT_OPENGL_SUPPORT
+ && !m_use_opengl
+#endif
+ ) {
+ if (!static_image || static_image->size() != size()) {
+ delete static_image;
+ static_image = new QImage(size(), QImage::Format_RGB32);
+ }
+ painter.begin(static_image);
+
+ int o = 10;
+
+ QBrush bg = palette().brush(QPalette::Background);
+ painter.fillRect(0, 0, o, o, bg);
+ painter.fillRect(width() - o, 0, o, o, bg);
+ painter.fillRect(0, height() - o, o, o, bg);
+ painter.fillRect(width() - o, height() - o, o, o, bg);
+ } else {
+#ifdef QT_OPENGL_SUPPORT
+ if (m_use_opengl) {
+ painter.begin(glw);
+ painter.fillRect(QRectF(0, 0, glw->width(), glw->height()), palette().color(backgroundRole()));
+ } else {
+ painter.begin(this);
+ }
+#else
+ painter.begin(this);
+#endif
+ }
+
+ painter.setClipRect(e->rect());
+
+ painter.setRenderHint(QPainter::Antialiasing);
+
+ QPainterPath clipPath;
+
+ QRect r = rect();
+ qreal left = r.x() + 1;
+ qreal top = r.y() + 1;
+ qreal right = r.right();
+ qreal bottom = r.bottom();
+ qreal radius2 = 8 * 2;
+
+ clipPath.moveTo(right - radius2, top);
+ clipPath.arcTo(right - radius2, top, radius2, radius2, 90, -90);
+ clipPath.arcTo(right - radius2, bottom - radius2, radius2, radius2, 0, -90);
+ clipPath.arcTo(left, bottom - radius2, radius2, radius2, 270, -90);
+ clipPath.arcTo(left, top, radius2, radius2, 180, -90);
+ clipPath.closeSubpath();
+
+ painter.save();
+ painter.setClipPath(clipPath, Qt::IntersectClip);
+
+ painter.drawTiledPixmap(rect(), m_tile);
+
+ // client painting
+
+ paint(&painter);
+
+ painter.restore();
+
+ painter.save();
+ if (m_show_doc)
+ paintDescription(&painter);
+ painter.restore();
+
+ int level = 180;
+ painter.setPen(QPen(QColor(level, level, level), 2));
+ painter.setBrush(Qt::NoBrush);
+ painter.drawPath(clipPath);
+
+ if (preferImage()
+#ifdef QT_OPENGL_SUPPORT
+ && !m_use_opengl
+#endif
+ ) {
+ painter.end();
+ painter.begin(this);
+ painter.drawImage(e->rect(), *static_image, e->rect());
+ }
+
+#ifdef QT_OPENGL_SUPPORT
+ if (m_use_opengl && (inherits("PathDeformRenderer") || inherits("PathStrokeRenderer") || inherits("CompositionRenderer") || m_show_doc))
+ glw->swapBuffers();
+#endif
+}
+
+void ArthurFrame::resizeEvent(QResizeEvent *e)
+{
+#ifdef QT_OPENGL_SUPPORT
+ if (glw)
+ glw->setGeometry(0, 0, e->size().width()-1, e->size().height()-1);
+#endif
+ QWidget::resizeEvent(e);
+}
+
+void ArthurFrame::setDescriptionEnabled(bool enabled)
+{
+ if (m_show_doc != enabled) {
+ m_show_doc = enabled;
+ emit descriptionEnabledChanged(m_show_doc);
+ update();
+ }
+}
+
+void ArthurFrame::loadDescription(const QString &fileName)
+{
+ QFile textFile(fileName);
+ QString text;
+ if (!textFile.open(QFile::ReadOnly))
+ text = QString("Unable to load resource file: '%1'").arg(fileName);
+ else
+ text = textFile.readAll();
+ setDescription(text);
+}
+
+
+void ArthurFrame::setDescription(const QString &text)
+{
+ m_document = new QTextDocument(this);
+ m_document->setHtml(text);
+}
+
+void ArthurFrame::paintDescription(QPainter *painter)
+{
+ if (!m_document)
+ return;
+
+ int pageWidth = qMax(width() - 100, 100);
+ int pageHeight = qMax(height() - 100, 100);
+ if (pageWidth != m_document->pageSize().width()) {
+ m_document->setPageSize(QSize(pageWidth, pageHeight));
+ }
+
+ QRect textRect(width() / 2 - pageWidth / 2,
+ height() / 2 - pageHeight / 2,
+ pageWidth,
+ pageHeight);
+ int pad = 10;
+ QRect clearRect = textRect.adjusted(-pad, -pad, pad, pad);
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(QColor(0, 0, 0, 63));
+ int shade = 10;
+ painter->drawRect(clearRect.x() + clearRect.width() + 1,
+ clearRect.y() + shade,
+ shade,
+ clearRect.height() + 1);
+ painter->drawRect(clearRect.x() + shade,
+ clearRect.y() + clearRect.height() + 1,
+ clearRect.width() - shade + 1,
+ shade);
+
+ painter->setRenderHint(QPainter::Antialiasing, false);
+ painter->setBrush(QColor(255, 255, 255, 220));
+ painter->setPen(Qt::black);
+ painter->drawRect(clearRect);
+
+ painter->setClipRegion(textRect, Qt::IntersectClip);
+ painter->translate(textRect.topLeft());
+
+ QAbstractTextDocumentLayout::PaintContext ctx;
+
+ QLinearGradient g(0, 0, 0, textRect.height());
+ g.setColorAt(0, Qt::black);
+ g.setColorAt(0.9, Qt::black);
+ g.setColorAt(1, Qt::transparent);
+
+ QPalette pal = palette();
+ pal.setBrush(QPalette::Text, g);
+
+ ctx.palette = pal;
+ ctx.clip = QRect(0, 0, textRect.width(), textRect.height());
+ m_document->documentLayout()->draw(painter, ctx);
+}
+
+void ArthurFrame::loadSourceFile(const QString &sourceFile)
+{
+ m_sourceFileName = sourceFile;
+}
+
+void ArthurFrame::showSource()
+{
+ // Check for existing source
+ if (findChild<QTextBrowser *>())
+ return;
+
+ QString contents;
+ if (m_sourceFileName.isEmpty()) {
+ contents = QString("No source for widget: '%1'").arg(objectName());
+ } else {
+ QFile f(m_sourceFileName);
+ if (!f.open(QFile::ReadOnly))
+ contents = QString("Could not open file: '%1'").arg(m_sourceFileName);
+ else
+ contents = f.readAll();
+ }
+
+ contents.replace('&', "&amp;");
+ contents.replace('<', "&lt;");
+ contents.replace('>', "&gt;");
+
+ QStringList keywords;
+ keywords << "for " << "if " << "switch " << " int " << "#include " << "const"
+ << "void " << "uint " << "case " << "double " << "#define " << "static"
+ << "new" << "this";
+
+ foreach (QString keyword, keywords)
+ contents.replace(keyword, QLatin1String("<font color=olive>") + keyword + QLatin1String("</font>"));
+ contents.replace("(int ", "(<font color=olive><b>int </b></font>");
+
+ QStringList ppKeywords;
+ ppKeywords << "#ifdef" << "#ifndef" << "#if" << "#endif" << "#else";
+
+ foreach (QString keyword, ppKeywords)
+ contents.replace(keyword, QLatin1String("<font color=navy>") + keyword + QLatin1String("</font>"));
+
+ contents.replace(QRegExp("(\\d\\d?)"), QLatin1String("<font color=navy>\\1</font>"));
+
+ QRegExp commentRe("(//.+)\\n");
+ commentRe.setMinimal(true);
+ contents.replace(commentRe, QLatin1String("<font color=red>\\1</font>\n"));
+
+ QRegExp stringLiteralRe("(\".+\")");
+ stringLiteralRe.setMinimal(true);
+ contents.replace(stringLiteralRe, QLatin1String("<font color=green>\\1</font>"));
+
+ QString html = contents;
+ html.prepend("<html><pre>");
+ html.append("</pre></html>");
+
+ QTextBrowser *sourceViewer = new QTextBrowser(0);
+ sourceViewer->setWindowTitle("Source: " + m_sourceFileName.mid(5));
+ sourceViewer->setParent(this, Qt::Dialog);
+ sourceViewer->setAttribute(Qt::WA_DeleteOnClose);
+ sourceViewer->setLineWrapMode(QTextEdit::NoWrap);
+ sourceViewer->setHtml(html);
+ sourceViewer->resize(600, 600);
+ sourceViewer->show();
+}
diff --git a/examples/widgets/painting/shared/arthurwidgets.h b/examples/widgets/painting/shared/arthurwidgets.h
new file mode 100644
index 0000000000..28b986dd0b
--- /dev/null
+++ b/examples/widgets/painting/shared/arthurwidgets.h
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef ARTHURWIDGETS_H
+#define ARTHURWIDGETS_H
+
+#include "arthurstyle.h"
+#include <QBitmap>
+#include <QPushButton>
+#include <QGroupBox>
+
+#if defined(QT_OPENGL_SUPPORT)
+#include <QGLWidget>
+#include <QEvent>
+class GLWidget : public QGLWidget
+{
+public:
+ GLWidget(QWidget *parent)
+ : QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
+ {
+ setAttribute(Qt::WA_AcceptTouchEvents);
+ }
+ void disableAutoBufferSwap() { setAutoBufferSwap(false); }
+ void paintEvent(QPaintEvent *) { parentWidget()->update(); }
+protected:
+ bool event(QEvent *event)
+ {
+ switch (event->type()) {
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ event->ignore();
+ return false;
+ break;
+ default:
+ break;
+ }
+ return QGLWidget::event(event);
+ }
+};
+#endif
+
+QT_FORWARD_DECLARE_CLASS(QTextDocument)
+QT_FORWARD_DECLARE_CLASS(QTextEdit)
+QT_FORWARD_DECLARE_CLASS(QVBoxLayout)
+
+class ArthurFrame : public QWidget
+{
+ Q_OBJECT
+public:
+ ArthurFrame(QWidget *parent);
+ virtual void paint(QPainter *) {}
+
+
+ void paintDescription(QPainter *p);
+
+ void loadDescription(const QString &filename);
+ void setDescription(const QString &htmlDesc);
+
+ void loadSourceFile(const QString &fileName);
+
+ bool preferImage() const { return m_prefer_image; }
+
+#if defined(QT_OPENGL_SUPPORT)
+ QGLWidget *glWidget() const { return glw; }
+#endif
+
+public slots:
+ void setPreferImage(bool pi) { m_prefer_image = pi; }
+ void setDescriptionEnabled(bool enabled);
+ void showSource();
+
+#if defined(QT_OPENGL_SUPPORT)
+ void enableOpenGL(bool use_opengl);
+ bool usesOpenGL() { return m_use_opengl; }
+#endif
+
+signals:
+ void descriptionEnabledChanged(bool);
+
+protected:
+ void paintEvent(QPaintEvent *);
+ void resizeEvent(QResizeEvent *);
+
+#if defined(QT_OPENGL_SUPPORT)
+ GLWidget *glw;
+ bool m_use_opengl;
+#endif
+ QPixmap m_tile;
+
+ bool m_show_doc;
+ bool m_prefer_image;
+ QTextDocument *m_document;
+
+ QString m_sourceFileName;
+
+};
+
+#endif
diff --git a/examples/widgets/painting/shared/hoverpoints.cpp b/examples/widgets/painting/shared/hoverpoints.cpp
new file mode 100644
index 0000000000..824d92eb30
--- /dev/null
+++ b/examples/widgets/painting/shared/hoverpoints.cpp
@@ -0,0 +1,415 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifdef QT_OPENGL_SUPPORT
+#include <QGLWidget>
+#endif
+
+#include "arthurwidgets.h"
+#include "hoverpoints.h"
+
+#define printf
+
+HoverPoints::HoverPoints(QWidget *widget, PointShape shape)
+ : QObject(widget)
+{
+ m_widget = widget;
+ widget->installEventFilter(this);
+ widget->setAttribute(Qt::WA_AcceptTouchEvents);
+
+ m_connectionType = CurveConnection;
+ m_sortType = NoSort;
+ m_shape = shape;
+ m_pointPen = QPen(QColor(255, 255, 255, 191), 1);
+ m_connectionPen = QPen(QColor(255, 255, 255, 127), 2);
+ m_pointBrush = QBrush(QColor(191, 191, 191, 127));
+ m_pointSize = QSize(11, 11);
+ m_currentIndex = -1;
+ m_editable = true;
+ m_enabled = true;
+
+ connect(this, SIGNAL(pointsChanged(QPolygonF)),
+ m_widget, SLOT(update()));
+}
+
+
+void HoverPoints::setEnabled(bool enabled)
+{
+ if (m_enabled != enabled) {
+ m_enabled = enabled;
+ m_widget->update();
+ }
+}
+
+
+bool HoverPoints::eventFilter(QObject *object, QEvent *event)
+{
+ if (object == m_widget && m_enabled) {
+ switch (event->type()) {
+
+ case QEvent::MouseButtonPress:
+ {
+ if (!m_fingerPointMapping.isEmpty())
+ return true;
+ QMouseEvent *me = (QMouseEvent *) event;
+
+ QPointF clickPos = me->pos();
+ int index = -1;
+ for (int i=0; i<m_points.size(); ++i) {
+ QPainterPath path;
+ if (m_shape == CircleShape)
+ path.addEllipse(pointBoundingRect(i));
+ else
+ path.addRect(pointBoundingRect(i));
+
+ if (path.contains(clickPos)) {
+ index = i;
+ break;
+ }
+ }
+
+ if (me->button() == Qt::LeftButton) {
+ if (index == -1) {
+ if (!m_editable)
+ return false;
+ int pos = 0;
+ // Insert sort for x or y
+ if (m_sortType == XSort) {
+ for (int i=0; i<m_points.size(); ++i)
+ if (m_points.at(i).x() > clickPos.x()) {
+ pos = i;
+ break;
+ }
+ } else if (m_sortType == YSort) {
+ for (int i=0; i<m_points.size(); ++i)
+ if (m_points.at(i).y() > clickPos.y()) {
+ pos = i;
+ break;
+ }
+ }
+
+ m_points.insert(pos, clickPos);
+ m_locks.insert(pos, 0);
+ m_currentIndex = pos;
+ firePointChange();
+ } else {
+ m_currentIndex = index;
+ }
+ return true;
+
+ } else if (me->button() == Qt::RightButton) {
+ if (index >= 0 && m_editable) {
+ if (m_locks[index] == 0) {
+ m_locks.remove(index);
+ m_points.remove(index);
+ }
+ firePointChange();
+ return true;
+ }
+ }
+
+ }
+ break;
+
+ case QEvent::MouseButtonRelease:
+ if (!m_fingerPointMapping.isEmpty())
+ return true;
+ m_currentIndex = -1;
+ break;
+
+ case QEvent::MouseMove:
+ if (!m_fingerPointMapping.isEmpty())
+ return true;
+ if (m_currentIndex >= 0)
+ movePoint(m_currentIndex, ((QMouseEvent *)event)->pos());
+ break;
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ {
+ const QTouchEvent *const touchEvent = static_cast<const QTouchEvent*>(event);
+ const QList<QTouchEvent::TouchPoint> points = touchEvent->touchPoints();
+ const qreal pointSize = qMax(m_pointSize.width(), m_pointSize.height());
+ foreach (const QTouchEvent::TouchPoint &touchPoint, points) {
+ const int id = touchPoint.id();
+ switch (touchPoint.state()) {
+ case Qt::TouchPointPressed:
+ {
+ // find the point, move it
+ QSet<int> activePoints = QSet<int>::fromList(m_fingerPointMapping.values());
+ int activePoint = -1;
+ qreal distance = -1;
+ const int pointsCount = m_points.size();
+ const int activePointCount = activePoints.size();
+ if (pointsCount == 2 && activePointCount == 1) { // only two points
+ activePoint = activePoints.contains(0) ? 1 : 0;
+ } else {
+ for (int i=0; i<pointsCount; ++i) {
+ if (activePoints.contains(i))
+ continue;
+
+ qreal d = QLineF(touchPoint.pos(), m_points.at(i)).length();
+ if ((distance < 0 && d < 12 * pointSize) || d < distance) {
+ distance = d;
+ activePoint = i;
+ }
+
+ }
+ }
+ if (activePoint != -1) {
+ m_fingerPointMapping.insert(touchPoint.id(), activePoint);
+ movePoint(activePoint, touchPoint.pos());
+ }
+ }
+ break;
+ case Qt::TouchPointReleased:
+ {
+ // move the point and release
+ QHash<int,int>::iterator it = m_fingerPointMapping.find(id);
+ movePoint(it.value(), touchPoint.pos());
+ m_fingerPointMapping.erase(it);
+ }
+ break;
+ case Qt::TouchPointMoved:
+ {
+ // move the point
+ const int pointIdx = m_fingerPointMapping.value(id, -1);
+ if (pointIdx >= 0) // do we track this point?
+ movePoint(pointIdx, touchPoint.pos());
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (m_fingerPointMapping.isEmpty()) {
+ event->ignore();
+ return false;
+ } else {
+ return true;
+ }
+ }
+ break;
+ case QEvent::TouchEnd:
+ if (m_fingerPointMapping.isEmpty()) {
+ event->ignore();
+ return false;
+ }
+ return true;
+ break;
+
+ case QEvent::Resize:
+ {
+ QResizeEvent *e = (QResizeEvent *) event;
+ if (e->oldSize().width() == 0 || e->oldSize().height() == 0)
+ break;
+ qreal stretch_x = e->size().width() / qreal(e->oldSize().width());
+ qreal stretch_y = e->size().height() / qreal(e->oldSize().height());
+ for (int i=0; i<m_points.size(); ++i) {
+ QPointF p = m_points[i];
+ movePoint(i, QPointF(p.x() * stretch_x, p.y() * stretch_y), false);
+ }
+
+ firePointChange();
+ break;
+ }
+
+ case QEvent::Paint:
+ {
+ QWidget *that_widget = m_widget;
+ m_widget = 0;
+ QApplication::sendEvent(object, event);
+ m_widget = that_widget;
+ paintPoints();
+#ifdef QT_OPENGL_SUPPORT
+ ArthurFrame *af = qobject_cast<ArthurFrame *>(that_widget);
+ if (af && af->usesOpenGL())
+ af->glWidget()->swapBuffers();
+#endif
+ return true;
+ }
+ default:
+ break;
+ }
+ }
+
+ return false;
+}
+
+
+void HoverPoints::paintPoints()
+{
+ QPainter p;
+#ifdef QT_OPENGL_SUPPORT
+ ArthurFrame *af = qobject_cast<ArthurFrame *>(m_widget);
+ if (af && af->usesOpenGL())
+ p.begin(af->glWidget());
+ else
+ p.begin(m_widget);
+#else
+ p.begin(m_widget);
+#endif
+
+ p.setRenderHint(QPainter::Antialiasing);
+
+ if (m_connectionPen.style() != Qt::NoPen && m_connectionType != NoConnection) {
+ p.setPen(m_connectionPen);
+
+ if (m_connectionType == CurveConnection) {
+ QPainterPath path;
+ path.moveTo(m_points.at(0));
+ for (int i=1; i<m_points.size(); ++i) {
+ QPointF p1 = m_points.at(i-1);
+ QPointF p2 = m_points.at(i);
+ qreal distance = p2.x() - p1.x();
+
+ path.cubicTo(p1.x() + distance / 2, p1.y(),
+ p1.x() + distance / 2, p2.y(),
+ p2.x(), p2.y());
+ }
+ p.drawPath(path);
+ } else {
+ p.drawPolyline(m_points);
+ }
+ }
+
+ p.setPen(m_pointPen);
+ p.setBrush(m_pointBrush);
+
+ for (int i=0; i<m_points.size(); ++i) {
+ QRectF bounds = pointBoundingRect(i);
+ if (m_shape == CircleShape)
+ p.drawEllipse(bounds);
+ else
+ p.drawRect(bounds);
+ }
+}
+
+static QPointF bound_point(const QPointF &point, const QRectF &bounds, int lock)
+{
+ QPointF p = point;
+
+ qreal left = bounds.left();
+ qreal right = bounds.right();
+ qreal top = bounds.top();
+ qreal bottom = bounds.bottom();
+
+ if (p.x() < left || (lock & HoverPoints::LockToLeft)) p.setX(left);
+ else if (p.x() > right || (lock & HoverPoints::LockToRight)) p.setX(right);
+
+ if (p.y() < top || (lock & HoverPoints::LockToTop)) p.setY(top);
+ else if (p.y() > bottom || (lock & HoverPoints::LockToBottom)) p.setY(bottom);
+
+ return p;
+}
+
+void HoverPoints::setPoints(const QPolygonF &points)
+{
+ if (points.size() != m_points.size())
+ m_fingerPointMapping.clear();
+ m_points.clear();
+ for (int i=0; i<points.size(); ++i)
+ m_points << bound_point(points.at(i), boundingRect(), 0);
+
+ m_locks.clear();
+ if (m_points.size() > 0) {
+ m_locks.resize(m_points.size());
+
+ m_locks.fill(0);
+ }
+}
+
+
+void HoverPoints::movePoint(int index, const QPointF &point, bool emitUpdate)
+{
+ m_points[index] = bound_point(point, boundingRect(), m_locks.at(index));
+ if (emitUpdate)
+ firePointChange();
+}
+
+
+inline static bool x_less_than(const QPointF &p1, const QPointF &p2)
+{
+ return p1.x() < p2.x();
+}
+
+
+inline static bool y_less_than(const QPointF &p1, const QPointF &p2)
+{
+ return p1.y() < p2.y();
+}
+
+void HoverPoints::firePointChange()
+{
+// printf("HoverPoints::firePointChange(), current=%d\n", m_currentIndex);
+
+ if (m_sortType != NoSort) {
+
+ QPointF oldCurrent;
+ if (m_currentIndex != -1) {
+ oldCurrent = m_points[m_currentIndex];
+ }
+
+ if (m_sortType == XSort)
+ qSort(m_points.begin(), m_points.end(), x_less_than);
+ else if (m_sortType == YSort)
+ qSort(m_points.begin(), m_points.end(), y_less_than);
+
+ // Compensate for changed order...
+ if (m_currentIndex != -1) {
+ for (int i=0; i<m_points.size(); ++i) {
+ if (m_points[i] == oldCurrent) {
+ m_currentIndex = i;
+ break;
+ }
+ }
+ }
+
+// printf(" - firePointChange(), current=%d\n", m_currentIndex);
+
+ }
+
+// for (int i=0; i<m_points.size(); ++i) {
+// printf(" - point(%2d)=[%.2f, %.2f], lock=%d\n",
+// i, m_points.at(i).x(), m_points.at(i).y(), m_locks.at(i));
+// }
+
+ emit pointsChanged(m_points);
+}
diff --git a/examples/widgets/painting/shared/hoverpoints.h b/examples/widgets/painting/shared/hoverpoints.h
new file mode 100644
index 0000000000..5472f10a3a
--- /dev/null
+++ b/examples/widgets/painting/shared/hoverpoints.h
@@ -0,0 +1,162 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef HOVERPOINTS_H
+#define HOVERPOINTS_H
+
+#include <QtWidgets>
+
+QT_FORWARD_DECLARE_CLASS(QBypassWidget)
+
+class HoverPoints : public QObject
+{
+ Q_OBJECT
+public:
+ enum PointShape {
+ CircleShape,
+ RectangleShape
+ };
+
+ enum LockType {
+ LockToLeft = 0x01,
+ LockToRight = 0x02,
+ LockToTop = 0x04,
+ LockToBottom = 0x08
+ };
+
+ enum SortType {
+ NoSort,
+ XSort,
+ YSort
+ };
+
+ enum ConnectionType {
+ NoConnection,
+ LineConnection,
+ CurveConnection
+ };
+
+ HoverPoints(QWidget *widget, PointShape shape);
+
+ bool eventFilter(QObject *object, QEvent *event);
+
+ void paintPoints();
+
+ inline QRectF boundingRect() const;
+ void setBoundingRect(const QRectF &boundingRect) { m_bounds = boundingRect; }
+
+ QPolygonF points() const { return m_points; }
+ void setPoints(const QPolygonF &points);
+
+ QSizeF pointSize() const { return m_pointSize; }
+ void setPointSize(const QSizeF &size) { m_pointSize = size; }
+
+ SortType sortType() const { return m_sortType; }
+ void setSortType(SortType sortType) { m_sortType = sortType; }
+
+ ConnectionType connectionType() const { return m_connectionType; }
+ void setConnectionType(ConnectionType connectionType) { m_connectionType = connectionType; }
+
+ void setConnectionPen(const QPen &pen) { m_connectionPen = pen; }
+ void setShapePen(const QPen &pen) { m_pointPen = pen; }
+ void setShapeBrush(const QBrush &brush) { m_pointBrush = brush; }
+
+ void setPointLock(int pos, LockType lock) { m_locks[pos] = lock; }
+
+ void setEditable(bool editable) { m_editable = editable; }
+ bool editable() const { return m_editable; }
+
+public slots:
+ void setEnabled(bool enabled);
+ void setDisabled(bool disabled) { setEnabled(!disabled); }
+
+signals:
+ void pointsChanged(const QPolygonF &points);
+
+public:
+ void firePointChange();
+
+private:
+ inline QRectF pointBoundingRect(int i) const;
+ void movePoint(int i, const QPointF &newPos, bool emitChange = true);
+
+ QWidget *m_widget;
+
+ QPolygonF m_points;
+ QRectF m_bounds;
+ PointShape m_shape;
+ SortType m_sortType;
+ ConnectionType m_connectionType;
+
+ QVector<uint> m_locks;
+
+ QSizeF m_pointSize;
+ int m_currentIndex;
+ bool m_editable;
+ bool m_enabled;
+
+ QHash<int, int> m_fingerPointMapping;
+
+ QPen m_pointPen;
+ QBrush m_pointBrush;
+ QPen m_connectionPen;
+};
+
+
+inline QRectF HoverPoints::pointBoundingRect(int i) const
+{
+ QPointF p = m_points.at(i);
+ qreal w = m_pointSize.width();
+ qreal h = m_pointSize.height();
+ qreal x = p.x() - w / 2;
+ qreal y = p.y() - h / 2;
+ return QRectF(x, y, w, h);
+}
+
+inline QRectF HoverPoints::boundingRect() const
+{
+ if (m_bounds.isEmpty())
+ return m_widget->rect();
+ else
+ return m_bounds;
+}
+
+#endif // HOVERPOINTS_H
diff --git a/examples/widgets/painting/shared/images/bg_pattern.png b/examples/widgets/painting/shared/images/bg_pattern.png
new file mode 100644
index 0000000000..ee670266f0
--- /dev/null
+++ b/examples/widgets/painting/shared/images/bg_pattern.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/button_normal_cap_left.png b/examples/widgets/painting/shared/images/button_normal_cap_left.png
new file mode 100644
index 0000000000..db31dd971d
--- /dev/null
+++ b/examples/widgets/painting/shared/images/button_normal_cap_left.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/button_normal_cap_right.png b/examples/widgets/painting/shared/images/button_normal_cap_right.png
new file mode 100644
index 0000000000..38ead1c719
--- /dev/null
+++ b/examples/widgets/painting/shared/images/button_normal_cap_right.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/button_normal_stretch.png b/examples/widgets/painting/shared/images/button_normal_stretch.png
new file mode 100644
index 0000000000..87abe67ac9
--- /dev/null
+++ b/examples/widgets/painting/shared/images/button_normal_stretch.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/button_pressed_cap_left.png b/examples/widgets/painting/shared/images/button_pressed_cap_left.png
new file mode 100644
index 0000000000..66bfc13cb4
--- /dev/null
+++ b/examples/widgets/painting/shared/images/button_pressed_cap_left.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/button_pressed_cap_right.png b/examples/widgets/painting/shared/images/button_pressed_cap_right.png
new file mode 100644
index 0000000000..3d4cfe25b1
--- /dev/null
+++ b/examples/widgets/painting/shared/images/button_pressed_cap_right.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/button_pressed_stretch.png b/examples/widgets/painting/shared/images/button_pressed_stretch.png
new file mode 100644
index 0000000000..4dd4ad11e6
--- /dev/null
+++ b/examples/widgets/painting/shared/images/button_pressed_stretch.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/curve_thing_edit-6.png b/examples/widgets/painting/shared/images/curve_thing_edit-6.png
new file mode 100644
index 0000000000..034b474d02
--- /dev/null
+++ b/examples/widgets/painting/shared/images/curve_thing_edit-6.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/frame_bottom.png b/examples/widgets/painting/shared/images/frame_bottom.png
new file mode 100644
index 0000000000..889b40d304
--- /dev/null
+++ b/examples/widgets/painting/shared/images/frame_bottom.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/frame_bottomleft.png b/examples/widgets/painting/shared/images/frame_bottomleft.png
new file mode 100644
index 0000000000..0b3023f397
--- /dev/null
+++ b/examples/widgets/painting/shared/images/frame_bottomleft.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/frame_bottomright.png b/examples/widgets/painting/shared/images/frame_bottomright.png
new file mode 100644
index 0000000000..0021e35864
--- /dev/null
+++ b/examples/widgets/painting/shared/images/frame_bottomright.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/frame_left.png b/examples/widgets/painting/shared/images/frame_left.png
new file mode 100644
index 0000000000..40f331c293
--- /dev/null
+++ b/examples/widgets/painting/shared/images/frame_left.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/frame_right.png b/examples/widgets/painting/shared/images/frame_right.png
new file mode 100644
index 0000000000..023af8c700
--- /dev/null
+++ b/examples/widgets/painting/shared/images/frame_right.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/frame_top.png b/examples/widgets/painting/shared/images/frame_top.png
new file mode 100644
index 0000000000..001f3a7144
--- /dev/null
+++ b/examples/widgets/painting/shared/images/frame_top.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/frame_topleft.png b/examples/widgets/painting/shared/images/frame_topleft.png
new file mode 100644
index 0000000000..58c68d407a
--- /dev/null
+++ b/examples/widgets/painting/shared/images/frame_topleft.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/frame_topright.png b/examples/widgets/painting/shared/images/frame_topright.png
new file mode 100644
index 0000000000..6a7e8d3eb3
--- /dev/null
+++ b/examples/widgets/painting/shared/images/frame_topright.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/groupframe_bottom_left.png b/examples/widgets/painting/shared/images/groupframe_bottom_left.png
new file mode 100644
index 0000000000..af2fe061e3
--- /dev/null
+++ b/examples/widgets/painting/shared/images/groupframe_bottom_left.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/groupframe_bottom_right.png b/examples/widgets/painting/shared/images/groupframe_bottom_right.png
new file mode 100644
index 0000000000..fdf2e97b13
--- /dev/null
+++ b/examples/widgets/painting/shared/images/groupframe_bottom_right.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/groupframe_bottom_stretch.png b/examples/widgets/painting/shared/images/groupframe_bottom_stretch.png
new file mode 100644
index 0000000000..f47b67d7c0
--- /dev/null
+++ b/examples/widgets/painting/shared/images/groupframe_bottom_stretch.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/groupframe_left_stretch.png b/examples/widgets/painting/shared/images/groupframe_left_stretch.png
new file mode 100644
index 0000000000..c122f462ed
--- /dev/null
+++ b/examples/widgets/painting/shared/images/groupframe_left_stretch.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/groupframe_right_stretch.png b/examples/widgets/painting/shared/images/groupframe_right_stretch.png
new file mode 100644
index 0000000000..1056b7812a
--- /dev/null
+++ b/examples/widgets/painting/shared/images/groupframe_right_stretch.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/groupframe_top_stretch.png b/examples/widgets/painting/shared/images/groupframe_top_stretch.png
new file mode 100644
index 0000000000..5746ef96fc
--- /dev/null
+++ b/examples/widgets/painting/shared/images/groupframe_top_stretch.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/groupframe_topleft.png b/examples/widgets/painting/shared/images/groupframe_topleft.png
new file mode 100644
index 0000000000..98d9cd96b4
--- /dev/null
+++ b/examples/widgets/painting/shared/images/groupframe_topleft.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/groupframe_topright.png b/examples/widgets/painting/shared/images/groupframe_topright.png
new file mode 100644
index 0000000000..1a0a328c20
--- /dev/null
+++ b/examples/widgets/painting/shared/images/groupframe_topright.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/line_dash_dot.png b/examples/widgets/painting/shared/images/line_dash_dot.png
new file mode 100644
index 0000000000..1c61442d9f
--- /dev/null
+++ b/examples/widgets/painting/shared/images/line_dash_dot.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/line_dash_dot_dot.png b/examples/widgets/painting/shared/images/line_dash_dot_dot.png
new file mode 100644
index 0000000000..0d9bb972f9
--- /dev/null
+++ b/examples/widgets/painting/shared/images/line_dash_dot_dot.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/line_dashed.png b/examples/widgets/painting/shared/images/line_dashed.png
new file mode 100644
index 0000000000..d5bc7ea5fe
--- /dev/null
+++ b/examples/widgets/painting/shared/images/line_dashed.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/line_dotted.png b/examples/widgets/painting/shared/images/line_dotted.png
new file mode 100644
index 0000000000..a2f9a35925
--- /dev/null
+++ b/examples/widgets/painting/shared/images/line_dotted.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/line_solid.png b/examples/widgets/painting/shared/images/line_solid.png
new file mode 100644
index 0000000000..60ef3f9485
--- /dev/null
+++ b/examples/widgets/painting/shared/images/line_solid.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/radiobutton-off.png b/examples/widgets/painting/shared/images/radiobutton-off.png
new file mode 100644
index 0000000000..af1753a3e7
--- /dev/null
+++ b/examples/widgets/painting/shared/images/radiobutton-off.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/radiobutton-on.png b/examples/widgets/painting/shared/images/radiobutton-on.png
new file mode 100644
index 0000000000..f875838bb5
--- /dev/null
+++ b/examples/widgets/painting/shared/images/radiobutton-on.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/radiobutton_off.png b/examples/widgets/painting/shared/images/radiobutton_off.png
new file mode 100644
index 0000000000..400906ebfa
--- /dev/null
+++ b/examples/widgets/painting/shared/images/radiobutton_off.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/radiobutton_on.png b/examples/widgets/painting/shared/images/radiobutton_on.png
new file mode 100644
index 0000000000..50a049ec56
--- /dev/null
+++ b/examples/widgets/painting/shared/images/radiobutton_on.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/slider_bar.png b/examples/widgets/painting/shared/images/slider_bar.png
new file mode 100644
index 0000000000..1b3d62c007
--- /dev/null
+++ b/examples/widgets/painting/shared/images/slider_bar.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/slider_thumb_off.png b/examples/widgets/painting/shared/images/slider_thumb_off.png
new file mode 100644
index 0000000000..d7f141daef
--- /dev/null
+++ b/examples/widgets/painting/shared/images/slider_thumb_off.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/slider_thumb_on.png b/examples/widgets/painting/shared/images/slider_thumb_on.png
new file mode 100644
index 0000000000..8e1f510813
--- /dev/null
+++ b/examples/widgets/painting/shared/images/slider_thumb_on.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/title_cap_left.png b/examples/widgets/painting/shared/images/title_cap_left.png
new file mode 100644
index 0000000000..2d475070c8
--- /dev/null
+++ b/examples/widgets/painting/shared/images/title_cap_left.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/title_cap_right.png b/examples/widgets/painting/shared/images/title_cap_right.png
new file mode 100644
index 0000000000..dc3ff8536c
--- /dev/null
+++ b/examples/widgets/painting/shared/images/title_cap_right.png
Binary files differ
diff --git a/examples/widgets/painting/shared/images/title_stretch.png b/examples/widgets/painting/shared/images/title_stretch.png
new file mode 100644
index 0000000000..11043345d0
--- /dev/null
+++ b/examples/widgets/painting/shared/images/title_stretch.png
Binary files differ
diff --git a/examples/widgets/painting/shared/shared.pri b/examples/widgets/painting/shared/shared.pri
new file mode 100644
index 0000000000..2d6b3c78f9
--- /dev/null
+++ b/examples/widgets/painting/shared/shared.pri
@@ -0,0 +1,20 @@
+INCLUDEPATH += $$SHARED_FOLDER
+
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+contains(CONFIG, debug_and_release_target) {
+ CONFIG(debug, debug|release) {
+ QMAKE_LIBDIR += $$SHARED_FOLDER/debug
+ } else {
+ QMAKE_LIBDIR += $$SHARED_FOLDER/release
+ }
+} else {
+ QMAKE_LIBDIR += $$SHARED_FOLDER
+}
+
+hpux-acc*:LIBS += $$SHARED_FOLDER/libdemo_shared.a
+hpuxi-acc*:LIBS += $$SHARED_FOLDER/libdemo_shared.a
+!hpuxi-acc*:!hpux-acc*:LIBS += -ldemo_shared
+
diff --git a/examples/widgets/painting/shared/shared.pro b/examples/widgets/painting/shared/shared.pro
new file mode 100644
index 0000000000..212f3a20d7
--- /dev/null
+++ b/examples/widgets/painting/shared/shared.pro
@@ -0,0 +1,34 @@
+TEMPLATE = lib
+CONFIG += static
+
+contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles2) {
+ DEFINES += QT_OPENGL_SUPPORT
+ QT += opengl widgets
+}
+
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+TARGET = demo_shared
+QT += widgets
+
+SOURCES += \
+ arthurstyle.cpp\
+ arthurwidgets.cpp \
+ hoverpoints.cpp
+
+HEADERS += \
+ arthurstyle.h \
+ arthurwidgets.h \
+ hoverpoints.h
+
+RESOURCES += shared.qrc
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/painting/shared
+sources.files = $$SOURCES $$HEADERS $$RESOURCES *.pro *.pri images
+sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/painting/shared
+INSTALLS += sources
+
+!cross_compile:INSTALLS += target
diff --git a/examples/widgets/painting/shared/shared.qrc b/examples/widgets/painting/shared/shared.qrc
new file mode 100644
index 0000000000..17336ecf80
--- /dev/null
+++ b/examples/widgets/painting/shared/shared.qrc
@@ -0,0 +1,39 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/res">
+ <file>images/button_normal_cap_left.png</file>
+ <file>images/button_normal_cap_right.png</file>
+ <file>images/button_normal_stretch.png</file>
+ <file>images/button_pressed_cap_left.png</file>
+ <file>images/button_pressed_cap_right.png</file>
+ <file>images/button_pressed_stretch.png</file>
+ <file>images/radiobutton-on.png</file>
+ <file>images/radiobutton_on.png</file>
+ <file>images/radiobutton_off.png</file>
+ <file>images/slider_bar.png</file>
+ <file>images/slider_thumb_on.png</file>
+ <file>images/groupframe_topleft.png</file>
+ <file>images/groupframe_topright.png</file>
+ <file>images/groupframe_bottom_left.png</file>
+ <file>images/groupframe_bottom_right.png</file>
+ <file>images/groupframe_top_stretch.png</file>
+ <file>images/groupframe_bottom_stretch.png</file>
+ <file>images/groupframe_left_stretch.png</file>
+ <file>images/groupframe_right_stretch.png</file>
+ <file>images/frame_topleft.png</file>
+ <file>images/frame_topright.png</file>
+ <file>images/frame_bottomleft.png</file>
+ <file>images/frame_bottomright.png</file>
+ <file>images/frame_left.png</file>
+ <file>images/frame_top.png</file>
+ <file>images/frame_right.png</file>
+ <file>images/frame_bottom.png</file>
+ <file>images/title_cap_left.png</file>
+ <file>images/title_cap_right.png</file>
+ <file>images/title_stretch.png</file>
+ <file>images/line_dash_dot.png</file>
+ <file>images/line_dotted.png</file>
+ <file>images/line_dashed.png</file>
+ <file>images/line_solid.png</file>
+ <file>images/line_dash_dot_dot.png</file>
+</qresource>
+</RCC>
diff --git a/examples/widgets/painting/svggenerator/svggenerator.desktop b/examples/widgets/painting/svggenerator/svggenerator.desktop
new file mode 100644
index 0000000000..3ae32a4908
--- /dev/null
+++ b/examples/widgets/painting/svggenerator/svggenerator.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Terminal=false
+Name=SVG Generator
+Exec=/opt/usr/bin/svggenerator
+Icon=svggenerator
+X-Window-Icon=
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
diff --git a/examples/widgets/painting/svgviewer/svgviewer.desktop b/examples/widgets/painting/svgviewer/svgviewer.desktop
new file mode 100644
index 0000000000..477ef789d8
--- /dev/null
+++ b/examples/widgets/painting/svgviewer/svgviewer.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Terminal=false
+Name=SVG Viewer
+Exec=/opt/usr/bin/svgviewer
+Icon=svgviewer
+X-Window-Icon=
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
diff --git a/examples/widgets/painting/transformations/main.cpp b/examples/widgets/painting/transformations/main.cpp
new file mode 100644
index 0000000000..dcbf1c0449
--- /dev/null
+++ b/examples/widgets/painting/transformations/main.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+
+#include "window.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ Window window;
+ window.show();
+ return app.exec();
+}
diff --git a/examples/widgets/painting/transformations/renderarea.cpp b/examples/widgets/painting/transformations/renderarea.cpp
new file mode 100644
index 0000000000..58be8143c3
--- /dev/null
+++ b/examples/widgets/painting/transformations/renderarea.cpp
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtWidgets>
+
+#include "renderarea.h"
+
+//! [0]
+RenderArea::RenderArea(QWidget *parent)
+ : QWidget(parent)
+{
+ QFont newFont = font();
+ newFont.setPixelSize(12);
+ setFont(newFont);
+
+ QFontMetrics fontMetrics(newFont);
+ xBoundingRect = fontMetrics.boundingRect(tr("x"));
+ yBoundingRect = fontMetrics.boundingRect(tr("y"));
+}
+//! [0]
+
+//! [1]
+void RenderArea::setOperations(const QList<Operation> &operations)
+{
+ this->operations = operations;
+ update();
+}
+//! [1]
+
+//! [2]
+void RenderArea::setShape(const QPainterPath &shape)
+{
+ this->shape = shape;
+ update();
+}
+//! [2]
+
+//! [3]
+QSize RenderArea::minimumSizeHint() const
+{
+ return QSize(182, 182);
+}
+//! [3]
+
+//! [4]
+QSize RenderArea::sizeHint() const
+{
+ return QSize(232, 232);
+}
+//! [4]
+
+//! [5]
+void RenderArea::paintEvent(QPaintEvent *event)
+{
+ QPainter painter(this);
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.fillRect(event->rect(), QBrush(Qt::white));
+
+ painter.translate(66, 66);
+//! [5]
+
+//! [6]
+ painter.save();
+ transformPainter(painter);
+ drawShape(painter);
+ painter.restore();
+//! [6]
+
+//! [7]
+ drawOutline(painter);
+//! [7]
+
+//! [8]
+ transformPainter(painter);
+ drawCoordinates(painter);
+}
+//! [8]
+
+//! [9]
+void RenderArea::drawCoordinates(QPainter &painter)
+{
+ painter.setPen(Qt::red);
+
+ painter.drawLine(0, 0, 50, 0);
+ painter.drawLine(48, -2, 50, 0);
+ painter.drawLine(48, 2, 50, 0);
+ painter.drawText(60 - xBoundingRect.width() / 2,
+ 0 + xBoundingRect.height() / 2, tr("x"));
+
+ painter.drawLine(0, 0, 0, 50);
+ painter.drawLine(-2, 48, 0, 50);
+ painter.drawLine(2, 48, 0, 50);
+ painter.drawText(0 - yBoundingRect.width() / 2,
+ 60 + yBoundingRect.height() / 2, tr("y"));
+}
+//! [9]
+
+//! [10]
+void RenderArea::drawOutline(QPainter &painter)
+{
+ painter.setPen(Qt::darkGreen);
+ painter.setPen(Qt::DashLine);
+ painter.setBrush(Qt::NoBrush);
+ painter.drawRect(0, 0, 100, 100);
+}
+//! [10]
+
+//! [11]
+void RenderArea::drawShape(QPainter &painter)
+{
+ painter.fillPath(shape, Qt::blue);
+}
+//! [11]
+
+//! [12]
+void RenderArea::transformPainter(QPainter &painter)
+{
+ for (int i = 0; i < operations.size(); ++i) {
+ switch (operations[i]) {
+ case Translate:
+ painter.translate(50, 50);
+ break;
+ case Scale:
+ painter.scale(0.75, 0.75);
+ break;
+ case Rotate:
+ painter.rotate(60);
+ break;
+ case NoTransformation:
+ default:
+ ;
+ }
+ }
+}
+//! [12]
diff --git a/examples/widgets/painting/transformations/renderarea.h b/examples/widgets/painting/transformations/renderarea.h
new file mode 100644
index 0000000000..adc6c1ad7f
--- /dev/null
+++ b/examples/widgets/painting/transformations/renderarea.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RENDERAREA_H
+#define RENDERAREA_H
+
+#include <QFont>
+#include <QList>
+#include <QPainterPath>
+#include <QRect>
+#include <QWidget>
+
+QT_BEGIN_NAMESPACE
+class QPaintEvent;
+QT_END_NAMESPACE
+
+//! [0]
+enum Operation { NoTransformation, Translate, Rotate, Scale };
+//! [0]
+
+//! [1]
+class RenderArea : public QWidget
+{
+ Q_OBJECT
+
+public:
+ RenderArea(QWidget *parent = 0);
+
+ void setOperations(const QList<Operation> &operations);
+ void setShape(const QPainterPath &shape);
+
+ QSize minimumSizeHint() const;
+ QSize sizeHint() const;
+
+protected:
+ void paintEvent(QPaintEvent *event);
+//! [1]
+
+//! [2]
+private:
+ void drawCoordinates(QPainter &painter);
+ void drawOutline(QPainter &painter);
+ void drawShape(QPainter &painter);
+ void transformPainter(QPainter &painter);
+
+ QList<Operation> operations;
+ QPainterPath shape;
+ QRect xBoundingRect;
+ QRect yBoundingRect;
+};
+//! [2]
+
+#endif
diff --git a/examples/widgets/painting/transformations/transformations.desktop b/examples/widgets/painting/transformations/transformations.desktop
new file mode 100644
index 0000000000..2f53891069
--- /dev/null
+++ b/examples/widgets/painting/transformations/transformations.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Terminal=false
+Name=Transformations
+Exec=/opt/usr/bin/transformations
+Icon=transformations
+X-Window-Icon=
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
diff --git a/examples/widgets/painting/transformations/transformations.pro b/examples/widgets/painting/transformations/transformations.pro
new file mode 100644
index 0000000000..a261c53371
--- /dev/null
+++ b/examples/widgets/painting/transformations/transformations.pro
@@ -0,0 +1,13 @@
+HEADERS = renderarea.h \
+ window.h
+SOURCES = main.cpp \
+ renderarea.cpp \
+ window.cpp
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/painting/transformations
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS transformations.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/painting/transformations
+INSTALLS += target sources
+
+QT += widgets
diff --git a/examples/widgets/painting/transformations/window.cpp b/examples/widgets/painting/transformations/window.cpp
new file mode 100644
index 0000000000..5f9296be7f
--- /dev/null
+++ b/examples/widgets/painting/transformations/window.cpp
@@ -0,0 +1,180 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtWidgets>
+
+#include "window.h"
+
+//! [0]
+Window::Window()
+{
+ originalRenderArea = new RenderArea;
+
+ shapeComboBox = new QComboBox;
+ shapeComboBox->addItem(tr("Clock"));
+ shapeComboBox->addItem(tr("House"));
+ shapeComboBox->addItem(tr("Text"));
+ shapeComboBox->addItem(tr("Truck"));
+
+ QGridLayout *layout = new QGridLayout;
+ layout->addWidget(originalRenderArea, 0, 0);
+ layout->addWidget(shapeComboBox, 1, 0);
+//! [0]
+
+//! [1]
+ for (int i = 0; i < NumTransformedAreas; ++i) {
+ transformedRenderAreas[i] = new RenderArea;
+
+ operationComboBoxes[i] = new QComboBox;
+ operationComboBoxes[i]->addItem(tr("No transformation"));
+ operationComboBoxes[i]->addItem(tr("Rotate by 60\xC2\xB0"));
+ operationComboBoxes[i]->addItem(tr("Scale to 75%"));
+ operationComboBoxes[i]->addItem(tr("Translate by (50, 50)"));
+
+ connect(operationComboBoxes[i], SIGNAL(activated(int)),
+ this, SLOT(operationChanged()));
+
+ layout->addWidget(transformedRenderAreas[i], 0, i + 1);
+ layout->addWidget(operationComboBoxes[i], 1, i + 1);
+ }
+//! [1]
+
+//! [2]
+ setLayout(layout);
+ setupShapes();
+ shapeSelected(0);
+
+ setWindowTitle(tr("Transformations"));
+}
+//! [2]
+
+//! [3]
+void Window::setupShapes()
+{
+ QPainterPath truck;
+//! [3]
+ truck.setFillRule(Qt::WindingFill);
+ truck.moveTo(0.0, 87.0);
+ truck.lineTo(0.0, 60.0);
+ truck.lineTo(10.0, 60.0);
+ truck.lineTo(35.0, 35.0);
+ truck.lineTo(100.0, 35.0);
+ truck.lineTo(100.0, 87.0);
+ truck.lineTo(0.0, 87.0);
+ truck.moveTo(17.0, 60.0);
+ truck.lineTo(55.0, 60.0);
+ truck.lineTo(55.0, 40.0);
+ truck.lineTo(37.0, 40.0);
+ truck.lineTo(17.0, 60.0);
+ truck.addEllipse(17.0, 75.0, 25.0, 25.0);
+ truck.addEllipse(63.0, 75.0, 25.0, 25.0);
+
+//! [4]
+ QPainterPath clock;
+//! [4]
+ clock.addEllipse(-50.0, -50.0, 100.0, 100.0);
+ clock.addEllipse(-48.0, -48.0, 96.0, 96.0);
+ clock.moveTo(0.0, 0.0);
+ clock.lineTo(-2.0, -2.0);
+ clock.lineTo(0.0, -42.0);
+ clock.lineTo(2.0, -2.0);
+ clock.lineTo(0.0, 0.0);
+ clock.moveTo(0.0, 0.0);
+ clock.lineTo(2.732, -0.732);
+ clock.lineTo(24.495, 14.142);
+ clock.lineTo(0.732, 2.732);
+ clock.lineTo(0.0, 0.0);
+
+//! [5]
+ QPainterPath house;
+//! [5]
+ house.moveTo(-45.0, -20.0);
+ house.lineTo(0.0, -45.0);
+ house.lineTo(45.0, -20.0);
+ house.lineTo(45.0, 45.0);
+ house.lineTo(-45.0, 45.0);
+ house.lineTo(-45.0, -20.0);
+ house.addRect(15.0, 5.0, 20.0, 35.0);
+ house.addRect(-35.0, -15.0, 25.0, 25.0);
+
+//! [6]
+ QPainterPath text;
+//! [6]
+ QFont font;
+ font.setPixelSize(50);
+ QRect fontBoundingRect = QFontMetrics(font).boundingRect(tr("Qt"));
+ text.addText(-QPointF(fontBoundingRect.center()), font, tr("Qt"));
+
+//! [7]
+ shapes.append(clock);
+ shapes.append(house);
+ shapes.append(text);
+ shapes.append(truck);
+
+ connect(shapeComboBox, SIGNAL(activated(int)),
+ this, SLOT(shapeSelected(int)));
+}
+//! [7]
+
+//! [8]
+void Window::operationChanged()
+{
+ static const Operation operationTable[] = {
+ NoTransformation, Rotate, Scale, Translate
+ };
+
+ QList<Operation> operations;
+ for (int i = 0; i < NumTransformedAreas; ++i) {
+ int index = operationComboBoxes[i]->currentIndex();
+ operations.append(operationTable[index]);
+ transformedRenderAreas[i]->setOperations(operations);
+ }
+}
+//! [8]
+
+//! [9]
+void Window::shapeSelected(int index)
+{
+ QPainterPath shape = shapes[index];
+ originalRenderArea->setShape(shape);
+ for (int i = 0; i < NumTransformedAreas; ++i)
+ transformedRenderAreas[i]->setShape(shape);
+}
+//! [9]
diff --git a/examples/widgets/painting/transformations/window.h b/examples/widgets/painting/transformations/window.h
new file mode 100644
index 0000000000..f28e53e494
--- /dev/null
+++ b/examples/widgets/painting/transformations/window.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WINDOW_H
+#define WINDOW_H
+
+#include <QList>
+#include <QPainterPath>
+#include <QWidget>
+
+#include "renderarea.h"
+
+QT_BEGIN_NAMESPACE
+class QComboBox;
+QT_END_NAMESPACE
+
+//! [0]
+class Window : public QWidget
+{
+ Q_OBJECT
+
+public:
+ Window();
+
+public slots:
+ void operationChanged();
+ void shapeSelected(int index);
+//! [0]
+
+//! [1]
+private:
+ void setupShapes();
+
+ enum { NumTransformedAreas = 3 };
+ RenderArea *originalRenderArea;
+ RenderArea *transformedRenderAreas[NumTransformedAreas];
+ QComboBox *shapeComboBox;
+ QComboBox *operationComboBoxes[NumTransformedAreas];
+ QList<QPainterPath> shapes;
+};
+//! [1]
+
+#endif