aboutsummaryrefslogtreecommitdiffstats
path: root/src/qtquick1/graphicsitems/qdeclarativegridview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qtquick1/graphicsitems/qdeclarativegridview.cpp')
-rw-r--r--src/qtquick1/graphicsitems/qdeclarativegridview.cpp3174
1 files changed, 0 insertions, 3174 deletions
diff --git a/src/qtquick1/graphicsitems/qdeclarativegridview.cpp b/src/qtquick1/graphicsitems/qdeclarativegridview.cpp
deleted file mode 100644
index dd002e5b6c..0000000000
--- a/src/qtquick1/graphicsitems/qdeclarativegridview.cpp
+++ /dev/null
@@ -1,3174 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** 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 "QtQuick1/private/qdeclarativegridview_p.h"
-
-#include "QtQuick1/private/qdeclarativevisualitemmodel_p.h"
-#include "QtQuick1/private/qdeclarativeflickable_p_p.h"
-
-#include "QtQuick1/private/qdeclarativesmoothedanimation_p_p.h"
-#include <QtDeclarative/private/qdeclarativeguard_p.h>
-
-#include <QKeyEvent>
-
-#include <qmath.h>
-#include <math.h>
-#include "qplatformdefs.h"
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QML_FLICK_SNAPONETHRESHOLD
-#define QML_FLICK_SNAPONETHRESHOLD 30
-#endif
-
-//----------------------------------------------------------------------------
-
-class FxGridItem1
-{
-public:
- FxGridItem1(QDeclarativeItem *i, QDeclarative1GridView *v) : item(i), view(v) {
- attached = static_cast<QDeclarative1GridViewAttached*>(qmlAttachedPropertiesObject<QDeclarative1GridView>(item));
- if (attached)
- attached->setView(view);
- }
- ~FxGridItem1() {}
-
- qreal rowPos() const {
- qreal rowPos = 0;
- if (view->flow() == QDeclarative1GridView::LeftToRight) {
- rowPos = item->y();
- } else {
- if (view->effectiveLayoutDirection() == Qt::RightToLeft)
- rowPos = -view->cellWidth()-item->x();
- else
- rowPos = item->x();
- }
- return rowPos;
- }
- qreal colPos() const {
- qreal colPos = 0;
- if (view->flow() == QDeclarative1GridView::LeftToRight) {
- if (view->effectiveLayoutDirection() == Qt::RightToLeft) {
- int colSize = view->cellWidth();
- int columns = view->width()/colSize;
- colPos = colSize * (columns-1) - item->x();
- } else {
- colPos = item->x();
- }
- } else {
- colPos = item->y();
- }
-
- return colPos;
- }
-
- qreal endRowPos() const {
- if (view->flow() == QDeclarative1GridView::LeftToRight) {
- return item->y() + view->cellHeight() - 1;
- } else {
- if (view->effectiveLayoutDirection() == Qt::RightToLeft)
- return -item->x() - 1;
- else
- return item->x() + view->cellWidth() - 1;
- }
- }
- void setPosition(qreal col, qreal row) {
- if (view->effectiveLayoutDirection() == Qt::RightToLeft) {
- if (view->flow() == QDeclarative1GridView::LeftToRight) {
- int columns = view->width()/view->cellWidth();
- item->setPos(QPointF((view->cellWidth() * (columns-1) - col), row));
- } else {
- item->setPos(QPointF(-view->cellWidth()-row, col));
- }
- } else {
- if (view->flow() == QDeclarative1GridView::LeftToRight)
- item->setPos(QPointF(col, row));
- else
- item->setPos(QPointF(row, col));
- }
-
- }
- bool contains(qreal x, qreal y) const {
- return (x >= item->x() && x < item->x() + view->cellWidth() &&
- y >= item->y() && y < item->y() + view->cellHeight());
- }
-
- QDeclarativeItem *item;
- QDeclarative1GridView *view;
- QDeclarative1GridViewAttached *attached;
- int index;
-};
-
-//----------------------------------------------------------------------------
-
-class QDeclarative1GridViewPrivate : public QDeclarative1FlickablePrivate
-{
- Q_DECLARE_PUBLIC(QDeclarative1GridView)
-
-public:
- QDeclarative1GridViewPrivate()
- : currentItem(0), layoutDirection(Qt::LeftToRight), flow(QDeclarative1GridView::LeftToRight)
- , visibleIndex(0) , currentIndex(-1)
- , cellWidth(100), cellHeight(100), columns(1), requestedIndex(-1), itemCount(0)
- , highlightRangeStart(0), highlightRangeEnd(0)
- , highlightRangeStartValid(false), highlightRangeEndValid(false)
- , highlightRange(QDeclarative1GridView::NoHighlightRange)
- , highlightComponent(0), highlight(0), trackedItem(0)
- , moveReason(Other), buffer(0), highlightXAnimator(0), highlightYAnimator(0)
- , highlightMoveDuration(150)
- , footerComponent(0), footer(0), headerComponent(0), header(0)
- , bufferMode(BufferBefore | BufferAfter), snapMode(QDeclarative1GridView::NoSnap)
- , ownModel(false), wrap(false), autoHighlight(true)
- , fixCurrentVisibility(false), lazyRelease(false), layoutScheduled(false)
- , deferredRelease(false), haveHighlightRange(false), currentIndexCleared(false) {}
-
- void init();
- void clear();
- FxGridItem1 *createItem(int modelIndex);
- void releaseItem(FxGridItem1 *item);
- void refill(qreal from, qreal to, bool doBuffer=false);
-
- void updateGrid();
- void scheduleLayout();
- void layout();
- void updateUnrequestedIndexes();
- void updateUnrequestedPositions();
- void updateTrackedItem();
- void createHighlight();
- void updateHighlight();
- void updateCurrent(int modelIndex);
- void updateHeader();
- void updateFooter();
- void fixupPosition();
-
- FxGridItem1 *visibleItem(int modelIndex) const {
- if (modelIndex >= visibleIndex && modelIndex < visibleIndex + visibleItems.count()) {
- for (int i = modelIndex - visibleIndex; i < visibleItems.count(); ++i) {
- FxGridItem1 *item = visibleItems.at(i);
- if (item->index == modelIndex)
- return item;
- }
- }
- return 0;
- }
-
- bool isRightToLeftTopToBottom() const {
- Q_Q(const QDeclarative1GridView);
- return flow == QDeclarative1GridView::TopToBottom && q->effectiveLayoutDirection() == Qt::RightToLeft;
- }
-
- void regenerate() {
- Q_Q(QDeclarative1GridView);
- if (q->isComponentComplete()) {
- clear();
- updateGrid();
- setPosition(0);
- q->refill();
- updateCurrent(currentIndex);
- }
- }
-
- void mirrorChange() {
- Q_Q(QDeclarative1GridView);
- regenerate();
- emit q->effectiveLayoutDirectionChanged();
- }
-
- qreal position() const {
- Q_Q(const QDeclarative1GridView);
- return flow == QDeclarative1GridView::LeftToRight ? q->contentY() : q->contentX();
- }
- void setPosition(qreal pos) {
- Q_Q(QDeclarative1GridView);
- if (flow == QDeclarative1GridView::LeftToRight) {
- q->QDeclarative1Flickable::setContentY(pos);
- q->QDeclarative1Flickable::setContentX(0);
- } else {
- if (q->effectiveLayoutDirection() == Qt::LeftToRight)
- q->QDeclarative1Flickable::setContentX(pos);
- else
- q->QDeclarative1Flickable::setContentX(-pos-size());
- q->QDeclarative1Flickable::setContentY(0);
- }
- }
- int size() const {
- Q_Q(const QDeclarative1GridView);
- return flow == QDeclarative1GridView::LeftToRight ? q->height() : q->width();
- }
- qreal originPosition() const {
- qreal pos = 0;
- if (!visibleItems.isEmpty())
- pos = visibleItems.first()->rowPos() - visibleIndex / columns * rowSize();
- return pos;
- }
-
- qreal lastPosition() const {
- qreal pos = 0;
- if (model && model->count())
- pos = rowPosAt(model->count() - 1) + rowSize();
- return pos;
- }
-
- qreal startPosition() const {
- return isRightToLeftTopToBottom() ? -lastPosition()+1 : originPosition();
- }
-
- qreal endPosition() const {
- return isRightToLeftTopToBottom() ? -originPosition()+1 : lastPosition();
-
- }
-
- bool isValid() const {
- return model && model->count() && model->isValid();
- }
-
- int rowSize() const {
- return flow == QDeclarative1GridView::LeftToRight ? cellHeight : cellWidth;
- }
- int colSize() const {
- return flow == QDeclarative1GridView::LeftToRight ? cellWidth : cellHeight;
- }
-
- qreal colPosAt(int modelIndex) const {
- if (FxGridItem1 *item = visibleItem(modelIndex))
- return item->colPos();
- if (!visibleItems.isEmpty()) {
- if (modelIndex < visibleIndex) {
- int count = (visibleIndex - modelIndex) % columns;
- int col = visibleItems.first()->colPos() / colSize();
- col = (columns - count + col) % columns;
- return col * colSize();
- } else {
- int count = columns - 1 - (modelIndex - visibleItems.last()->index - 1) % columns;
- return visibleItems.last()->colPos() - count * colSize();
- }
- } else {
- return (modelIndex % columns) * colSize();
- }
- return 0;
- }
- qreal rowPosAt(int modelIndex) const {
- if (FxGridItem1 *item = visibleItem(modelIndex))
- return item->rowPos();
- if (!visibleItems.isEmpty()) {
- if (modelIndex < visibleIndex) {
- int firstCol = visibleItems.first()->colPos() / colSize();
- int col = visibleIndex - modelIndex + (columns - firstCol - 1);
- int rows = col / columns;
- return visibleItems.first()->rowPos() - rows * rowSize();
- } else {
- int count = modelIndex - visibleItems.last()->index;
- int col = visibleItems.last()->colPos() + count * colSize();
- int rows = col / (columns * colSize());
- return visibleItems.last()->rowPos() + rows * rowSize();
- }
- } else {
- qreal pos = (modelIndex / columns) * rowSize();
- if (header)
- pos += headerSize();
- return pos;
- }
- return 0;
- }
-
- FxGridItem1 *firstVisibleItem() const {
- const qreal pos = isRightToLeftTopToBottom() ? -position()-size() : position();
- for (int i = 0; i < visibleItems.count(); ++i) {
- FxGridItem1 *item = visibleItems.at(i);
- if (item->index != -1 && item->endRowPos() > pos)
- return item;
- }
- return visibleItems.count() ? visibleItems.first() : 0;
- }
-
- int lastVisibleIndex() const {
- for (int i = 0; i < visibleItems.count(); ++i) {
- FxGridItem1 *item = visibleItems.at(i);
- if (item->index != -1)
- return item->index;
- }
- return -1;
- }
-
- // Map a model index to visibleItems list index.
- // These may differ if removed items are still present in the visible list,
- // e.g. doing a removal animation
- int mapFromModel(int modelIndex) const {
- if (modelIndex < visibleIndex || modelIndex >= visibleIndex + visibleItems.count())
- return -1;
- for (int i = 0; i < visibleItems.count(); ++i) {
- FxGridItem1 *listItem = visibleItems.at(i);
- if (listItem->index == modelIndex)
- return i + visibleIndex;
- if (listItem->index > modelIndex)
- return -1;
- }
- return -1; // Not in visibleList
- }
-
- qreal snapPosAt(qreal pos) const {
- Q_Q(const QDeclarative1GridView);
- qreal snapPos = 0;
- if (!visibleItems.isEmpty()) {
- qreal highlightStart = isRightToLeftTopToBottom() && highlightRangeStartValid ? size()-highlightRangeEnd : highlightRangeStart;
- pos += highlightStart;
- pos += rowSize()/2;
- snapPos = visibleItems.first()->rowPos() - visibleIndex / columns * rowSize();
- snapPos = pos - fmodf(pos - snapPos, qreal(rowSize()));
- snapPos -= highlightStart;
- qreal maxExtent;
- qreal minExtent;
- if (isRightToLeftTopToBottom()) {
- maxExtent = q->minXExtent();
- minExtent = q->maxXExtent();
- } else {
- maxExtent = flow == QDeclarative1GridView::LeftToRight ? -q->maxYExtent() : -q->maxXExtent();
- minExtent = flow == QDeclarative1GridView::LeftToRight ? -q->minYExtent() : -q->minXExtent();
- }
- if (snapPos > maxExtent)
- snapPos = maxExtent;
- if (snapPos < minExtent)
- snapPos = minExtent;
- }
- return snapPos;
- }
-
- FxGridItem1 *snapItemAt(qreal pos) {
- for (int i = 0; i < visibleItems.count(); ++i) {
- FxGridItem1 *item = visibleItems[i];
- if (item->index == -1)
- continue;
- qreal itemTop = item->rowPos();
- if (itemTop+rowSize()/2 >= pos && itemTop - rowSize()/2 <= pos)
- return item;
- }
- return 0;
- }
-
- int snapIndex() {
- int index = currentIndex;
- for (int i = 0; i < visibleItems.count(); ++i) {
- FxGridItem1 *item = visibleItems[i];
- if (item->index == -1)
- continue;
- qreal itemTop = item->rowPos();
- if (itemTop >= highlight->rowPos()-rowSize()/2 && itemTop < highlight->rowPos()+rowSize()/2) {
- index = item->index;
- if (item->colPos() >= highlight->colPos()-colSize()/2 && item->colPos() < highlight->colPos()+colSize()/2)
- return item->index;
- }
- }
- return index;
- }
-
- qreal headerSize() const {
- if (!header)
- return 0.0;
-
- return flow == QDeclarative1GridView::LeftToRight
- ? header->item->height()
- : header->item->width();
- }
-
-
- virtual void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) {
- Q_Q(const QDeclarative1GridView);
- QDeclarative1FlickablePrivate::itemGeometryChanged(item, newGeometry, oldGeometry);
- if (item == q) {
- if (newGeometry.height() != oldGeometry.height()
- || newGeometry.width() != oldGeometry.width()) {
- if (q->isComponentComplete()) {
- updateGrid();
- scheduleLayout();
- }
- }
- } else if ((header && header->item == item) || (footer && footer->item == item)) {
- if (header)
- updateHeader();
- if (footer)
- updateFooter();
- }
- }
-
- void positionViewAtIndex(int index, int mode);
- virtual void fixup(AxisData &data, qreal minExtent, qreal maxExtent);
- virtual void flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
- QDeclarative1TimeLineCallback::Callback fixupCallback, qreal velocity);
-
- // for debugging only
- void checkVisible() const {
- int skip = 0;
- for (int i = 0; i < visibleItems.count(); ++i) {
- FxGridItem1 *listItem = visibleItems.at(i);
- if (listItem->index == -1) {
- ++skip;
- } else if (listItem->index != visibleIndex + i - skip) {
- for (int j = 0; j < visibleItems.count(); j++)
- qDebug() << " index" << j << "item index" << visibleItems.at(j)->index;
- qFatal("index %d %d %d", visibleIndex, i, listItem->index);
- }
- }
- }
-
- QDeclarativeGuard<QDeclarative1VisualModel> model;
- QVariant modelVariant;
- QList<FxGridItem1*> visibleItems;
- QHash<QDeclarativeItem*,int> unrequestedItems;
- FxGridItem1 *currentItem;
- Qt::LayoutDirection layoutDirection;
- QDeclarative1GridView::Flow flow;
- int visibleIndex;
- int currentIndex;
- int cellWidth;
- int cellHeight;
- int columns;
- int requestedIndex;
- int itemCount;
- qreal highlightRangeStart;
- qreal highlightRangeEnd;
- bool highlightRangeStartValid;
- bool highlightRangeEndValid;
- QDeclarative1GridView::HighlightRangeMode highlightRange;
- QDeclarativeComponent *highlightComponent;
- FxGridItem1 *highlight;
- FxGridItem1 *trackedItem;
- enum MovementReason { Other, SetIndex, Mouse };
- MovementReason moveReason;
- int buffer;
- QSmoothedAnimation_1 *highlightXAnimator;
- QSmoothedAnimation_1 *highlightYAnimator;
- int highlightMoveDuration;
- QDeclarativeComponent *footerComponent;
- FxGridItem1 *footer;
- QDeclarativeComponent *headerComponent;
- FxGridItem1 *header;
- enum BufferMode { NoBuffer = 0x00, BufferBefore = 0x01, BufferAfter = 0x02 };
- int bufferMode;
- QDeclarative1GridView::SnapMode snapMode;
-
- bool ownModel : 1;
- bool wrap : 1;
- bool autoHighlight : 1;
- bool fixCurrentVisibility : 1;
- bool lazyRelease : 1;
- bool layoutScheduled : 1;
- bool deferredRelease : 1;
- bool haveHighlightRange : 1;
- bool currentIndexCleared : 1;
-};
-
-void QDeclarative1GridViewPrivate::init()
-{
- Q_Q(QDeclarative1GridView);
- QObject::connect(q, SIGNAL(movementEnded()), q, SLOT(animStopped()));
- q->setFlag(QGraphicsItem::ItemIsFocusScope);
- q->setFlickableDirection(QDeclarative1Flickable::VerticalFlick);
- addItemChangeListener(this, Geometry);
-}
-
-void QDeclarative1GridViewPrivate::clear()
-{
- for (int i = 0; i < visibleItems.count(); ++i)
- releaseItem(visibleItems.at(i));
- visibleItems.clear();
- visibleIndex = 0;
- releaseItem(currentItem);
- currentItem = 0;
- createHighlight();
- trackedItem = 0;
- itemCount = 0;
-}
-
-FxGridItem1 *QDeclarative1GridViewPrivate::createItem(int modelIndex)
-{
- Q_Q(QDeclarative1GridView);
- // create object
- requestedIndex = modelIndex;
- FxGridItem1 *listItem = 0;
- if (QDeclarativeItem *item = model->item(modelIndex, false)) {
- listItem = new FxGridItem1(item, q);
- listItem->index = modelIndex;
- if (model->completePending()) {
- // complete
- listItem->item->setZValue(1);
- listItem->item->setParentItem(q->contentItem());
- model->completeItem();
- } else {
- listItem->item->setParentItem(q->contentItem());
- }
- unrequestedItems.remove(listItem->item);
- }
- requestedIndex = -1;
- return listItem;
-}
-
-
-void QDeclarative1GridViewPrivate::releaseItem(FxGridItem1 *item)
-{
- Q_Q(QDeclarative1GridView);
- if (!item || !model)
- return;
- if (trackedItem == item) {
- QObject::disconnect(trackedItem->item, SIGNAL(yChanged()), q, SLOT(trackedPositionChanged()));
- QObject::disconnect(trackedItem->item, SIGNAL(xChanged()), q, SLOT(trackedPositionChanged()));
- trackedItem = 0;
- }
- if (model->release(item->item) == 0) {
- // item was not destroyed, and we no longer reference it.
- unrequestedItems.insert(item->item, model->indexOf(item->item, q));
- }
- delete item;
-}
-
-void QDeclarative1GridViewPrivate::refill(qreal from, qreal to, bool doBuffer)
-{
- Q_Q(QDeclarative1GridView);
- if (!isValid() || !q->isComponentComplete())
- return;
- itemCount = model->count();
- qreal bufferFrom = from - buffer;
- qreal bufferTo = to + buffer;
- qreal fillFrom = from;
- qreal fillTo = to;
- if (doBuffer && (bufferMode & BufferAfter))
- fillTo = bufferTo;
- if (doBuffer && (bufferMode & BufferBefore))
- fillFrom = bufferFrom;
-
- bool changed = false;
-
- int colPos = colPosAt(visibleIndex);
- int rowPos = rowPosAt(visibleIndex);
- int modelIndex = visibleIndex;
- if (visibleItems.count()) {
- rowPos = visibleItems.last()->rowPos();
- colPos = visibleItems.last()->colPos() + colSize();
- if (colPos > colSize() * (columns-1)) {
- colPos = 0;
- rowPos += rowSize();
- }
- int i = visibleItems.count() - 1;
- while (i > 0 && visibleItems.at(i)->index == -1)
- --i;
- modelIndex = visibleItems.at(i)->index + 1;
- }
-
- if (visibleItems.count() && (fillFrom > rowPos + rowSize()*2
- || fillTo < rowPosAt(visibleIndex) - rowSize())) {
- // We've jumped more than a page. Estimate which items are now
- // visible and fill from there.
- int count = (fillFrom - (rowPos + rowSize())) / (rowSize()) * columns;
- for (int i = 0; i < visibleItems.count(); ++i)
- releaseItem(visibleItems.at(i));
- visibleItems.clear();
- modelIndex += count;
- if (modelIndex >= model->count())
- modelIndex = model->count() - 1;
- else if (modelIndex < 0)
- modelIndex = 0;
- modelIndex = modelIndex / columns * columns;
- visibleIndex = modelIndex;
- colPos = colPosAt(visibleIndex);
- rowPos = rowPosAt(visibleIndex);
- }
-
- int colNum = colPos / colSize();
-
- FxGridItem1 *item = 0;
-
- // Item creation and release is staggered in order to avoid
- // creating/releasing multiple items in one frame
- // while flicking (as much as possible).
- while (modelIndex < model->count() && rowPos <= fillTo + rowSize()*(columns - colNum)/(columns+1)) {
-// qDebug() << "refill: append item" << modelIndex;
- if (!(item = createItem(modelIndex)))
- break;
- item->setPosition(colPos, rowPos);
- visibleItems.append(item);
- colPos += colSize();
- colNum++;
- if (colPos > colSize() * (columns-1)) {
- colPos = 0;
- colNum = 0;
- rowPos += rowSize();
- }
- ++modelIndex;
- changed = true;
- if (doBuffer) // never buffer more than one item per frame
- break;
- }
-
- if (visibleItems.count()) {
- rowPos = visibleItems.first()->rowPos();
- colPos = visibleItems.first()->colPos() - colSize();
- if (colPos < 0) {
- colPos = colSize() * (columns - 1);
- rowPos -= rowSize();
- }
- }
- colNum = colPos / colSize();
- while (visibleIndex > 0 && rowPos + rowSize() - 1 >= fillFrom - rowSize()*(colNum+1)/(columns+1)){
-// qDebug() << "refill: prepend item" << visibleIndex-1 << "top pos" << rowPos << colPos;
- if (!(item = createItem(visibleIndex-1)))
- break;
- --visibleIndex;
- item->setPosition(colPos, rowPos);
- visibleItems.prepend(item);
- colPos -= colSize();
- colNum--;
- if (colPos < 0) {
- colPos = colSize() * (columns - 1);
- colNum = columns-1;
- rowPos -= rowSize();
- }
- changed = true;
- if (doBuffer) // never buffer more than one item per frame
- break;
- }
-
- if (!lazyRelease || !changed || deferredRelease) { // avoid destroying items in the same frame that we create
- while (visibleItems.count() > 1
- && (item = visibleItems.first())
- && item->rowPos()+rowSize()-1 < bufferFrom - rowSize()*(item->colPos()/colSize()+1)/(columns+1)) {
- if (item->attached->delayRemove())
- break;
-// qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endRowPos();
- if (item->index != -1)
- visibleIndex++;
- visibleItems.removeFirst();
- releaseItem(item);
- changed = true;
- }
- while (visibleItems.count() > 1
- && (item = visibleItems.last())
- && item->rowPos() > bufferTo + rowSize()*(columns - item->colPos()/colSize())/(columns+1)) {
- if (item->attached->delayRemove())
- break;
-// qDebug() << "refill: remove last" << visibleIndex+visibleItems.count()-1;
- visibleItems.removeLast();
- releaseItem(item);
- changed = true;
- }
- deferredRelease = false;
- } else {
- deferredRelease = true;
- }
- if (changed) {
- if (header)
- updateHeader();
- if (footer)
- updateFooter();
- if (flow == QDeclarative1GridView::LeftToRight)
- q->setContentHeight(endPosition() - startPosition());
- else
- q->setContentWidth(endPosition() - startPosition());
- } else if (!doBuffer && buffer && bufferMode != NoBuffer) {
- refill(from, to, true);
- }
- lazyRelease = false;
-}
-
-void QDeclarative1GridViewPrivate::updateGrid()
-{
- Q_Q(QDeclarative1GridView);
-
- columns = (int)qMax((flow == QDeclarative1GridView::LeftToRight ? q->width() : q->height()) / colSize(), qreal(1.));
- if (isValid()) {
- if (flow == QDeclarative1GridView::LeftToRight)
- q->setContentHeight(endPosition() - startPosition());
- else
- q->setContentWidth(lastPosition() - originPosition());
- }
-}
-
-void QDeclarative1GridViewPrivate::scheduleLayout()
-{
- Q_Q(QDeclarative1GridView);
- if (!layoutScheduled) {
- layoutScheduled = true;
- QCoreApplication::postEvent(q, new QEvent(QEvent::User), Qt::HighEventPriority);
- }
-}
-
-void QDeclarative1GridViewPrivate::layout()
-{
- Q_Q(QDeclarative1GridView);
- layoutScheduled = false;
- if (!isValid() && !visibleItems.count()) {
- clear();
- return;
- }
- if (visibleItems.count()) {
- qreal rowPos = visibleItems.first()->rowPos();
- qreal colPos = visibleItems.first()->colPos();
- int col = visibleIndex % columns;
- if (colPos != col * colSize()) {
- colPos = col * colSize();
- visibleItems.first()->setPosition(colPos, rowPos);
- }
- for (int i = 1; i < visibleItems.count(); ++i) {
- FxGridItem1 *item = visibleItems.at(i);
- colPos += colSize();
- if (colPos > colSize() * (columns-1)) {
- colPos = 0;
- rowPos += rowSize();
- }
- item->setPosition(colPos, rowPos);
- }
- }
- if (header)
- updateHeader();
- if (footer)
- updateFooter();
- q->refill();
- updateHighlight();
- moveReason = Other;
- if (flow == QDeclarative1GridView::LeftToRight) {
- q->setContentHeight(endPosition() - startPosition());
- fixupY();
- } else {
- q->setContentWidth(endPosition() - startPosition());
- fixupX();
- }
- updateUnrequestedPositions();
-}
-
-void QDeclarative1GridViewPrivate::updateUnrequestedIndexes()
-{
- Q_Q(QDeclarative1GridView);
- QHash<QDeclarativeItem*,int>::iterator it;
- for (it = unrequestedItems.begin(); it != unrequestedItems.end(); ++it)
- *it = model->indexOf(it.key(), q);
-}
-
-void QDeclarative1GridViewPrivate::updateUnrequestedPositions()
-{
- QHash<QDeclarativeItem*,int>::const_iterator it;
- for (it = unrequestedItems.begin(); it != unrequestedItems.end(); ++it) {
- QDeclarativeItem *item = it.key();
- if (flow == QDeclarative1GridView::LeftToRight) {
- item->setPos(QPointF(colPosAt(*it), rowPosAt(*it)));
- } else {
- if (isRightToLeftTopToBottom())
- item->setPos(QPointF(-rowPosAt(*it)-item->width(), colPosAt(*it)));
- else
- item->setPos(QPointF(rowPosAt(*it), colPosAt(*it)));
- }
- }
-}
-
-void QDeclarative1GridViewPrivate::updateTrackedItem()
-{
- Q_Q(QDeclarative1GridView);
- FxGridItem1 *item = currentItem;
- if (highlight)
- item = highlight;
-
- if (trackedItem && item != trackedItem) {
- QObject::disconnect(trackedItem->item, SIGNAL(yChanged()), q, SLOT(trackedPositionChanged()));
- QObject::disconnect(trackedItem->item, SIGNAL(xChanged()), q, SLOT(trackedPositionChanged()));
- trackedItem = 0;
- }
-
- if (!trackedItem && item) {
- trackedItem = item;
- QObject::connect(trackedItem->item, SIGNAL(yChanged()), q, SLOT(trackedPositionChanged()));
- QObject::connect(trackedItem->item, SIGNAL(xChanged()), q, SLOT(trackedPositionChanged()));
- }
- if (trackedItem)
- q->trackedPositionChanged();
-}
-
-void QDeclarative1GridViewPrivate::createHighlight()
-{
- Q_Q(QDeclarative1GridView);
- bool changed = false;
- if (highlight) {
- if (trackedItem == highlight)
- trackedItem = 0;
- if (highlight->item->scene())
- highlight->item->scene()->removeItem(highlight->item);
- highlight->item->deleteLater();
- delete highlight;
- highlight = 0;
- delete highlightXAnimator;
- delete highlightYAnimator;
- highlightXAnimator = 0;
- highlightYAnimator = 0;
- changed = true;
- }
-
- if (currentItem) {
- QDeclarativeItem *item = 0;
- if (highlightComponent) {
- QDeclarativeContext *highlightContext = new QDeclarativeContext(qmlContext(q));
- QObject *nobj = highlightComponent->create(highlightContext);
- if (nobj) {
- QDeclarative_setParent_noEvent(highlightContext, nobj);
- item = qobject_cast<QDeclarativeItem *>(nobj);
- if (!item)
- delete nobj;
- } else {
- delete highlightContext;
- }
- } else {
- item = new QDeclarativeItem;
- QDeclarative_setParent_noEvent(item, q->contentItem());
- item->setParentItem(q->contentItem());
- }
- if (item) {
- QDeclarative_setParent_noEvent(item, q->contentItem());
- item->setParentItem(q->contentItem());
- highlight = new FxGridItem1(item, q);
- if (currentItem && autoHighlight)
- highlight->setPosition(currentItem->colPos(), currentItem->rowPos());
- highlightXAnimator = new QSmoothedAnimation_1(q);
- highlightXAnimator->target = QDeclarativeProperty(highlight->item, QLatin1String("x"));
- highlightXAnimator->userDuration = highlightMoveDuration;
- highlightYAnimator = new QSmoothedAnimation_1(q);
- highlightYAnimator->target = QDeclarativeProperty(highlight->item, QLatin1String("y"));
- highlightYAnimator->userDuration = highlightMoveDuration;
- if (autoHighlight) {
- highlightXAnimator->restart();
- highlightYAnimator->restart();
- }
- changed = true;
- }
- }
- if (changed)
- emit q->highlightItemChanged();
-}
-
-void QDeclarative1GridViewPrivate::updateHighlight()
-{
- if ((!currentItem && highlight) || (currentItem && !highlight))
- createHighlight();
- if (currentItem && autoHighlight && highlight && !hData.moving && !vData.moving) {
- // auto-update highlight
- highlightXAnimator->to = currentItem->item->x();
- highlightYAnimator->to = currentItem->item->y();
- highlight->item->setWidth(currentItem->item->width());
- highlight->item->setHeight(currentItem->item->height());
- highlightXAnimator->restart();
- highlightYAnimator->restart();
- }
- updateTrackedItem();
-}
-
-void QDeclarative1GridViewPrivate::updateCurrent(int modelIndex)
-{
- Q_Q(QDeclarative1GridView);
- if (!q->isComponentComplete() || !isValid() || modelIndex < 0 || modelIndex >= model->count()) {
- if (currentItem) {
- currentItem->attached->setIsCurrentItem(false);
- releaseItem(currentItem);
- currentItem = 0;
- currentIndex = modelIndex;
- emit q->currentIndexChanged();
- updateHighlight();
- } else if (currentIndex != modelIndex) {
- currentIndex = modelIndex;
- emit q->currentIndexChanged();
- }
- return;
- }
-
- if (currentItem && currentIndex == modelIndex) {
- updateHighlight();
- return;
- }
-
- FxGridItem1 *oldCurrentItem = currentItem;
- currentIndex = modelIndex;
- currentItem = createItem(modelIndex);
- fixCurrentVisibility = true;
- if (oldCurrentItem && (!currentItem || oldCurrentItem->item != currentItem->item))
- oldCurrentItem->attached->setIsCurrentItem(false);
- if (currentItem) {
- currentItem->setPosition(colPosAt(modelIndex), rowPosAt(modelIndex));
- currentItem->item->setFocus(true);
- currentItem->attached->setIsCurrentItem(true);
- }
- updateHighlight();
- emit q->currentIndexChanged();
- releaseItem(oldCurrentItem);
-}
-
-void QDeclarative1GridViewPrivate::updateFooter()
-{
- Q_Q(QDeclarative1GridView);
- if (!footer && footerComponent) {
- QDeclarativeItem *item = 0;
- QDeclarativeContext *context = new QDeclarativeContext(qmlContext(q));
- QObject *nobj = footerComponent->create(context);
- if (nobj) {
- QDeclarative_setParent_noEvent(context, nobj);
- item = qobject_cast<QDeclarativeItem *>(nobj);
- if (!item)
- delete nobj;
- } else {
- delete context;
- }
- if (item) {
- QDeclarative_setParent_noEvent(item, q->contentItem());
- item->setParentItem(q->contentItem());
- item->setZValue(1);
- QDeclarativeItemPrivate *itemPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(item));
- itemPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry);
- footer = new FxGridItem1(item, q);
- }
- }
- if (footer) {
- qreal colOffset = 0;
- qreal rowOffset;
- if (isRightToLeftTopToBottom()) {
- rowOffset = footer->item->width()-cellWidth;
- } else {
- rowOffset = 0;
- if (q->effectiveLayoutDirection() == Qt::RightToLeft)
- colOffset = footer->item->width()-cellWidth;
- }
- if (visibleItems.count()) {
- qreal endPos = lastPosition();
- if (lastVisibleIndex() == model->count()-1) {
- footer->setPosition(colOffset, endPos + rowOffset);
- } else {
- qreal visiblePos = isRightToLeftTopToBottom() ? -position() : position() + size();
- if (endPos <= visiblePos || footer->endRowPos() < endPos + rowOffset)
- footer->setPosition(colOffset, endPos + rowOffset);
- }
- } else {
- qreal endPos = 0;
- if (header) {
- endPos += flow == QDeclarative1GridView::LeftToRight ? header->item->height() : header->item->width();
- }
- footer->setPosition(colOffset, endPos);
- }
- }
-}
-
-void QDeclarative1GridViewPrivate::updateHeader()
-{
- Q_Q(QDeclarative1GridView);
- if (!header && headerComponent) {
- QDeclarativeItem *item = 0;
- QDeclarativeContext *context = new QDeclarativeContext(qmlContext(q));
- QObject *nobj = headerComponent->create(context);
- if (nobj) {
- QDeclarative_setParent_noEvent(context, nobj);
- item = qobject_cast<QDeclarativeItem *>(nobj);
- if (!item)
- delete nobj;
- } else {
- delete context;
- }
- if (item) {
- QDeclarative_setParent_noEvent(item, q->contentItem());
- item->setParentItem(q->contentItem());
- item->setZValue(1);
- QDeclarativeItemPrivate *itemPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(item));
- itemPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry);
- header = new FxGridItem1(item, q);
- }
- }
- if (header) {
- qreal colOffset = 0;
- qreal rowOffset;
- if (isRightToLeftTopToBottom()) {
- rowOffset = -cellWidth;
- } else {
- rowOffset = -headerSize();
- if (q->effectiveLayoutDirection() == Qt::RightToLeft)
- colOffset = header->item->width()-cellWidth;
- }
- if (visibleItems.count()) {
- qreal startPos = originPosition();
- if (visibleIndex == 0) {
- header->setPosition(colOffset, startPos + rowOffset);
- } else {
- qreal tempPos = isRightToLeftTopToBottom() ? -position()-size() : position();
- qreal headerPos = isRightToLeftTopToBottom() ? header->rowPos() + cellWidth - headerSize() : header->rowPos();
- if (tempPos <= startPos || headerPos > startPos + rowOffset)
- header->setPosition(colOffset, startPos + rowOffset);
- }
- } else {
- header->setPosition(colOffset, 0);
- }
- }
-}
-
-void QDeclarative1GridViewPrivate::fixupPosition()
-{
- moveReason = Other;
- if (flow == QDeclarative1GridView::LeftToRight)
- fixupY();
- else
- fixupX();
-}
-
-void QDeclarative1GridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent)
-{
- if ((flow == QDeclarative1GridView::TopToBottom && &data == &vData)
- || (flow == QDeclarative1GridView::LeftToRight && &data == &hData))
- return;
-
- fixupMode = moveReason == Mouse ? fixupMode : Immediate;
-
- qreal highlightStart;
- qreal highlightEnd;
- qreal viewPos;
- if (isRightToLeftTopToBottom()) {
- // Handle Right-To-Left exceptions
- viewPos = -position()-size();
- highlightStart = highlightRangeStartValid ? size()-highlightRangeEnd : highlightRangeStart;
- highlightEnd = highlightRangeEndValid ? size()-highlightRangeStart : highlightRangeEnd;
- } else {
- viewPos = position();
- highlightStart = highlightRangeStart;
- highlightEnd = highlightRangeEnd;
- }
-
- bool strictHighlightRange = haveHighlightRange && highlightRange == QDeclarative1GridView::StrictlyEnforceRange;
-
- if (snapMode != QDeclarative1GridView::NoSnap) {
- qreal tempPosition = isRightToLeftTopToBottom() ? -position()-size() : position();
- if (snapMode == QDeclarative1GridView::SnapOneRow && moveReason == Mouse) {
- // if we've been dragged < rowSize()/2 then bias towards the next row
- qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset);
- qreal bias = 0;
- if (data.velocity > 0 && dist > QML_FLICK_SNAPONETHRESHOLD && dist < rowSize()/2)
- bias = rowSize()/2;
- else if (data.velocity < 0 && dist < -QML_FLICK_SNAPONETHRESHOLD && dist > -rowSize()/2)
- bias = -rowSize()/2;
- if (isRightToLeftTopToBottom())
- bias = -bias;
- tempPosition -= bias;
- }
- FxGridItem1 *topItem = snapItemAt(tempPosition+highlightStart);
- if (!topItem && strictHighlightRange && currentItem) {
- // StrictlyEnforceRange always keeps an item in range
- updateHighlight();
- topItem = currentItem;
- }
- FxGridItem1 *bottomItem = snapItemAt(tempPosition+highlightEnd);
- if (!bottomItem && strictHighlightRange && currentItem) {
- // StrictlyEnforceRange always keeps an item in range
- updateHighlight();
- bottomItem = currentItem;
- }
- qreal pos;
- bool isInBounds = -position() > maxExtent && -position() <= minExtent;
- if (topItem && (isInBounds || strictHighlightRange)) {
- if (topItem->index == 0 && header && tempPosition+highlightStart < header->rowPos()+headerSize()/2 && !strictHighlightRange) {
- pos = isRightToLeftTopToBottom() ? - header->rowPos() + highlightStart - size() : header->rowPos() - highlightStart;
- } else {
- if (isRightToLeftTopToBottom())
- pos = qMax(qMin(-topItem->rowPos() + highlightStart - size(), -maxExtent), -minExtent);
- else
- pos = qMax(qMin(topItem->rowPos() - highlightStart, -maxExtent), -minExtent);
- }
- } else if (bottomItem && isInBounds) {
- if (isRightToLeftTopToBottom())
- pos = qMax(qMin(-bottomItem->rowPos() + highlightEnd - size(), -maxExtent), -minExtent);
- else
- pos = qMax(qMin(bottomItem->rowPos() - highlightEnd, -maxExtent), -minExtent);
- } else {
- QDeclarative1FlickablePrivate::fixup(data, minExtent, maxExtent);
- return;
- }
- qreal dist = qAbs(data.move + pos);
- if (dist > 0) {
- timeline.reset(data.move);
- if (fixupMode != Immediate) {
- timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
- data.fixingUp = true;
- } else {
- timeline.set(data.move, -pos);
- }
- vTime = timeline.time();
- }
- } else if (haveHighlightRange && highlightRange == QDeclarative1GridView::StrictlyEnforceRange) {
- if (currentItem) {
- updateHighlight();
- qreal pos = currentItem->rowPos();
- if (viewPos < pos + rowSize() - highlightEnd)
- viewPos = pos + rowSize() - highlightEnd;
- if (viewPos > pos - highlightStart)
- viewPos = pos - highlightStart;
- if (isRightToLeftTopToBottom())
- viewPos = -viewPos-size();
- timeline.reset(data.move);
- if (viewPos != position()) {
- if (fixupMode != Immediate) {
- timeline.move(data.move, -viewPos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
- data.fixingUp = true;
- } else {
- timeline.set(data.move, -viewPos);
- }
- }
- vTime = timeline.time();
- }
- } else {
- QDeclarative1FlickablePrivate::fixup(data, minExtent, maxExtent);
- }
- data.inOvershoot = false;
- fixupMode = Normal;
-}
-
-void QDeclarative1GridViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
- QDeclarative1TimeLineCallback::Callback fixupCallback, qreal velocity)
-{
- Q_Q(QDeclarative1GridView);
- data.fixingUp = false;
- moveReason = Mouse;
- if ((!haveHighlightRange || highlightRange != QDeclarative1GridView::StrictlyEnforceRange)
- && snapMode == QDeclarative1GridView::NoSnap) {
- QDeclarative1FlickablePrivate::flick(data, minExtent, maxExtent, vSize, fixupCallback, velocity);
- return;
- }
- qreal maxDistance = 0;
- qreal dataValue = isRightToLeftTopToBottom() ? -data.move.value()+size() : data.move.value();
- // -ve velocity means list is moving up/left
- if (velocity > 0) {
- if (data.move.value() < minExtent) {
- if (snapMode == QDeclarative1GridView::SnapOneRow) {
- // if we've been dragged < averageSize/2 then bias towards the next item
- qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset);
- qreal bias = dist < rowSize()/2 ? rowSize()/2 : 0;
- if (isRightToLeftTopToBottom())
- bias = -bias;
- data.flickTarget = -snapPosAt(-dataValue - bias);
- maxDistance = qAbs(data.flickTarget - data.move.value());
- velocity = maxVelocity;
- } else {
- maxDistance = qAbs(minExtent - data.move.value());
- }
- }
- if (snapMode == QDeclarative1GridView::NoSnap && highlightRange != QDeclarative1GridView::StrictlyEnforceRange)
- data.flickTarget = minExtent;
- } else {
- if (data.move.value() > maxExtent) {
- if (snapMode == QDeclarative1GridView::SnapOneRow) {
- // if we've been dragged < averageSize/2 then bias towards the next item
- qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset);
- qreal bias = -dist < rowSize()/2 ? rowSize()/2 : 0;
- if (isRightToLeftTopToBottom())
- bias = -bias;
- data.flickTarget = -snapPosAt(-dataValue + bias);
- maxDistance = qAbs(data.flickTarget - data.move.value());
- velocity = -maxVelocity;
- } else {
- maxDistance = qAbs(maxExtent - data.move.value());
- }
- }
- if (snapMode == QDeclarative1GridView::NoSnap && highlightRange != QDeclarative1GridView::StrictlyEnforceRange)
- data.flickTarget = maxExtent;
- }
-
- bool overShoot = boundsBehavior == QDeclarative1Flickable::DragAndOvershootBounds;
-
- if (maxDistance > 0 || overShoot) {
- // This mode requires the grid to stop exactly on a row boundary.
- qreal v = velocity;
- if (maxVelocity != -1 && maxVelocity < qAbs(v)) {
- if (v < 0)
- v = -maxVelocity;
- else
- v = maxVelocity;
- }
- qreal accel = deceleration;
- qreal v2 = v * v;
- qreal overshootDist = 0.0;
- if ((maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) || snapMode == QDeclarative1GridView::SnapOneRow) {
- // + rowSize()/4 to encourage moving at least one item in the flick direction
- qreal dist = v2 / (accel * 2.0) + rowSize()/4;
- dist = qMin(dist, maxDistance);
- if (v > 0)
- dist = -dist;
- if (snapMode != QDeclarative1GridView::SnapOneRow) {
- qreal distTemp = isRightToLeftTopToBottom() ? -dist : dist;
- data.flickTarget = -snapPosAt(-dataValue + distTemp);
- }
- data.flickTarget = isRightToLeftTopToBottom() ? -data.flickTarget+size() : data.flickTarget;
- if (overShoot) {
- if (data.flickTarget >= minExtent) {
- overshootDist = overShootDistance(vSize);
- data.flickTarget += overshootDist;
- } else if (data.flickTarget <= maxExtent) {
- overshootDist = overShootDistance(vSize);
- data.flickTarget -= overshootDist;
- }
- }
- qreal adjDist = -data.flickTarget + data.move.value();
- if (qAbs(adjDist) > qAbs(dist)) {
- // Prevent painfully slow flicking - adjust velocity to suit flickDeceleration
- qreal adjv2 = accel * 2.0f * qAbs(adjDist);
- if (adjv2 > v2) {
- v2 = adjv2;
- v = qSqrt(v2);
- if (dist > 0)
- v = -v;
- }
- }
- dist = adjDist;
- accel = v2 / (2.0f * qAbs(dist));
- } else {
- data.flickTarget = velocity > 0 ? minExtent : maxExtent;
- overshootDist = overShoot ? overShootDistance(vSize) : 0;
- }
- timeline.reset(data.move);
- timeline.accel(data.move, v, accel, maxDistance + overshootDist);
- timeline.callback(QDeclarative1TimeLineCallback(&data.move, fixupCallback, this));
- if (!hData.flicking && q->xflick()) {
- hData.flicking = true;
- emit q->flickingChanged();
- emit q->flickingHorizontallyChanged();
- emit q->flickStarted();
- }
- if (!vData.flicking && q->yflick()) {
- vData.flicking = true;
- emit q->flickingChanged();
- emit q->flickingVerticallyChanged();
- emit q->flickStarted();
- }
- } else {
- timeline.reset(data.move);
- fixup(data, minExtent, maxExtent);
- }
-}
-
-
-//----------------------------------------------------------------------------
-
-/*!
- \qmlclass GridView QDeclarative1GridView
- \inqmlmodule QtQuick 1
- \since QtQuick 1.0
- \ingroup qml-view-elements
-
- \inherits Flickable
- \brief The GridView item provides a grid view of items provided by a model.
-
- A GridView displays data from models created from built-in QML elements like ListModel
- and XmlListModel, or custom model classes defined in C++ that inherit from
- QAbstractListModel.
-
- A GridView has a \l model, which defines the data to be displayed, and
- a \l delegate, which defines how the data should be displayed. Items in a
- GridView are laid out horizontally or vertically. Grid views are inherently flickable
- as GridView inherits from \l Flickable.
-
- \section1 Example Usage
-
- The following example shows the definition of a simple list model defined
- in a file called \c ContactModel.qml:
-
- \snippet doc/src/snippets/qtquick1/gridview/ContactModel.qml 0
-
- \div {class="float-right"}
- \inlineimage gridview-simple.png
- \enddiv
-
- This model can be referenced as \c ContactModel in other QML files. See \l{QML Modules}
- for more information about creating reusable components like this.
-
- Another component can display this model data in a GridView, as in the following
- example, which creates a \c ContactModel component for its model, and a \l Column element
- (containing \l Image and \l Text elements) for its delegate.
-
- \clearfloat
- \snippet doc/src/snippets/qtquick1/gridview/gridview.qml import
- \codeline
- \snippet doc/src/snippets/qtquick1/gridview/gridview.qml classdocs simple
-
- \div {class="float-right"}
- \inlineimage gridview-highlight.png
- \enddiv
-
- The view will create a new delegate for each item in the model. Note that the delegate
- is able to access the model's \c name and \c portrait data directly.
-
- An improved grid view is shown below. The delegate is visually improved and is moved
- into a separate \c contactDelegate component.
-
- \clearfloat
- \snippet doc/src/snippets/qtquick1/gridview/gridview.qml classdocs advanced
-
- The currently selected item is highlighted with a blue \l Rectangle using the \l highlight property,
- and \c focus is set to \c true to enable keyboard navigation for the grid view.
- The grid view itself is a focus scope (see \l{qmlfocus#Acquiring Focus and Focus Scopes}{the focus documentation page} for more details).
-
- Delegates are instantiated as needed and may be destroyed at any time.
- State should \e never be stored in a delegate.
-
- GridView attaches a number of properties to the root item of the delegate, for example
- \c {GridView.isCurrentItem}. In the following example, the root delegate item can access
- this attached property directly as \c GridView.isCurrentItem, while the child
- \c contactInfo object must refer to this property as \c wrapper.GridView.isCurrentItem.
-
- \snippet doc/src/snippets/qtquick1/gridview/gridview.qml isCurrentItem
-
- \note Views do not set the \l{Item::}{clip} property automatically.
- If the view is not clipped by another item or the screen, it will be necessary
- to set this property to true in order to clip the items that are partially or
- fully outside the view.
-
- \sa {declarative/modelviews/gridview}{GridView example}
-*/
-QDeclarative1GridView::QDeclarative1GridView(QDeclarativeItem *parent)
- : QDeclarative1Flickable(*(new QDeclarative1GridViewPrivate), parent)
-{
- Q_D(QDeclarative1GridView);
- d->init();
-}
-
-QDeclarative1GridView::~QDeclarative1GridView()
-{
- Q_D(QDeclarative1GridView);
- d->clear();
- if (d->ownModel)
- delete d->model;
- delete d->header;
- delete d->footer;
-}
-
-/*!
- \qmlattachedproperty bool GridView::isCurrentItem
- This attached property is true if this delegate is the current item; otherwise false.
-
- It is attached to each instance of the delegate.
-*/
-
-/*!
- \qmlattachedproperty GridView GridView::view
- This attached property holds the view that manages this delegate instance.
-
- It is attached to each instance of the delegate.
-
- \snippet doc/src/snippets/qtquick1/gridview/gridview.qml isCurrentItem
-*/
-
-/*!
- \qmlattachedproperty bool GridView::delayRemove
- This attached property holds whether the delegate may be destroyed.
-
- It is attached to each instance of the delegate.
-
- It is sometimes necessary to delay the destruction of an item
- until an animation completes.
-
- The example below ensures that the animation completes before
- the item is removed from the grid.
-
- \snippet doc/src/snippets/qtquick1/gridview/gridview.qml delayRemove
-*/
-
-/*!
- \qmlattachedsignal QtQuick1::GridView::onAdd()
- This attached handler is called immediately after an item is added to the view.
-*/
-
-/*!
- \qmlattachedsignal QtQuick1::GridView::onRemove()
- This attached handler is called immediately before an item is removed from the view.
-*/
-
-
-/*!
- \qmlproperty model QtQuick1::GridView::model
- This property holds the model providing data for the grid.
-
- The model provides the set of data that is used to create the items
- in the view. Models can be created directly in QML using \l ListModel, \l XmlListModel
- or \l VisualItemModel, or provided by C++ model classes. If a C++ model class is
- used, it must be a subclass of \l QAbstractItemModel or a simple list.
-
- \sa {qmlmodels}{Data Models}
-*/
-QVariant QDeclarative1GridView::model() const
-{
- Q_D(const QDeclarative1GridView);
- return d->modelVariant;
-}
-
-// For internal use
-int QDeclarative1GridView::modelCount() const
-{
- Q_D(const QDeclarative1GridView);
- return d->model->count();
-}
-
-void QDeclarative1GridView::setModel(const QVariant &model)
-{
- Q_D(QDeclarative1GridView);
- if (d->modelVariant == model)
- return;
- if (d->model) {
- disconnect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int)));
- disconnect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int)));
- disconnect(d->model, SIGNAL(itemsMoved(int,int,int)), this, SLOT(itemsMoved(int,int,int)));
- disconnect(d->model, SIGNAL(modelReset()), this, SLOT(modelReset()));
- disconnect(d->model, SIGNAL(createdItem(int,QDeclarativeItem*)), this, SLOT(createdItem(int,QDeclarativeItem*)));
- disconnect(d->model, SIGNAL(destroyingItem(QDeclarativeItem*)), this, SLOT(destroyingItem(QDeclarativeItem*)));
- }
- d->clear();
- d->modelVariant = model;
- QObject *object = qvariant_cast<QObject*>(model);
- QDeclarative1VisualModel *vim = 0;
- if (object && (vim = qobject_cast<QDeclarative1VisualModel *>(object))) {
- if (d->ownModel) {
- delete d->model;
- d->ownModel = false;
- }
- d->model = vim;
- } else {
- if (!d->ownModel) {
- d->model = new QDeclarative1VisualDataModel(qmlContext(this), this);
- d->ownModel = true;
- }
- if (QDeclarative1VisualDataModel *dataModel = qobject_cast<QDeclarative1VisualDataModel*>(d->model))
- dataModel->setModel(model);
- }
- if (d->model) {
- d->bufferMode = QDeclarative1GridViewPrivate::BufferBefore | QDeclarative1GridViewPrivate::BufferAfter;
- if (isComponentComplete()) {
- refill();
- if ((d->currentIndex >= d->model->count() || d->currentIndex < 0) && !d->currentIndexCleared) {
- setCurrentIndex(0);
- } else {
- d->moveReason = QDeclarative1GridViewPrivate::SetIndex;
- d->updateCurrent(d->currentIndex);
- if (d->highlight && d->currentItem) {
- if (d->autoHighlight)
- d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos());
- d->updateTrackedItem();
- }
- d->moveReason = QDeclarative1GridViewPrivate::Other;
- }
- }
- connect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int)));
- connect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int)));
- connect(d->model, SIGNAL(itemsMoved(int,int,int)), this, SLOT(itemsMoved(int,int,int)));
- connect(d->model, SIGNAL(modelReset()), this, SLOT(modelReset()));
- connect(d->model, SIGNAL(createdItem(int,QDeclarativeItem*)), this, SLOT(createdItem(int,QDeclarativeItem*)));
- connect(d->model, SIGNAL(destroyingItem(QDeclarativeItem*)), this, SLOT(destroyingItem(QDeclarativeItem*)));
- emit countChanged();
- }
- emit modelChanged();
-}
-
-/*!
- \qmlproperty Component QtQuick1::GridView::delegate
-
- The delegate provides a template defining each item instantiated by the view.
- The index is exposed as an accessible \c index property. Properties of the
- model are also available depending upon the type of \l {qmlmodels}{Data Model}.
-
- The number of elements in the delegate has a direct effect on the
- flicking performance of the view. If at all possible, place functionality
- that is not needed for the normal display of the delegate in a \l Loader which
- can load additional elements when needed.
-
- The GridView will layout the items based on the size of the root item
- in the delegate.
-
- \note Delegates are instantiated as needed and may be destroyed at any time.
- State should \e never be stored in a delegate.
-*/
-QDeclarativeComponent *QDeclarative1GridView::delegate() const
-{
- Q_D(const QDeclarative1GridView);
- if (d->model) {
- if (QDeclarative1VisualDataModel *dataModel = qobject_cast<QDeclarative1VisualDataModel*>(d->model))
- return dataModel->delegate();
- }
-
- return 0;
-}
-
-void QDeclarative1GridView::setDelegate(QDeclarativeComponent *delegate)
-{
- Q_D(QDeclarative1GridView);
- if (delegate == this->delegate())
- return;
-
- if (!d->ownModel) {
- d->model = new QDeclarative1VisualDataModel(qmlContext(this));
- d->ownModel = true;
- }
- if (QDeclarative1VisualDataModel *dataModel = qobject_cast<QDeclarative1VisualDataModel*>(d->model)) {
- int oldCount = dataModel->count();
- dataModel->setDelegate(delegate);
- if (isComponentComplete()) {
- for (int i = 0; i < d->visibleItems.count(); ++i)
- d->releaseItem(d->visibleItems.at(i));
- d->visibleItems.clear();
- d->releaseItem(d->currentItem);
- d->currentItem = 0;
- refill();
- d->moveReason = QDeclarative1GridViewPrivate::SetIndex;
- d->updateCurrent(d->currentIndex);
- if (d->highlight && d->currentItem) {
- if (d->autoHighlight)
- d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos());
- d->updateTrackedItem();
- }
- d->moveReason = QDeclarative1GridViewPrivate::Other;
- }
- if (oldCount != dataModel->count())
- emit countChanged();
- emit delegateChanged();
- }
-}
-
-/*!
- \qmlproperty int QtQuick1::GridView::currentIndex
- \qmlproperty Item QtQuick1::GridView::currentItem
-
- The \c currentIndex property holds the index of the current item, and
- \c currentItem holds the current item. Setting the currentIndex to -1
- will clear the highlight and set currentItem to null.
-
- If highlightFollowsCurrentItem is \c true, setting either of these
- properties will smoothly scroll the GridView so that the current
- item becomes visible.
-
- Note that the position of the current item
- may only be approximate until it becomes visible in the view.
-*/
-int QDeclarative1GridView::currentIndex() const
-{
- Q_D(const QDeclarative1GridView);
- return d->currentIndex;
-}
-
-void QDeclarative1GridView::setCurrentIndex(int index)
-{
- Q_D(QDeclarative1GridView);
- if (d->requestedIndex >= 0) // currently creating item
- return;
- d->currentIndexCleared = (index == -1);
- if (index == d->currentIndex)
- return;
- if (isComponentComplete() && d->isValid()) {
- if (d->layoutScheduled)
- d->layout();
- d->moveReason = QDeclarative1GridViewPrivate::SetIndex;
- d->updateCurrent(index);
- } else {
- d->currentIndex = index;
- emit currentIndexChanged();
- }
-}
-
-QDeclarativeItem *QDeclarative1GridView::currentItem()
-{
- Q_D(QDeclarative1GridView);
- if (!d->currentItem)
- return 0;
- return d->currentItem->item;
-}
-
-/*!
- \qmlproperty Item QtQuick1::GridView::highlightItem
-
- This holds the highlight item created from the \l highlight component.
-
- The highlightItem is managed by the view unless
- \l highlightFollowsCurrentItem is set to false.
-
- \sa highlight, highlightFollowsCurrentItem
-*/
-QDeclarativeItem *QDeclarative1GridView::highlightItem()
-{
- Q_D(QDeclarative1GridView);
- if (!d->highlight)
- return 0;
- return d->highlight->item;
-}
-
-/*!
- \qmlproperty int QtQuick1::GridView::count
- This property holds the number of items in the view.
-*/
-int QDeclarative1GridView::count() const
-{
- Q_D(const QDeclarative1GridView);
- if (d->model)
- return d->model->count();
- return 0;
-}
-
-/*!
- \qmlproperty Component QtQuick1::GridView::highlight
- This property holds the component to use as the highlight.
-
- An instance of the highlight component is created for each view.
- The geometry of the resulting component instance will be managed by the view
- so as to stay with the current item, unless the highlightFollowsCurrentItem property is false.
-
- \sa highlightItem, highlightFollowsCurrentItem
-*/
-QDeclarativeComponent *QDeclarative1GridView::highlight() const
-{
- Q_D(const QDeclarative1GridView);
- return d->highlightComponent;
-}
-
-void QDeclarative1GridView::setHighlight(QDeclarativeComponent *highlight)
-{
- Q_D(QDeclarative1GridView);
- if (highlight != d->highlightComponent) {
- d->highlightComponent = highlight;
- d->updateCurrent(d->currentIndex);
- emit highlightChanged();
- }
-}
-
-/*!
- \qmlproperty bool QtQuick1::GridView::highlightFollowsCurrentItem
- This property sets whether the highlight is managed by the view.
-
- If this property is true (the default value), the highlight is moved smoothly
- to follow the current item. Otherwise, the
- highlight is not moved by the view, and any movement must be implemented
- by the highlight.
-
- Here is a highlight with its motion defined by a \l {SpringAnimation} item:
-
- \snippet doc/src/snippets/qtquick1/gridview/gridview.qml highlightFollowsCurrentItem
-*/
-bool QDeclarative1GridView::highlightFollowsCurrentItem() const
-{
- Q_D(const QDeclarative1GridView);
- return d->autoHighlight;
-}
-
-void QDeclarative1GridView::setHighlightFollowsCurrentItem(bool autoHighlight)
-{
- Q_D(QDeclarative1GridView);
- if (d->autoHighlight != autoHighlight) {
- d->autoHighlight = autoHighlight;
- if (autoHighlight) {
- d->updateHighlight();
- } else if (d->highlightXAnimator) {
- d->highlightXAnimator->stop();
- d->highlightYAnimator->stop();
- }
- }
-}
-
-/*!
- \qmlproperty int QtQuick1::GridView::highlightMoveDuration
- This property holds the move animation duration of the highlight delegate.
-
- highlightFollowsCurrentItem must be true for this property
- to have effect.
-
- The default value for the duration is 150ms.
-
- \sa highlightFollowsCurrentItem
-*/
-int QDeclarative1GridView::highlightMoveDuration() const
-{
- Q_D(const QDeclarative1GridView);
- return d->highlightMoveDuration;
-}
-
-void QDeclarative1GridView::setHighlightMoveDuration(int duration)
-{
- Q_D(QDeclarative1GridView);
- if (d->highlightMoveDuration != duration) {
- d->highlightMoveDuration = duration;
- if (d->highlightYAnimator) {
- d->highlightXAnimator->userDuration = d->highlightMoveDuration;
- d->highlightYAnimator->userDuration = d->highlightMoveDuration;
- }
- emit highlightMoveDurationChanged();
- }
-}
-
-
-/*!
- \qmlproperty real QtQuick1::GridView::preferredHighlightBegin
- \qmlproperty real QtQuick1::GridView::preferredHighlightEnd
- \qmlproperty enumeration QtQuick1::GridView::highlightRangeMode
-
- These properties define the preferred range of the highlight (for the current item)
- within the view. The \c preferredHighlightBegin value must be less than the
- \c preferredHighlightEnd value.
-
- These properties affect the position of the current item when the view is scrolled.
- For example, if the currently selected item should stay in the middle of the
- view when it is scrolled, set the \c preferredHighlightBegin and
- \c preferredHighlightEnd values to the top and bottom coordinates of where the middle
- item would be. If the \c currentItem is changed programmatically, the view will
- automatically scroll so that the current item is in the middle of the view.
- Furthermore, the behavior of the current item index will occur whether or not a
- highlight exists.
-
- Valid values for \c highlightRangeMode are:
-
- \list
- \o GridView.ApplyRange - the view attempts to maintain the highlight within the range.
- However, the highlight can move outside of the range at the ends of the view or due
- to mouse interaction.
- \o GridView.StrictlyEnforceRange - the highlight never moves outside of the range.
- The current item changes if a keyboard or mouse action would cause the highlight to move
- outside of the range.
- \o GridView.NoHighlightRange - this is the default value.
- \endlist
-*/
-qreal QDeclarative1GridView::preferredHighlightBegin() const
-{
- Q_D(const QDeclarative1GridView);
- return d->highlightRangeStart;
-}
-
-void QDeclarative1GridView::setPreferredHighlightBegin(qreal start)
-{
- Q_D(QDeclarative1GridView);
- d->highlightRangeStartValid = true;
- if (d->highlightRangeStart == start)
- return;
- d->highlightRangeStart = start;
- d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
- emit preferredHighlightBeginChanged();
-}
-
-void QDeclarative1GridView::resetPreferredHighlightBegin()
-{
- Q_D(QDeclarative1GridView);
- d->highlightRangeStartValid = false;
- if (d->highlightRangeStart == 0)
- return;
- d->highlightRangeStart = 0;
- emit preferredHighlightBeginChanged();
-}
-
-qreal QDeclarative1GridView::preferredHighlightEnd() const
-{
- Q_D(const QDeclarative1GridView);
- return d->highlightRangeEnd;
-}
-
-void QDeclarative1GridView::setPreferredHighlightEnd(qreal end)
-{
- Q_D(QDeclarative1GridView);
- d->highlightRangeEndValid = true;
- if (d->highlightRangeEnd == end)
- return;
- d->highlightRangeEnd = end;
- d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
- emit preferredHighlightEndChanged();
-}
-
-void QDeclarative1GridView::resetPreferredHighlightEnd()
-{
- Q_D(QDeclarative1GridView);
- d->highlightRangeEndValid = false;
- if (d->highlightRangeEnd == 0)
- return;
- d->highlightRangeEnd = 0;
- emit preferredHighlightEndChanged();
-}
-
-QDeclarative1GridView::HighlightRangeMode QDeclarative1GridView::highlightRangeMode() const
-{
- Q_D(const QDeclarative1GridView);
- return d->highlightRange;
-}
-
-void QDeclarative1GridView::setHighlightRangeMode(HighlightRangeMode mode)
-{
- Q_D(QDeclarative1GridView);
- if (d->highlightRange == mode)
- return;
- d->highlightRange = mode;
- d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
- emit highlightRangeModeChanged();
-}
-
-/*!
- \qmlproperty enumeration QtQuick1::GridView::layoutDirection
- This property holds the layout direction of the grid.
-
- Possible values:
-
- \list
- \o Qt.LeftToRight (default) - Items will be laid out starting in the top, left corner. The flow is
- dependent on the \l GridView::flow property.
- \o Qt.RightToLeft - Items will be laid out starting in the top, right corner. The flow is dependent
- on the \l GridView::flow property.
- \endlist
-
- \bold Note: If GridView::flow is set to GridView.LeftToRight, this is not to be confused if
- GridView::layoutDirection is set to Qt.RightToLeft. The GridView.LeftToRight flow value simply
- indicates that the flow is horizontal.
-*/
-
-Qt::LayoutDirection QDeclarative1GridView::layoutDirection() const
-{
- Q_D(const QDeclarative1GridView);
- return d->layoutDirection;
-}
-
-void QDeclarative1GridView::setLayoutDirection(Qt::LayoutDirection layoutDirection)
-{
- Q_D(QDeclarative1GridView);
- if (d->layoutDirection != layoutDirection) {
- d->layoutDirection = layoutDirection;
- d->regenerate();
- emit layoutDirectionChanged();
- emit effectiveLayoutDirectionChanged();
- }
-}
-
-/*!
- \qmlproperty enumeration QtQuick1::GridView::effectiveLayoutDirection
- This property holds the effective layout direction of the grid.
-
- When using the attached property \l {LayoutMirroring::enabled}{LayoutMirroring::enabled} for locale layouts,
- the visual layout direction of the grid will be mirrored. However, the
- property \l {GridView::layoutDirection}{layoutDirection} will remain unchanged.
-
- \sa GridView::layoutDirection, {LayoutMirroring}{LayoutMirroring}
-*/
-
-Qt::LayoutDirection QDeclarative1GridView::effectiveLayoutDirection() const
-{
- Q_D(const QDeclarative1GridView);
- if (d->effectiveLayoutMirror)
- return d->layoutDirection == Qt::RightToLeft ? Qt::LeftToRight : Qt::RightToLeft;
- else
- return d->layoutDirection;
-}
-
-/*!
- \qmlproperty enumeration QtQuick1::GridView::flow
- This property holds the flow of the grid.
-
- Possible values:
-
- \list
- \o GridView.LeftToRight (default) - Items are laid out from left to right, and the view scrolls vertically
- \o GridView.TopToBottom - Items are laid out from top to bottom, and the view scrolls horizontally
- \endlist
-*/
-QDeclarative1GridView::Flow QDeclarative1GridView::flow() const
-{
- Q_D(const QDeclarative1GridView);
- return d->flow;
-}
-
-void QDeclarative1GridView::setFlow(Flow flow)
-{
- Q_D(QDeclarative1GridView);
- if (d->flow != flow) {
- d->flow = flow;
- if (d->flow == LeftToRight) {
- setContentWidth(-1);
- setFlickableDirection(QDeclarative1Flickable::VerticalFlick);
- } else {
- setContentHeight(-1);
- setFlickableDirection(QDeclarative1Flickable::HorizontalFlick);
- }
- setContentX(0);
- setContentY(0);
- d->regenerate();
- emit flowChanged();
- }
-}
-
-/*!
- \qmlproperty bool QtQuick1::GridView::keyNavigationWraps
- This property holds whether the grid wraps key navigation
-
- If this is true, key navigation that would move the current item selection
- past one end of the view instead wraps around and moves the selection to
- the other end of the view.
-
- By default, key navigation is not wrapped.
-*/
-bool QDeclarative1GridView::isWrapEnabled() const
-{
- Q_D(const QDeclarative1GridView);
- return d->wrap;
-}
-
-void QDeclarative1GridView::setWrapEnabled(bool wrap)
-{
- Q_D(QDeclarative1GridView);
- if (d->wrap == wrap)
- return;
- d->wrap = wrap;
- emit keyNavigationWrapsChanged();
-}
-
-/*!
- \qmlproperty int QtQuick1::GridView::cacheBuffer
- This property determines whether delegates are retained outside the
- visible area of the view.
-
- If non-zero the view will keep as many delegates
- instantiated as will fit within the buffer specified. For example,
- if in a vertical view the delegate is 20 pixels high and \c cacheBuffer is
- set to 40, then up to 2 delegates above and 2 delegates below the visible
- area may be retained.
-
- Note that cacheBuffer is not a pixel buffer - it only maintains additional
- instantiated delegates.
-
- Setting this value can make scrolling the list smoother at the expense
- of additional memory usage. It is not a substitute for creating efficient
- delegates; the fewer elements in a delegate, the faster a view may be
- scrolled.
-*/
-int QDeclarative1GridView::cacheBuffer() const
-{
- Q_D(const QDeclarative1GridView);
- return d->buffer;
-}
-
-void QDeclarative1GridView::setCacheBuffer(int buffer)
-{
- Q_D(QDeclarative1GridView);
- if (d->buffer != buffer) {
- d->buffer = buffer;
- if (isComponentComplete())
- refill();
- emit cacheBufferChanged();
- }
-}
-
-/*!
- \qmlproperty int QtQuick1::GridView::cellWidth
- \qmlproperty int QtQuick1::GridView::cellHeight
-
- These properties holds the width and height of each cell in the grid.
-
- The default cell size is 100x100.
-*/
-int QDeclarative1GridView::cellWidth() const
-{
- Q_D(const QDeclarative1GridView);
- return d->cellWidth;
-}
-
-void QDeclarative1GridView::setCellWidth(int cellWidth)
-{
- Q_D(QDeclarative1GridView);
- if (cellWidth != d->cellWidth && cellWidth > 0) {
- d->cellWidth = qMax(1, cellWidth);
- d->updateGrid();
- emit cellWidthChanged();
- d->layout();
- }
-}
-
-int QDeclarative1GridView::cellHeight() const
-{
- Q_D(const QDeclarative1GridView);
- return d->cellHeight;
-}
-
-void QDeclarative1GridView::setCellHeight(int cellHeight)
-{
- Q_D(QDeclarative1GridView);
- if (cellHeight != d->cellHeight && cellHeight > 0) {
- d->cellHeight = qMax(1, cellHeight);
- d->updateGrid();
- emit cellHeightChanged();
- d->layout();
- }
-}
-/*!
- \qmlproperty enumeration QtQuick1::GridView::snapMode
-
- This property determines how the view scrolling will settle following a drag or flick.
- The possible values are:
-
- \list
- \o GridView.NoSnap (default) - the view stops anywhere within the visible area.
- \o GridView.SnapToRow - the view settles with a row (or column for \c GridView.TopToBottom flow)
- aligned with the start of the view.
- \o GridView.SnapOneRow - the view will settle no more than one row (or column for \c GridView.TopToBottom flow)
- away from the first visible row at the time the mouse button is released.
- This mode is particularly useful for moving one page at a time.
- \endlist
-
-*/
-QDeclarative1GridView::SnapMode QDeclarative1GridView::snapMode() const
-{
- Q_D(const QDeclarative1GridView);
- return d->snapMode;
-}
-
-void QDeclarative1GridView::setSnapMode(SnapMode mode)
-{
- Q_D(QDeclarative1GridView);
- if (d->snapMode != mode) {
- d->snapMode = mode;
- emit snapModeChanged();
- }
-}
-
-/*!
- \qmlproperty Component QtQuick1::GridView::footer
- This property holds the component to use as the footer.
-
- An instance of the footer component is created for each view. The
- footer is positioned at the end of the view, after any items.
-
- \sa header
-*/
-QDeclarativeComponent *QDeclarative1GridView::footer() const
-{
- Q_D(const QDeclarative1GridView);
- return d->footerComponent;
-}
-
-void QDeclarative1GridView::setFooter(QDeclarativeComponent *footer)
-{
- Q_D(QDeclarative1GridView);
- if (d->footerComponent != footer) {
- if (d->footer) {
- if (scene())
- scene()->removeItem(d->footer->item);
- d->footer->item->deleteLater();
- delete d->footer;
- d->footer = 0;
- }
- d->footerComponent = footer;
- if (isComponentComplete()) {
- d->updateFooter();
- d->updateGrid();
- d->fixupPosition();
- }
- emit footerChanged();
- }
-}
-
-/*!
- \qmlproperty Component QtQuick1::GridView::header
- This property holds the component to use as the header.
-
- An instance of the header component is created for each view. The
- header is positioned at the beginning of the view, before any items.
-
- \sa footer
-*/
-QDeclarativeComponent *QDeclarative1GridView::header() const
-{
- Q_D(const QDeclarative1GridView);
- return d->headerComponent;
-}
-
-void QDeclarative1GridView::setHeader(QDeclarativeComponent *header)
-{
- Q_D(QDeclarative1GridView);
- if (d->headerComponent != header) {
- if (d->header) {
- if (scene())
- scene()->removeItem(d->header->item);
- d->header->item->deleteLater();
- delete d->header;
- d->header = 0;
- }
- d->headerComponent = header;
- if (isComponentComplete()) {
- d->updateHeader();
- d->updateFooter();
- d->updateGrid();
- d->fixupPosition();
- }
- emit headerChanged();
- }
-}
-
-void QDeclarative1GridView::setContentX(qreal pos)
-{
- Q_D(QDeclarative1GridView);
- // Positioning the view manually should override any current movement state
- d->moveReason = QDeclarative1GridViewPrivate::Other;
- QDeclarative1Flickable::setContentX(pos);
-}
-
-void QDeclarative1GridView::setContentY(qreal pos)
-{
- Q_D(QDeclarative1GridView);
- // Positioning the view manually should override any current movement state
- d->moveReason = QDeclarative1GridViewPrivate::Other;
- QDeclarative1Flickable::setContentY(pos);
-}
-
-bool QDeclarative1GridView::event(QEvent *event)
-{
- Q_D(QDeclarative1GridView);
- if (event->type() == QEvent::User) {
- if (d->layoutScheduled)
- d->layout();
- return true;
- }
-
- return QDeclarative1Flickable::event(event);
-}
-
-void QDeclarative1GridView::viewportMoved()
-{
- Q_D(QDeclarative1GridView);
- QDeclarative1Flickable::viewportMoved();
- if (!d->itemCount)
- return;
- d->lazyRelease = true;
- if (d->hData.flicking || d->vData.flicking) {
- if (yflick()) {
- if (d->vData.velocity > 0)
- d->bufferMode = QDeclarative1GridViewPrivate::BufferBefore;
- else if (d->vData.velocity < 0)
- d->bufferMode = QDeclarative1GridViewPrivate::BufferAfter;
- }
-
- if (xflick()) {
- if (d->hData.velocity > 0)
- d->bufferMode = QDeclarative1GridViewPrivate::BufferBefore;
- else if (d->hData.velocity < 0)
- d->bufferMode = QDeclarative1GridViewPrivate::BufferAfter;
- }
- }
- refill();
- if (d->hData.flicking || d->vData.flicking || d->hData.moving || d->vData.moving)
- d->moveReason = QDeclarative1GridViewPrivate::Mouse;
- if (d->moveReason != QDeclarative1GridViewPrivate::SetIndex) {
- if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) {
- // reposition highlight
- qreal pos = d->highlight->rowPos();
- qreal viewPos;
- qreal highlightStart;
- qreal highlightEnd;
- if (d->isRightToLeftTopToBottom()) {
- highlightStart = d->highlightRangeStartValid ? d->size()-d->highlightRangeEnd : d->highlightRangeStart;
- highlightEnd = d->highlightRangeEndValid ? d->size()-d->highlightRangeStart : d->highlightRangeEnd;
- viewPos = -d->position()-d->size();
- } else {
- highlightStart = d->highlightRangeStart;
- highlightEnd = d->highlightRangeEnd;
- viewPos = d->position();
- }
- if (pos > viewPos + highlightEnd - d->rowSize())
- pos = viewPos + highlightEnd - d->rowSize();
- if (pos < viewPos + highlightStart)
- pos = viewPos + highlightStart;
-
- d->highlight->setPosition(d->highlight->colPos(), qRound(pos));
-
- // update current index
- int idx = d->snapIndex();
- if (idx >= 0 && idx != d->currentIndex) {
- d->updateCurrent(idx);
- if (d->currentItem && d->currentItem->colPos() != d->highlight->colPos() && d->autoHighlight) {
- if (d->flow == LeftToRight)
- d->highlightXAnimator->to = d->currentItem->item->x();
- else
- d->highlightYAnimator->to = d->currentItem->item->y();
- }
- }
- }
- }
-}
-
-qreal QDeclarative1GridView::minYExtent() const
-{
- Q_D(const QDeclarative1GridView);
- if (d->flow == QDeclarative1GridView::TopToBottom)
- return QDeclarative1Flickable::minYExtent();
- qreal extent = -d->startPosition();
- if (d->header && d->visibleItems.count())
- extent += d->header->item->height();
- if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
- extent += d->highlightRangeStart;
- extent = qMax(extent, -(d->rowPosAt(0) + d->rowSize() - d->highlightRangeEnd));
- }
- return extent;
-}
-
-qreal QDeclarative1GridView::maxYExtent() const
-{
- Q_D(const QDeclarative1GridView);
- if (d->flow == QDeclarative1GridView::TopToBottom)
- return QDeclarative1Flickable::maxYExtent();
- qreal extent;
- if (!d->model || !d->model->count()) {
- extent = 0;
- } else if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
- extent = -(d->rowPosAt(d->model->count()-1) - d->highlightRangeStart);
- if (d->highlightRangeEnd != d->highlightRangeStart)
- extent = qMin(extent, -(d->endPosition() - d->highlightRangeEnd + 1));
- } else {
- extent = -(d->endPosition() - height());
- }
- if (d->footer)
- extent -= d->footer->item->height();
- const qreal minY = minYExtent();
- if (extent > minY)
- extent = minY;
- return extent;
-}
-
-qreal QDeclarative1GridView::minXExtent() const
-{
- Q_D(const QDeclarative1GridView);
- if (d->flow == QDeclarative1GridView::LeftToRight)
- return QDeclarative1Flickable::minXExtent();
- qreal extent = -d->startPosition();
- qreal highlightStart;
- qreal highlightEnd;
- qreal endPositionFirstItem = 0;
- if (d->isRightToLeftTopToBottom()) {
- if (d->model && d->model->count())
- endPositionFirstItem = d->rowPosAt(d->model->count()-1);
- highlightStart = d->highlightRangeStartValid
- ? d->highlightRangeStart - (d->lastPosition()-endPositionFirstItem)
- : d->size() - (d->lastPosition()-endPositionFirstItem);
- highlightEnd = d->highlightRangeEndValid ? d->highlightRangeEnd : d->size();
- if (d->footer && d->visibleItems.count())
- extent += d->footer->item->width();
- } else {
- endPositionFirstItem = d->rowPosAt(0)+d->rowSize();
- highlightStart = d->highlightRangeStart;
- highlightEnd = d->highlightRangeEnd;
- if (d->header && d->visibleItems.count())
- extent += d->header->item->width();
- }
- if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
- extent += d->isRightToLeftTopToBottom() ? -highlightStart : highlightStart;
- extent = qMax(extent, -(endPositionFirstItem - highlightEnd));
- }
- return extent;
-}
-
-qreal QDeclarative1GridView::maxXExtent() const
-{
- Q_D(const QDeclarative1GridView);
- if (d->flow == QDeclarative1GridView::LeftToRight)
- return QDeclarative1Flickable::maxXExtent();
- qreal extent;
- qreal highlightStart;
- qreal highlightEnd;
- qreal lastItemPosition = 0;
- if (d->isRightToLeftTopToBottom()){
- highlightStart = d->highlightRangeStartValid ? d->highlightRangeEnd : d->size();
- highlightEnd = d->highlightRangeEndValid ? d->highlightRangeStart : d->size();
- lastItemPosition = d->endPosition();
- } else {
- highlightStart = d->highlightRangeStart;
- highlightEnd = d->highlightRangeEnd;
- lastItemPosition = 0;
- if (d->model && d->model->count())
- lastItemPosition = d->rowPosAt(d->model->count()-1);
- }
- if (!d->model || !d->model->count()) {
- extent = 0;
- } else if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
- extent = -(lastItemPosition - highlightStart);
- if (highlightEnd != highlightStart)
- extent = d->isRightToLeftTopToBottom()
- ? qMax(extent, -(d->endPosition() - highlightEnd + 1))
- : qMin(extent, -(d->endPosition() - highlightEnd + 1));
- } else {
- extent = -(d->endPosition() - width());
- }
- if (d->isRightToLeftTopToBottom()) {
- if (d->header)
- extent -= d->header->item->width();
- } else {
- if (d->footer)
- extent -= d->footer->item->width();
- }
-
- const qreal minX = minXExtent();
- if (extent > minX)
- extent = minX;
- return extent;
-}
-
-void QDeclarative1GridView::keyPressEvent(QKeyEvent *event)
-{
- Q_D(QDeclarative1GridView);
- keyPressPreHandler(event);
- if (event->isAccepted())
- return;
- if (d->model && d->model->count() && d->interactive) {
- d->moveReason = QDeclarative1GridViewPrivate::SetIndex;
- int oldCurrent = currentIndex();
- switch (event->key()) {
- case Qt::Key_Up:
- moveCurrentIndexUp();
- break;
- case Qt::Key_Down:
- moveCurrentIndexDown();
- break;
- case Qt::Key_Left:
- moveCurrentIndexLeft();
- break;
- case Qt::Key_Right:
- moveCurrentIndexRight();
- break;
- default:
- break;
- }
- if (oldCurrent != currentIndex()) {
- event->accept();
- return;
- }
- }
- d->moveReason = QDeclarative1GridViewPrivate::Other;
- event->ignore();
- QDeclarative1Flickable::keyPressEvent(event);
-}
-
-/*!
- \qmlmethod QtQuick1::GridView::moveCurrentIndexUp()
-
- Move the currentIndex up one item in the view.
- The current index will wrap if keyNavigationWraps is true and it
- is currently at the end. This method has no effect if the \l count is zero.
-
- \bold Note: methods should only be called after the Component has completed.
-*/
-void QDeclarative1GridView::moveCurrentIndexUp()
-{
- Q_D(QDeclarative1GridView);
- const int count = d->model ? d->model->count() : 0;
- if (!count)
- return;
- if (d->flow == QDeclarative1GridView::LeftToRight) {
- if (currentIndex() >= d->columns || d->wrap) {
- int index = currentIndex() - d->columns;
- setCurrentIndex((index >= 0 && index < count) ? index : count-1);
- }
- } else {
- if (currentIndex() > 0 || d->wrap) {
- int index = currentIndex() - 1;
- setCurrentIndex((index >= 0 && index < count) ? index : count-1);
- }
- }
-}
-
-/*!
- \qmlmethod QtQuick1::GridView::moveCurrentIndexDown()
-
- Move the currentIndex down one item in the view.
- The current index will wrap if keyNavigationWraps is true and it
- is currently at the end. This method has no effect if the \l count is zero.
-
- \bold Note: methods should only be called after the Component has completed.
-*/
-void QDeclarative1GridView::moveCurrentIndexDown()
-{
- Q_D(QDeclarative1GridView);
- const int count = d->model ? d->model->count() : 0;
- if (!count)
- return;
- if (d->flow == QDeclarative1GridView::LeftToRight) {
- if (currentIndex() < count - d->columns || d->wrap) {
- int index = currentIndex()+d->columns;
- setCurrentIndex((index >= 0 && index < count) ? index : 0);
- }
- } else {
- if (currentIndex() < count - 1 || d->wrap) {
- int index = currentIndex() + 1;
- setCurrentIndex((index >= 0 && index < count) ? index : 0);
- }
- }
-}
-
-/*!
- \qmlmethod QtQuick1::GridView::moveCurrentIndexLeft()
-
- Move the currentIndex left one item in the view.
- The current index will wrap if keyNavigationWraps is true and it
- is currently at the end. This method has no effect if the \l count is zero.
-
- \bold Note: methods should only be called after the Component has completed.
-*/
-void QDeclarative1GridView::moveCurrentIndexLeft()
-{
- Q_D(QDeclarative1GridView);
- const int count = d->model ? d->model->count() : 0;
- if (!count)
- return;
-
- if (effectiveLayoutDirection() == Qt::LeftToRight) {
- if (d->flow == QDeclarative1GridView::LeftToRight) {
- if (currentIndex() > 0 || d->wrap) {
- int index = currentIndex() - 1;
- setCurrentIndex((index >= 0 && index < count) ? index : count-1);
- }
- } else {
- if (currentIndex() >= d->columns || d->wrap) {
- int index = currentIndex() - d->columns;
- setCurrentIndex((index >= 0 && index < count) ? index : count-1);
- }
- }
- } else {
- if (d->flow == QDeclarative1GridView::LeftToRight) {
- if (currentIndex() < count - 1 || d->wrap) {
- int index = currentIndex() + 1;
- setCurrentIndex((index >= 0 && index < count) ? index : 0);
- }
- } else {
- if (currentIndex() < count - d->columns || d->wrap) {
- int index = currentIndex() + d->columns;
- setCurrentIndex((index >= 0 && index < count) ? index : 0);
- }
- }
- }
-}
-
-/*!
- \qmlmethod QtQuick1::GridView::moveCurrentIndexRight()
-
- Move the currentIndex right one item in the view.
- The current index will wrap if keyNavigationWraps is true and it
- is currently at the end. This method has no effect if the \l count is zero.
-
- \bold Note: methods should only be called after the Component has completed.
-*/
-void QDeclarative1GridView::moveCurrentIndexRight()
-{
- Q_D(QDeclarative1GridView);
- const int count = d->model ? d->model->count() : 0;
- if (!count)
- return;
-
- if (effectiveLayoutDirection() == Qt::LeftToRight) {
- if (d->flow == QDeclarative1GridView::LeftToRight) {
- if (currentIndex() < count - 1 || d->wrap) {
- int index = currentIndex() + 1;
- setCurrentIndex((index >= 0 && index < count) ? index : 0);
- }
- } else {
- if (currentIndex() < count - d->columns || d->wrap) {
- int index = currentIndex()+d->columns;
- setCurrentIndex((index >= 0 && index < count) ? index : 0);
- }
- }
- } else {
- if (d->flow == QDeclarative1GridView::LeftToRight) {
- if (currentIndex() > 0 || d->wrap) {
- int index = currentIndex() - 1;
- setCurrentIndex((index >= 0 && index < count) ? index : count-1);
- }
- } else {
- if (currentIndex() >= d->columns || d->wrap) {
- int index = currentIndex() - d->columns;
- setCurrentIndex((index >= 0 && index < count) ? index : count-1);
- }
- }
- }
-}
-
-void QDeclarative1GridViewPrivate::positionViewAtIndex(int index, int mode)
-{
- Q_Q(QDeclarative1GridView);
- if (!isValid())
- return;
- if (mode < QDeclarative1GridView::Beginning || mode > QDeclarative1GridView::Contain)
- return;
-
- int idx = qMax(qMin(index, model->count()-1), 0);
-
- if (layoutScheduled)
- layout();
- qreal pos = isRightToLeftTopToBottom() ? -position() - size() : position();
- FxGridItem1 *item = visibleItem(idx);
- qreal maxExtent;
- if (flow == QDeclarative1GridView::LeftToRight)
- maxExtent = -q->maxYExtent();
- else
- maxExtent = isRightToLeftTopToBottom() ? q->minXExtent()-size() : -q->maxXExtent();
-
- if (!item) {
- int itemPos = rowPosAt(idx);
- // save the currently visible items in case any of them end up visible again
- QList<FxGridItem1*> oldVisible = visibleItems;
- visibleItems.clear();
- visibleIndex = idx - idx % columns;
- if (flow == QDeclarative1GridView::LeftToRight)
- maxExtent = -q->maxYExtent();
- else
- maxExtent = isRightToLeftTopToBottom() ? q->minXExtent()-size() : -q->maxXExtent();
- setPosition(qMin(qreal(itemPos), maxExtent));
- // now release the reference to all the old visible items.
- for (int i = 0; i < oldVisible.count(); ++i)
- releaseItem(oldVisible.at(i));
- item = visibleItem(idx);
- }
- if (item) {
- qreal itemPos = item->rowPos();
- switch (mode) {
- case QDeclarative1GridView::Beginning:
- pos = itemPos;
- if (index < 0 && header) {
- pos -= flow == QDeclarative1GridView::LeftToRight
- ? header->item->height()
- : header->item->width();
- }
- break;
- case QDeclarative1GridView::Center:
- pos = itemPos - (size() - rowSize())/2;
- break;
- case QDeclarative1GridView::End:
- pos = itemPos - size() + rowSize();
- if (index >= model->count() && footer) {
- pos += flow == QDeclarative1GridView::LeftToRight
- ? footer->item->height()
- : footer->item->width();
- }
- break;
- case QDeclarative1GridView::Visible:
- if (itemPos > pos + size())
- pos = itemPos - size() + rowSize();
- else if (item->endRowPos() < pos)
- pos = itemPos;
- break;
- case QDeclarative1GridView::Contain:
- if (item->endRowPos() > pos + size())
- pos = itemPos - size() + rowSize();
- if (itemPos < pos)
- pos = itemPos;
- }
-
- pos = qMin(pos, maxExtent);
- qreal minExtent;
- if (flow == QDeclarative1GridView::LeftToRight)
- minExtent = -q->minYExtent();
- else
- minExtent = isRightToLeftTopToBottom() ? q->maxXExtent()-size() : -q->minXExtent();
- pos = qMax(pos, minExtent);
- moveReason = QDeclarative1GridViewPrivate::Other;
- q->cancelFlick();
- setPosition(pos);
- }
- fixupPosition();
-}
-
-/*!
- \qmlmethod QtQuick1::GridView::positionViewAtIndex(int index, PositionMode mode)
-
- Positions the view such that the \a index is at the position specified by
- \a mode:
-
- \list
- \o GridView.Beginning - position item at the top (or left for \c GridView.TopToBottom flow) of the view.
- \o GridView.Center - position item in the center of the view.
- \o GridView.End - position item at bottom (or right for horizontal orientation) of the view.
- \o GridView.Visible - if any part of the item is visible then take no action, otherwise
- bring the item into view.
- \o GridView.Contain - ensure the entire item is visible. If the item is larger than
- the view the item is positioned at the top (or left for \c GridView.TopToBottom flow) of the view.
- \endlist
-
- If positioning the view at the index would cause empty space to be displayed at
- the beginning or end of the view, the view will be positioned at the boundary.
-
- It is not recommended to use \l {Flickable::}{contentX} or \l {Flickable::}{contentY} to position the view
- at a particular index. This is unreliable since removing items from the start
- of the view does not cause all other items to be repositioned.
- The correct way to bring an item into view is with \c positionViewAtIndex.
-
- \bold Note: methods should only be called after the Component has completed. To position
- the view at startup, this method should be called by Component.onCompleted. For
- example, to position the view at the end:
-
- \code
- Component.onCompleted: positionViewAtIndex(count - 1, GridView.Beginning)
- \endcode
-*/
-void QDeclarative1GridView::positionViewAtIndex(int index, int mode)
-{
- Q_D(QDeclarative1GridView);
- if (!d->isValid() || index < 0 || index >= d->model->count())
- return;
- d->positionViewAtIndex(index, mode);
-}
-
-/*!
- \qmlmethod QtQuick1::GridView::positionViewAtBeginning()
- \qmlmethod QtQuick1::GridView::positionViewAtEnd()
- \since Quick 1.1
-
- Positions the view at the beginning or end, taking into account any header or footer.
-
- It is not recommended to use \l {Flickable::}{contentX} or \l {Flickable::}{contentY} to position the view
- at a particular index. This is unreliable since removing items from the start
- of the list does not cause all other items to be repositioned, and because
- the actual start of the view can vary based on the size of the delegates.
-
- \bold Note: methods should only be called after the Component has completed. To position
- the view at startup, this method should be called by Component.onCompleted. For
- example, to position the view at the end on startup:
-
- \code
- Component.onCompleted: positionViewAtEnd()
- \endcode
-*/
-void QDeclarative1GridView::positionViewAtBeginning()
-{
- Q_D(QDeclarative1GridView);
- if (!d->isValid())
- return;
- d->positionViewAtIndex(-1, Beginning);
-}
-
-void QDeclarative1GridView::positionViewAtEnd()
-{
- Q_D(QDeclarative1GridView);
- if (!d->isValid())
- return;
- d->positionViewAtIndex(d->model->count(), End);
-}
-
-/*!
- \qmlmethod int QtQuick1::GridView::indexAt(int x, int y)
-
- Returns the index of the visible item containing the point \a x, \a y in content
- coordinates. If there is no item at the point specified, or the item is
- not visible -1 is returned.
-
- If the item is outside the visible area, -1 is returned, regardless of
- whether an item will exist at that point when scrolled into view.
-
- \bold Note: methods should only be called after the Component has completed.
-*/
-int QDeclarative1GridView::indexAt(qreal x, qreal y) const
-{
- Q_D(const QDeclarative1GridView);
- for (int i = 0; i < d->visibleItems.count(); ++i) {
- const FxGridItem1 *listItem = d->visibleItems.at(i);
- if(listItem->contains(x, y))
- return listItem->index;
- }
-
- return -1;
-}
-
-void QDeclarative1GridView::componentComplete()
-{
- Q_D(QDeclarative1GridView);
- QDeclarative1Flickable::componentComplete();
- d->updateHeader();
- d->updateFooter();
- d->updateGrid();
- if (d->isValid()) {
- refill();
- d->moveReason = QDeclarative1GridViewPrivate::SetIndex;
- if (d->currentIndex < 0 && !d->currentIndexCleared)
- d->updateCurrent(0);
- else
- d->updateCurrent(d->currentIndex);
- if (d->highlight && d->currentItem) {
- if (d->autoHighlight)
- d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos());
- d->updateTrackedItem();
- }
- d->moveReason = QDeclarative1GridViewPrivate::Other;
- d->fixupPosition();
- }
-}
-
-void QDeclarative1GridView::trackedPositionChanged()
-{
- Q_D(QDeclarative1GridView);
- if (!d->trackedItem || !d->currentItem)
- return;
- if (d->moveReason == QDeclarative1GridViewPrivate::SetIndex) {
- const qreal trackedPos = d->trackedItem->rowPos();
- qreal viewPos;
- qreal highlightStart;
- qreal highlightEnd;
- if (d->isRightToLeftTopToBottom()) {
- viewPos = -d->position()-d->size();
- highlightStart = d->highlightRangeStartValid ? d->size()-d->highlightRangeEnd : d->highlightRangeStart;
- highlightEnd = d->highlightRangeEndValid ? d->size()-d->highlightRangeStart : d->highlightRangeEnd;
- } else {
- viewPos = d->position();
- highlightStart = d->highlightRangeStart;
- highlightEnd = d->highlightRangeEnd;
- }
- qreal pos = viewPos;
- if (d->haveHighlightRange) {
- if (d->highlightRange == StrictlyEnforceRange) {
- if (trackedPos > pos + highlightEnd - d->rowSize())
- pos = trackedPos - highlightEnd + d->rowSize();
- if (trackedPos < pos + highlightStart)
- pos = trackedPos - highlightStart;
- } else {
- if (trackedPos < d->startPosition() + highlightStart) {
- pos = d->startPosition();
- } else if (d->trackedItem->endRowPos() > d->endPosition() - d->size() + highlightEnd) {
- pos = d->endPosition() - d->size() + 1;
- if (pos < d->startPosition())
- pos = d->startPosition();
- } else {
- if (trackedPos > pos + highlightEnd - d->rowSize())
- pos = trackedPos - highlightEnd + d->rowSize();
- if (trackedPos < pos + highlightStart)
- pos = trackedPos - highlightStart;
- }
- }
- } else {
- if (trackedPos < viewPos && d->currentItem->rowPos() < viewPos) {
- pos = qMax(trackedPos, d->currentItem->rowPos());
- } else if (d->trackedItem->endRowPos() >= viewPos + d->size()
- && d->currentItem->endRowPos() >= viewPos + d->size()) {
- if (d->trackedItem->endRowPos() <= d->currentItem->endRowPos()) {
- pos = d->trackedItem->endRowPos() - d->size() + 1;
- if (d->rowSize() > d->size())
- pos = trackedPos;
- } else {
- pos = d->currentItem->endRowPos() - d->size() + 1;
- if (d->rowSize() > d->size())
- pos = d->currentItem->rowPos();
- }
- }
- }
- if (viewPos != pos) {
- cancelFlick();
- d->calcVelocity = true;
- d->setPosition(pos);
- d->calcVelocity = false;
- }
- }
-}
-
-void QDeclarative1GridView::itemsInserted(int modelIndex, int count)
-{
- Q_D(QDeclarative1GridView);
- if (!isComponentComplete() || !d->model || !d->model->isValid())
- return;
-
- int index = d->visibleItems.count() ? d->mapFromModel(modelIndex) : 0;
- if (index < 0) {
- int i = d->visibleItems.count() - 1;
- while (i > 0 && d->visibleItems.at(i)->index == -1)
- --i;
- if (d->visibleItems.at(i)->index + 1 == modelIndex) {
- // Special case of appending an item to the model.
- index = d->visibleIndex + d->visibleItems.count();
- } else {
- if (modelIndex <= d->visibleIndex) {
- // Insert before visible items
- d->visibleIndex += count;
- for (int i = 0; i < d->visibleItems.count(); ++i) {
- FxGridItem1 *listItem = d->visibleItems.at(i);
- if (listItem->index != -1 && listItem->index >= modelIndex)
- listItem->index += count;
- }
- }
- if (d->currentIndex >= modelIndex) {
- // adjust current item index
- d->currentIndex += count;
- if (d->currentItem)
- d->currentItem->index = d->currentIndex;
- emit currentIndexChanged();
- }
- d->scheduleLayout();
- d->itemCount += count;
- emit countChanged();
- return;
- }
- }
-
- int insertCount = count;
- if (index < d->visibleIndex && d->visibleItems.count()) {
- insertCount -= d->visibleIndex - index;
- index = d->visibleIndex;
- modelIndex = d->visibleIndex;
- }
-
- qreal tempPos = d->isRightToLeftTopToBottom() ? -d->position()-d->size()+d->width()+1 : d->position();
- int to = d->buffer+tempPos+d->size()-1;
- int colPos = 0;
- int rowPos = 0;
- if (d->visibleItems.count()) {
- index -= d->visibleIndex;
- if (index < d->visibleItems.count()) {
- colPos = d->visibleItems.at(index)->colPos();
- rowPos = d->visibleItems.at(index)->rowPos();
- } else {
- // appending items to visible list
- colPos = d->visibleItems.at(index-1)->colPos() + d->colSize();
- rowPos = d->visibleItems.at(index-1)->rowPos();
- if (colPos > d->colSize() * (d->columns-1)) {
- colPos = 0;
- rowPos += d->rowSize();
- }
- }
- } else if (d->itemCount == 0 && d->header) {
- rowPos = d->headerSize();
- }
-
- // Update the indexes of the following visible items.
- for (int i = 0; i < d->visibleItems.count(); ++i) {
- FxGridItem1 *listItem = d->visibleItems.at(i);
- if (listItem->index != -1 && listItem->index >= modelIndex)
- listItem->index += count;
- }
-
- bool addedVisible = false;
- QList<FxGridItem1*> added;
- int i = 0;
- while (i < insertCount && rowPos <= to + d->rowSize()*(d->columns - (colPos/d->colSize()))/qreal(d->columns)) {
- if (!addedVisible) {
- d->scheduleLayout();
- addedVisible = true;
- }
- FxGridItem1 *item = d->createItem(modelIndex + i);
- d->visibleItems.insert(index, item);
- item->setPosition(colPos, rowPos);
- added.append(item);
- colPos += d->colSize();
- if (colPos > d->colSize() * (d->columns-1)) {
- colPos = 0;
- rowPos += d->rowSize();
- }
- ++index;
- ++i;
- }
- if (i < insertCount) {
- // We didn't insert all our new items, which means anything
- // beyond the current index is not visible - remove it.
- while (d->visibleItems.count() > index) {
- d->releaseItem(d->visibleItems.takeLast());
- }
- }
-
- // update visibleIndex
- d->visibleIndex = 0;
- for (QList<FxGridItem1*>::Iterator it = d->visibleItems.begin(); it != d->visibleItems.end(); ++it) {
- if ((*it)->index != -1) {
- d->visibleIndex = (*it)->index;
- break;
- }
- }
-
- if (d->itemCount && d->currentIndex >= modelIndex) {
- // adjust current item index
- d->currentIndex += count;
- if (d->currentItem) {
- d->currentItem->index = d->currentIndex;
- d->currentItem->setPosition(d->colPosAt(d->currentIndex), d->rowPosAt(d->currentIndex));
- }
- emit currentIndexChanged();
- } else if (d->itemCount == 0 && (!d->currentIndex || (d->currentIndex < 0 && !d->currentIndexCleared))) {
- setCurrentIndex(0);
- }
-
- // everything is in order now - emit add() signal
- for (int j = 0; j < added.count(); ++j)
- added.at(j)->attached->emitAdd();
-
- d->itemCount += count;
- emit countChanged();
-}
-
-void QDeclarative1GridView::itemsRemoved(int modelIndex, int count)
-{
- Q_D(QDeclarative1GridView);
- if (!isComponentComplete() || !d->model || !d->model->isValid())
- return;
-
- d->itemCount -= count;
- bool currentRemoved = d->currentIndex >= modelIndex && d->currentIndex < modelIndex + count;
- bool removedVisible = false;
-
- // Remove the items from the visible list, skipping anything already marked for removal
- QList<FxGridItem1*>::Iterator it = d->visibleItems.begin();
- while (it != d->visibleItems.end()) {
- FxGridItem1 *item = *it;
- if (item->index == -1 || item->index < modelIndex) {
- // already removed, or before removed items
- if (item->index < modelIndex && !removedVisible) {
- d->scheduleLayout();
- removedVisible = true;
- }
- ++it;
- } else if (item->index >= modelIndex + count) {
- // after removed items
- item->index -= count;
- ++it;
- } else {
- // removed item
- if (!removedVisible) {
- d->scheduleLayout();
- removedVisible = true;
- }
- item->attached->emitRemove();
- if (item->attached->delayRemove()) {
- item->index = -1;
- connect(item->attached, SIGNAL(delayRemoveChanged()), this, SLOT(destroyRemoved()), Qt::QueuedConnection);
- ++it;
- } else {
- it = d->visibleItems.erase(it);
- d->releaseItem(item);
- }
- }
- }
-
- // update visibleIndex
- d->visibleIndex = 0;
- for (it = d->visibleItems.begin(); it != d->visibleItems.end(); ++it) {
- if ((*it)->index != -1) {
- d->visibleIndex = (*it)->index;
- break;
- }
- }
-
- // If we removed items before visible items a layout may be
- // required to ensure item 0 is in the first column.
- if (!removedVisible && modelIndex < d->visibleIndex)
- d->scheduleLayout();
-
- // fix current
- if (d->currentIndex >= modelIndex + count) {
- d->currentIndex -= count;
- if (d->currentItem)
- d->currentItem->index -= count;
- emit currentIndexChanged();
- } else if (currentRemoved) {
- // current item has been removed.
- d->releaseItem(d->currentItem);
- d->currentItem = 0;
- d->currentIndex = -1;
- if (d->itemCount)
- d->updateCurrent(qMin(modelIndex, d->itemCount-1));
- else
- emit currentIndexChanged();
- }
-
- if (removedVisible && d->visibleItems.isEmpty()) {
- d->timeline.clear();
- if (d->itemCount == 0) {
- d->setPosition(0);
- d->updateHeader();
- d->updateFooter();
- update();
- }
- }
-
- emit countChanged();
-}
-
-void QDeclarative1GridView::destroyRemoved()
-{
- Q_D(QDeclarative1GridView);
- for (QList<FxGridItem1*>::Iterator it = d->visibleItems.begin();
- it != d->visibleItems.end();) {
- FxGridItem1 *listItem = *it;
- if (listItem->index == -1 && listItem->attached->delayRemove() == false) {
- d->releaseItem(listItem);
- it = d->visibleItems.erase(it);
- } else {
- ++it;
- }
- }
-
- // Correct the positioning of the items
- d->layout();
-}
-
-void QDeclarative1GridView::itemsMoved(int from, int to, int count)
-{
- Q_D(QDeclarative1GridView);
- if (!isComponentComplete() || !d->isValid())
- return;
- QHash<int,FxGridItem1*> moved;
-
- FxGridItem1 *firstItem = d->firstVisibleItem();
-
- QList<FxGridItem1*>::Iterator it = d->visibleItems.begin();
- while (it != d->visibleItems.end()) {
- FxGridItem1 *item = *it;
- if (item->index >= from && item->index < from + count) {
- // take the items that are moving
- item->index += (to-from);
- moved.insert(item->index, item);
- it = d->visibleItems.erase(it);
- } else {
- if (item->index > from && item->index != -1) {
- // move everything after the moved items.
- item->index -= count;
- if (item->index < d->visibleIndex)
- d->visibleIndex = item->index;
- }
- ++it;
- }
- }
-
- int remaining = count;
- int endIndex = d->visibleIndex;
- it = d->visibleItems.begin();
- while (it != d->visibleItems.end()) {
- FxGridItem1 *item = *it;
- if (remaining && item->index >= to && item->index < to + count) {
- // place items in the target position, reusing any existing items
- FxGridItem1 *movedItem = moved.take(item->index);
- if (!movedItem)
- movedItem = d->createItem(item->index);
- it = d->visibleItems.insert(it, movedItem);
- if (it == d->visibleItems.begin() && firstItem)
- movedItem->setPosition(firstItem->colPos(), firstItem->rowPos());
- ++it;
- --remaining;
- } else {
- if (item->index != -1) {
- if (item->index >= to) {
- // update everything after the moved items.
- item->index += count;
- }
- endIndex = item->index;
- }
- ++it;
- }
- }
-
- // If we have moved items to the end of the visible items
- // then add any existing moved items that we have
- while (FxGridItem1 *item = moved.take(endIndex+1)) {
- d->visibleItems.append(item);
- ++endIndex;
- }
-
- // update visibleIndex
- for (it = d->visibleItems.begin(); it != d->visibleItems.end(); ++it) {
- if ((*it)->index != -1) {
- d->visibleIndex = (*it)->index;
- break;
- }
- }
-
- // Fix current index
- if (d->currentIndex >= 0 && d->currentItem) {
- int oldCurrent = d->currentIndex;
- d->currentIndex = d->model->indexOf(d->currentItem->item, this);
- if (oldCurrent != d->currentIndex) {
- d->currentItem->index = d->currentIndex;
- emit currentIndexChanged();
- }
- }
-
- // Whatever moved items remain are no longer visible items.
- while (moved.count()) {
- int idx = moved.begin().key();
- FxGridItem1 *item = moved.take(idx);
- if (d->currentItem && item->item == d->currentItem->item)
- item->setPosition(d->colPosAt(idx), d->rowPosAt(idx));
- d->releaseItem(item);
- }
-
- d->layout();
-}
-
-void QDeclarative1GridView::modelReset()
-{
- Q_D(QDeclarative1GridView);
- d->clear();
- refill();
- d->moveReason = QDeclarative1GridViewPrivate::SetIndex;
- d->updateCurrent(d->currentIndex);
- if (d->highlight && d->currentItem) {
- if (d->autoHighlight)
- d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos());
- d->updateTrackedItem();
- }
- d->moveReason = QDeclarative1GridViewPrivate::Other;
-
- emit countChanged();
-}
-
-void QDeclarative1GridView::createdItem(int index, QDeclarativeItem *item)
-{
- Q_D(QDeclarative1GridView);
- if (d->requestedIndex != index) {
- item->setParentItem(this);
- d->unrequestedItems.insert(item, index);
- if (d->flow == QDeclarative1GridView::LeftToRight) {
- item->setPos(QPointF(d->colPosAt(index), d->rowPosAt(index)));
- } else {
- item->setPos(QPointF(d->rowPosAt(index), d->colPosAt(index)));
- }
- }
-}
-
-void QDeclarative1GridView::destroyingItem(QDeclarativeItem *item)
-{
- Q_D(QDeclarative1GridView);
- d->unrequestedItems.remove(item);
-}
-
-void QDeclarative1GridView::animStopped()
-{
- Q_D(QDeclarative1GridView);
- d->bufferMode = QDeclarative1GridViewPrivate::NoBuffer;
- if (d->haveHighlightRange && d->highlightRange == QDeclarative1GridView::StrictlyEnforceRange)
- d->updateHighlight();
-}
-
-void QDeclarative1GridView::refill()
-{
- Q_D(QDeclarative1GridView);
- if (d->isRightToLeftTopToBottom())
- d->refill(-d->position()-d->size()+1, -d->position());
- else
- d->refill(d->position(), d->position()+d->size()-1);
-}
-
-
-QDeclarative1GridViewAttached *QDeclarative1GridView::qmlAttachedProperties(QObject *obj)
-{
- return new QDeclarative1GridViewAttached(obj);
-}
-
-
-
-QT_END_NAMESPACE