aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/items/qquickimage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/items/qquickimage.cpp')
-rw-r--r--src/declarative/items/qquickimage.cpp746
1 files changed, 0 insertions, 746 deletions
diff --git a/src/declarative/items/qquickimage.cpp b/src/declarative/items/qquickimage.cpp
deleted file mode 100644
index 46b8ea0915..0000000000
--- a/src/declarative/items/qquickimage.cpp
+++ /dev/null
@@ -1,746 +0,0 @@
-/****************************************************************************
-**
-** 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 QtDeclarative module 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 "qquickimage_p.h"
-#include "qquickimage_p_p.h"
-
-#include <private/qsgtextureprovider_p.h>
-
-#include <private/qsgcontext_p.h>
-#include <private/qsgadaptationlayer_p.h>
-
-#include <QtGui/qpainter.h>
-#include <qmath.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQuickImageTextureProvider : public QSGTextureProvider
-{
- Q_OBJECT
-public:
- QQuickImageTextureProvider()
- : m_texture(0)
- , m_smooth(false)
- {
- }
-
- QSGTexture *texture() const {
-
- if (m_texture && m_texture->isAtlasTexture())
- const_cast<QQuickImageTextureProvider *>(this)->m_texture = m_texture->removedFromAtlas();
-
- if (m_texture) {
- m_texture->setFiltering(m_smooth ? QSGTexture::Linear : QSGTexture::Nearest);
- m_texture->setMipmapFiltering(QSGTexture::Nearest);
- m_texture->setHorizontalWrapMode(QSGTexture::ClampToEdge);
- m_texture->setVerticalWrapMode(QSGTexture::ClampToEdge);
- }
- return m_texture;
- }
-
- friend class QQuickImage;
-
- QSGTexture *m_texture;
- bool m_smooth;
-};
-
-#include "qquickimage.moc"
-
-QQuickImagePrivate::QQuickImagePrivate()
- : fillMode(QQuickImage::Stretch)
- , paintedWidth(0)
- , paintedHeight(0)
- , pixmapChanged(false)
- , hAlign(QQuickImage::AlignHCenter)
- , vAlign(QQuickImage::AlignVCenter)
- , provider(0)
-{
-}
-
-/*!
- \qmlclass Image QQuickImage
- \inqmlmodule QtQuick 2
- \ingroup qml-basic-visual-elements
- \brief The Image element displays an image in a declarative user interface
- \inherits Item
-
- The Image element is used to display images in a declarative user interface.
-
- The source of the image is specified as a URL using the \l source property.
- Images can be supplied in any of the standard image formats supported by Qt,
- including bitmap formats such as PNG and JPEG, and vector graphics formats
- such as SVG. If you need to display animated images, use the \l AnimatedImage
- element.
-
- If the \l{Item::width}{width} and \l{Item::height}{height} properties are not
- specified, the Image element automatically uses the size of the loaded image.
- By default, specifying the width and height of the element causes the image
- to be scaled to that size. This behavior can be changed by setting the
- \l fillMode property, allowing the image to be stretched and tiled instead.
-
- \section1 Example Usage
-
- The following example shows the simplest usage of the Image element.
-
- \snippet doc/src/snippets/declarative/image.qml document
-
- \beginfloatleft
- \image declarative-qtlogo.png
- \endfloat
-
- \clearfloat
-
- \section1 Performance
-
- By default, locally available images are loaded immediately, and the user interface
- is blocked until loading is complete. If a large image is to be loaded, it may be
- preferable to load the image in a low priority thread, by enabling the \l asynchronous
- property.
-
- If the image is obtained from a network rather than a local resource, it is
- automatically loaded asynchronously, and the \l progress and \l status properties
- are updated as appropriate.
-
- Images are cached and shared internally, so if several Image elements have the same \l source,
- only one copy of the image will be loaded.
-
- \bold Note: Images are often the greatest user of memory in QML user interfaces. It is recommended
- that images which do not form part of the user interface have their
- size bounded via the \l sourceSize property. This is especially important for content
- that is loaded from external sources or provided by the user.
-
- \sa {declarative/imageelements/image}{Image example}, QDeclarativeImageProvider
-*/
-
-QQuickImage::QQuickImage(QQuickItem *parent)
- : QQuickImageBase(*(new QQuickImagePrivate), parent)
-{
-}
-
-QQuickImage::QQuickImage(QQuickImagePrivate &dd, QQuickItem *parent)
- : QQuickImageBase(dd, parent)
-{
-}
-
-QQuickImage::~QQuickImage()
-{
- Q_D(QQuickImage);
- if (d->provider)
- d->provider->deleteLater();
-}
-
-void QQuickImagePrivate::setImage(const QImage &image)
-{
- Q_Q(QQuickImage);
- pix.setImage(image);
-
- q->pixmapChange();
- status = pix.isNull() ? QQuickImageBase::Null : QQuickImageBase::Ready;
-
- q->update();
-}
-
-/*!
- \qmlproperty enumeration QtQuick2::Image::fillMode
-
- Set this property to define what happens when the source image has a different size
- than the item.
-
- \list
- \o Image.Stretch - the image is scaled to fit
- \o Image.PreserveAspectFit - the image is scaled uniformly to fit without cropping
- \o Image.PreserveAspectCrop - the image is scaled uniformly to fill, cropping if necessary
- \o Image.Tile - the image is duplicated horizontally and vertically
- \o Image.TileVertically - the image is stretched horizontally and tiled vertically
- \o Image.TileHorizontally - the image is stretched vertically and tiled horizontally
- \o Image.Pad - the image is not transformed
- \endlist
-
- \table
-
- \row
- \o \image declarative-qtlogo-stretch.png
- \o Stretch (default)
- \qml
- Image {
- width: 130; height: 100
- smooth: true
- source: "qtlogo.png"
- }
- \endqml
-
- \row
- \o \image declarative-qtlogo-preserveaspectfit.png
- \o PreserveAspectFit
- \qml
- Image {
- width: 130; height: 100
- fillMode: Image.PreserveAspectFit
- smooth: true
- source: "qtlogo.png"
- }
- \endqml
-
- \row
- \o \image declarative-qtlogo-preserveaspectcrop.png
- \o PreserveAspectCrop
- \qml
- Image {
- width: 130; height: 100
- fillMode: Image.PreserveAspectCrop
- smooth: true
- source: "qtlogo.png"
- clip: true
- }
- \endqml
-
- \row
- \o \image declarative-qtlogo-tile.png
- \o Tile
- \qml
- Image {
- width: 120; height: 120
- fillMode: Image.Tile
- source: "qtlogo.png"
- }
- \endqml
-
- \row
- \o \image declarative-qtlogo-tilevertically.png
- \o TileVertically
- \qml
- Image {
- width: 120; height: 120
- fillMode: Image.TileVertically
- smooth: true
- source: "qtlogo.png"
- }
- \endqml
-
- \row
- \o \image declarative-qtlogo-tilehorizontally.png
- \o TileHorizontally
- \qml
- Image {
- width: 120; height: 120
- fillMode: Image.TileHorizontally
- smooth: true
- source: "qtlogo.png"
- }
- \endqml
-
- \endtable
-
- Note that \c clip is \c false by default which means that the element might
- paint outside its bounding rectangle even if the fillMode is set to \c PreserveAspectCrop.
-
- \sa {declarative/imageelements/image}{Image example}
-*/
-QQuickImage::FillMode QQuickImage::fillMode() const
-{
- Q_D(const QQuickImage);
- return d->fillMode;
-}
-
-void QQuickImage::setFillMode(FillMode mode)
-{
- Q_D(QQuickImage);
- if (d->fillMode == mode)
- return;
- d->fillMode = mode;
- update();
- updatePaintedGeometry();
- emit fillModeChanged();
-}
-
-/*!
-
- \qmlproperty real QtQuick2::Image::paintedWidth
- \qmlproperty real QtQuick2::Image::paintedHeight
-
- These properties hold the size of the image that is actually painted.
- In most cases it is the same as \c width and \c height, but when using a
- \c fillMode \c PreserveAspectFit or \c fillMode \c PreserveAspectCrop
- \c paintedWidth or \c paintedHeight can be smaller or larger than
- \c width and \c height of the Image element.
-*/
-qreal QQuickImage::paintedWidth() const
-{
- Q_D(const QQuickImage);
- return d->paintedWidth;
-}
-
-qreal QQuickImage::paintedHeight() const
-{
- Q_D(const QQuickImage);
- return d->paintedHeight;
-}
-
-/*!
- \qmlproperty enumeration QtQuick2::Image::status
-
- This property holds the status of image loading. It can be one of:
- \list
- \o Image.Null - no image has been set
- \o Image.Ready - the image has been loaded
- \o Image.Loading - the image is currently being loaded
- \o Image.Error - an error occurred while loading the image
- \endlist
-
- Use this status to provide an update or respond to the status change in some way.
- For example, you could:
-
- \list
- \o Trigger a state change:
- \qml
- State { name: 'loaded'; when: image.status == Image.Ready }
- \endqml
-
- \o Implement an \c onStatusChanged signal handler:
- \qml
- Image {
- id: image
- onStatusChanged: if (image.status == Image.Ready) console.log('Loaded')
- }
- \endqml
-
- \o Bind to the status value:
- \qml
- Text { text: image.status == Image.Ready ? 'Loaded' : 'Not loaded' }
- \endqml
- \endlist
-
- \sa progress
-*/
-
-/*!
- \qmlproperty real QtQuick2::Image::progress
-
- This property holds the progress of image loading, from 0.0 (nothing loaded)
- to 1.0 (finished).
-
- \sa status
-*/
-
-/*!
- \qmlproperty bool QtQuick2::Image::smooth
-
- Set this property if you want the image to be smoothly filtered when scaled or
- transformed. Smooth filtering gives better visual quality, but is slower. If
- the image is displayed at its natural size, this property has no visual or
- performance effect.
-
- \note Generally scaling artifacts are only visible if the image is stationary on
- the screen. A common pattern when animating an image is to disable smooth
- filtering at the beginning of the animation and reenable it at the conclusion.
-*/
-
-/*!
- \qmlproperty QSize QtQuick2::Image::sourceSize
-
- This property holds the actual width and height of the loaded image.
-
- Unlike the \l {Item::}{width} and \l {Item::}{height} properties, which scale
- the painting of the image, this property sets the actual number of pixels
- stored for the loaded image so that large images do not use more
- memory than necessary. For example, this ensures the image in memory is no
- larger than 1024x1024 pixels, regardless of the Image's \l {Item::}{width} and
- \l {Item::}{height} values:
-
- \code
- Rectangle {
- width: ...
- height: ...
-
- Image {
- anchors.fill: parent
- source: "reallyBigImage.jpg"
- sourceSize.width: 1024
- sourceSize.height: 1024
- }
- }
- \endcode
-
- If the image's actual size is larger than the sourceSize, the image is scaled down.
- If only one dimension of the size is set to greater than 0, the
- other dimension is set in proportion to preserve the source image's aspect ratio.
- (The \l fillMode is independent of this.)
-
- If the source is an intrinsically scalable image (eg. SVG), this property
- determines the size of the loaded image regardless of intrinsic size.
- Avoid changing this property dynamically; rendering an SVG is \e slow compared
- to an image.
-
- If the source is a non-scalable image (eg. JPEG), the loaded image will
- be no greater than this property specifies. For some formats (currently only JPEG),
- the whole image will never actually be loaded into memory.
-
- Since QtQuick 1.1 the sourceSize can be cleared to the natural size of the image
- by setting sourceSize to \c undefined.
-
- \note \e {Changing this property dynamically causes the image source to be reloaded,
- potentially even from the network, if it is not in the disk cache.}
-*/
-
-/*!
- \qmlproperty url QtQuick2::Image::source
-
- Image can handle any image format supported by Qt, loaded from any URL scheme supported by Qt.
-
- The URL may be absolute, or relative to the URL of the component.
-
- \sa QDeclarativeImageProvider
-*/
-
-/*!
- \qmlproperty bool QtQuick2::Image::asynchronous
-
- Specifies that images on the local filesystem should be loaded
- asynchronously in a separate thread. The default value is
- false, causing the user interface thread to block while the
- image is loaded. Setting \a asynchronous to true is useful where
- maintaining a responsive user interface is more desirable
- than having images immediately visible.
-
- Note that this property is only valid for images read from the
- local filesystem. Images loaded via a network resource (e.g. HTTP)
- are always loaded asynchronously.
-*/
-
-/*!
- \qmlproperty bool QtQuick2::Image::cache
-
- Specifies whether the image should be cached. The default value is
- true. Setting \a cache to false is useful when dealing with large images,
- to make sure that they aren't cached at the expense of small 'ui element' images.
-*/
-
-/*!
- \qmlproperty bool QtQuick2::Image::mirror
-
- This property holds whether the image should be horizontally inverted
- (effectively displaying a mirrored image).
-
- The default value is false.
-*/
-
-/*!
- \qmlproperty enumeration QtQuick2::Image::horizontalAlignment
- \qmlproperty enumeration QtQuick2::Image::verticalAlignment
-
- Sets the horizontal and vertical alignment of the image. By default, the image is top-left aligned.
-
- The valid values for \c horizontalAlignment are \c Image.AlignLeft, \c Image.AlignRight and \c Image.AlignHCenter.
- The valid values for \c verticalAlignment are \c Image.AlignTop, \c Image.AlignBottom
- and \c Image.AlignVCenter.
-*/
-void QQuickImage::updatePaintedGeometry()
-{
- Q_D(QQuickImage);
-
- if (d->fillMode == PreserveAspectFit) {
- if (!d->pix.width() || !d->pix.height()) {
- setImplicitSize(0, 0);
- return;
- }
- qreal w = widthValid() ? width() : d->pix.width();
- qreal widthScale = w / qreal(d->pix.width());
- qreal h = heightValid() ? height() : d->pix.height();
- qreal heightScale = h / qreal(d->pix.height());
- if (widthScale <= heightScale) {
- d->paintedWidth = w;
- d->paintedHeight = widthScale * qreal(d->pix.height());
- } else if (heightScale < widthScale) {
- d->paintedWidth = heightScale * qreal(d->pix.width());
- d->paintedHeight = h;
- }
- qreal iHeight = (widthValid() && !heightValid()) ? d->paintedHeight : d->pix.height();
- qreal iWidth = (heightValid() && !widthValid()) ? d->paintedWidth : d->pix.width();
- setImplicitSize(iWidth, iHeight);
-
- } else if (d->fillMode == PreserveAspectCrop) {
- if (!d->pix.width() || !d->pix.height())
- return;
- qreal widthScale = width() / qreal(d->pix.width());
- qreal heightScale = height() / qreal(d->pix.height());
- if (widthScale < heightScale) {
- widthScale = heightScale;
- } else if (heightScale < widthScale) {
- heightScale = widthScale;
- }
-
- d->paintedHeight = heightScale * qreal(d->pix.height());
- d->paintedWidth = widthScale * qreal(d->pix.width());
- } else if (d->fillMode == Pad) {
- d->paintedWidth = d->pix.width();
- d->paintedHeight = d->pix.height();
- } else {
- d->paintedWidth = width();
- d->paintedHeight = height();
- }
- emit paintedGeometryChanged();
-}
-
-void QQuickImage::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
-{
- QQuickImageBase::geometryChanged(newGeometry, oldGeometry);
- updatePaintedGeometry();
-}
-
-QRectF QQuickImage::boundingRect() const
-{
- Q_D(const QQuickImage);
- return QRectF(0, 0, qMax(width(), d->paintedWidth), qMax(height(), d->paintedHeight));
-}
-
-QSGTextureProvider *QQuickImage::textureProvider() const
-{
- Q_D(const QQuickImage);
- if (!d->provider) {
- // Make sure it gets thread affinity on the rendering thread so deletion works properly..
- Q_ASSERT_X(d->canvas
- && d->sceneGraphContext()
- && QThread::currentThread() == d->sceneGraphContext()->thread(),
- "QQuickImage::textureProvider",
- "Cannot be used outside the GUI thread");
- QQuickImagePrivate *dd = const_cast<QQuickImagePrivate *>(d);
- dd->provider = new QQuickImageTextureProvider;
- dd->provider->m_smooth = d->smooth;
- dd->provider->m_texture = d->sceneGraphContext()->textureForFactory(d->pix.textureFactory());
- }
-
- return d->provider;
-}
-
-QSGNode *QQuickImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
-{
- Q_D(QQuickImage);
-
- QSGTexture *texture = d->sceneGraphContext()->textureForFactory(d->pix.textureFactory());
-
- // Copy over the current texture state into the texture provider...
- if (d->provider) {
- d->provider->m_smooth = d->smooth;
- d->provider->m_texture = texture;
- }
-
- if (!texture || width() <= 0 || height() <= 0) {
- delete oldNode;
- return 0;
- }
-
- QSGImageNode *node = static_cast<QSGImageNode *>(oldNode);
- if (!node) {
- d->pixmapChanged = true;
- node = d->sceneGraphContext()->createImageNode();
- node->setTexture(texture);
- }
-
- if (d->pixmapChanged) {
- // force update the texture in the node to trigger reconstruction of
- // geometry and the likes when a atlas segment has changed.
- node->setTexture(0);
- node->setTexture(texture);
- d->pixmapChanged = false;
- }
-
- QRectF targetRect;
- QRectF sourceRect;
- QSGTexture::WrapMode hWrap = QSGTexture::ClampToEdge;
- QSGTexture::WrapMode vWrap = QSGTexture::ClampToEdge;
-
- qreal pixWidth = (d->fillMode == PreserveAspectFit) ? d->paintedWidth : d->pix.width();
- qreal pixHeight = (d->fillMode == PreserveAspectFit) ? d->paintedHeight : d->pix.height();
-
- int xOffset = 0;
- if (d->hAlign == QQuickImage::AlignHCenter)
- xOffset = qCeil((width() - pixWidth) / 2.);
- else if (d->hAlign == QQuickImage::AlignRight)
- xOffset = qCeil(width() - pixWidth);
-
- int yOffset = 0;
- if (d->vAlign == QQuickImage::AlignVCenter)
- yOffset = qCeil((height() - pixHeight) / 2.);
- else if (d->vAlign == QQuickImage::AlignBottom)
- yOffset = qCeil(height() - pixHeight);
-
- switch (d->fillMode) {
- default:
- case Stretch:
- targetRect = QRectF(0, 0, width(), height());
- sourceRect = d->pix.rect();
- break;
-
- case PreserveAspectFit:
- targetRect = QRectF(xOffset, yOffset, d->paintedWidth, d->paintedHeight);
- sourceRect = d->pix.rect();
- break;
-
- case PreserveAspectCrop: {
- targetRect = QRect(0, 0, width(), height());
- qreal wscale = width() / qreal(d->pix.width());
- qreal hscale = height() / qreal(d->pix.height());
-
- if (wscale > hscale) {
- int src = (hscale / wscale) * qreal(d->pix.height());
- int y = 0;
- if (d->vAlign == QQuickImage::AlignVCenter)
- y = qCeil((d->pix.height() - src) / 2.);
- else if (d->vAlign == QQuickImage::AlignBottom)
- y = qCeil(d->pix.height() - src);
- sourceRect = QRectF(0, y, d->pix.width(), src);
-
- } else {
- int src = (wscale / hscale) * qreal(d->pix.width());
- int x = 0;
- if (d->hAlign == QQuickImage::AlignHCenter)
- x = qCeil((d->pix.width() - src) / 2.);
- else if (d->hAlign == QQuickImage::AlignRight)
- x = qCeil(d->pix.width() - src);
- sourceRect = QRectF(x, 0, src, d->pix.height());
- }
- }
- break;
-
- case Tile:
- targetRect = QRectF(0, 0, width(), height());
- sourceRect = QRectF(-xOffset, -yOffset, width(), height());
- hWrap = QSGTexture::Repeat;
- vWrap = QSGTexture::Repeat;
- break;
-
- case TileHorizontally:
- targetRect = QRectF(0, 0, width(), height());
- sourceRect = QRectF(-xOffset, 0, width(), d->pix.height());
- hWrap = QSGTexture::Repeat;
- break;
-
- case TileVertically:
- targetRect = QRectF(0, 0, width(), height());
- sourceRect = QRectF(0, -yOffset, d->pix.width(), height());
- vWrap = QSGTexture::Repeat;
- break;
-
- case Pad:
- qreal w = qMin(qreal(d->pix.width()), width());
- qreal h = qMin(qreal(d->pix.height()), height());
- qreal x = (d->pix.width() > width()) ? -xOffset : 0;
- qreal y = (d->pix.height() > height()) ? -yOffset : 0;
- targetRect = QRectF(x + xOffset, y + yOffset, w, h);
- sourceRect = QRectF(x, y, w, h);
- break;
- };
-
- QRectF nsrect(sourceRect.x() / d->pix.width(),
- sourceRect.y() / d->pix.height(),
- sourceRect.width() / d->pix.width(),
- sourceRect.height() / d->pix.height());
-
- if (d->mirror) {
- qreal oldLeft = nsrect.left();
- nsrect.setLeft(nsrect.right());
- nsrect.setRight(oldLeft);
- }
-
- node->setHorizontalWrapMode(hWrap);
- node->setVerticalWrapMode(vWrap);
- node->setFiltering(d->smooth ? QSGTexture::Linear : QSGTexture::Nearest);
-
- node->setTargetRect(targetRect);
- node->setSourceRect(nsrect);
- node->update();
-
- return node;
-}
-
-void QQuickImage::pixmapChange()
-{
- Q_D(QQuickImage);
- // PreserveAspectFit calculates the implicit size differently so we
- // don't call our superclass pixmapChange(), since that would
- // result in the implicit size being set incorrectly, then updated
- // in updatePaintedGeometry()
- if (d->fillMode != PreserveAspectFit)
- QQuickImageBase::pixmapChange();
- updatePaintedGeometry();
- d->pixmapChanged = true;
-
- // When the pixmap changes, such as being deleted, we need to update the textures
- update();
-}
-
-QQuickImage::VAlignment QQuickImage::verticalAlignment() const
-{
- Q_D(const QQuickImage);
- return d->vAlign;
-}
-
-void QQuickImage::setVerticalAlignment(VAlignment align)
-{
- Q_D(QQuickImage);
- if (d->vAlign == align)
- return;
-
- d->vAlign = align;
- update();
- updatePaintedGeometry();
- emit verticalAlignmentChanged(align);
-}
-
-QQuickImage::HAlignment QQuickImage::horizontalAlignment() const
-{
- Q_D(const QQuickImage);
- return d->hAlign;
-}
-
-void QQuickImage::setHorizontalAlignment(HAlignment align)
-{
- Q_D(QQuickImage);
- if (d->hAlign == align)
- return;
-
- d->hAlign = align;
- update();
- updatePaintedGeometry();
- emit horizontalAlignmentChanged(align);
-}
-
-QT_END_NAMESPACE