summaryrefslogtreecommitdiffstats
path: root/src/declarative/fx/qfximage.cpp
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2009-08-10 00:25:29 (GMT)
committerAaron Kennedy <aaron.kennedy@nokia.com>2009-08-10 00:25:29 (GMT)
commit4cbb70502828d0cac808e891f3b9e586c9c9b0c1 (patch)
treebdaadfde810d450f94085f7bfe28008d900893de /src/declarative/fx/qfximage.cpp
parentb1f10dc22091f80fba651e32e824175f25956313 (diff)
parentc4235f6f90613f1a877da067354b912ef0004259 (diff)
downloadQt-4cbb70502828d0cac808e891f3b9e586c9c9b0c1.zip
Qt-4cbb70502828d0cac808e891f3b9e586c9c9b0c1.tar.gz
Qt-4cbb70502828d0cac808e891f3b9e586c9c9b0c1.tar.bz2
Merge branch 'kinetic-declarativeui' of git@scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui
Diffstat (limited to 'src/declarative/fx/qfximage.cpp')
-rw-r--r--src/declarative/fx/qfximage.cpp437
1 files changed, 82 insertions, 355 deletions
diff --git a/src/declarative/fx/qfximage.cpp b/src/declarative/fx/qfximage.cpp
index 26e2727..0cb7988 100644
--- a/src/declarative/fx/qfximage.cpp
+++ b/src/declarative/fx/qfximage.cpp
@@ -41,11 +41,6 @@
#include "qfximage.h"
#include "qfximage_p.h"
-#include <private/qfxperf_p.h>
-#include <QNetworkRequest>
-#include <QNetworkReply>
-#include <QFile>
-#include <QtDeclarative/qmlengine.h>
#include <QKeyEvent>
#include <QPainter>
@@ -60,13 +55,10 @@ QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Image,QFxImage)
\brief The Image element allows you to add bitmaps to a scene.
\inherits Item
- The Image element supports untransformed, stretched, tiled, and grid-scaled images.
+ The Image element supports untransformed, stretched and tiled.
For an explanation of stretching and tiling, see the fillMode property description.
- For an explanation of grid-scaling see the scaleGrid property description
- or the QFxScaleGrid class description.
-
Examples:
\table
\row
@@ -86,16 +78,6 @@ QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Image,QFxImage)
}
\endqml
\row
- \o \image declarative-qtlogo4.png
- \o Grid-scaled (only with fillMode: Stretch)
- \qml
- Image { scaleGrid.left: 20; scaleGrid.right: 10
- scaleGrid.top: 14; scaleGrid.bottom: 14
- width: 160; height: 160
- source: "pics/qtlogo.png"
- }
- \endqml
- \row
\o \image declarative-qtlogo3.png
\o fillMode: Tile
\qml
@@ -144,33 +126,26 @@ QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Image,QFxImage)
*/
QFxImage::QFxImage(QFxItem *parent)
- : QFxItem(*(new QFxImagePrivate), parent)
+ : QFxImageBase(*(new QFxImagePrivate), parent)
{
setFlag(QGraphicsItem::ItemHasNoContents, false);
}
QFxImage::QFxImage(QFxImagePrivate &dd, QFxItem *parent)
- : QFxItem(dd, parent)
+ : QFxImageBase(dd, parent)
{
setFlag(QGraphicsItem::ItemHasNoContents, false);
}
QFxImage::~QFxImage()
{
- Q_D(QFxImage);
- if (d->sciReply)
- d->sciReply->deleteLater();
- if (!d->url.isEmpty())
- QFxPixmap::cancelGet(d->url, this);
- if (!d->sciurl.isEmpty())
- QFxPixmap::cancelGet(d->sciurl, this);
}
/*!
- \property QFxImage::image
+ \property QFxImage::pixmap
\brief the image displayed in this item.
- This property contains the image currently being displayed by this item,
+ This property contains the pixmap currently being displayed by this item,
which may be empty if nothing is currently displayed. Setting the source
property overrides any setting of this property.
*/
@@ -194,37 +169,6 @@ void QFxImage::setPixmap(const QPixmap &pix)
}
/*!
- \qmlproperty int Image::scaleGrid.left
- \qmlproperty int Image::scaleGrid.right
- \qmlproperty int Image::scaleGrid.top
- \qmlproperty int Image::scaleGrid.bottom
-
- \target ImagexmlpropertiesscaleGrid
-
- A scale grid uses 4 grid lines (2 horizontal and 2 vertical) to break an image into 9 sections, as shown below:
-
- \image declarative-scalegrid.png
-
- When the image is scaled:
- \list
- \i the corners (sections 1, 3, 7, and 9) are not scaled at all
- \i the middle (section 5) is scaled both horizontally and vertically
- \i sections 2 and 8 are scaled horizontally
- \i sections 4 and 6 are scaled vertically
- \endlist
-
- Each scale grid property (left, right, top, and bottom) specifies an offset from the respective side. For example, \c scaleGrid.bottom="10" sets the bottom scale grid line 10 pixels up from the bottom of the image.
-
- A scale grid can also be specified using a
- \l {Image::source}{.sci file}.
-*/
-QFxScaleGrid *QFxImage::scaleGrid()
-{
- Q_D(QFxImage);
- return d->getScaleGrid();
-}
-
-/*!
\qmlproperty FillMode Image::fillMode
Set this property to define what happens when the image set for the item is smaller
@@ -239,10 +183,6 @@ QFxScaleGrid *QFxImage::scaleGrid()
\endlist
\image declarative-image_fillMode.gif
-
- Only fillMode: Stretch can be used with scaleGrid. Other settings
- will cause a run-time warning.
-
\sa examples/declarative/aspectratio
*/
QFxImage::FillMode QFxImage::fillMode() const
@@ -261,105 +201,6 @@ void QFxImage::setFillMode(FillMode mode)
emit fillModeChanged();
}
-void QFxImage::componentComplete()
-{
- QFxItem::componentComplete();
-}
-
-/*!
- \property QFxImage::scaleGrid
- \brief the 3x3 grid used to scale an image, excluding the corners.
-*/
-
-void QFxImage::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
-{
- Q_D(QFxImage);
- if (d->pix.isNull())
- return;
-
- bool oldAA = p->testRenderHint(QPainter::Antialiasing);
- bool oldSmooth = p->testRenderHint(QPainter::SmoothPixmapTransform);
- if (d->smooth)
- p->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, d->smooth);
-
- QPixmap pix = d->pix;
-
- if (!d->scaleGrid || d->scaleGrid->isNull()) {
- if (width() != pix.width() || height() != pix.height()) {
- if (d->fillMode >= Tile) {
- p->save();
- p->setClipRect(0, 0, width(), height(), Qt::IntersectClip);
-
- if (d->fillMode == Tile) {
- const int pw = pix.width();
- const int ph = pix.height();
- int yy = 0;
-
- while(yy < height()) {
- int xx = 0;
- while(xx < width()) {
- p->drawPixmap(xx, yy, pix);
- xx += pw;
- }
- yy += ph;
- }
- } else if (d->fillMode == TileVertically) {
- const int ph = pix.height();
- int yy = 0;
-
- while(yy < height()) {
- p->drawPixmap(QRect(0, yy, width(), ph), pix);
- yy += ph;
- }
- } else {
- const int pw = pix.width();
- int xx = 0;
-
- while(xx < width()) {
- p->drawPixmap(QRect(xx, 0, pw, height()), pix);
- xx += pw;
- }
- }
-
- p->restore();
- } else {
- qreal widthScale = width() / qreal(pix.width());
- qreal heightScale = height() / qreal(pix.height());
-
- QTransform scale;
-
- if (d->fillMode == PreserveAspect) {
- if (widthScale < heightScale) {
- heightScale = widthScale;
- scale.translate(0, (height() - heightScale * pix.height()) / 2);
- } else if(heightScale < widthScale) {
- widthScale = heightScale;
- scale.translate((width() - widthScale * pix.width()) / 2, 0);
- }
- }
-
- scale.scale(widthScale, heightScale);
- QTransform old = p->transform();
- p->setWorldTransform(scale * old);
- p->drawPixmap(0, 0, pix);
- p->setWorldTransform(old);
- }
- } else {
- p->drawPixmap(0, 0, pix);
- }
- } else {
- QMargins margins(d->scaleGrid->top(), d->scaleGrid->left(), d->scaleGrid->bottom(), d->scaleGrid->right());
- QTileRules rules((Qt::TileRule)d->scaleGrid->horizontalTileRule(),
- (Qt::TileRule)d->scaleGrid->verticalTileRule());
- qDrawBorderPixmap(p, QRect(0, 0, (int)d->width, (int)d->height), margins, pix, pix.rect(), margins, rules);
- }
-
- if (d->smooth) {
- p->setRenderHint(QPainter::Antialiasing, oldAA);
- p->setRenderHint(QPainter::SmoothPixmapTransform, oldSmooth);
- }
-}
-
/*!
\qmlproperty enum Image::status
@@ -374,12 +215,6 @@ void QFxImage::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
\sa progress
*/
-QFxImage::Status QFxImage::status() const
-{
- Q_D(const QFxImage);
- return d->status;
-}
-
/*!
\qmlproperty real Image::progress
@@ -389,215 +224,107 @@ QFxImage::Status QFxImage::status() const
\sa status
*/
-qreal QFxImage::progress() const
-{
- Q_D(const QFxImage);
- return d->progress;
-}
-
/*!
- \qmlproperty url Image::source
-
- Image can handle any image format supported by Qt, loaded from any URL scheme supported by Qt.
+ \qmlproperty bool Image::smooth
- It can also handle .sci files, which are a Qml-specific format. A .sci file uses a simple text-based format that specifies
- \list
- \i the grid lines describing a \l {Image::scaleGrid.left}{scale grid}.
- \i an image file.
- \endlist
-
- The following .sci file sets grid line offsets of 10 on each side for the image \c picture.png:
- \code
- gridLeft: 10
- gridTop: 10
- gridBottom: 10
- gridRight: 10
- imageFile: picture.png
- \endcode
+ 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.
- The URL may be absolute, or relative to the URL of the component.
+ \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.
*/
/*!
- \property QFxImage::source
- \brief the url of the image to be displayed in this item.
+ \qmlproperty url Image::source
- The content specified can be of any image type loadable by QImage. Alternatively,
- you can specify an sci format file, which specifies both an image and it's scale grid.
+ 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.
*/
-QUrl QFxImage::source() const
-{
- Q_D(const QFxImage);
- return d->url;
-}
-void QFxImage::setSource(const QUrl &url)
+void QFxImage::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxPerfTimer<QFxPerf::PixmapLoad> perf;
-#endif
Q_D(QFxImage);
- //equality is fairly expensive, so we bypass for simple, common case
- if ((d->url.isEmpty() == url.isEmpty()) && url == d->url)
+ if (d->pix.isNull())
return;
- if (d->sciReply) {
- d->sciReply->deleteLater();
- d->sciReply = 0;
- }
+ bool oldAA = p->testRenderHint(QPainter::Antialiasing);
+ bool oldSmooth = p->testRenderHint(QPainter::SmoothPixmapTransform);
+ if (d->smooth)
+ p->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, d->smooth);
- if (!d->url.isEmpty())
- QFxPixmap::cancelGet(d->url, this);
- if (!d->sciurl.isEmpty())
- QFxPixmap::cancelGet(d->sciurl, this);
-
- d->url = url;
- d->sciurl = QUrl();
- if (d->progress != 0.0) {
- d->progress = 0.0;
- emit progressChanged(d->progress);
- }
+ QPixmap pix = d->pix;
- if (url.isEmpty()) {
- d->pix = QPixmap();
- d->status = Null;
- d->progress = 1.0;
- setImplicitWidth(0);
- setImplicitHeight(0);
- emit statusChanged(d->status);
- emit sourceChanged(d->url);
- emit progressChanged(1.0);
- update();
- } else {
- d->status = Loading;
- if (d->url.path().endsWith(QLatin1String(".sci"))) {
-#ifndef QT_NO_LOCALFILE_OPTIMIZED_QML
- if (d->url.scheme() == QLatin1String("file")) {
- QFile file(d->url.toLocalFile());
- file.open(QIODevice::ReadOnly);
- setGridScaledImage(QFxGridScaledImage(&file));
- } else
-#endif
- {
- QNetworkRequest req(d->url);
- req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
- d->sciReply = qmlEngine(this)->networkAccessManager()->get(req);
- QObject::connect(d->sciReply, SIGNAL(finished()),
- this, SLOT(sciRequestFinished()));
- }
- } else {
- d->reply = QFxPixmap::get(qmlEngine(this), d->url, &d->pix);
- if (d->reply) {
- connect(d->reply, SIGNAL(finished()), this, SLOT(requestFinished()));
- connect(d->reply, SIGNAL(downloadProgress(qint64,qint64)),
- this, SLOT(requestProgress(qint64,qint64)));
+ if (width() != pix.width() || height() != pix.height()) {
+ if (d->fillMode >= Tile) {
+ p->save();
+ p->setClipRect(0, 0, width(), height(), Qt::IntersectClip);
+
+ if (d->fillMode == Tile) {
+ const int pw = pix.width();
+ const int ph = pix.height();
+ int yy = 0;
+
+ while(yy < height()) {
+ int xx = 0;
+ while(xx < width()) {
+ p->drawPixmap(xx, yy, pix);
+ xx += pw;
+ }
+ yy += ph;
+ }
+ } else if (d->fillMode == TileVertically) {
+ const int ph = pix.height();
+ int yy = 0;
+
+ while(yy < height()) {
+ p->drawPixmap(QRect(0, yy, width(), ph), pix);
+ yy += ph;
+ }
} else {
- //### should be unified with requestFinished
- setImplicitWidth(d->pix.width());
- setImplicitHeight(d->pix.height());
-
- if (d->status == Loading)
- d->status = Ready;
- d->progress = 1.0;
- emit statusChanged(d->status);
- emit sourceChanged(d->url);
- emit progressChanged(1.0);
- update();
+ const int pw = pix.width();
+ int xx = 0;
+
+ while(xx < width()) {
+ p->drawPixmap(QRect(xx, 0, pw, height()), pix);
+ xx += pw;
+ }
}
- }
- }
- emit statusChanged(d->status);
-}
+ p->restore();
+ } else {
+ qreal widthScale = width() / qreal(pix.width());
+ qreal heightScale = height() / qreal(pix.height());
+
+ QTransform scale;
+
+ if (d->fillMode == PreserveAspect) {
+ if (widthScale < heightScale) {
+ heightScale = widthScale;
+ scale.translate(0, (height() - heightScale * pix.height()) / 2);
+ } else if(heightScale < widthScale) {
+ widthScale = heightScale;
+ scale.translate((width() - widthScale * pix.width()) / 2, 0);
+ }
+ }
-void QFxImage::requestFinished()
-{
- Q_D(QFxImage);
- if (d->url.path().endsWith(QLatin1String(".sci"))) {
- QFxPixmap::find(d->sciurl, &d->pix);
- } else {
- if (d->reply) {
- //###disconnect really needed?
- disconnect(d->reply, SIGNAL(downloadProgress(qint64,qint64)),
- this, SLOT(requestProgress(qint64,qint64)));
- if (d->reply->error() != QNetworkReply::NoError)
- d->status = Error;
+ scale.scale(widthScale, heightScale);
+ QTransform old = p->transform();
+ p->setWorldTransform(scale * old);
+ p->drawPixmap(0, 0, pix);
+ p->setWorldTransform(old);
}
- QFxPixmap::find(d->url, &d->pix);
- }
- setImplicitWidth(d->pix.width());
- setImplicitHeight(d->pix.height());
-
- if (d->status == Loading)
- d->status = Ready;
- d->progress = 1.0;
- emit statusChanged(d->status);
- emit sourceChanged(d->url);
- emit progressChanged(1.0);
- update();
-}
-
-void QFxImage::sciRequestFinished()
-{
- Q_D(QFxImage);
- if (d->sciReply->error() != QNetworkReply::NoError) {
- d->status = Error;
- d->sciReply->deleteLater();
- d->sciReply = 0;
- emit statusChanged(d->status);
} else {
- QFxGridScaledImage sci(d->sciReply);
- d->sciReply->deleteLater();
- d->sciReply = 0;
- setGridScaledImage(sci);
+ p->drawPixmap(0, 0, pix);
}
-}
-
-void QFxImage::requestProgress(qint64 received, qint64 total)
-{
- Q_D(QFxImage);
- if (d->status == Loading && total > 0) {
- d->progress = qreal(received)/total;
- emit progressChanged(d->progress);
- }
-}
-void QFxImage::setGridScaledImage(const QFxGridScaledImage& sci)
-{
- Q_D(QFxImage);
- if (!sci.isValid()) {
- d->status = Error;
- emit statusChanged(d->status);
- } else {
- QFxScaleGrid *sg = scaleGrid();
- sg->setTop(sci.gridTop());
- sg->setBottom(sci.gridBottom());
- sg->setLeft(sci.gridLeft());
- sg->setRight(sci.gridRight());
- sg->setHorizontalTileRule(sci.horizontalTileRule());
- sg->setVerticalTileRule(sci.verticalTileRule());
-
- d->sciurl = d->url.resolved(QUrl(sci.pixmapUrl()));
- d->reply = QFxPixmap::get(qmlEngine(this), d->sciurl, &d->pix);
- if (d->reply) {
- connect(d->reply, SIGNAL(finished()), this, SLOT(requestFinished()));
- connect(d->reply, SIGNAL(downloadProgress(qint64,qint64)),
- this, SLOT(requestProgress(qint64,qint64)));
- } else {
- //### should be unified with requestFinished
- setImplicitWidth(d->pix.width());
- setImplicitHeight(d->pix.height());
-
- if (d->status == Loading)
- d->status = Ready;
- d->progress = 1.0;
- emit statusChanged(d->status);
- emit sourceChanged(d->url);
- emit progressChanged(1.0);
- update();
- }
+ if (d->smooth) {
+ p->setRenderHint(QPainter::Antialiasing, oldAA);
+ p->setRenderHint(QPainter::SmoothPixmapTransform, oldSmooth);
}
}
-
QT_END_NAMESPACE