diff options
-rw-r--r-- | doc/src/images/declarative-image_fillMode.gif | bin | 0 -> 42648 bytes | |||
-rw-r--r-- | doc/src/images/declarative-qtlogo3.png | bin | 5848 -> 4783 bytes | |||
-rw-r--r-- | doc/src/images/declarative-qtlogo5.png | bin | 0 -> 3553 bytes | |||
-rw-r--r-- | doc/src/images/declarative-qtlogo6.png | bin | 0 -> 4763 bytes | |||
-rw-r--r-- | examples/declarative/aspectratio/scale_to_fit_simple.qml | 2 | ||||
-rw-r--r-- | examples/declarative/fillmode/face.png | bin | 0 -> 905 bytes | |||
-rw-r--r-- | examples/declarative/fillmode/fillmode.qml | 39 | ||||
-rw-r--r-- | examples/declarative/minehunt/minehunt.qml | 2 | ||||
-rw-r--r-- | examples/declarative/snow/ImageBatch.qml | 2 | ||||
-rw-r--r-- | src/declarative/fx/qfxevents.cpp | 11 | ||||
-rw-r--r-- | src/declarative/fx/qfximage.cpp | 207 | ||||
-rw-r--r-- | src/declarative/fx/qfximage.h | 14 | ||||
-rw-r--r-- | src/declarative/fx/qfximage_p.h | 8 | ||||
-rw-r--r-- | src/declarative/fx/qfxpathview.cpp | 19 | ||||
-rw-r--r-- | src/declarative/fx/qfxpixmap.cpp | 83 | ||||
-rw-r--r-- | tools/qmlviewer/qmlviewer.cpp | 4 |
16 files changed, 250 insertions, 141 deletions
diff --git a/doc/src/images/declarative-image_fillMode.gif b/doc/src/images/declarative-image_fillMode.gif Binary files differnew file mode 100644 index 0000000..c81b4d7 --- /dev/null +++ b/doc/src/images/declarative-image_fillMode.gif diff --git a/doc/src/images/declarative-qtlogo3.png b/doc/src/images/declarative-qtlogo3.png Binary files differindex 3f2f93f..d516524 100644 --- a/doc/src/images/declarative-qtlogo3.png +++ b/doc/src/images/declarative-qtlogo3.png diff --git a/doc/src/images/declarative-qtlogo5.png b/doc/src/images/declarative-qtlogo5.png Binary files differnew file mode 100644 index 0000000..b7b3513 --- /dev/null +++ b/doc/src/images/declarative-qtlogo5.png diff --git a/doc/src/images/declarative-qtlogo6.png b/doc/src/images/declarative-qtlogo6.png Binary files differnew file mode 100644 index 0000000..07a078f --- /dev/null +++ b/doc/src/images/declarative-qtlogo6.png diff --git a/examples/declarative/aspectratio/scale_to_fit_simple.qml b/examples/declarative/aspectratio/scale_to_fit_simple.qml index f9c0e04..5381bb4 100644 --- a/examples/declarative/aspectratio/scale_to_fit_simple.qml +++ b/examples/declarative/aspectratio/scale_to_fit_simple.qml @@ -13,7 +13,7 @@ Rect { Image { id: Image source: "pics/face.png" - preserveAspect: true + fillMode: "PreserveAspect" anchors.fill: parent } } diff --git a/examples/declarative/fillmode/face.png b/examples/declarative/fillmode/face.png Binary files differnew file mode 100644 index 0000000..9623b1a --- /dev/null +++ b/examples/declarative/fillmode/face.png diff --git a/examples/declarative/fillmode/fillmode.qml b/examples/declarative/fillmode/fillmode.qml new file mode 100644 index 0000000..6bf1c12 --- /dev/null +++ b/examples/declarative/fillmode/fillmode.qml @@ -0,0 +1,39 @@ +import Qt 4.6 + +Image { + width: 400 + height: 250 + source: "face.png" + fillMode: SequentialAnimation { + running: true + repeat: true + SetPropertyAction { value: "Stretch" } + SetPropertyAction { target: Label; property: "text"; value: "Stretch" } + PauseAnimation { duration: 1000 } + SetPropertyAction { value: "PreserveAspect" } + SetPropertyAction { target: Label; property: "text"; value: "PreserveAspect" } + PauseAnimation { duration: 1000 } + SetPropertyAction { value: "Tile" } + SetPropertyAction { target: Label; property: "text"; value: "Tile" } + PauseAnimation { duration: 1000 } + SetPropertyAction { value: "TileHorizontally" } + SetPropertyAction { target: Label; property: "text"; value: "TileHorizontally" } + PauseAnimation { duration: 1000 } + SetPropertyAction { value: "TileVertically" } + SetPropertyAction { target: Label; property: "text"; value: "TileVertically" } + PauseAnimation { duration: 1000 } + } + Text { + id: Label + font.size: 24 + color: "blue" + style: "Outline" + styleColor: "white" + anchors { centerIn: parent } + } + Rect { + border.color: "black" + color: "transparent" + anchors { fill: parent; rightMargin: 1; bottomMargin: 1} + } +} diff --git a/examples/declarative/minehunt/minehunt.qml b/examples/declarative/minehunt/minehunt.qml index e1f48ef..6b45b79 100644 --- a/examples/declarative/minehunt/minehunt.qml +++ b/examples/declarative/minehunt/minehunt.qml @@ -119,7 +119,7 @@ Item { ] Image { source: "pics/No-Ones-Laughing-3.jpg" - tile: true + fillMode: "Tile" } Description { text: "Use the 'minehunt' executable to run this demo!" diff --git a/examples/declarative/snow/ImageBatch.qml b/examples/declarative/snow/ImageBatch.qml index 4b52991..8aa4bb2 100644 --- a/examples/declarative/snow/ImageBatch.qml +++ b/examples/declarative/snow/ImageBatch.qml @@ -41,7 +41,7 @@ GridView { transformOrigin: "Center" width: MyGrid.imageWidth; height: MyGrid.imageHeight; - Image { id: Image; source: url; preserveAspect: true; smooth: true; anchors.fill: parent; + Image { id: Image; source: url; fillMode: "PreserveAspect"; smooth: true; anchors.fill: parent; opacity: (status == 0)?1:0; opacity: Behavior { NumberAnimation { properties: "opacity" } } } Loading { anchors.centerIn: parent; visible: Image.status } diff --git a/src/declarative/fx/qfxevents.cpp b/src/declarative/fx/qfxevents.cpp index 94c2d2e..f3a3427 100644 --- a/src/declarative/fx/qfxevents.cpp +++ b/src/declarative/fx/qfxevents.cpp @@ -106,6 +106,17 @@ Item { */ /*! + \qmlproperty bool KeyEvent::accepted + + Setting \a accepted to true prevents the key event from being + propagated to the item's parent. + + Generally, if the item acts on the key event then it should be accepted + so that ancestor items do not also respond to the same event. +*/ + + +/*! \qmlclass MouseEvent QFxMouseEvent \brief The MouseEvent object provides information about a mouse event. diff --git a/src/declarative/fx/qfximage.cpp b/src/declarative/fx/qfximage.cpp index 15dc620..98e8985 100644 --- a/src/declarative/fx/qfximage.cpp +++ b/src/declarative/fx/qfximage.cpp @@ -60,7 +60,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, grid-scaled and tiled images. + The Image element supports untransformed, stretched, tiled, and grid-scaled images. + + 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. @@ -74,23 +77,53 @@ QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Image,QFxImage) \endqml \row \o \image declarative-qtlogo2.png - \o Stretched + \o fillMode: Stretch (default) \qml - Image { width: 160; height: 160; source: "pics/qtlogo.png" } + Image { + width: 160 + height: 160 + source: "pics/qtlogo.png" + } \endqml \row \o \image declarative-qtlogo4.png - \o Grid-scaled + \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" } + width: 160; height: 160 + source: "pics/qtlogo.png" + } \endqml \row \o \image declarative-qtlogo3.png - \o Tiled + \o fillMode: Tile + \qml + Image { + fillMode: "Tile" + width: 160; height: 160 + source: "pics/qtlogo.png" + } + \endqml + \row + \o \image declarative-qtlogo6.png + \o fillMode: TileVertically + \qml + Image { + fillMode: "TileVertically" + width: 160; height: 160 + source: "pics/qtlogo.png" + } + \endqml + \row + \o \image declarative-qtlogo5.png + \o fillMode: TileHorizontally \qml - Image { tile: true; width: 160; height: 160; source: "pics/qtlogo.png" } + Image { + fillMode: "TileHorizontally" + width: 160; height: 160 + source: "pics/qtlogo.png" + } \endqml \endtable */ @@ -193,33 +226,40 @@ QFxScaleGrid *QFxImage::scaleGrid() } /*! - \qmlproperty bool Image::tile + \qmlproperty FillMode Image::fillMode - Set this property to enable image tiling. Normally the Image element scales the - bitmap file to its size. If tiling is enabled, the bitmap is repeated as a set - of unscaled tiles, clipped to the size of the Image. + Set this property to define what happens when the image set for the item is smaller + than the size of the item. - \qml - Item { - Image { source: "tile.png" } - Image { x: 80; width: 100; height: 100; source: "tile.png" } - Image { x: 190; width: 100; height: 100; tile: true; source: "tile.png" } - } - \endqml - \image declarative-image_tile.png + \list + \o Stretch - the image is scaled to fit + \o PreserveAspect - the image is scaled uniformly to fit + \o Tile - the image is duplicated horizontally and vertically + \o TileVertically - the image is stretched horizontally and tiled vertically + \o TileHorizontally - the image is stretched vertically and tiled horizontally + \endlist + + \image declarative-image_fillMode.gif - If both tiling and the scaleGrid are set, tiling takes precedence. + Only fillMode: Stretch can be used with scaleGrid. Other settings + will cause a run-time warning. + + \sa examples/declarative/aspectratio */ -bool QFxImage::isTiled() const +QFxImage::FillMode QFxImage::fillMode() const { Q_D(const QFxImage); - return d->tiled; + return d->fillMode; } -void QFxImage::setTiled(bool tile) +void QFxImage::setFillMode(FillMode mode) { Q_D(QFxImage); - d->tiled = tile; + if (d->fillMode == mode) + return; + d->fillMode = mode; + update(); + emit fillModeChanged(); } void QFxImage::componentComplete() @@ -283,51 +323,72 @@ void QFxImage::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *) QPixmap pix = d->pix; - if (d->tiled) { - p->save(); - p->setClipRect(0, 0, width(), height(), Qt::IntersectClip); - QRect me = QRect(0, 0, width(), height()); - - int pw = pix.width(); - 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; - } - - p->restore(); - } else if (!d->scaleGrid || d->scaleGrid->isNull()) { + if (!d->scaleGrid || d->scaleGrid->isNull()) { if (width() != pix.width() || height() != pix.height()) { - qreal widthScale = width() / qreal(pix.width()); - qreal heightScale = height() / qreal(pix.height()); - - QTransform scale; - - if (d->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); + 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; + } } - } - scale.scale(widthScale, heightScale); - QTransform old = p->transform(); - p->setWorldTransform(scale * old); - p->drawPixmap(0, 0, pix); - p->setWorldTransform(old); + 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 { + if (d->fillMode != Stretch) + qWarning("Only fillmode:Stretch supported for scale grid images"); int sgl = d->scaleGrid->left(); int sgr = d->scaleGrid->right(); int sgt = d->scaleGrid->top(); @@ -458,28 +519,6 @@ QUrl QFxImage::source() const return d->url; } -/*! - \qmlproperty bool Image::preserveAspect - - Whether the image's aspect ratio should be preserved when resizing. By default this - is false. -*/ -bool QFxImage::preserveAspect() const -{ - Q_D(const QFxImage); - return d->preserveAspect; -} - -void QFxImage::setPreserveAspect(bool p) -{ - Q_D(QFxImage); - - if (p == d->preserveAspect) - return; - d->preserveAspect = p; - update(); -} - void QFxImage::setSource(const QUrl &url) { #ifdef Q_ENABLE_PERFORMANCE_LOG diff --git a/src/declarative/fx/qfximage.h b/src/declarative/fx/qfximage.h index 633289f..9573ce5 100644 --- a/src/declarative/fx/qfximage.h +++ b/src/declarative/fx/qfximage.h @@ -57,24 +57,26 @@ class Q_DECLARATIVE_EXPORT QFxImage : public QFxItem { Q_OBJECT Q_ENUMS(Status) + Q_ENUMS(FillMode) Q_PROPERTY(Status status READ status NOTIFY statusChanged) Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged) Q_PROPERTY(QFxScaleGrid *scaleGrid READ scaleGrid) - Q_PROPERTY(bool tile READ isTiled WRITE setTiled) Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap DESIGNABLE false) Q_PROPERTY(bool smooth READ smoothTransform WRITE setSmoothTransform) - Q_PROPERTY(bool preserveAspect READ preserveAspect WRITE setPreserveAspect); + Q_PROPERTY(FillMode fillMode READ fillMode WRITE setFillMode NOTIFY fillModeChanged); + public: QFxImage(QFxItem *parent=0); ~QFxImage(); QFxScaleGrid *scaleGrid(); - bool isTiled() const; - void setTiled(bool tile); + enum FillMode { Stretch, PreserveAspect, Tile, TileVertically, TileHorizontally }; + FillMode fillMode() const; + void setFillMode(FillMode); QPixmap pixmap() const; void setPixmap(const QPixmap &); @@ -86,9 +88,6 @@ public: Status status() const; qreal progress() const; - bool preserveAspect() const; - void setPreserveAspect(bool); - QUrl source() const; virtual void setSource(const QUrl &url); @@ -98,6 +97,7 @@ Q_SIGNALS: void sourceChanged(const QUrl &); void statusChanged(Status); void progressChanged(qreal progress); + void fillModeChanged(); protected: QFxImage(QFxImagePrivate &dd, QFxItem *parent); diff --git a/src/declarative/fx/qfximage_p.h b/src/declarative/fx/qfximage_p.h index 7792dbf..a9ad054 100644 --- a/src/declarative/fx/qfximage_p.h +++ b/src/declarative/fx/qfximage_p.h @@ -70,8 +70,9 @@ class QFxImagePrivate : public QFxItemPrivate public: QFxImagePrivate() - : scaleGrid(0), tiled(false), smooth(false), opaque(false), - preserveAspect(false), status(QFxImage::Idle), sciReply(0), + : scaleGrid(0), smooth(false), opaque(false), + fillMode(QFxImage::Stretch), + status(QFxImage::Idle), sciReply(0), progress(0.0) { } @@ -92,11 +93,10 @@ public: QFxScaleGrid *scaleGrid; QPixmap pix; - bool tiled : 1; bool smooth : 1; bool opaque : 1; - bool preserveAspect : 1; + QFxImage::FillMode fillMode; QFxImage::Status status; QUrl url; QUrl sciurl; diff --git a/src/declarative/fx/qfxpathview.cpp b/src/declarative/fx/qfxpathview.cpp index 6546f69..ee3ad2b 100644 --- a/src/declarative/fx/qfxpathview.cpp +++ b/src/declarative/fx/qfxpathview.cpp @@ -576,13 +576,16 @@ void QFxPathViewPrivate::regenerate() int numItems = pathItems >= 0 ? pathItems : model->count(); for (int i=0; i < numItems && i < model->count(); ++i){ - QFxItem *item = getItem((i + firstIndex) % model->count()); + int index = (i + firstIndex) % model->count(); + QFxItem *item = getItem(index); if (!item) { qWarning() << "PathView: Cannot create item, index" << (i + firstIndex) % model->count(); return; } items.append(item); item->setZValue(i); + if (currentIndex == index) + item->setFocus(true); } q->refill(); } @@ -639,8 +642,11 @@ void QFxPathView::refill() d->firstIndex++; d->firstIndex %= d->model->count(); int index = (d->firstIndex + d->items.count())%d->model->count(); - d->items << d->getItem(index); - d->items.last()->setZValue(wrapIndex); + QFxItem *item = d->getItem(index); + item->setZValue(wrapIndex); + if (d->currentIndex == index) + item->setFocus(true); + d->items << item; d->pathOffset++; d->pathOffset=d->pathOffset % d->items.count(); } @@ -652,8 +658,11 @@ void QFxPathView::refill() d->firstIndex--; if (d->firstIndex < 0) d->firstIndex = d->model->count() - 1; - d->items.prepend(d->getItem(d->firstIndex)); - d->items.first()->setZValue(d->firstIndex); + QFxItem *item = d->getItem(d->firstIndex); + item->setZValue(d->firstIndex); + if (d->currentIndex == d->firstIndex) + item->setFocus(true); + d->items.prepend(item); d->pathOffset--; if (d->pathOffset < 0) d->pathOffset = d->items.count() - 1; diff --git a/src/declarative/fx/qfxpixmap.cpp b/src/declarative/fx/qfxpixmap.cpp index e4d79f4..6647b21 100644 --- a/src/declarative/fx/qfxpixmap.cpp +++ b/src/declarative/fx/qfxpixmap.cpp @@ -87,6 +87,39 @@ public: QFxPixmapPrivate() {} QPixmap pixmap; + + bool readImage(QIODevice *dev) + { + QImageReader imgio(dev); + +//#define QT_TEST_SCALED_SIZE +#ifdef QT_TEST_SCALED_SIZE + /* + Some mechanism is needed for loading images at a limited size, especially + for remote images. Loading only thumbnails of remote progressive JPEG + images can be efficient. (Qt jpeg handler does not do so currently) + */ + + QSize limit(60,60); + QSize sz = imgio.size(); + if (sz.width() > limit.width() || sz.height() > limit.height()) { + sz.scale(limit,Qt::KeepAspectRatio); + imgio.setScaledSize(sz); + } +#endif + + QImage img; + if (imgio.read(&img)) { +#ifdef QT_TEST_SCALED_SIZE + if (!sz.isValid()) + img = img.scaled(limit,Qt::KeepAspectRatio); +#endif + pixmap = QPixmap::fromImage(img); + return true; + } else { + return false; + } + } }; /*! @@ -109,55 +142,31 @@ QFxPixmap::QFxPixmap(const QUrl &url) #ifdef Q_ENABLE_PERFORMANCE_LOG QFxPerfTimer<QFxPerf::PixmapLoad> perf; #endif + QString key = url.toString(); + if (!QPixmapCache::find(key,&d->pixmap)) { #ifndef QT_NO_LOCALFILE_OPTIMIZED_QML - if (url.scheme()==QLatin1String("file")) { - d->pixmap.load(url.toLocalFile()); - } else + if (url.scheme()==QLatin1String("file")) { + QFile f(url.toLocalFile()); + if (f.open(QIODevice::ReadOnly)) + if (!d->readImage(&f)) + qWarning() << "Format error loading" << url; + } else #endif - { - QString key = url.toString(); - if (!QPixmapCache::find(key,&d->pixmap)) { + { QFxSharedNetworkReplyHash::Iterator iter = qfxActiveNetworkReplies.find(key); if (iter == qfxActiveNetworkReplies.end()) { // API usage error qWarning() << "QFxPixmap: URL not loaded" << url; } else { - if ((*iter)->reply->error()) { + if ((*iter)->reply->error()) qWarning() << "Network error loading" << url << (*iter)->reply->errorString(); - } else { - QImageReader imgio((*iter)->reply); - -//#define QT_TEST_SCALED_SIZE -#ifdef QT_TEST_SCALED_SIZE - /* - Some mechanism is needed for loading images at a limited size, especially - for remote images. Loading only thumbnails of remote progressive JPEG - images can be efficient. (Qt jpeg handler does not do so currently) - */ - - QSize limit(60,60); - QSize sz = imgio.size(); - if (sz.width() > limit.width() || sz.height() > limit.height()) { - sz.scale(limit,Qt::KeepAspectRatio); - imgio.setScaledSize(sz); - } -#endif - - QImage img; - if (imgio.read(&img)) { -#ifdef QT_TEST_SCALED_SIZE - if (!sz.isValid()) - img = img.scaled(limit,Qt::KeepAspectRatio); -#endif - d->pixmap = QPixmap::fromImage(img); - QPixmapCache::insert(key, d->pixmap); - } else { + else + if (!d->readImage((*iter)->reply)) qWarning() << "Format error loading" << url; - } - } (*iter)->release(); } } + QPixmapCache::insert(key, d->pixmap); } } diff --git a/tools/qmlviewer/qmlviewer.cpp b/tools/qmlviewer/qmlviewer.cpp index 098f749..c1b9eb1 100644 --- a/tools/qmlviewer/qmlviewer.cpp +++ b/tools/qmlviewer/qmlviewer.cpp @@ -640,8 +640,10 @@ void QmlViewer::setSkin(const QString& skinDirectory) void QmlViewer::setAutoRecord(int from, int to) { + if (from==0) from=1; // ensure resized record_autotime = to-from; autoStartTimer.setInterval(from); + autoStartTimer.setRunning(true); } void QmlViewer::setRecordArgs(const QStringList& a) @@ -866,7 +868,7 @@ void QmlViewer::autoStartRecording() void QmlViewer::autoStopRecording() { - setRecording(true); + setRecording(false); } void QmlViewer::recordFrame() |