From d7c37d9bacc016b1156e15780080cfc8c24f6e6a Mon Sep 17 00:00:00 2001 From: Casper van Donderen Date: Wed, 22 Jun 2011 12:33:28 +0200 Subject: Move the affine example. Change-Id: I27a164495e469cb2a5c82688f35062b54be5e62f Reviewed-on: http://codereview.qt.nokia.com/598 Reviewed-by: Qt Sanity Bot Reviewed-by: David Boddie --- examples/painting/affine/affine.pro | 25 + examples/painting/affine/affine.qrc | 7 + examples/painting/affine/bg1.jpg | Bin 0 -> 23771 bytes examples/painting/affine/main.cpp | 65 +++ examples/painting/affine/xform.cpp | 902 ++++++++++++++++++++++++++++++++++++ examples/painting/affine/xform.h | 141 ++++++ examples/painting/affine/xform.html | 23 + 7 files changed, 1163 insertions(+) create mode 100644 examples/painting/affine/affine.pro create mode 100644 examples/painting/affine/affine.qrc create mode 100644 examples/painting/affine/bg1.jpg create mode 100644 examples/painting/affine/main.cpp create mode 100644 examples/painting/affine/xform.cpp create mode 100644 examples/painting/affine/xform.h create mode 100644 examples/painting/affine/xform.html (limited to 'examples/painting') diff --git a/examples/painting/affine/affine.pro b/examples/painting/affine/affine.pro new file mode 100644 index 0000000000..a3d6e30ad1 --- /dev/null +++ b/examples/painting/affine/affine.pro @@ -0,0 +1,25 @@ +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 +} + +SHARED_FOLDER = ../shared + +include($$SHARED_FOLDER/shared.pri) + +RESOURCES += affine.qrc + +# install +target.path = $$[QT_INSTALL_DEMOS]/qtbase/affine +sources.files = $$SOURCES $$HEADERS $$RESOURCES *.pro *.html *.jpg +sources.path = $$[QT_INSTALL_DEMOS]/qtbase/affine +INSTALLS += target sources + +symbian: CONFIG += qt_demo + +wince*: { + DEPLOYMENT_PLUGIN += qjpeg +} diff --git a/examples/painting/affine/affine.qrc b/examples/painting/affine/affine.qrc new file mode 100644 index 0000000000..d8a7ae40cb --- /dev/null +++ b/examples/painting/affine/affine.qrc @@ -0,0 +1,7 @@ + + + xform.cpp + xform.html + bg1.jpg + + diff --git a/examples/painting/affine/bg1.jpg b/examples/painting/affine/bg1.jpg new file mode 100644 index 0000000000..dfc7cee6ad Binary files /dev/null and b/examples/painting/affine/bg1.jpg differ diff --git a/examples/painting/affine/main.cpp b/examples/painting/affine/main.cpp new file mode 100644 index 0000000000..19758938f8 --- /dev/null +++ b/examples/painting/affine/main.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** 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 + +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 widgets = xformWidget.findChildren(); + foreach (QWidget *w, widgets) { + w->setStyle(arthurStyle); + w->setAttribute(Qt::WA_AcceptTouchEvents); + } + + xformWidget.show(); + + return app.exec(); +} diff --git a/examples/painting/affine/xform.cpp b/examples/painting/affine/xform.cpp new file mode 100644 index 0000000000..ea1916acc8 --- /dev/null +++ b/examples/painting/affine/xform.cpp @@ -0,0 +1,902 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** 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 +#include +#include + +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 Demo"); + textEditor->setEnabled(false); + + animateButton->animateClick(); +} diff --git a/examples/painting/affine/xform.h b/examples/painting/affine/xform.h new file mode 100644 index 0000000000..0cf837cbdd --- /dev/null +++ b/examples/painting/affine/xform.h @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** 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 +#include + +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/painting/affine/xform.html b/examples/painting/affine/xform.html new file mode 100644 index 0000000000..17325ac2a0 --- /dev/null +++ b/examples/painting/affine/xform.html @@ -0,0 +1,23 @@ + +
+

Affine Transformations

+
+ +

In this demo we demonstrate Qt's ability to perform affine transformations +on painting operations.

+ +

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:

+ +
    +
  • Dragging the red circle in the centre of each drawing moves it to a new + position.
  • +
  • Dragging the displaced red circle causes the current drawing to be + rotated about the central circle. Rotation can also be controlled with + the Rotate slider.
  • +
  • Scaling is controlled with the Scale slider.
  • +
  • Each drawing can be sheared with the Shear slider.
  • +
