69c426e5902821f1ab09eaae733bce4c6ca8acf5
[profile/ivi/qtdeclarative.git] / src / quick / util / qquickimageprovider.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtQml module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qquickimageprovider.h"
43
44 QT_BEGIN_NAMESPACE
45
46 class QQuickImageProviderPrivate
47 {
48 public:
49     QQuickImageProvider::ImageType type;
50     QQuickImageProvider::Flags flags;
51 };
52
53 /*!
54     \class QQuickTextureFactory
55     \since 5.0
56     \brief The QQuickTextureFactory class provides an interface for loading custom textures from QML.
57     \inmodule QtQuick
58
59     The purpose of the texture factory is to provide a placeholder for a image
60     data that can be converted into an OpenGL texture.
61
62     Creating a texture directly is not possible as there is rarely an OpenGL context
63     available in the thread that is responsible for loading the image data.
64 */
65
66 /*!
67     Constructs a texture factory. Since QQuickTextureFactory is abstract, it
68     cannot be instantiated directly.
69 */
70
71 QQuickTextureFactory::QQuickTextureFactory()
72 {
73 }
74
75 /*!
76     Destroys the texture factory.
77 */
78
79 QQuickTextureFactory::~QQuickTextureFactory()
80 {
81 }
82
83 /*!
84     \fn int QQuickTextureFactory::textureByteCount() const
85
86     Returns the number of bytes of memory the texture consumes.
87 */
88
89 /*!
90     \fn QImage QQuickTextureFactory::image() const
91
92     Returns an image version of this texture.
93
94     The lifespan of the returned image is unknown, so the implementation should
95     return a self contained QImage, not make use of the QImage(uchar *, ...)
96     constructor.
97
98     This function is not commonly used and is expected to be slow.
99  */
100
101 QImage QQuickTextureFactory::image() const
102 {
103     return QImage();
104 }
105
106
107 /*!
108     \fn QSGTexture *QQuickTextureFactory::createTexture(QQuickWindow *window) const
109
110     This function is called on the scene graph rendering thread to create a QSGTexture
111     instance from the factory. \a window provides the context which this texture is
112     created in.
113
114     QML will internally cache the returned texture as needed. Each call to this
115     function should return a unique instance.
116
117     The OpenGL context used for rendering is bound when this function is called.
118  */
119
120 /*!
121     \fn QSize QQuickTextureFactory::textureSize() const
122
123     Returns the size of the texture. This function will be called from arbitrary threads
124     and should not rely on an OpenGL context bound.
125  */
126
127
128 /*!
129     \class QQuickImageProvider
130     \since 5.0
131     \inmodule QtQuick
132     \brief The QQuickImageProvider class provides an interface for supporting pixmaps and threaded image requests in QML.
133
134     QQuickImageProvider is used to provide advanced image loading features
135     in QML applications. It allows images in QML to be:
136
137     \list
138     \li Loaded using QPixmaps rather than actual image files
139     \li Loaded asynchronously in a separate thread, if imageType() is \l{QQuickImageProvider::ImageType}{ImageType::Image}
140     \endlist
141
142     To specify that an image should be loaded by an image provider, use the
143     \b {"image:"} scheme for the URL source of the image, followed by the
144     identifiers of the image provider and the requested image. For example:
145
146     \qml
147     Image { source: "image://myimageprovider/image.png" }
148     \endqml
149
150     This specifies that the image should be loaded by the image provider named 
151     "myimageprovider", and the image to be loaded is named "image.png". The QML engine 
152     invokes the appropriate image provider according to the providers that have
153     been registered through QQmlEngine::addImageProvider().
154
155     Note that the identifiers are case-insensitive, but the rest of the URL will be passed on with
156     preserved case. For example, the below snippet would still specify that the image is loaded by the
157     image provider named "myimageprovider", but it would request a different image than the above snippet
158     ("Image.png" instead of "image.png").
159     \qml
160     Image { source: "image://MyImageProvider/Image.png" }
161     \endqml
162
163     If you want the rest of the URL to be case insensitive, you will have to take care
164     of that yourself inside your image provider.
165
166     \section2 An example
167
168     Here are two images. Their \c source values indicate they should be loaded by
169     an image provider named "colors", and the images to be loaded are "yellow"
170     and "red", respectively:
171
172     \snippet examples/qml/imageprovider/imageprovider-example.qml 0
173
174     When these images are loaded by QML, it looks for a matching image provider
175     and calls its requestImage() or requestPixmap() method (depending on its
176     imageType()) to load the image. The method is called with the \c id 
177     parameter set to "yellow" for the first image, and "red" for the second.
178
179     Here is an image provider implementation that can load the images 
180     requested by the above QML. This implementation dynamically 
181     generates QPixmap images that are filled with the requested color:
182
183     \snippet examples/qml/imageprovider/imageprovider.cpp 0
184     \codeline
185     \snippet examples/qml/imageprovider/imageprovider.cpp 1
186
187     To make this provider accessible to QML, it is registered with the QML engine
188     with a "colors" identifier:
189
190     \code
191     int main(int argc, char *argv[]) 
192     {
193         ...
194
195         QQmlEngine engine;
196         engine->addImageProvider(QLatin1String("colors"), new ColorPixmapProvider);
197
198         ...
199     }
200     \endcode
201
202     Now the images can be successfully loaded in QML:
203
204     \image imageprovider.png
205
206     A complete example is available in Qt's 
207     \l {qml/imageprovider}{examples/qml/imageprovider}
208     directory. Note the example registers the provider via a \l{QQmlExtensionPlugin}{plugin}
209     instead of registering it in the application \c main() function as shown above.
210
211
212     \section2 Asynchronous image loading
213
214     Image providers that support QImage loading automatically include support
215     for asychronous loading of images. To enable asynchronous loading for an
216     image source, set the \c asynchronous property to \c true for the relevant
217     \l Image, \l BorderImage or \l AnimatedImage object. When this is enabled, 
218     the image request to the provider is run in a low priority thread,
219     allowing image loading to be executed in the background, and reducing the
220     performance impact on the user interface.
221
222     To force asynchronous image loading, even for image sources that do not
223     have the \c asynchronous property set to \c true, you may pass the
224     \c QQuickImageProvider::ForceAsynchronousImageLoading flag to the image
225     provider constructor. This ensures that all image requests for the
226     provider are handled in a separate thread.
227
228     Asynchronous loading is not supported for image providers that provide
229     QPixmap rather than QImage values, as pixmaps can only be created in the
230     main thread. In this case, if \l {Image::}{asynchronous} is set to 
231     \c true, the value is ignored and the image is loaded
232     synchronously.
233
234
235     \section2 Image caching
236
237     Images returned by a QQuickImageProvider are automatically cached,
238     similar to any image loaded by the QML engine. When an image with a
239     "image://" prefix is loaded from cache, requestImage() and requestPixmap()
240     will not be called for the relevant image provider. If an image should always
241     be fetched from the image provider, and should not be cached at all, set the
242     \c cache property to \c false for the relevant \l Image, \l BorderImage or
243     \l AnimatedImage object.
244
245     The QtQuick 1 version of this class is named QDeclarativeImageProvider.
246
247     \sa QQmlEngine::addImageProvider()
248 */
249
250 /*!
251     Creates an image provider that will provide images of the given \a type and
252     behave according to the given \a flags.
253 */
254 QQuickImageProvider::QQuickImageProvider(ImageType type, Flags flags)
255     : d(new QQuickImageProviderPrivate)
256 {
257     d->type = type;
258     d->flags = flags;
259 }
260
261 /*!
262     Destroys the QQuickImageProvider
263
264     \note The destructor of your derived class need to be thread safe.
265 */
266 QQuickImageProvider::~QQuickImageProvider()
267 {
268     delete d;
269 }
270
271 /*!
272     Returns the image type supported by this provider.
273 */
274 QQuickImageProvider::ImageType QQuickImageProvider::imageType() const
275 {
276     return d->type;
277 }
278
279 /*!
280     Returns the flags set for this provider.
281 */
282 QQuickImageProvider::Flags QQuickImageProvider::flags() const
283 {
284     return d->flags;
285 }
286
287 /*!
288     Implement this method to return the image with \a id. The default 
289     implementation returns an empty image.
290
291     The \a id is the requested image source, with the "image:" scheme and
292     provider identifier removed. For example, if the image \l{Image::}{source}
293     was "image://myprovider/icons/home", the given \a id would be "icons/home".
294
295     The \a requestedSize corresponds to the \l {Image::sourceSize} requested by
296     an Image item. If \a requestedSize is a valid size, the image
297     returned should be of that size.
298
299     In all cases, \a size must be set to the original size of the image. This
300     is used to set the \l {Item::}{width} and \l {Item::}{height} of the
301     relevant \l Image if these values have not been set explicitly.
302
303     \note this method may be called by multiple threads, so ensure the
304     implementation of this method is reentrant.
305 */
306 QImage QQuickImageProvider::requestImage(const QString &id, QSize *size, const QSize& requestedSize)
307 {
308     Q_UNUSED(id);
309     Q_UNUSED(size);
310     Q_UNUSED(requestedSize);
311     if (d->type == Image)
312         qWarning("ImageProvider supports Image type but has not implemented requestImage()");
313     return QImage();
314 }
315
316 /*!
317     Implement this method to return the pixmap with \a id. The default
318     implementation returns an empty pixmap.
319
320     The \a id is the requested image source, with the "image:" scheme and
321     provider identifier removed. For example, if the image \l{Image::}{source}
322     was "image://myprovider/icons/home", the given \a id would be "icons/home".
323
324     The \a requestedSize corresponds to the \l {Image::sourceSize} requested by
325     an Image item. If \a requestedSize is a valid size, the image
326     returned should be of that size.
327
328     In all cases, \a size must be set to the original size of the image. This
329     is used to set the \l {Item::}{width} and \l {Item::}{height} of the
330     relevant \l Image if these values have not been set explicitly.
331 */
332 QPixmap QQuickImageProvider::requestPixmap(const QString &id, QSize *size, const QSize& requestedSize)
333 {
334     Q_UNUSED(id);
335     Q_UNUSED(size);
336     Q_UNUSED(requestedSize);
337     if (d->type == Pixmap)
338         qWarning("ImageProvider supports Pixmap type but has not implemented requestPixmap()");
339     return QPixmap();
340 }
341
342
343 /*!
344     Implement this method to return the texture with \a id. The default
345     implementation returns 0.
346
347     The \a id is the requested image source, with the "image:" scheme and
348     provider identifier removed. For example, if the image \l{Image::}{source}
349     was "image://myprovider/icons/home", the given \a id would be "icons/home".
350
351     The \a requestedSize corresponds to the \l {Image::sourceSize} requested by
352     an Image item. If \a requestedSize is a valid size, the image
353     returned should be of that size.
354
355     In all cases, \a size must be set to the original size of the image. This
356     is used to set the \l {Item::}{width} and \l {Item::}{height} of the
357     relevant \l Image if these values have not been set explicitly.
358
359     \note this method may be called by multiple threads, so ensure the
360     implementation of this method is reentrant.
361 */
362
363 QQuickTextureFactory *QQuickImageProvider::requestTexture(const QString &id, QSize *size, const QSize &requestedSize)
364 {
365     Q_UNUSED(id);
366     Q_UNUSED(size);
367     Q_UNUSED(requestedSize);
368     if (d->type == Texture)
369         qWarning("ImageProvider supports Texture type but has not implemented requestTexture()");
370     return 0;
371 }
372
373 QT_END_NAMESPACE
374