virtual void init();
virtual void clear();
- virtual bool addVisibleItems(qreal fillFrom, qreal fillTo, bool doBuffer);
+ virtual bool addVisibleItems(qreal fillFrom, qreal fillTo, qreal bufferFrom, qreal bufferTo, bool doBuffer);
virtual bool removeNonVisibleItems(qreal bufferFrom, qreal bufferTo);
virtual void visibleItemsChanged();
virtual bool applyInsertionChange(const QQuickChangeSet::Insert &insert, ChangeResult *changeResult, QList<FxViewItem *> *addedItems, QList<MovedItem> *movingIntoView);
virtual void translateAndTransitionItemsAfter(int afterIndex, const ChangeResult &insertionResult, const ChangeResult &removalResult);
+ virtual void updateSectionCriteria();
virtual void updateSections();
QQuickItem *getSectionItem(const QString §ion);
void releaseSectionItem(QQuickItem *item);
+ void releaseSectionItems();
void updateInlineSection(FxListItemSG *);
void updateCurrentSection();
void updateStickySections();
QSmoothedAnimation *highlightPosAnimator;
QSmoothedAnimation *highlightSizeAnimator;
+ qreal highlightMoveVelocity;
+ qreal highlightResizeVelocity;
int highlightResizeDuration;
QQuickViewSection *sectionCriteria;
, averageSize(100.0), spacing(0.0)
, snapMode(QQuickListView::NoSnap)
, highlightPosAnimator(0), highlightSizeAnimator(0)
- , highlightResizeDuration(250)
+ , highlightMoveVelocity(400), highlightResizeVelocity(400), highlightResizeDuration(-1)
, sectionCriteria(0), currentSectionItem(0), nextSectionItem(0)
, overshootDist(0.0), correctFlick(false), inFlickCorrection(false)
{}
if (property != m_property) {
m_property = property;
emit propertyChanged();
- m_view->updateSections();
+ // notify view that the contents of the sections must be recalculated
+ m_view->updateSectionCriteria();
}
}
if (criteria != m_criteria) {
m_criteria = criteria;
emit criteriaChanged();
- m_view->updateSections();
+ // notify view that the contents of the sections must be recalculated
+ m_view->updateSectionCriteria();
}
}
void QQuickViewSection::setDelegate(QQmlComponent *delegate)
{
if (delegate != m_delegate) {
+ if (m_delegate)
+ m_view->releaseSectionItems();
m_delegate = delegate;
emit delegateChanged();
- m_view->updateSections();
+ m_view->forceLayoutPolish();
}
}
if (m_labelPositioning != l) {
m_labelPositioning = l;
emit labelPositioningChanged();
- m_view->updateSections();
+ m_view->forceLayoutPolish();
}
}
public:
FxListItemSG(QQuickItem *i, QQuickListView *v, bool own, bool trackGeometry) : FxViewItem(i, own, trackGeometry), view(v) {
attached = static_cast<QQuickListViewAttached*>(qmlAttachedPropertiesObject<QQuickListView>(item));
- if (attached)
- static_cast<QQuickListViewAttached*>(attached)->setView(view);
if (trackGeometry) {
QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
itemPrivate->addItemChangeListener(QQuickItemViewPrivate::get(view), QQuickItemPrivate::Geometry);
// initialise attached properties
if (sectionCriteria) {
QString propValue = model->stringValue(modelIndex, sectionCriteria->property());
- listItem->attached->m_section = sectionCriteria->sectionString(propValue);
+ listItem->attached->setSection(sectionCriteria->sectionString(propValue));
if (modelIndex > 0) {
if (FxViewItem *item = itemBefore(modelIndex))
- listItem->attached->m_prevSection = item->attached->section();
+ listItem->attached->setPrevSection(item->attached->section());
else
- listItem->attached->m_prevSection = sectionAt(modelIndex-1);
+ listItem->attached->setPrevSection(sectionAt(modelIndex-1));
}
if (modelIndex < model->count()-1) {
if (FxViewItem *item = visibleItem(modelIndex+1))
- listItem->attached->m_nextSection = static_cast<QQuickListViewAttached*>(item->attached)->section();
+ listItem->attached->setNextSection(static_cast<QQuickListViewAttached*>(item->attached)->section());
else
- listItem->attached->m_nextSection = sectionAt(modelIndex+1);
+ listItem->attached->setNextSection(sectionAt(modelIndex+1));
}
}
return released;
}
-bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool doBuffer)
+bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal bufferFrom, qreal bufferTo, bool doBuffer)
{
qreal itemEnd = visiblePos;
if (visibleItems.count()) {
bool haveValidItems = modelIndex >= 0;
modelIndex = modelIndex < 0 ? visibleIndex : modelIndex + 1;
- if (haveValidItems && (fillFrom > itemEnd+averageSize+spacing
- || fillTo < visiblePos - averageSize - spacing)) {
+ if (haveValidItems && (bufferFrom > itemEnd+averageSize+spacing
+ || bufferTo < visiblePos - averageSize - spacing)) {
// We've jumped more than a page. Estimate which items are now
// visible and fill from there.
int count = (fillFrom - itemEnd) / (averageSize + spacing);
// move current item if it is not a visible item.
if (currentIndex >= 0 && currentItem && !fixedCurrent)
static_cast<FxListItemSG*>(currentItem)->setPosition(positionAt(currentIndex));
+
+ updateCurrentSection();
+ updateStickySections();
}
}
const QLatin1String posProp(orient == QQuickListView::Vertical ? "y" : "x");
highlightPosAnimator = new QSmoothedAnimation;
highlightPosAnimator->target = QQmlProperty(item, posProp);
+ highlightPosAnimator->velocity = highlightMoveVelocity;
highlightPosAnimator->userDuration = highlightMoveDuration;
const QLatin1String sizeProp(orient == QQuickListView::Vertical ? "height" : "width");
highlightSizeAnimator = new QSmoothedAnimation;
+ highlightSizeAnimator->velocity = highlightResizeVelocity;
highlightSizeAnimator->userDuration = highlightResizeDuration;
highlightSizeAnimator->target = QQmlProperty(item, sizeProp);
delete item;
}
+
+void QQuickListViewPrivate::releaseSectionItems()
+{
+ for (int i = 0; i < visibleItems.count(); ++i) {
+ FxListItemSG *listItem = static_cast<FxListItemSG *>(visibleItems.at(i));
+ if (listItem->section()) {
+ qreal pos = listItem->position();
+ releaseSectionItem(listItem->section());
+ listItem->setSection(0);
+ listItem->setPosition(pos);
+ }
+ }
+ for (int i = 0; i < sectionCacheSize; ++i) {
+ delete sectionCache[i];
+ sectionCache[i] = 0;
+ }
+}
+
void QQuickListViewPrivate::updateInlineSection(FxListItemSG *listItem)
{
if (!sectionCriteria || !sectionCriteria->delegate())
}
lastVisibleSection = QString();
- updateCurrentSection();
- updateStickySections();
}
void QQuickListViewPrivate::updateCurrentSection()
listItem->setPosition(listItem->position() + diff, true);
}
}
- forceLayout = true;
- q->polish();
+ forceLayoutPolish();
}
}
}
is scrolled. This is because the view moves to maintain the
highlight within the preferred highlight range (or visible viewport).
- \sa highlight
+ \sa highlight, highlightMoveVelocity
*/
//###Possibly rename these properties, since they are very useful even without a highlight?
/*!
Q_D(QQuickListView);
if (spacing != d->spacing) {
d->spacing = spacing;
- d->forceLayout = true;
- polish();
+ d->forceLayoutPolish();
emit spacingChanged();
}
}
QQuickViewSection *QQuickListView::sectionCriteria()
{
Q_D(QQuickListView);
- if (!d->sectionCriteria) {
+ if (!d->sectionCriteria)
d->sectionCriteria = new QQuickViewSection(this);
- connect(d->sectionCriteria, SIGNAL(propertyChanged()), this, SLOT(updateSections()));
- }
return d->sectionCriteria;
}
}
/*!
+ \qmlproperty real QtQuick2::ListView::highlightMoveVelocity
\qmlproperty int QtQuick2::ListView::highlightMoveDuration
+ \qmlproperty real QtQuick2::ListView::highlightResizeVelocity
\qmlproperty int QtQuick2::ListView::highlightResizeDuration
- These properties hold the move and resize animation duration of
- the highlight delegate.
+ These properties control the speed of the move and resize animations for the
+ highlight delegate.
\l highlightFollowsCurrentItem must be true for these properties
to have effect.
- The default value for highlightMoveDuration is 150ms and the
- default value for highlightResizeDuration is 250ms.
+ The default value for the velocity properties is 400 pixels/second.
+ The default value for the duration properties is -1, i.e. the
+ highlight will take as much time as necessary to move at the set speed.
+
+ These properties have the same characteristics as a SmoothedAnimation.
\sa highlightFollowsCurrentItem
*/
+qreal QQuickListView::highlightMoveVelocity() const
+{
+ Q_D(const QQuickListView);
+ return d->highlightMoveVelocity;
+}
+
+void QQuickListView::setHighlightMoveVelocity(qreal speed)
+{
+ Q_D(QQuickListView);
+ if (d->highlightMoveVelocity != speed) {
+ d->highlightMoveVelocity = speed;
+ if (d->highlightPosAnimator)
+ d->highlightPosAnimator->velocity = d->highlightMoveVelocity;
+ emit highlightMoveVelocityChanged();
+ }
+}
+
void QQuickListView::setHighlightMoveDuration(int duration)
{
Q_D(QQuickListView);
}
}
+qreal QQuickListView::highlightResizeVelocity() const
+{
+ Q_D(const QQuickListView);
+ return d->highlightResizeVelocity;
+}
+
+void QQuickListView::setHighlightResizeVelocity(qreal speed)
+{
+ Q_D(QQuickListView);
+ if (d->highlightResizeVelocity != speed) {
+ d->highlightResizeVelocity = speed;
+ if (d->highlightSizeAnimator)
+ d->highlightSizeAnimator->velocity = d->highlightResizeVelocity;
+ emit highlightResizeVelocityChanged();
+ }
+}
+
int QQuickListView::highlightResizeDuration() const
{
Q_D(const QQuickListView);
QQuickItemView::geometryChanged(newGeometry, oldGeometry);
}
+void QQuickListView::initItem(int index, QQuickItem *item)
+{
+ QQuickItemView::initItem(index, item);
+ QQuickListViewAttached *attached = static_cast<QQuickListViewAttached *>(
+ qmlAttachedPropertiesObject<QQuickListView>(item));
+ if (attached)
+ attached->setView(this);
+}
+
/*!
\qmlmethod QtQuick2::ListView::incrementCurrentIndex()
}
}
-void QQuickListView::updateSections()
+void QQuickListViewPrivate::updateSectionCriteria()
{
- Q_D(QQuickListView);
- if (isComponentComplete() && d->model) {
+ Q_Q(QQuickListView);
+ if (q->isComponentComplete() && model) {
QList<QByteArray> roles;
- if (d->sectionCriteria && !d->sectionCriteria->property().isEmpty())
- roles << d->sectionCriteria->property().toUtf8();
- d->model->setWatchedRoles(roles);
- d->updateSections();
- if (d->itemCount) {
- d->forceLayout = true;
- polish();
- }
+ if (sectionCriteria && !sectionCriteria->property().isEmpty())
+ roles << sectionCriteria->property().toUtf8();
+ model->setWatchedRoles(roles);
+ updateSections();
+ if (itemCount)
+ forceLayoutPolish();
}
}