+ + -- cgit v1.2.3 From e0d5221957bf0d7857f924f1f2ae63d490de0a0a Mon Sep 17 00:00:00 2001 From: Casper van Donderen Date: Wed, 22 Jun 2011 13:54:56 +0200 Subject: Move all other demos in qtbase to examples. Change-Id: Iab0e7364d1f6b348d0e3033ea9304139f5bd6d0d Reviewed-on: http://codereview.qt.nokia.com/617 Reviewed-by: Qt Sanity Bot Reviewed-by: David Boddie --- examples/painting/composition/composition.cpp | 544 ++++++++++++++++ examples/painting/composition/composition.h | 193 ++++++ examples/painting/composition/composition.html | 23 + examples/painting/composition/composition.pro | 29 + examples/painting/composition/composition.qrc | 8 + examples/painting/composition/flower.jpg | Bin 0 -> 49616 bytes examples/painting/composition/flower_alpha.jpg | Bin 0 -> 67326 bytes examples/painting/composition/main.cpp | 68 ++ examples/painting/deform/deform.pro | 24 + examples/painting/deform/deform.qrc | 6 + examples/painting/deform/main.cpp | 72 +++ examples/painting/deform/pathdeform.cpp | 647 +++++++++++++++++++ examples/painting/deform/pathdeform.h | 153 +++++ examples/painting/deform/pathdeform.html | 24 + examples/painting/gradients/gradients.cpp | 516 ++++++++++++++++ examples/painting/gradients/gradients.h | 170 +++++ examples/painting/gradients/gradients.html | 31 + examples/painting/gradients/gradients.pro | 20 + examples/painting/gradients/gradients.qrc | 6 + examples/painting/gradients/main.cpp | 63 ++ examples/painting/pathstroke/main.cpp | 71 +++ examples/painting/pathstroke/pathstroke.cpp | 686 +++++++++++++++++++++ examples/painting/pathstroke/pathstroke.h | 171 +++++ examples/painting/pathstroke/pathstroke.html | 20 + examples/painting/pathstroke/pathstroke.pro | 24 + examples/painting/pathstroke/pathstroke.qrc | 6 + examples/painting/shared/arthurstyle.cpp | 452 ++++++++++++++ examples/painting/shared/arthurstyle.h | 79 +++ examples/painting/shared/arthurwidgets.cpp | 371 +++++++++++ examples/painting/shared/arthurwidgets.h | 137 ++++ examples/painting/shared/hoverpoints.cpp | 415 +++++++++++++ examples/painting/shared/hoverpoints.h | 162 +++++ examples/painting/shared/images/bg_pattern.png | Bin 0 -> 104 bytes .../shared/images/button_normal_cap_left.png | Bin 0 -> 654 bytes .../shared/images/button_normal_cap_right.png | Bin 0 -> 674 bytes .../shared/images/button_normal_stretch.png | Bin 0 -> 185 bytes .../shared/images/button_pressed_cap_left.png | Bin 0 -> 710 bytes .../shared/images/button_pressed_cap_right.png | Bin 0 -> 785 bytes .../shared/images/button_pressed_stretch.png | Bin 0 -> 217 bytes .../painting/shared/images/curve_thing_edit-6.png | Bin 0 -> 58097 bytes examples/painting/shared/images/frame_bottom.png | Bin 0 -> 166 bytes .../painting/shared/images/frame_bottomleft.png | Bin 0 -> 602 bytes .../painting/shared/images/frame_bottomright.png | Bin 0 -> 553 bytes examples/painting/shared/images/frame_left.png | Bin 0 -> 182 bytes examples/painting/shared/images/frame_right.png | Bin 0 -> 175 bytes examples/painting/shared/images/frame_top.png | Bin 0 -> 188 bytes examples/painting/shared/images/frame_topleft.png | Bin 0 -> 801 bytes examples/painting/shared/images/frame_topright.png | Bin 0 -> 851 bytes .../shared/images/groupframe_bottom_left.png | Bin 0 -> 397 bytes .../shared/images/groupframe_bottom_right.png | Bin 0 -> 383 bytes .../shared/images/groupframe_bottom_stretch.png | Bin 0 -> 141 bytes .../shared/images/groupframe_left_stretch.png | Bin 0 -> 132 bytes .../shared/images/groupframe_right_stretch.png | Bin 0 -> 113 bytes .../shared/images/groupframe_top_stretch.png | Bin 0 -> 115 bytes .../painting/shared/images/groupframe_topleft.png | Bin 0 -> 412 bytes .../painting/shared/images/groupframe_topright.png | Bin 0 -> 449 bytes examples/painting/shared/images/line_dash_dot.png | Bin 0 -> 151 bytes .../painting/shared/images/line_dash_dot_dot.png | Bin 0 -> 155 bytes examples/painting/shared/images/line_dashed.png | Bin 0 -> 121 bytes examples/painting/shared/images/line_dotted.png | Bin 0 -> 116 bytes examples/painting/shared/images/line_solid.png | Bin 0 -> 110 bytes .../painting/shared/images/radiobutton-off.png | Bin 0 -> 442 bytes examples/painting/shared/images/radiobutton-on.png | Bin 0 -> 474 bytes .../painting/shared/images/radiobutton_off.png | Bin 0 -> 442 bytes examples/painting/shared/images/radiobutton_on.png | Bin 0 -> 499 bytes examples/painting/shared/images/slider_bar.png | Bin 0 -> 748 bytes .../painting/shared/images/slider_thumb_off.png | Bin 0 -> 823 bytes .../painting/shared/images/slider_thumb_on.png | Bin 0 -> 798 bytes examples/painting/shared/images/title_cap_left.png | Bin 0 -> 179 bytes .../painting/shared/images/title_cap_right.png | Bin 0 -> 184 bytes examples/painting/shared/images/title_stretch.png | Bin 0 -> 106 bytes examples/painting/shared/shared.pri | 21 + examples/painting/shared/shared.pro | 39 ++ examples/painting/shared/shared.qrc | 39 ++ 74 files changed, 5290 insertions(+) create mode 100644 examples/painting/composition/composition.cpp create mode 100644 examples/painting/composition/composition.h create mode 100644 examples/painting/composition/composition.html create mode 100644 examples/painting/composition/composition.pro create mode 100644 examples/painting/composition/composition.qrc create mode 100644 examples/painting/composition/flower.jpg create mode 100644 examples/painting/composition/flower_alpha.jpg create mode 100644 examples/painting/composition/main.cpp create mode 100644 examples/painting/deform/deform.pro create mode 100644 examples/painting/deform/deform.qrc create mode 100644 examples/painting/deform/main.cpp create mode 100644 examples/painting/deform/pathdeform.cpp create mode 100644 examples/painting/deform/pathdeform.h create mode 100644 examples/painting/deform/pathdeform.html create mode 100644 examples/painting/gradients/gradients.cpp create mode 100644 examples/painting/gradients/gradients.h create mode 100644 examples/painting/gradients/gradients.html create mode 100644 examples/painting/gradients/gradients.pro create mode 100644 examples/painting/gradients/gradients.qrc create mode 100644 examples/painting/gradients/main.cpp create mode 100644 examples/painting/pathstroke/main.cpp create mode 100644 examples/painting/pathstroke/pathstroke.cpp create mode 100644 examples/painting/pathstroke/pathstroke.h create mode 100644 examples/painting/pathstroke/pathstroke.html create mode 100644 examples/painting/pathstroke/pathstroke.pro create mode 100644 examples/painting/pathstroke/pathstroke.qrc create mode 100644 examples/painting/shared/arthurstyle.cpp create mode 100644 examples/painting/shared/arthurstyle.h create mode 100644 examples/painting/shared/arthurwidgets.cpp create mode 100644 examples/painting/shared/arthurwidgets.h create mode 100644 examples/painting/shared/hoverpoints.cpp create mode 100644 examples/painting/shared/hoverpoints.h create mode 100644 examples/painting/shared/images/bg_pattern.png create mode 100644 examples/painting/shared/images/button_normal_cap_left.png create mode 100644 examples/painting/shared/images/button_normal_cap_right.png create mode 100644 examples/painting/shared/images/button_normal_stretch.png create mode 100644 examples/painting/shared/images/button_pressed_cap_left.png create mode 100644 examples/painting/shared/images/button_pressed_cap_right.png create mode 100644 examples/painting/shared/images/button_pressed_stretch.png create mode 100644 examples/painting/shared/images/curve_thing_edit-6.png create mode 100644 examples/painting/shared/images/frame_bottom.png create mode 100644 examples/painting/shared/images/frame_bottomleft.png create mode 100644 examples/painting/shared/images/frame_bottomright.png create mode 100644 examples/painting/shared/images/frame_left.png create mode 100644 examples/painting/shared/images/frame_right.png create mode 100644 examples/painting/shared/images/frame_top.png create mode 100644 examples/painting/shared/images/frame_topleft.png create mode 100644 examples/painting/shared/images/frame_topright.png create mode 100644 examples/painting/shared/images/groupframe_bottom_left.png create mode 100644 examples/painting/shared/images/groupframe_bottom_right.png create mode 100644 examples/painting/shared/images/groupframe_bottom_stretch.png create mode 100644 examples/painting/shared/images/groupframe_left_stretch.png create mode 100644 examples/painting/shared/images/groupframe_right_stretch.png create mode 100644 examples/painting/shared/images/groupframe_top_stretch.png create mode 100644 examples/painting/shared/images/groupframe_topleft.png create mode 100644 examples/painting/shared/images/groupframe_topright.png create mode 100644 examples/painting/shared/images/line_dash_dot.png create mode 100644 examples/painting/shared/images/line_dash_dot_dot.png create mode 100644 examples/painting/shared/images/line_dashed.png create mode 100644 examples/painting/shared/images/line_dotted.png create mode 100644 examples/painting/shared/images/line_solid.png create mode 100644 examples/painting/shared/images/radiobutton-off.png create mode 100644 examples/painting/shared/images/radiobutton-on.png create mode 100644 examples/painting/shared/images/radiobutton_off.png create mode 100644 examples/painting/shared/images/radiobutton_on.png create mode 100644 examples/painting/shared/images/slider_bar.png create mode 100644 examples/painting/shared/images/slider_thumb_off.png create mode 100644 examples/painting/shared/images/slider_thumb_on.png create mode 100644 examples/painting/shared/images/title_cap_left.png create mode 100644 examples/painting/shared/images/title_cap_right.png create mode 100644 examples/painting/shared/images/title_stretch.png create mode 100644 examples/painting/shared/shared.pri create mode 100644 examples/painting/shared/shared.pro create mode 100644 examples/painting/shared/shared.qrc (limited to 'examples/painting') diff --git a/examples/painting/composition/composition.cpp b/examples/painting/composition/composition.cpp new file mode 100644 index 0000000000..b3f810b26c --- /dev/null +++ b/examples/painting/composition/composition.cpp @@ -0,0 +1,544 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** 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 +#include +#include +#include +#include +#include +#include + +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); +#ifdef Q_WS_QWS + m_image = QPixmap(":res/composition/flower.jpg"); + m_image.setAlphaChannel(QPixmap(":res/composition/flower_alpha.jpg")); +#else + m_image = QImage(":res/composition/flower.jpg"); + m_image.setAlphaChannel(QImage(":res/composition/flower_alpha.jpg")); +#endif + 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); +#ifdef Q_WS_QWS + p.drawPixmap(rect(), m_image); +#else + p.drawImage(rect(), m_image); +#endif +} + +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()) { +#ifdef Q_WS_QWS + m_base_buffer = QPixmap(size()); + m_base_buffer.fill(Qt::transparent); +#else + m_buffer = QImage(size(), QImage::Format_ARGB32_Premultiplied); + m_base_buffer = QImage(size(), QImage::Format_ARGB32_Premultiplied); + + m_base_buffer.fill(0); +#endif + + QPainter p(&m_base_buffer); + + drawBase(p); + } + +#ifdef Q_WS_QWS + m_buffer = m_base_buffer; +#else + memcpy(m_buffer.bits(), m_base_buffer.bits(), m_buffer.byteCount()); +#endif + + { + QPainter p(&m_buffer); + drawSource(p); + } + +#ifdef Q_WS_QWS + painter->drawPixmap(0, 0, m_buffer); +#else + painter->drawImage(0, 0, m_buffer); +#endif + } +} + +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/painting/composition/composition.h b/examples/painting/composition/composition.h new file mode 100644 index 0000000000..86e8f5c0df --- /dev/null +++ b/examples/painting/composition/composition.h @@ -0,0 +1,193 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** 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 +#include + +QT_FORWARD_DECLARE_CLASS(QPushButton) +QT_FORWARD_DECLARE_CLASS(QRadioButton) + +#ifdef QT_OPENGL_SUPPORT +#include +#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; + +#ifdef Q_WS_QWS + QPixmap m_image; + QPixmap m_buffer; + QPixmap m_base_buffer; +#else + QImage m_image; + QImage m_buffer; + QImage m_base_buffer; +#endif + + 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/painting/composition/composition.html b/examples/painting/composition/composition.html new file mode 100644 index 0000000000..1848ad8bd1 --- /dev/null +++ b/examples/painting/composition/composition.html @@ -0,0 +1,23 @@ + + +

