diff options
author | Martin Jones <martin.jones@nokia.com> | 2011-01-11 03:09:01 (GMT) |
---|---|---|
committer | Martin Jones <martin.jones@nokia.com> | 2011-01-11 03:11:17 (GMT) |
commit | 11347a267125ecd0eaa5b022547297082954eb86 (patch) | |
tree | b1d26c63667d6d9cd4a0ca979baa319c9db27b42 /src/declarative | |
parent | 39d2f837f5d5ac67d0cfcc3710aa23d22a84d3c1 (diff) | |
download | Qt-11347a267125ecd0eaa5b022547297082954eb86.zip Qt-11347a267125ecd0eaa5b022547297082954eb86.tar.gz Qt-11347a267125ecd0eaa5b022547297082954eb86.tar.bz2 |
Add methods to position view at beginning or end.
Takes into account header/footer.
Task-number: QTBUG-16213
Reviewed-by: Michael Brasser
Diffstat (limited to 'src/declarative')
5 files changed, 220 insertions, 108 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index c2c28c2..6e6e8c1 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -336,6 +336,7 @@ public: } } + 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, QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity); @@ -2124,6 +2125,77 @@ void QDeclarativeGridView::moveCurrentIndexRight() } } +void QDeclarativeGridViewPrivate::positionViewAtIndex(int index, int mode) +{ + Q_Q(QDeclarativeGridView); + if (!isValid()) + return; + if (mode < QDeclarativeGridView::Beginning || mode > QDeclarativeGridView::Contain) + return; + + int idx = qMax(qMin(index, model->count()-1), 0); + + if (layoutScheduled) + layout(); + qreal pos = position(); + FxGridItem *item = visibleItem(idx); + if (!item) { + int itemPos = rowPosAt(idx); + // save the currently visible items in case any of them end up visible again + QList<FxGridItem*> oldVisible = visibleItems; + visibleItems.clear(); + visibleIndex = idx - idx % columns; + setPosition(itemPos); + // 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 QDeclarativeGridView::Beginning: + pos = itemPos; + if (index < 0 && header) { + pos -= flow == QDeclarativeGridView::LeftToRight + ? header->item->height() + : header->item->width(); + } + break; + case QDeclarativeGridView::Center: + pos = itemPos - (size() - rowSize())/2; + break; + case QDeclarativeGridView::End: + pos = itemPos - size() + rowSize(); + if (index >= model->count() && footer) { + pos += flow == QDeclarativeGridView::LeftToRight + ? footer->item->height() + : footer->item->width(); + } + break; + case QDeclarativeGridView::Visible: + if (itemPos > pos + size()) + pos = itemPos - size() + rowSize(); + else if (item->endRowPos() < pos) + pos = itemPos; + break; + case QDeclarativeGridView::Contain: + if (item->endRowPos() > pos + size()) + pos = itemPos - size() + rowSize(); + if (itemPos < pos) + pos = itemPos; + } + qreal maxExtent = flow == QDeclarativeGridView::LeftToRight ? -q->maxYExtent() : -q->maxXExtent(); + pos = qMin(pos, maxExtent); + qreal minExtent = flow == QDeclarativeGridView::LeftToRight ? -q->minYExtent() : -q->minXExtent(); + pos = qMax(pos, minExtent); + moveReason = QDeclarativeGridViewPrivate::Other; + q->cancelFlick(); + setPosition(pos); + } + fixupPosition(); +} + /*! \qmlmethod GridView::positionViewAtIndex(int index, PositionMode mode) @@ -2161,58 +2233,42 @@ void QDeclarativeGridView::positionViewAtIndex(int index, int mode) Q_D(QDeclarativeGridView); if (!d->isValid() || index < 0 || index >= d->model->count()) return; - if (mode < Beginning || mode > Contain) + d->positionViewAtIndex(index, mode); +} + +/*! + \qmlmethod GridView::positionViewAtBeginning() + \qmlmethod GridView::positionViewAtEnd() + + 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 QDeclarativeGridView::positionViewAtBeginning() +{ + Q_D(QDeclarativeGridView); + if (!d->isValid()) return; + d->positionViewAtIndex(-1, Beginning); +} - if (d->layoutScheduled) - d->layout(); - qreal pos = d->position(); - FxGridItem *item = d->visibleItem(index); - if (!item) { - int itemPos = d->rowPosAt(index); - // save the currently visible items in case any of them end up visible again - QList<FxGridItem*> oldVisible = d->visibleItems; - d->visibleItems.clear(); - d->visibleIndex = index - index % d->columns; - d->setPosition(itemPos); - // now release the reference to all the old visible items. - for (int i = 0; i < oldVisible.count(); ++i) - d->releaseItem(oldVisible.at(i)); - item = d->visibleItem(index); - } - if (item) { - qreal itemPos = item->rowPos(); - switch (mode) { - case Beginning: - pos = itemPos; - break; - case Center: - pos = itemPos - (d->size() - d->rowSize())/2; - break; - case End: - pos = itemPos - d->size() + d->rowSize(); - break; - case Visible: - if (itemPos > pos + d->size()) - pos = itemPos - d->size() + d->rowSize(); - else if (item->endRowPos() < pos) - pos = itemPos; - break; - case Contain: - if (item->endRowPos() > pos + d->size()) - pos = itemPos - d->size() + d->rowSize(); - if (itemPos < pos) - pos = itemPos; - } - qreal maxExtent = d->flow == QDeclarativeGridView::LeftToRight ? -maxYExtent() : -maxXExtent(); - pos = qMin(pos, maxExtent); - qreal minExtent = d->flow == QDeclarativeGridView::LeftToRight ? -minYExtent() : -minXExtent(); - pos = qMax(pos, minExtent); - d->moveReason = QDeclarativeGridViewPrivate::Other; - cancelFlick(); - d->setPosition(pos); - } - d->fixupPosition(); +void QDeclarativeGridView::positionViewAtEnd() +{ + Q_D(QDeclarativeGridView); + if (!d->isValid()) + return; + d->positionViewAtIndex(d->model->count(), End); } /*! diff --git a/src/declarative/graphicsitems/qdeclarativegridview_p.h b/src/declarative/graphicsitems/qdeclarativegridview_p.h index ee632b1..e41537c 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview_p.h +++ b/src/declarative/graphicsitems/qdeclarativegridview_p.h @@ -159,6 +159,8 @@ public: Q_INVOKABLE void positionViewAtIndex(int index, int mode); Q_INVOKABLE int indexAt(int x, int y) const; + Q_INVOKABLE Q_REVISION(1) void positionViewAtBeginning(); + Q_INVOKABLE Q_REVISION(1) void positionViewAtEnd(); static QDeclarativeGridViewAttached *qmlAttachedProperties(QObject *); diff --git a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp index ddbde0b..529686e 100644 --- a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp @@ -180,6 +180,8 @@ void QDeclarativeItemModule::defineModule() qmlRegisterType<QDeclarativePinch>("QtQuick",1,1,"Pinch"); qmlRegisterType<QDeclarativePinchEvent>(); qmlRegisterType<QDeclarativeFlickable,1>("QtQuick",1,1,"Flickable"); + qmlRegisterType<QDeclarativeListView,1>("QtQuick",1,1,"ListView"); + qmlRegisterType<QDeclarativeGridView,1>("QtQuick",1,1,"GridView"); qmlRegisterType<QDeclarativeRepeater,1>("QtQuick",1,1,"Repeater"); qmlRegisterType<QDeclarativeTextEdit,1>("QtQuick",1,1,"TextEdit"); #ifndef QT_NO_LINEEDIT diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 702442b..470f947 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -451,6 +451,7 @@ public: void updateHeader(); void updateFooter(); void fixupPosition(); + void positionViewAtIndex(int index, int mode); virtual void fixup(AxisData &data, qreal minExtent, qreal maxExtent); virtual void flick(QDeclarativeFlickablePrivate::AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize, QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity); @@ -2558,6 +2559,79 @@ void QDeclarativeListView::decrementCurrentIndex() } } +void QDeclarativeListViewPrivate::positionViewAtIndex(int index, int mode) +{ + Q_Q(QDeclarativeListView); + if (!isValid()) + return; + if (mode < QDeclarativeListView::Beginning || mode > QDeclarativeListView::Contain) + return; +qDebug() << "positionViewAtIndex"; + int idx = qMax(qMin(index, model->count()-1), 0); + + if (layoutScheduled) + layout(); + qreal pos = position(); + FxListItem *item = visibleItem(idx); + if (!item) { + int itemPos = positionAt(idx); + // save the currently visible items in case any of them end up visible again + QList<FxListItem*> oldVisible = visibleItems; + visibleItems.clear(); + visiblePos = itemPos; + visibleIndex = idx; + setPosition(itemPos); + // 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) { + const qreal itemPos = item->position(); + switch (mode) { + case QDeclarativeListView::Beginning: + pos = itemPos; + if (index < 0 && header) + pos -= header->size(); + break; + case QDeclarativeListView::Center: + pos = itemPos - (size() - item->size())/2; + break; + case QDeclarativeListView::End: + pos = itemPos - size() + item->size(); + if (index >= model->count() && footer) + pos += footer->size(); + break; + case QDeclarativeListView::Visible: + if (itemPos > pos + size()) + pos = itemPos - size() + item->size(); + else if (item->endPosition() < pos) + pos = itemPos; + break; + case QDeclarativeListView::Contain: + if (item->endPosition() > pos + size()) + pos = itemPos - size() + item->size(); + if (itemPos < pos) + pos = itemPos; + } + qreal maxExtent = orient == QDeclarativeListView::Vertical ? -q->maxYExtent() : -q->maxXExtent(); + pos = qMin(pos, maxExtent); + qreal minExtent = orient == QDeclarativeListView::Vertical ? -q->minYExtent() : -q->minXExtent(); + pos = qMax(pos, minExtent); + moveReason = QDeclarativeListViewPrivate::Other; + q->cancelFlick(); + setPosition(pos); + if (highlight) { + if (autoHighlight) { + highlight->setPosition(currentItem->itemPosition()); + highlight->setSize(currentItem->itemSize()); + } + updateHighlight(); + } + } + fixupPosition(); +} + /*! \qmlmethod ListView::positionViewAtIndex(int index, PositionMode mode) @@ -2596,66 +2670,42 @@ void QDeclarativeListView::positionViewAtIndex(int index, int mode) Q_D(QDeclarativeListView); if (!d->isValid() || index < 0 || index >= d->model->count()) return; - if (mode < Beginning || mode > Contain) + d->positionViewAtIndex(index, mode); +} + +/*! + \qmlmethod ListView::positionViewAtBeginning() + \qmlmethod ListView::positionViewAtEnd() + + 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 QDeclarativeListView::positionViewAtBeginning() +{ + Q_D(QDeclarativeListView); + if (!d->isValid()) return; + d->positionViewAtIndex(-1, Beginning); +} - if (d->layoutScheduled) - d->layout(); - qreal pos = d->position(); - FxListItem *item = d->visibleItem(index); - if (!item) { - int itemPos = d->positionAt(index); - // save the currently visible items in case any of them end up visible again - QList<FxListItem*> oldVisible = d->visibleItems; - d->visibleItems.clear(); - d->visiblePos = itemPos; - d->visibleIndex = index; - d->setPosition(itemPos); - // now release the reference to all the old visible items. - for (int i = 0; i < oldVisible.count(); ++i) - d->releaseItem(oldVisible.at(i)); - item = d->visibleItem(index); - } - if (item) { - const qreal itemPos = item->position(); - switch (mode) { - case Beginning: - pos = itemPos; - break; - case Center: - pos = itemPos - (d->size() - item->size())/2; - break; - case End: - pos = itemPos - d->size() + item->size(); - break; - case Visible: - if (itemPos > pos + d->size()) - pos = itemPos - d->size() + item->size(); - else if (item->endPosition() < pos) - pos = itemPos; - break; - case Contain: - if (item->endPosition() > pos + d->size()) - pos = itemPos - d->size() + item->size(); - if (itemPos < pos) - pos = itemPos; - } - qreal maxExtent = d->orient == QDeclarativeListView::Vertical ? -maxYExtent() : -maxXExtent(); - pos = qMin(pos, maxExtent); - qreal minExtent = d->orient == QDeclarativeListView::Vertical ? -minYExtent() : -minXExtent(); - pos = qMax(pos, minExtent); - d->moveReason = QDeclarativeListViewPrivate::Other; - cancelFlick(); - d->setPosition(pos); - if (d->highlight) { - if (d->autoHighlight) { - d->highlight->setPosition(d->currentItem->itemPosition()); - d->highlight->setSize(d->currentItem->itemSize()); - } - d->updateHighlight(); - } - } - d->fixupPosition(); +void QDeclarativeListView::positionViewAtEnd() +{ + Q_D(QDeclarativeListView); + if (!d->isValid()) + return; + d->positionViewAtIndex(d->model->count(), End); } /*! diff --git a/src/declarative/graphicsitems/qdeclarativelistview_p.h b/src/declarative/graphicsitems/qdeclarativelistview_p.h index 2678b90..2f7f6da 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview_p.h +++ b/src/declarative/graphicsitems/qdeclarativelistview_p.h @@ -209,6 +209,8 @@ public: Q_INVOKABLE void positionViewAtIndex(int index, int mode); Q_INVOKABLE int indexAt(int x, int y) const; + Q_INVOKABLE Q_REVISION(1) void positionViewAtBeginning(); + Q_INVOKABLE Q_REVISION(1) void positionViewAtEnd(); public Q_SLOTS: void incrementCurrentIndex(); |