1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
10 ** GNU Lesser General Public License Usage
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at info@qt.nokia.com.
31 **************************************************************************/
33 #include "qdeclarativecanvas.h"
34 #include "qdeclarativecanvastimer.h"
35 #include "qdeclarativecontext2d.h"
37 #include <QtGui/qpainter.h>
41 Canvas::Canvas(QDeclarativeItem
*parent
)
42 : QDeclarativeItem(parent
),
43 m_context(new Context2D(this)),
46 m_fillMode(Canvas::Stretch
),
49 setFlag(QGraphicsItem::ItemHasNoContents
, false);
50 setCacheMode(QGraphicsItem::DeviceCoordinateCache
);
54 void Canvas::componentComplete()
56 if (m_canvasWidth
== 0 && m_canvasHeight
== 0)
57 m_context
->setSize(width(), height());
59 m_context
->setSize(m_canvasWidth
, m_canvasHeight
);
61 connect(m_context
, SIGNAL(changed()), this, SLOT(requestPaint()));
63 QDeclarativeItem::componentComplete();
66 void Canvas::paint(QPainter
*painter
, const QStyleOptionGraphicsItem
*, QWidget
*)
68 m_context
->setInPaint(true);
71 bool oldAA
= painter
->testRenderHint(QPainter::Antialiasing
);
72 bool oldSmooth
= painter
->testRenderHint(QPainter::SmoothPixmapTransform
);
74 painter
->setRenderHints(QPainter::Antialiasing
| QPainter::SmoothPixmapTransform
, smooth());
76 if (m_context
->pixmap().isNull()) {
77 painter
->fillRect(0, 0, width(), height(), m_color
);
78 } else if (width() != m_context
->pixmap().width() || height() != m_context
->pixmap().height()) {
79 if (m_fillMode
>= Tile
) {
80 if (m_fillMode
== Tile
) {
81 painter
->drawTiledPixmap(QRectF(0,0,width(),height()), m_context
->pixmap());
83 qreal widthScale
= width() / qreal(m_context
->pixmap().width());
84 qreal heightScale
= height() / qreal(m_context
->pixmap().height());
87 if (m_fillMode
== TileVertically
) {
88 scale
.scale(widthScale
, 1.0);
89 QTransform old
= painter
->transform();
90 painter
->setWorldTransform(scale
* old
);
91 painter
->drawTiledPixmap(QRectF(0,0,m_context
->pixmap().width(),height()), m_context
->pixmap());
92 painter
->setWorldTransform(old
);
94 scale
.scale(1.0, heightScale
);
95 QTransform old
= painter
->transform();
96 painter
->setWorldTransform(scale
* old
);
97 painter
->drawTiledPixmap(QRectF(0,0,width(),m_context
->pixmap().height()), m_context
->pixmap());
98 painter
->setWorldTransform(old
);
102 qreal widthScale
= width() / qreal(m_context
->pixmap().width());
103 qreal heightScale
= height() / qreal(m_context
->pixmap().height());
107 if (m_fillMode
== PreserveAspectFit
) {
108 if (widthScale
<= heightScale
) {
109 heightScale
= widthScale
;
110 scale
.translate(0, (height() - heightScale
* m_context
->pixmap().height()) / 2);
111 } else if (heightScale
< widthScale
) {
112 widthScale
= heightScale
;
113 scale
.translate((width() - widthScale
* m_context
->pixmap().width()) / 2, 0);
115 } else if (m_fillMode
== PreserveAspectCrop
) {
116 if (widthScale
< heightScale
) {
117 widthScale
= heightScale
;
118 scale
.translate((width() - widthScale
* m_context
->pixmap().width()) / 2, 0);
119 } else if (heightScale
< widthScale
) {
120 heightScale
= widthScale
;
121 scale
.translate(0, (height() - heightScale
* m_context
->pixmap().height()) / 2);
126 painter
->setClipRect(boundingRect(), Qt::IntersectClip
);
128 scale
.scale(widthScale
, heightScale
);
129 QTransform old
= painter
->transform();
130 painter
->setWorldTransform(scale
* old
);
131 painter
->drawPixmap(0, 0, m_context
->pixmap());
132 painter
->setWorldTransform(old
);
138 painter
->drawPixmap(0, 0, m_context
->pixmap());
142 painter
->setRenderHint(QPainter::Antialiasing
, oldAA
);
143 painter
->setRenderHint(QPainter::SmoothPixmapTransform
, oldSmooth
);
145 m_context
->setInPaint(false);
148 Context2D
*Canvas::getContext(const QString
&contextId
)
150 if (contextId
== QLatin1String("2d"))
152 qDebug("Canvas:requesting unsupported context");
156 void Canvas::requestPaint()
161 void Canvas::geometryChanged(const QRectF
&newGeometry
, const QRectF
&oldGeometry
)
163 if (m_canvasWidth
== 0 && m_canvasHeight
== 0
164 && newGeometry
.width() > 0 && newGeometry
.height() > 0) {
165 m_context
->setSize(width(), height());
167 QDeclarativeItem::geometryChanged(newGeometry
, oldGeometry
);
170 void Canvas::setCanvasWidth(int newWidth
)
172 if (m_canvasWidth
!= newWidth
) {
173 m_canvasWidth
= newWidth
;
174 m_context
->setSize(m_canvasWidth
, m_canvasHeight
);
175 emit
canvasWidthChanged();
179 void Canvas::setCanvasHeight(int newHeight
)
181 if (m_canvasHeight
!= newHeight
) {
182 m_canvasHeight
= newHeight
;
183 m_context
->setSize(m_canvasWidth
, m_canvasHeight
);
184 emit
canvasHeightChanged();
188 void Canvas::setFillMode(FillMode mode
)
190 if (m_fillMode
== mode
)
195 emit
fillModeChanged();
198 QColor
Canvas::color()
203 void Canvas::setColor(const QColor
&color
)
205 if (m_color
!=color
) {
211 Canvas::FillMode
Canvas::fillMode() const
216 bool Canvas::save(const QString
&filename
) const
218 return m_context
->pixmap().save(filename
);
221 CanvasImage
*Canvas::toImage() const
223 return new CanvasImage(m_context
->pixmap());
226 void Canvas::setTimeout(const QScriptValue
&handler
, long timeout
)
228 if (handler
.isFunction())
229 CanvasTimer::createTimer(this, handler
, timeout
, true);
232 void Canvas::setInterval(const QScriptValue
&handler
, long interval
)
234 if (handler
.isFunction())
235 CanvasTimer::createTimer(this, handler
, interval
, false);
238 void Canvas::clearTimeout(const QScriptValue
&handler
)
240 CanvasTimer::removeTimer(handler
);
243 void Canvas::clearInterval(const QScriptValue
&handler
)
245 CanvasTimer::removeTimer(handler
);
248 #include "qdeclarativecanvas.moc"