Demo for composition modes

+ +

+ This demo shows some of the more advanced composition modes supported by Qt. +

+ +

+ The two most common forms of composition are Source and SourceOver. + Source 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 SourceOver composition mode, the source object is transparent and is + drawn on top of the destination. +

+ +

+ In addition to these standard modes, Qt defines the complete set of composition + modes as defined by Thomas Porter and Tom Duff. See the QPainter documentation + for details. +

+ + diff --git a/examples/painting/composition/composition.pro b/examples/painting/composition/composition.pro new file mode 100644 index 0000000000..59b91126b9 --- /dev/null +++ b/examples/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 +} + +# install +target.path = $$[QT_INSTALL_DEMOS]/qtbase/composition +sources.files = $$SOURCES $$HEADERS $$RESOURCES *.png *.jpg *.pro *.html +sources.path = $$[QT_INSTALL_DEMOS]/qtbase/composition +INSTALLS += target sources + +symbian: CONFIG += qt_demo + +win32-msvc* { + QMAKE_CXXFLAGS += /Zm500 + QMAKE_CFLAGS += /Zm500 +} + +wince* { + DEPLOYMENT_PLUGIN += qjpeg +} diff --git a/examples/painting/composition/composition.qrc b/examples/painting/composition/composition.qrc new file mode 100644 index 0000000000..d02c397ee8 --- /dev/null +++ b/examples/painting/composition/composition.qrc @@ -0,0 +1,8 @@ + + + composition.cpp + composition.html + flower.jpg + flower_alpha.jpg + + diff --git a/examples/painting/composition/flower.jpg b/examples/painting/composition/flower.jpg new file mode 100644 index 0000000000..f8e022c98c Binary files /dev/null and b/examples/painting/composition/flower.jpg differ diff --git a/examples/painting/composition/flower_alpha.jpg b/examples/painting/composition/flower_alpha.jpg new file mode 100644 index 0000000000..6a3c2a02ef Binary files /dev/null and b/examples/painting/composition/flower_alpha.jpg differ diff --git a/examples/painting/composition/main.cpp b/examples/painting/composition/main.cpp new file mode 100644 index 0000000000..d6bc170a97 --- /dev/null +++ b/examples/painting/composition/main.cpp @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** 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 +#ifdef QT_OPENGL_SUPPORT +#include +#endif + +int main(int argc, char **argv) +{ + // Q_INIT_RESOURCE(deform); + +#ifdef QT_OPENGL_SUPPORT + QGL::setPreferredPaintEngine(QPaintEngine::OpenGL); +#endif + QApplication app(argc, argv); + + CompositionWidget compWidget(0); + QStyle *arthurStyle = new ArthurStyle(); + compWidget.setStyle(arthurStyle); + + QList widgets = compWidget.findChildren(); + foreach (QWidget *w, widgets) + w->setStyle(arthurStyle); + compWidget.show(); + + return app.exec(); +} diff --git a/examples/painting/deform/deform.pro b/examples/painting/deform/deform.pro new file mode 100644 index 0000000000..3393b8e83c --- /dev/null +++ b/examples/painting/deform/deform.pro @@ -0,0 +1,24 @@ +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 +} + +# install +target.path = $$[QT_INSTALL_DEMOS]/qtbase/deform +sources.files = $$SOURCES $$HEADERS $$RESOURCES *.pro *.html +sources.path = $$[QT_INSTALL_DEMOS]/qtbase/deform +INSTALLS += target sources + +symbian { + TARGET.UID3 = 0xA000A63D + CONFIG += qt_demo +} diff --git a/examples/painting/deform/deform.qrc b/examples/painting/deform/deform.qrc new file mode 100644 index 0000000000..2e59ebcfc5 --- /dev/null +++ b/examples/painting/deform/deform.qrc @@ -0,0 +1,6 @@ + + + pathdeform.cpp + pathdeform.html + + diff --git a/examples/painting/deform/main.cpp b/examples/painting/deform/main.cpp new file mode 100644 index 0000000000..c49117a2f2 --- /dev/null +++ b/examples/painting/deform/main.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "pathdeform.h" + +#include +#include + +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 widgets = deformWidget.findChildren(); + 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/painting/deform/pathdeform.cpp b/examples/painting/deform/pathdeform.cpp new file mode 100644 index 0000000000..f80ef2b8be --- /dev/null +++ b/examples/painting/deform/pathdeform.cpp @@ -0,0 +1,647 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "pathdeform.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PathDeformControls::PathDeformControls(QWidget *parent, PathDeformRenderer* renderer, bool smallScreen) + : QWidget(parent) +{ + m_renderer = renderer; + + if (smallScreen) + layoutForSmallScreen(); + else + layoutForDesktop(); +} + + +void PathDeformControls::layoutForDesktop() +{ + QGroupBox* mainGroup = new QGroupBox(this); + mainGroup->setTitle(tr("Controls")); + + QGroupBox *radiusGroup = new QGroupBox(mainGroup); + radiusGroup->setTitle(tr("Lens Radius")); + QSlider *radiusSlider = new QSlider(Qt::Horizontal, radiusGroup); + radiusSlider->setRange(15, 150); + radiusSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + + QGroupBox *deformGroup = new QGroupBox(mainGroup); + deformGroup->setTitle(tr("Deformation")); + QSlider *deformSlider = new QSlider(Qt::Horizontal, deformGroup); + deformSlider->setRange(-100, 100); + deformSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + + QGroupBox *fontSizeGroup = new QGroupBox(mainGroup); + fontSizeGroup->setTitle(tr("Font Size")); + QSlider *fontSizeSlider = new QSlider(Qt::Horizontal, fontSizeGroup); + fontSizeSlider->setRange(16, 200); + fontSizeSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + + QGroupBox *textGroup = new QGroupBox(mainGroup); + textGroup->setTitle(tr("Text")); + QLineEdit *textInput = new QLineEdit(textGroup); + + QPushButton *animateButton = new QPushButton(mainGroup); + animateButton->setText(tr("Animated")); + animateButton->setCheckable(true); + + QPushButton *showSourceButton = new QPushButton(mainGroup); + showSourceButton->setText(tr("Show Source")); + +#ifdef QT_OPENGL_SUPPORT + QPushButton *enableOpenGLButton = new QPushButton(mainGroup); + enableOpenGLButton->setText(tr("Use OpenGL")); + enableOpenGLButton->setCheckable(true); + enableOpenGLButton->setChecked(m_renderer->usesOpenGL()); + if (!QGLFormat::hasOpenGL()) + enableOpenGLButton->hide(); +#endif + + QPushButton *whatsThisButton = new QPushButton(mainGroup); + whatsThisButton->setText(tr("What's This?")); + whatsThisButton->setCheckable(true); + + + mainGroup->setFixedWidth(180); + + QVBoxLayout *mainGroupLayout = new QVBoxLayout(mainGroup); + mainGroupLayout->addWidget(radiusGroup); + mainGroupLayout->addWidget(deformGroup); + mainGroupLayout->addWidget(fontSizeGroup); + mainGroupLayout->addWidget(textGroup); + mainGroupLayout->addWidget(animateButton); + mainGroupLayout->addStretch(1); +#ifdef QT_OPENGL_SUPPORT + mainGroupLayout->addWidget(enableOpenGLButton); +#endif + mainGroupLayout->addWidget(showSourceButton); + mainGroupLayout->addWidget(whatsThisButton); + + QVBoxLayout *radiusGroupLayout = new QVBoxLayout(radiusGroup); + radiusGroupLayout->addWidget(radiusSlider); + + QVBoxLayout *deformGroupLayout = new QVBoxLayout(deformGroup); + deformGroupLayout->addWidget(deformSlider); + + QVBoxLayout *fontSizeGroupLayout = new QVBoxLayout(fontSizeGroup); + fontSizeGroupLayout->addWidget(fontSizeSlider); + + QVBoxLayout *textGroupLayout = new QVBoxLayout(textGroup); + textGroupLayout->addWidget(textInput); + + QVBoxLayout * mainLayout = new QVBoxLayout(this); + mainLayout->addWidget(mainGroup); + mainLayout->setMargin(0); + + connect(radiusSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setRadius(int))); + connect(deformSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setIntensity(int))); + connect(fontSizeSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setFontSize(int))); + connect(animateButton, SIGNAL(clicked(bool)), m_renderer, SLOT(setAnimated(bool))); +#ifdef QT_OPENGL_SUPPORT + connect(enableOpenGLButton, SIGNAL(clicked(bool)), m_renderer, SLOT(enableOpenGL(bool))); +#endif + + connect(textInput, SIGNAL(textChanged(QString)), m_renderer, SLOT(setText(QString))); + connect(m_renderer, SIGNAL(descriptionEnabledChanged(bool)), + whatsThisButton, SLOT(setChecked(bool))); + connect(whatsThisButton, SIGNAL(clicked(bool)), m_renderer, SLOT(setDescriptionEnabled(bool))); + connect(showSourceButton, SIGNAL(clicked()), m_renderer, SLOT(showSource())); + + animateButton->animateClick(); + deformSlider->setValue(80); + fontSizeSlider->setValue(120); + radiusSlider->setValue(100); + textInput->setText(tr("Qt")); +} + +void PathDeformControls::layoutForSmallScreen() +{ + QGroupBox* mainGroup = new QGroupBox(this); + mainGroup->setTitle(tr("Controls")); + + QLabel *radiusLabel = new QLabel(mainGroup); + radiusLabel->setText(tr("Lens Radius:")); + QSlider *radiusSlider = new QSlider(Qt::Horizontal, mainGroup); + radiusSlider->setRange(15, 150); + radiusSlider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + + QLabel *deformLabel = new QLabel(mainGroup); + deformLabel->setText(tr("Deformation:")); + QSlider *deformSlider = new QSlider(Qt::Horizontal, mainGroup); + deformSlider->setRange(-100, 100); + deformSlider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + + QLabel *fontSizeLabel = new QLabel(mainGroup); + fontSizeLabel->setText(tr("Font Size:")); + QSlider *fontSizeSlider = new QSlider(Qt::Horizontal, mainGroup); + fontSizeSlider->setRange(16, 200); + fontSizeSlider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + + QPushButton *animateButton = new QPushButton(tr("Animated"), mainGroup); + animateButton->setCheckable(true); + +#ifdef QT_OPENGL_SUPPORT + QPushButton *enableOpenGLButton = new QPushButton(mainGroup); + enableOpenGLButton->setText(tr("Use OpenGL")); + enableOpenGLButton->setCheckable(mainGroup); + enableOpenGLButton->setChecked(m_renderer->usesOpenGL()); + if (!QGLFormat::hasOpenGL()) + enableOpenGLButton->hide(); +#endif + + QPushButton *quitButton = new QPushButton(tr("Quit"), mainGroup); + QPushButton *okButton = new QPushButton(tr("OK"), mainGroup); + + + QGridLayout *mainGroupLayout = new QGridLayout(mainGroup); + mainGroupLayout->setMargin(0); + mainGroupLayout->addWidget(radiusLabel, 0, 0, Qt::AlignRight); + mainGroupLayout->addWidget(radiusSlider, 0, 1); + mainGroupLayout->addWidget(deformLabel, 1, 0, Qt::AlignRight); + mainGroupLayout->addWidget(deformSlider, 1, 1); + mainGroupLayout->addWidget(fontSizeLabel, 2, 0, Qt::AlignRight); + mainGroupLayout->addWidget(fontSizeSlider, 2, 1); + mainGroupLayout->addWidget(animateButton, 3,0, 1,2); +#ifdef QT_OPENGL_SUPPORT + mainGroupLayout->addWidget(enableOpenGLButton, 4,0, 1,2); +#endif + + QVBoxLayout *mainLayout = new QVBoxLayout(this); + mainLayout->addWidget(mainGroup); + mainLayout->addStretch(1); + mainLayout->addWidget(okButton); + mainLayout->addWidget(quitButton); + + connect(quitButton, SIGNAL(clicked()), this, SLOT(emitQuitSignal())); + connect(okButton, SIGNAL(clicked()), this, SLOT(emitOkSignal())); + connect(radiusSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setRadius(int))); + connect(deformSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setIntensity(int))); + connect(fontSizeSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setFontSize(int))); + connect(animateButton, SIGNAL(clicked(bool)), m_renderer, SLOT(setAnimated(bool))); +#ifdef QT_OPENGL_SUPPORT + connect(enableOpenGLButton, SIGNAL(clicked(bool)), m_renderer, SLOT(enableOpenGL(bool))); +#endif + + + animateButton->animateClick(); + deformSlider->setValue(80); + fontSizeSlider->setValue(120); + + QRect screen_size = QApplication::desktop()->screenGeometry(); + radiusSlider->setValue(qMin(screen_size.width(), screen_size.height())/5); + + m_renderer->setText(tr("Qt")); +} + + +void PathDeformControls::emitQuitSignal() +{ emit quitPressed(); } + +void PathDeformControls::emitOkSignal() +{ emit okPressed(); } + + +PathDeformWidget::PathDeformWidget(QWidget *parent, bool smallScreen) + : QWidget(parent) +{ + setWindowTitle(tr("Vector Deformation")); + + m_renderer = new PathDeformRenderer(this, smallScreen); + m_renderer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + // Layouts + QHBoxLayout *mainLayout = new QHBoxLayout(this); + mainLayout->addWidget(m_renderer); + + m_controls = new PathDeformControls(0, m_renderer, smallScreen); + m_controls->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); + + if (!smallScreen) + mainLayout->addWidget(m_controls); + + m_renderer->loadSourceFile(":res/deform/pathdeform.cpp"); + m_renderer->loadDescription(":res/deform/pathdeform.html"); + m_renderer->setDescriptionEnabled(false); + + connect(m_renderer, SIGNAL(clicked()), this, SLOT(showControls())); + connect(m_controls, SIGNAL(okPressed()), this, SLOT(hideControls())); + connect(m_controls, SIGNAL(quitPressed()), QApplication::instance(), SLOT(quit())); +} + + +void PathDeformWidget::showControls() +{ + m_controls->showFullScreen(); +} + +void PathDeformWidget::hideControls() +{ + m_controls->hide(); +} + +void PathDeformWidget::setStyle( QStyle * style ) +{ + QWidget::setStyle(style); + if (m_controls != 0) + { + m_controls->setStyle(style); + + QList widgets = m_controls->findChildren(); + foreach (QWidget *w, widgets) + w->setStyle(style); + } +} + +static inline QRect circle_bounds(const QPointF ¢er, qreal radius, qreal compensation) +{ + return QRect(qRound(center.x() - radius - compensation), + qRound(center.y() - radius - compensation), + qRound((radius + compensation) * 2), + qRound((radius + compensation) * 2)); + +} + +const int LENS_EXTENT = 10; + +PathDeformRenderer::PathDeformRenderer(QWidget *widget, bool smallScreen) + : ArthurFrame(widget) +{ + m_radius = 100; + m_pos = QPointF(m_radius, m_radius); + m_direction = QPointF(1, 1); + m_fontSize = 24; + m_animated = true; + m_repaintTimer.start(25, this); + m_repaintTracker.start(); + m_intensity = 100; + m_smallScreen = smallScreen; + +// m_fpsTimer.start(1000, this); +// m_fpsCounter = 0; + + generateLensPixmap(); +} + +void PathDeformRenderer::setText(const QString &text) +{ + m_text = text; + + QFont f("times new roman,utopia"); + f.setStyleStrategy(QFont::ForceOutline); + f.setPointSize(m_fontSize); + f.setStyleHint(QFont::Times); + + QFontMetrics fm(f); + + m_paths.clear(); + m_pathBounds = QRect(); + + QPointF advance(0, 0); + + bool do_quick = true; + for (int i=0; i= 0x4ff && text.at(i).unicode() <= 0x1e00) { + do_quick = false; + break; + } + } + + if (do_quick) { + for (int i=0; itimerId() == m_repaintTimer.timerId()) { + + if (QLineF(QPointF(0,0), m_direction).length() > 1) + m_direction *= 0.995; + qreal time = m_repaintTracker.restart(); + + QRect rectBefore = circle_bounds(m_pos, m_radius, m_fontSize); + + qreal dx = m_direction.x(); + qreal dy = m_direction.y(); + if (time > 0) { + dx = dx * time * .1; + dy = dy * time * .1; + } + + m_pos += QPointF(dx, dy); + + + + if (m_pos.x() - m_radius < 0) { + m_direction.setX(-m_direction.x()); + m_pos.setX(m_radius); + } else if (m_pos.x() + m_radius > width()) { + m_direction.setX(-m_direction.x()); + m_pos.setX(width() - m_radius); + } + + if (m_pos.y() - m_radius < 0) { + m_direction.setY(-m_direction.y()); + m_pos.setY(m_radius); + } else if (m_pos.y() + m_radius > height()) { + m_direction.setY(-m_direction.y()); + m_pos.setY(height() - m_radius); + } + +#ifdef QT_OPENGL_SUPPORT + if (usesOpenGL()) { + update(); + } else +#endif + { + QRect rectAfter = circle_bounds(m_pos, m_radius, m_fontSize); + update(rectAfter | rectBefore); + QApplication::syncX(); + } + } +// else if (e->timerId() == m_fpsTimer.timerId()) { +// printf("fps: %d\n", m_fpsCounter); +// emit frameRate(m_fpsCounter); +// m_fpsCounter = 0; + +// } +} + +void PathDeformRenderer::mousePressEvent(QMouseEvent *e) +{ + setDescriptionEnabled(false); + + m_repaintTimer.stop(); + m_offset = QPointF(); + if (QLineF(m_pos, e->pos()).length() <= m_radius) + m_offset = m_pos - e->pos(); + + m_mousePress = e->pos(); + + // If we're not running in small screen mode, always assume we're dragging + m_mouseDrag = !m_smallScreen; + + mouseMoveEvent(e); +} + +void PathDeformRenderer::mouseReleaseEvent(QMouseEvent *e) +{ + if (e->buttons() == Qt::NoButton && m_animated) { + m_repaintTimer.start(10, this); + m_repaintTracker.start(); + } + + if (!m_mouseDrag && m_smallScreen) + emit clicked(); +} + +void PathDeformRenderer::mouseMoveEvent(QMouseEvent *e) +{ + if (!m_mouseDrag && (QLineF(m_mousePress, e->pos()).length() > 25.0) ) + m_mouseDrag = true; + + if (m_mouseDrag) { + QRect rectBefore = circle_bounds(m_pos, m_radius, m_fontSize); + if (e->type() == QEvent::MouseMove) { + QLineF line(m_pos, e->pos() + m_offset); + line.setLength(line.length() * .1); + QPointF dir(line.dx(), line.dy()); + m_direction = (m_direction + dir) / 2; + } + m_pos = e->pos() + m_offset; +#ifdef QT_OPENGL_SUPPORT + if (usesOpenGL()) { + update(); + } else +#endif + { + QRect rectAfter = circle_bounds(m_pos, m_radius, m_fontSize); + update(rectBefore | rectAfter); + } + } +} + +QPainterPath PathDeformRenderer::lensDeform(const QPainterPath &source, const QPointF &offset) +{ + QPainterPath path; + path.addPath(source); + + qreal flip = m_intensity / qreal(100); + + for (int i=0; i 0) { + path.setElementPositionAt(i, + x + flip * dx * len / m_radius, + y + flip * dy * len / m_radius); + } else { + path.setElementPositionAt(i, x, y); + } + + } + + return path; +} + + +void PathDeformRenderer::paint(QPainter *painter) +{ + int pad_x = 5; + int pad_y = 5; + + int skip_x = qRound(m_pathBounds.width() + pad_x + m_fontSize/2); + int skip_y = qRound(m_pathBounds.height() + pad_y); + + painter->setPen(Qt::NoPen); + painter->setBrush(Qt::black); + + QRectF clip(painter->clipPath().boundingRect()); + + int overlap = pad_x / 2; + + for (int start_y=0; start_y < height(); start_y += skip_y) { + + if (start_y > clip.bottom()) + break; + + int start_x = -overlap; + for (; start_x < width(); start_x += skip_x) { + + if (start_y + skip_y >= clip.top() && + start_x + skip_x >= clip.left() && + start_x <= clip.right()) { + for (int i=0; idrawPath(path); + } + } + } + overlap = skip_x - (start_x - width()); + + } + + if (preferImage()) { + painter->drawImage(m_pos - QPointF(m_radius + LENS_EXTENT, m_radius + LENS_EXTENT), + m_lens_image); + } else { + painter->drawPixmap(m_pos - QPointF(m_radius + LENS_EXTENT, m_radius + LENS_EXTENT), + m_lens_pixmap); + } +} + + + +void PathDeformRenderer::setRadius(int radius) +{ + qreal max = qMax(m_radius, (qreal)radius); + m_radius = radius; + generateLensPixmap(); + if (!m_animated || m_radius < max) { +#ifdef QT_OPENGL_SUPPORT + if (usesOpenGL()) { + update(); + } else +#endif + { + update(circle_bounds(m_pos, max, m_fontSize)); + } + } +} + +void PathDeformRenderer::setIntensity(int intensity) +{ + m_intensity = intensity; + if (!m_animated) { +#ifdef QT_OPENGL_SUPPORT + if (usesOpenGL()) { + update(); + } else +#endif + { + update(circle_bounds(m_pos, m_radius, m_fontSize)); + } + } +} diff --git a/examples/painting/deform/pathdeform.h b/examples/painting/deform/pathdeform.h new file mode 100644 index 0000000000..73a1955082 --- /dev/null +++ b/examples/painting/deform/pathdeform.h @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** 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 +#include +#include + +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 m_paths; + QVector 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/painting/deform/pathdeform.html b/examples/painting/deform/pathdeform.html new file mode 100644 index 0000000000..b3f63a8e0a --- /dev/null +++ b/examples/painting/deform/pathdeform.html @@ -0,0 +1,24 @@ + +
+

