Initial import from qtquick2.
[profile/ivi/qtdeclarative.git] / src / declarative / items / qsgpainteditem.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file.  Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 **
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qsgpainteditem.h"
43 #include <private/qsgpainteditem_p.h>
44 #include <private/qsgpainternode_p.h>
45
46 #include <private/qsgcontext_p.h>
47 #include <private/qsgadaptationlayer_p.h>
48
49 QT_BEGIN_NAMESPACE
50
51 /*!
52     \class QSGPaintedItem
53     \brief The QSGPaintedItem class provides a way to use the QPainter API in the
54     QML Scene Graph.
55
56     The QSGPaintedItem makes it possible to use the QPainter API with the QML Scene Graph.
57     It sets up a textured rectangle in the Scene Graph and uses a QPainter to paint
58     onto the texture. The render target can be either a QImage or a QGLFramebufferObject.
59     When the render target is a QImage, QPainter first renders into the image then
60     the content is uploaded to the texture.
61     When a QGLFramebufferObject is used, QPainter paints directly onto the texture.
62     Call update() to trigger a repaint.
63
64     Set the \l smooth property to true to enable QPainter to do anti-aliased rendering.
65
66     QSGPaintedItem is meant to make it easier to port old code that is using the
67     QPainter API to the QML Scene Graph API and it should be used only for that purpose.
68
69     To write your own painted item, you first create a subclass of QSGPaintedItem, and then
70     start by implementing its only pure virtual public function: paint(), which implements
71     the actual painting. To get the size of the area painted by the item, use
72     QSGItem::width() and QSGItem::height().
73 */
74
75 /*!
76     \enum QSGPaintedItem::RenderTarget
77
78     This enum describes QSGPaintedItem's render targets. The render target is the
79     surface QPainter paints onto before the item is rendered on screen.
80
81     \value Image The default; QPainter paints into a QImage using the raster paint engine.
82     The image's content needs to be uploaded to graphics memory afterward, this operation
83     can potentially be slow if the item is large. This render target allows high quality
84     anti-aliasing and fast item resizing.
85
86     \value FramebufferObject QPainter paints into a QGLFramebufferObject using the GL
87     paint engine. Painting can be faster as no texture upload is required, but anti-aliasing
88     quality is not as good as if using an image. This render target allows faster rendering
89     in some cases, but you should avoid using it if the item is resized often.
90
91     \sa setRenderTarget()
92 */
93
94 /*!
95     \internal
96 */
97 QSGPaintedItemPrivate::QSGPaintedItemPrivate()
98     : QSGItemPrivate()
99     , fillColor(Qt::transparent)
100     , renderTarget(QSGPaintedItem::Image)
101     , geometryDirty(false)
102     , contentsDirty(false)
103     , opaquePainting(false)
104 {
105 }
106
107 /*!
108     Constructs a QSGPaintedItem with the given \a parent item.
109  */
110 QSGPaintedItem::QSGPaintedItem(QSGItem *parent)
111     : QSGItem(*(new QSGPaintedItemPrivate), parent)
112 {
113     setFlag(ItemHasContents);
114 }
115
116 /*!
117     \internal
118 */
119 QSGPaintedItem::QSGPaintedItem(QSGPaintedItemPrivate &dd, QSGItem *parent)
120     : QSGItem(dd, parent)
121 {
122     setFlag(ItemHasContents);
123 }
124
125 /*!
126     Destroys the QSGPaintedItem.
127 */
128 QSGPaintedItem::~QSGPaintedItem()
129 {
130 }
131
132 /*!
133     Schedules a redraw of the area covered by \a rect in this item. You can call this function
134     whenever your item needs to be redrawn, such as if it changes appearance or size.
135
136     This function does not cause an immediate paint; instead it schedules a paint request that
137     is processed by the QML Scene Graph when the next frame is rendered. The item will only be
138     redrawn if it is visible.
139
140     Note that calling this function will trigger a repaint of the whole scene.
141
142     \sa paint()
143 */
144 void QSGPaintedItem::update(const QRect &rect)
145 {
146     Q_D(QSGPaintedItem);
147     d->contentsDirty = true;
148     if (rect.isNull() && !d->dirtyRect.isNull())
149         d->dirtyRect = boundingRect().toAlignedRect();
150     else
151         d->dirtyRect |= (boundingRect() & rect).toAlignedRect();
152     QSGItem::update();
153 }
154
155 /*!
156     Returns true if this item is opaque; otherwise, false is returned.
157
158     By default, painted items are not opaque.
159
160     \sa setOpaquePainting()
161 */
162 bool QSGPaintedItem::opaquePainting() const
163 {
164     Q_D(const QSGPaintedItem);
165     return d->opaquePainting;
166 }
167
168 /*!
169     If \a opaque is true, the item is opaque; otherwise, it is considered as translucent.
170
171     Opaque items are not blended with the rest of the scene, you should set this to true
172     if the content of the item is opaque to speed up rendering.
173
174     By default, painted items are not opaque.
175
176     \sa opaquePainting()
177 */
178 void QSGPaintedItem::setOpaquePainting(bool opaque)
179 {
180     Q_D(QSGPaintedItem);
181
182     if (d->opaquePainting == opaque)
183         return;
184
185     d->opaquePainting = opaque;
186     QSGItem::update();
187 }
188
189 QSize QSGPaintedItem::contentsSize() const
190 {
191     // XXX todo
192     return QSize();
193 }
194
195 void QSGPaintedItem::setContentsSize(const QSize &)
196 {
197     // XXX todo
198 }
199
200 void QSGPaintedItem::resetContentsSize()
201 {
202     // XXX todo
203 }
204
205 qreal QSGPaintedItem::contentsScale() const
206 {
207     // XXX todo
208     return 1;
209 }
210
211 void QSGPaintedItem::setContentsScale(qreal)
212 {
213     // XXX todo
214 }
215
216 int QSGPaintedItem::pixelCacheSize() const
217 {
218     // XXX todo
219     return 0;
220 }
221
222 void QSGPaintedItem::setPixelCacheSize(int)
223 {
224     // XXX todo
225 }
226
227 bool QSGPaintedItem::smoothCache() const
228 {
229     // XXX todo
230     return false;
231 }
232
233 void QSGPaintedItem::setSmoothCache(bool)
234 {
235     // XXX todo
236 }
237
238 /*!
239     \property QSGPaintedItem::fillColor
240     \brief The item's background fill color.
241
242     By default, the fill color is set to Qt::transparent.
243 */
244 QColor QSGPaintedItem::fillColor() const
245 {
246     Q_D(const QSGPaintedItem);
247     return d->fillColor;
248 }
249
250 void QSGPaintedItem::setFillColor(const QColor &c)
251 {
252     Q_D(QSGPaintedItem);
253
254     if (d->fillColor == c)
255         return;
256
257     d->fillColor = c;
258     update();
259
260     emit fillColorChanged();
261 }
262
263 /*!
264     \property QSGPaintedItem::renderTarget
265     \brief The item's render target.
266
267     This property defines which render target the QPainter renders into, it can be either
268     QSGPaintedItem::Image or QSGPaintedItem::FramebufferObject. Both have certains benefits,
269     typically performance versus quality. Using a framebuffer object avoids a costly upload
270     of the image contents to the texture in graphics memory, while using an image enables
271     high quality anti-aliasing.
272
273     \warning Resizing a framebuffer object is a costly operation, avoid using
274     the QSGPaintedItem::FramebufferObject render target if the item gets resized often.
275
276     By default, the render target is QSGPaintedItem::Image.
277 */
278 QSGPaintedItem::RenderTarget QSGPaintedItem::renderTarget() const
279 {
280     Q_D(const QSGPaintedItem);
281     return d->renderTarget;
282 }
283
284 void QSGPaintedItem::setRenderTarget(RenderTarget target)
285 {
286     Q_D(QSGPaintedItem);
287
288     if (d->renderTarget == target)
289         return;
290
291     d->renderTarget = target;
292     update();
293
294     emit renderTargetChanged();
295 }
296
297 /*!
298     \fn virtual void QSGPaintedItem::paint(QPainter *painter) = 0
299
300     This function, which is usually called by the QML Scene Graph, paints the
301     contents of an item in local coordinates.
302
303     The function is called after the item has been filled with the fillColor.
304
305     Reimplement this function in a QSGPaintedItem subclass to provide the
306     item's painting implementation, using \a painter.
307 */
308
309 /*!
310     This function is called after the item's geometry has changed.
311 */
312 void QSGPaintedItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
313 {
314     Q_D(QSGPaintedItem);
315     d->geometryDirty = true;
316     QSGItem::geometryChanged(newGeometry, oldGeometry);
317 }
318
319
320 /*!
321     This function is called when the Scene Graph node associated to the item needs to
322     be updated.
323 */
324 QSGNode *QSGPaintedItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
325 {
326     Q_UNUSED(data);
327     Q_D(QSGPaintedItem);
328
329     if (width() <= 0 || height() <= 0) {
330         delete oldNode;
331         return 0;
332     }
333
334     QSGPainterNode *node = static_cast<QSGPainterNode *>(oldNode);
335     if (!node)
336         node = new QSGPainterNode(this);
337
338     node->setPreferredRenderTarget(d->renderTarget);
339     node->setSize(QSize(d->width, d->height));
340     node->setSmoothPainting(d->smooth);
341     node->setLinearFiltering(d->smooth);
342     node->setOpaquePainting(d->opaquePainting);
343     node->setFillColor(d->fillColor);
344     node->setDirty(d->contentsDirty || d->geometryDirty, d->dirtyRect);
345     node->update();
346
347     d->contentsDirty = false;
348     d->geometryDirty = false;
349     d->dirtyRect = QRect();
350
351     return node;
352 }
353
354 QT_END_NAMESPACE