Vector deformation

+
+ +

This demo shows how to use advanced vector techniques to draw text +using a QPainterPath.

+ +

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.

+ +

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 +QPainterPath::addText() function.

+ +

The lens is drawn using a single call to drawEllipse(), using +a QRadialGradient 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.

+ + diff --git a/examples/painting/gradients/gradients.cpp b/examples/painting/gradients/gradients.cpp new file mode 100644 index 0000000000..d8b739b3b0 --- /dev/null +++ b/examples/painting/gradients/gradients.cpp @@ -0,0 +1,516 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** 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; isetSpacing(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; icolorAt(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; iwidth(), 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 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; isetBrush(g); + p->setPen(Qt::NoPen); + + p->drawRect(rect()); + +} diff --git a/examples/painting/gradients/gradients.h b/examples/painting/gradients/gradients.h new file mode 100644 index 0000000000..e1a2bcb41e --- /dev/null +++ b/examples/painting/gradients/gradients.h @@ -0,0 +1,170 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** 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 + +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/painting/gradients/gradients.html b/examples/painting/gradients/gradients.html new file mode 100644 index 0000000000..1ea2c0ed6c --- /dev/null +++ b/examples/painting/gradients/gradients.html @@ -0,0 +1,31 @@ + +
+

Gradients

+
+ +

In this demo we show the various types of gradients that can +be used in Qt.

+ +

There are three types of gradients: + +

    +
  • Linear gradients interpolate colors between start and end + points.
  • +
  • Radial gradients interpolate colors between a focal point and the + points on a circle surrounding it.
  • +
  • Conical gradients interpolate colors around a center point.
  • +
+ +

+ +

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.

+ +

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.

+ + diff --git a/examples/painting/gradients/gradients.pro b/examples/painting/gradients/gradients.pro new file mode 100644 index 0000000000..ed4120e01c --- /dev/null +++ b/examples/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 +} + +# install +target.path = $$[QT_INSTALL_DEMOS]/qtbase/gradients +sources.files = $$SOURCES $$HEADERS $$RESOURCES *.pro *.html +sources.path = $$[QT_INSTALL_DEMOS]/qtbase/gradients +INSTALLS += target sources + +symbian: CONFIG += qt_demo diff --git a/examples/painting/gradients/gradients.qrc b/examples/painting/gradients/gradients.qrc new file mode 100644 index 0000000000..fb971eb17b --- /dev/null +++ b/examples/painting/gradients/gradients.qrc @@ -0,0 +1,6 @@ + + + gradients.cpp + gradients.html + + diff --git a/examples/painting/gradients/main.cpp b/examples/painting/gradients/main.cpp new file mode 100644 index 0000000000..1d2f0d5775 --- /dev/null +++ b/examples/painting/gradients/main.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** 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 + +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 widgets = gradientWidget.findChildren(); + foreach (QWidget *w, widgets) { + w->setStyle(arthurStyle); + w->setAttribute(Qt::WA_AcceptTouchEvents); + } + gradientWidget.show(); + + return app.exec(); +} diff --git a/examples/painting/pathstroke/main.cpp b/examples/painting/pathstroke/main.cpp new file mode 100644 index 0000000000..b357f99336 --- /dev/null +++ b/examples/painting/pathstroke/main.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** 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 + +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 widgets = pathStrokeWidget.findChildren(); + 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/painting/pathstroke/pathstroke.cpp b/examples/painting/pathstroke/pathstroke.cpp new file mode 100644 index 0000000000..02c35f7721 --- /dev/null +++ b/examples/painting/pathstroke/pathstroke.cpp @@ -0,0 +1,686 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** 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 + +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 widgets = m_controls->findChildren(); + 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 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; idrawEllipse(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 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; ipos(), 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(); + QApplication::syncX(); + } // 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(e); + const QList 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 activePoints = QSet::fromList(m_fingerPointMapping.values()); + int activePoint = -1; + qreal distance = -1; + const int pointsCount = m_points.size(); + for (int i=0; i::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/painting/pathstroke/pathstroke.h b/examples/painting/pathstroke/pathstroke.h new file mode 100644 index 0000000000..f0360b6648 --- /dev/null +++ b/examples/painting/pathstroke/pathstroke.h @@ -0,0 +1,171 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** 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 + +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 m_points; + QVector m_vectors; + + Qt::PenJoinStyle m_joinStyle; + Qt::PenCapStyle m_capStyle; + + Qt::PenStyle m_penStyle; + + bool m_smallScreen; + QPoint m_mousePress; + bool m_mouseDrag; + + QHash 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/painting/pathstroke/pathstroke.html b/examples/painting/pathstroke/pathstroke.html new file mode 100644 index 0000000000..9e7e50de76 --- /dev/null +++ b/examples/painting/pathstroke/pathstroke.html @@ -0,0 +1,20 @@ + +
+

Primitive Stroking

+
+ +

In this demo we show some of the various types of pens that can be +used in Qt.

+ +

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 +QPen.

+ +

In addition to the predefined patterns available in +QPen we also demonstrate direct use of the +QPainterPathStroker class which can be used to define +custom dash patterns. You can see this by enabling the +Custom Pattern option.

+ + diff --git a/examples/painting/pathstroke/pathstroke.pro b/examples/painting/pathstroke/pathstroke.pro new file mode 100644 index 0000000000..9bbf8a6f77 --- /dev/null +++ b/examples/painting/pathstroke/pathstroke.pro @@ -0,0 +1,24 @@ +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 +} + +# install +target.path = $$[QT_INSTALL_DEMOS]/qtbase/pathstroke +sources.files = $$SOURCES $$HEADERS $$RESOURCES *.pro *.html +sources.path = $$[QT_INSTALL_DEMOS]/qtbase/pathstroke +INSTALLS += target sources + +symbian { + TARGET.UID3 = 0xA000A63E + CONFIG += qt_demo +} diff --git a/examples/painting/pathstroke/pathstroke.qrc b/examples/painting/pathstroke/pathstroke.qrc new file mode 100644 index 0000000000..a9a723409e --- /dev/null +++ b/examples/painting/pathstroke/pathstroke.qrc @@ -0,0 +1,6 @@ + + + pathstroke.cpp + pathstroke.html + + diff --git a/examples/painting/shared/arthurstyle.cpp b/examples/painting/shared/arthurstyle.cpp new file mode 100644 index 0000000000..432b8b34e5 --- /dev/null +++ b/examples/painting/shared/arthurstyle.cpp @@ -0,0 +1,452 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** 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 +#include +#include +#include +#include +#include +#include +#include + +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(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(option)) { + bool hover = (button->state & State_Enabled) && (button->state & State_MouseOver); + + painter->save(); + const QPushButton *pushButton = qobject_cast(widget); + Q_ASSERT(pushButton); + QWidget *parent = pushButton->parentWidget(); + if (parent && qobject_cast(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(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(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(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(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(widget)) { + if (widget->findChildren().size() == 0) { + widget->layout()->setSpacing(0); + widget->layout()->setMargin(12); + } else { + widget->layout()->setMargin(13); + } + } + + if (qobject_cast(widget) + || qobject_cast(widget) + || qobject_cast(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(widget) + || qobject_cast(widget) + || qobject_cast(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(widget)) + r = r.adjusted(5, 0, -5, 0); + + return r; +} diff --git a/examples/painting/shared/arthurstyle.h b/examples/painting/shared/arthurstyle.h new file mode 100644 index 0000000000..32c7fad970 --- /dev/null +++ b/examples/painting/shared/arthurstyle.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** 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 + +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/painting/shared/arthurwidgets.cpp b/examples/painting/shared/arthurwidgets.cpp new file mode 100644 index 0000000000..b3c75f0fc4 --- /dev/null +++ b/examples/painting/shared/arthurwidgets.cpp @@ -0,0 +1,371 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +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 Q_WS_X11 + QPixmap xRenderPixmap(1, 1); + m_prefer_image = xRenderPixmap.pixmapData()->classId() == QPixmapData::X11Class && !xRenderPixmap.x11PictureHandle(); +#endif +} + + +#ifdef QT_OPENGL_SUPPORT +void ArthurFrame::enableOpenGL(bool use_opengl) +{ + m_use_opengl = use_opengl; + + if (!glw) { + glw = new GLWidget(this); + glw->setAutoFillBackground(false); + glw->disableAutoBufferSwap(); + QApplication::postEvent(this, new QResizeEvent(size(), size())); + } + + if (use_opengl) { + glw->show(); + } else { + glw->hide(); + } + + update(); +} +#endif + +void ArthurFrame::paintEvent(QPaintEvent *e) +{ +#ifdef Q_WS_QWS + static QPixmap *static_image = 0; +#else + static QImage *static_image = 0; +#endif + QPainter painter; + if (preferImage() +#ifdef QT_OPENGL_SUPPORT + && !m_use_opengl +#endif + ) { + if (!static_image || static_image->size() != size()) { + delete static_image; +#ifdef Q_WS_QWS + static_image = new QPixmap(size()); +#else + static_image = new QImage(size(), QImage::Format_RGB32); +#endif + } + 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); +#ifdef Q_WS_QWS + painter.drawPixmap(e->rect(), *static_image, e->rect()); +#else + painter.drawImage(e->rect(), *static_image, e->rect()); +#endif + } + +#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()) + 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('&', "&"); + contents.replace('<', "<"); + contents.replace('>', ">"); + + 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("") + keyword + QLatin1String("")); + contents.replace("(int ", "(int "); + + QStringList ppKeywords; + ppKeywords << "#ifdef" << "#ifndef" << "#if" << "#endif" << "#else"; + + foreach (QString keyword, ppKeywords) + contents.replace(keyword, QLatin1String("") + keyword + QLatin1String("")); + + contents.replace(QRegExp("(\\d\\d?)"), QLatin1String("\\1")); + + QRegExp commentRe("(//.+)\\n"); + commentRe.setMinimal(true); + contents.replace(commentRe, QLatin1String("\\1\n")); + + QRegExp stringLiteralRe("(\".+\")"); + stringLiteralRe.setMinimal(true); + contents.replace(stringLiteralRe, QLatin1String("\\1")); + + QString html = contents; + html.prepend("
");
+    html.append("
"); + + 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/painting/shared/arthurwidgets.h b/examples/painting/shared/arthurwidgets.h new file mode 100644 index 0000000000..dc8f92505d --- /dev/null +++ b/examples/painting/shared/arthurwidgets.h @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** 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 +#include +#include + +#if defined(QT_OPENGL_SUPPORT) +#include +#include +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/painting/shared/hoverpoints.cpp b/examples/painting/shared/hoverpoints.cpp new file mode 100644 index 0000000000..36c24186d3 --- /dev/null +++ b/examples/painting/shared/hoverpoints.cpp @@ -0,0 +1,415 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** 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 +#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; ibutton() == 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 clickPos.x()) { + pos = i; + break; + } + } else if (m_sortType == YSort) { + for (int i=0; i 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(event); + const QList 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 activePoints = QSet::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::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(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(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 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 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 + +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 m_locks; + + QSizeF m_pointSize; + int m_currentIndex; + bool m_editable; + bool m_enabled; + + QHash 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/painting/shared/images/bg_pattern.png b/examples/painting/shared/images/bg_pattern.png new file mode 100644 index 0000000000..ee670266f0 Binary files /dev/null and b/examples/painting/shared/images/bg_pattern.png differ diff --git a/examples/painting/shared/images/button_normal_cap_left.png b/examples/painting/shared/images/button_normal_cap_left.png new file mode 100644 index 0000000000..db31dd971d Binary files /dev/null and b/examples/painting/shared/images/button_normal_cap_left.png differ diff --git a/examples/painting/shared/images/button_normal_cap_right.png b/examples/painting/shared/images/button_normal_cap_right.png new file mode 100644 index 0000000000..38ead1c719 Binary files /dev/null and b/examples/painting/shared/images/button_normal_cap_right.png differ diff --git a/examples/painting/shared/images/button_normal_stretch.png b/examples/painting/shared/images/button_normal_stretch.png new file mode 100644 index 0000000000..87abe67ac9 Binary files /dev/null and b/examples/painting/shared/images/button_normal_stretch.png differ diff --git a/examples/painting/shared/images/button_pressed_cap_left.png b/examples/painting/shared/images/button_pressed_cap_left.png new file mode 100644 index 0000000000..66bfc13cb4 Binary files /dev/null and b/examples/painting/shared/images/button_pressed_cap_left.png differ diff --git a/examples/painting/shared/images/button_pressed_cap_right.png b/examples/painting/shared/images/button_pressed_cap_right.png new file mode 100644 index 0000000000..3d4cfe25b1 Binary files /dev/null and b/examples/painting/shared/images/button_pressed_cap_right.png differ diff --git a/examples/painting/shared/images/button_pressed_stretch.png b/examples/painting/shared/images/button_pressed_stretch.png new file mode 100644 index 0000000000..4dd4ad11e6 Binary files /dev/null and b/examples/painting/shared/images/button_pressed_stretch.png differ diff --git a/examples/painting/shared/images/curve_thing_edit-6.png b/examples/painting/shared/images/curve_thing_edit-6.png new file mode 100644 index 0000000000..034b474d02 Binary files /dev/null and b/examples/painting/shared/images/curve_thing_edit-6.png differ diff --git a/examples/painting/shared/images/frame_bottom.png b/examples/painting/shared/images/frame_bottom.png new file mode 100644 index 0000000000..889b40d304 Binary files /dev/null and b/examples/painting/shared/images/frame_bottom.png differ diff --git a/examples/painting/shared/images/frame_bottomleft.png b/examples/painting/shared/images/frame_bottomleft.png new file mode 100644 index 0000000000..0b3023f397 Binary files /dev/null and b/examples/painting/shared/images/frame_bottomleft.png differ diff --git a/examples/painting/shared/images/frame_bottomright.png b/examples/painting/shared/images/frame_bottomright.png new file mode 100644 index 0000000000..0021e35864 Binary files /dev/null and b/examples/painting/shared/images/frame_bottomright.png differ diff --git a/examples/painting/shared/images/frame_left.png b/examples/painting/shared/images/frame_left.png new file mode 100644 index 0000000000..40f331c293 Binary files /dev/null and b/examples/painting/shared/images/frame_left.png differ diff --git a/examples/painting/shared/images/frame_right.png b/examples/painting/shared/images/frame_right.png new file mode 100644 index 0000000000..023af8c700 Binary files /dev/null and b/examples/painting/shared/images/frame_right.png differ diff --git a/examples/painting/shared/images/frame_top.png b/examples/painting/shared/images/frame_top.png new file mode 100644 index 0000000000..001f3a7144 Binary files /dev/null and b/examples/painting/shared/images/frame_top.png differ diff --git a/examples/painting/shared/images/frame_topleft.png b/examples/painting/shared/images/frame_topleft.png new file mode 100644 index 0000000000..58c68d407a Binary files /dev/null and b/examples/painting/shared/images/frame_topleft.png differ diff --git a/examples/painting/shared/images/frame_topright.png b/examples/painting/shared/images/frame_topright.png new file mode 100644 index 0000000000..6a7e8d3eb3 Binary files /dev/null and b/examples/painting/shared/images/frame_topright.png differ diff --git a/examples/painting/shared/images/groupframe_bottom_left.png b/examples/painting/shared/images/groupframe_bottom_left.png new file mode 100644 index 0000000000..af2fe061e3 Binary files /dev/null and b/examples/painting/shared/images/groupframe_bottom_left.png differ diff --git a/examples/painting/shared/images/groupframe_bottom_right.png b/examples/painting/shared/images/groupframe_bottom_right.png new file mode 100644 index 0000000000..fdf2e97b13 Binary files /dev/null and b/examples/painting/shared/images/groupframe_bottom_right.png differ diff --git a/examples/painting/shared/images/groupframe_bottom_stretch.png b/examples/painting/shared/images/groupframe_bottom_stretch.png new file mode 100644 index 0000000000..f47b67d7c0 Binary files /dev/null and b/examples/painting/shared/images/groupframe_bottom_stretch.png differ diff --git a/examples/painting/shared/images/groupframe_left_stretch.png b/examples/painting/shared/images/groupframe_left_stretch.png new file mode 100644 index 0000000000..c122f462ed Binary files /dev/null and b/examples/painting/shared/images/groupframe_left_stretch.png differ diff --git a/examples/painting/shared/images/groupframe_right_stretch.png b/examples/painting/shared/images/groupframe_right_stretch.png new file mode 100644 index 0000000000..1056b7812a Binary files /dev/null and b/examples/painting/shared/images/groupframe_right_stretch.png differ diff --git a/examples/painting/shared/images/groupframe_top_stretch.png b/examples/painting/shared/images/groupframe_top_stretch.png new file mode 100644 index 0000000000..5746ef96fc Binary files /dev/null and b/examples/painting/shared/images/groupframe_top_stretch.png differ diff --git a/examples/painting/shared/images/groupframe_topleft.png b/examples/painting/shared/images/groupframe_topleft.png new file mode 100644 index 0000000000..98d9cd96b4 Binary files /dev/null and b/examples/painting/shared/images/groupframe_topleft.png differ diff --git a/examples/painting/shared/images/groupframe_topright.png b/examples/painting/shared/images/groupframe_topright.png new file mode 100644 index 0000000000..1a0a328c20 Binary files /dev/null and b/examples/painting/shared/images/groupframe_topright.png differ diff --git a/examples/painting/shared/images/line_dash_dot.png b/examples/painting/shared/images/line_dash_dot.png new file mode 100644 index 0000000000..1c61442d9f Binary files /dev/null and b/examples/painting/shared/images/line_dash_dot.png differ diff --git a/examples/painting/shared/images/line_dash_dot_dot.png b/examples/painting/shared/images/line_dash_dot_dot.png new file mode 100644 index 0000000000..0d9bb972f9 Binary files /dev/null and b/examples/painting/shared/images/line_dash_dot_dot.png differ diff --git a/examples/painting/shared/images/line_dashed.png b/examples/painting/shared/images/line_dashed.png new file mode 100644 index 0000000000..d5bc7ea5fe Binary files /dev/null and b/examples/painting/shared/images/line_dashed.png differ diff --git a/examples/painting/shared/images/line_dotted.png b/examples/painting/shared/images/line_dotted.png new file mode 100644 index 0000000000..a2f9a35925 Binary files /dev/null and b/examples/painting/shared/images/line_dotted.png differ diff --git a/examples/painting/shared/images/line_solid.png b/examples/painting/shared/images/line_solid.png new file mode 100644 index 0000000000..60ef3f9485 Binary files /dev/null and b/examples/painting/shared/images/line_solid.png differ diff --git a/examples/painting/shared/images/radiobutton-off.png b/examples/painting/shared/images/radiobutton-off.png new file mode 100644 index 0000000000..af1753a3e7 Binary files /dev/null and b/examples/painting/shared/images/radiobutton-off.png differ diff --git a/examples/painting/shared/images/radiobutton-on.png b/examples/painting/shared/images/radiobutton-on.png new file mode 100644 index 0000000000..f875838bb5 Binary files /dev/null and b/examples/painting/shared/images/radiobutton-on.png differ diff --git a/examples/painting/shared/images/radiobutton_off.png b/examples/painting/shared/images/radiobutton_off.png new file mode 100644 index 0000000000..400906ebfa Binary files /dev/null and b/examples/painting/shared/images/radiobutton_off.png differ diff --git a/examples/painting/shared/images/radiobutton_on.png b/examples/painting/shared/images/radiobutton_on.png new file mode 100644 index 0000000000..50a049ec56 Binary files /dev/null and b/examples/painting/shared/images/radiobutton_on.png differ diff --git a/examples/painting/shared/images/slider_bar.png b/examples/painting/shared/images/slider_bar.png new file mode 100644 index 0000000000..1b3d62c007 Binary files /dev/null and b/examples/painting/shared/images/slider_bar.png differ diff --git a/examples/painting/shared/images/slider_thumb_off.png b/examples/painting/shared/images/slider_thumb_off.png new file mode 100644 index 0000000000..d7f141daef Binary files /dev/null and b/examples/painting/shared/images/slider_thumb_off.png differ diff --git a/examples/painting/shared/images/slider_thumb_on.png b/examples/painting/shared/images/slider_thumb_on.png new file mode 100644 index 0000000000..8e1f510813 Binary files /dev/null and b/examples/painting/shared/images/slider_thumb_on.png differ diff --git a/examples/painting/shared/images/title_cap_left.png b/examples/painting/shared/images/title_cap_left.png new file mode 100644 index 0000000000..2d475070c8 Binary files /dev/null and b/examples/painting/shared/images/title_cap_left.png differ diff --git a/examples/painting/shared/images/title_cap_right.png b/examples/painting/shared/images/title_cap_right.png new file mode 100644 index 0000000000..dc3ff8536c Binary files /dev/null and b/examples/painting/shared/images/title_cap_right.png differ diff --git a/examples/painting/shared/images/title_stretch.png b/examples/painting/shared/images/title_stretch.png new file mode 100644 index 0000000000..11043345d0 Binary files /dev/null and b/examples/painting/shared/images/title_stretch.png differ diff --git a/examples/painting/shared/shared.pri b/examples/painting/shared/shared.pri new file mode 100644 index 0000000000..fb7b04c0be --- /dev/null +++ b/examples/painting/shared/shared.pri @@ -0,0 +1,21 @@ +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 +symbian:LIBS += -ldemo_shared.lib +!hpuxi-acc*:!hpux-acc*:!symbian:LIBS += -ldemo_shared + diff --git a/examples/painting/shared/shared.pro b/examples/painting/shared/shared.pro new file mode 100644 index 0000000000..88d7fbedab --- /dev/null +++ b/examples/painting/shared/shared.pro @@ -0,0 +1,39 @@ +TEMPLATE = lib +CONFIG += static + +contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles2) { + DEFINES += QT_OPENGL_SUPPORT + QT += opengl +} + +build_all:!build_pass { + CONFIG -= build_all + CONFIG += release +} +TARGET = demo_shared +QT += gui-private + +SOURCES += \ + arthurstyle.cpp\ + arthurwidgets.cpp \ + hoverpoints.cpp + +HEADERS += \ + arthurstyle.h \ + arthurwidgets.h \ + hoverpoints.h + +RESOURCES += shared.qrc + +# install +target.path = $$[QT_INSTALL_DEMOS]/qtbase/shared +sources.files = $$SOURCES $$HEADERS $$RESOURCES *.pro *.pri images +sources.path = $$[QT_INSTALL_DEMOS]/qtbase/shared +INSTALLS += sources + +!cross_compile:INSTALLS += target + +symbian { + TARGET.UID3 = 0xA000A63C + CONFIG += qt_demo +} diff --git a/examples/painting/shared/shared.qrc b/examples/painting/shared/shared.qrc new file mode 100644 index 0000000000..17336ecf80 --- /dev/null +++ b/examples/painting/shared/shared.qrc @@ -0,0 +1,39 @@ + + + images/button_normal_cap_left.png + images/button_normal_cap_right.png + images/button_normal_stretch.png + images/button_pressed_cap_left.png + images/button_pressed_cap_right.png + images/button_pressed_stretch.png + images/radiobutton-on.png + images/radiobutton_on.png + images/radiobutton_off.png + images/slider_bar.png + images/slider_thumb_on.png + images/groupframe_topleft.png + images/groupframe_topright.png + images/groupframe_bottom_left.png + images/groupframe_bottom_right.png + images/groupframe_top_stretch.png + images/groupframe_bottom_stretch.png + images/groupframe_left_stretch.png + images/groupframe_right_stretch.png + images/frame_topleft.png + images/frame_topright.png + images/frame_bottomleft.png + images/frame_bottomright.png + images/frame_left.png + images/frame_top.png + images/frame_right.png + images/frame_bottom.png + images/title_cap_left.png + images/title_cap_right.png + images/title_stretch.png + images/line_dash_dot.png + images/line_dotted.png + images/line_dashed.png + images/line_solid.png + images/line_dash_dot_dot.png + + -- cgit v1.2.3