2011-04-27 12:13:26 +00:00
/****************************************************************************
* *
2014-08-22 06:13:59 +00:00
* * Copyright ( C ) 2014 Digia Plc and / or its subsidiary ( - ies ) .
2012-09-20 05:21:40 +00:00
* * Contact : http : //www.qt-project.org/legal
2011-04-27 12:13:26 +00:00
* *
2013-09-30 05:28:31 +00:00
* * This file is part of the QtQuick module of the Qt Toolkit .
2011-04-27 12:13:26 +00:00
* *
2014-08-22 06:13:59 +00:00
* * $ QT_BEGIN_LICENSE : LGPL21 $
2012-09-20 05:21:40 +00:00
* * Commercial License Usage
* * Licensees holding valid commercial Qt licenses may use this file in
* * accordance with the commercial license agreement provided with the
* * Software or , alternatively , in accordance with the terms contained in
2014-08-22 06:13:59 +00:00
* * a written agreement between you and Digia . For licensing terms and
* * conditions see http : //qt.digia.com/licensing. For further information
2012-09-20 05:21:40 +00:00
* * use the contact form at http : //qt.digia.com/contact-us.
* *
2011-04-27 12:13:26 +00:00
* * GNU Lesser General Public License Usage
2012-09-20 05:21:40 +00:00
* * Alternatively , this file may be used under the terms of the GNU Lesser
2014-08-22 06:13:59 +00:00
* * General Public License version 2.1 or version 3 as published by the Free
* * Software Foundation and appearing in the file LICENSE . LGPLv21 and
* * LICENSE . LGPLv3 included in the packaging of this file . Please review the
* * following information to ensure the GNU Lesser General Public License
* * requirements will be met : https : //www.gnu.org/licenses/lgpl.html and
* * http : //www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
2012-09-20 05:21:40 +00:00
* *
* * In addition , as a special exception , Digia gives you certain additional
2014-08-22 06:13:59 +00:00
* * rights . These rights are described in the Digia Qt LGPL Exception
2011-04-27 12:13:26 +00:00
* * version 1.1 , included in the file LGPL_EXCEPTION . txt in this package .
* *
* * $ QT_END_LICENSE $
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-10-14 08:51:42 +00:00
# include "qquicklistview_p.h"
# include "qquickitemview_p_p.h"
2011-04-27 12:13:26 +00:00
2013-01-15 22:26:59 +00:00
# include <private/qqmlobjectmodel_p.h>
2012-02-16 04:43:03 +00:00
# include <QtQml/qqmlexpression.h>
# include <QtQml/qqmlengine.h>
# include <QtQml/qqmlinfo.h>
2011-04-27 12:13:26 +00:00
# include <QtGui/qevent.h>
# include <QtCore/qmath.h>
# include <QtCore/qcoreapplication.h>
2012-02-16 04:43:03 +00:00
# include <private/qquicksmoothedanimation_p_p.h>
2011-09-26 03:13:02 +00:00
# include "qplatformdefs.h"
2011-04-27 12:13:26 +00:00
QT_BEGIN_NAMESPACE
2011-09-26 03:13:02 +00:00
# ifndef QML_FLICK_SNAPONETHRESHOLD
# define QML_FLICK_SNAPONETHRESHOLD 30
# endif
2011-09-20 05:58:05 +00:00
class FxListItemSG ;
2011-10-14 08:51:42 +00:00
class QQuickListViewPrivate : public QQuickItemViewPrivate
2011-09-20 05:58:05 +00:00
{
2011-10-14 08:51:42 +00:00
Q_DECLARE_PUBLIC ( QQuickListView )
2011-09-20 05:58:05 +00:00
public :
2011-10-14 08:51:42 +00:00
static QQuickListViewPrivate * get ( QQuickListView * item ) { return item - > d_func ( ) ; }
2011-09-20 05:58:05 +00:00
virtual Qt : : Orientation layoutOrientation ( ) const ;
virtual bool isContentFlowReversed ( ) const ;
bool isRightToLeft ( ) const ;
2012-03-20 01:37:10 +00:00
bool isBottomToTop ( ) const ;
2011-09-20 05:58:05 +00:00
virtual qreal positionAt ( int index ) const ;
virtual qreal endPositionAt ( int index ) const ;
virtual qreal originPosition ( ) const ;
virtual qreal lastPosition ( ) const ;
FxViewItem * itemBefore ( int modelIndex ) const ;
QString sectionAt ( int modelIndex ) ;
qreal snapPosAt ( qreal pos ) ;
FxViewItem * snapItemAt ( qreal pos ) ;
virtual void init ( ) ;
virtual void clear ( ) ;
2012-06-14 05:11:54 +00:00
virtual bool addVisibleItems ( qreal fillFrom , qreal fillTo , qreal bufferFrom , qreal bufferTo , bool doBuffer ) ;
2011-09-20 05:58:05 +00:00
virtual bool removeNonVisibleItems ( qreal bufferFrom , qreal bufferTo ) ;
virtual void visibleItemsChanged ( ) ;
2011-10-14 08:51:42 +00:00
virtual FxViewItem * newViewItem ( int index , QQuickItem * item ) ;
2011-09-20 05:58:05 +00:00
virtual void initializeViewItem ( FxViewItem * item ) ;
2012-02-23 06:57:06 +00:00
virtual bool releaseItem ( FxViewItem * item ) ;
2012-02-09 07:59:44 +00:00
virtual void repositionItemAt ( FxViewItem * item , int index , qreal sizeBuffer ) ;
2011-10-14 08:51:42 +00:00
virtual void repositionPackageItemAt ( QQuickItem * item , int index ) ;
2012-01-13 04:35:04 +00:00
virtual void resetFirstItemPosition ( qreal pos = 0.0 ) ;
2012-01-18 06:21:50 +00:00
virtual void adjustFirstItem ( qreal forwards , qreal backwards , int ) ;
2013-09-23 06:30:40 +00:00
virtual void updateSizeChangesBeforeVisiblePos ( FxViewItem * item , ChangeResult * removeResult ) ;
2011-09-20 05:58:05 +00:00
virtual void createHighlight ( ) ;
virtual void updateHighlight ( ) ;
virtual void resetHighlightPosition ( ) ;
virtual void setPosition ( qreal pos ) ;
2012-01-13 04:35:04 +00:00
virtual void layoutVisibleItems ( int fromModelIndex = 0 ) ;
2012-02-09 07:59:44 +00:00
2014-04-30 18:29:39 +00:00
virtual bool applyInsertionChange ( const QQmlChangeSet : : Change & insert , ChangeResult * changeResult , QList < FxViewItem * > * addedItems , QList < MovedItem > * movingIntoView ) ;
2012-02-09 07:59:44 +00:00
virtual void translateAndTransitionItemsAfter ( int afterIndex , const ChangeResult & insertionResult , const ChangeResult & removalResult ) ;
2011-09-20 05:58:05 +00:00
2012-06-29 01:57:02 +00:00
virtual void updateSectionCriteria ( ) ;
2011-09-20 05:58:05 +00:00
virtual void updateSections ( ) ;
2011-10-14 08:51:42 +00:00
QQuickItem * getSectionItem ( const QString & section ) ;
void releaseSectionItem ( QQuickItem * item ) ;
2012-06-26 03:13:11 +00:00
void releaseSectionItems ( ) ;
2011-09-20 05:58:05 +00:00
void updateInlineSection ( FxListItemSG * ) ;
void updateCurrentSection ( ) ;
void updateStickySections ( ) ;
virtual qreal headerSize ( ) const ;
virtual qreal footerSize ( ) const ;
virtual bool showHeaderForIndex ( int index ) const ;
virtual bool showFooterForIndex ( int index ) const ;
virtual void updateHeader ( ) ;
virtual void updateFooter ( ) ;
2014-03-03 14:53:27 +00:00
bool hasStickyHeader ( ) const ;
bool hasStickyFooter ( ) const ;
2011-09-20 05:58:05 +00:00
virtual void changedVisibleIndex ( int newIndex ) ;
virtual void initializeCurrentItem ( ) ;
void updateAverage ( ) ;
2011-10-14 08:51:42 +00:00
void itemGeometryChanged ( QQuickItem * item , const QRectF & newGeometry , const QRectF & oldGeometry ) ;
2011-09-20 05:58:05 +00:00
virtual void fixupPosition ( ) ;
virtual void fixup ( AxisData & data , qreal minExtent , qreal maxExtent ) ;
2012-06-04 03:34:57 +00:00
virtual bool flick ( QQuickItemViewPrivate : : AxisData & data , qreal minExtent , qreal maxExtent , qreal vSize ,
2012-02-16 04:43:03 +00:00
QQuickTimeLineCallback : : Callback fixupCallback , qreal velocity ) ;
2011-09-20 05:58:05 +00:00
2011-10-14 08:51:42 +00:00
QQuickListView : : Orientation orient ;
2011-09-20 05:58:05 +00:00
qreal visiblePos ;
qreal averageSize ;
qreal spacing ;
2011-10-14 08:51:42 +00:00
QQuickListView : : SnapMode snapMode ;
2011-09-20 05:58:05 +00:00
2014-03-03 14:53:27 +00:00
QQuickListView : : HeaderPositioning headerPositioning ;
QQuickListView : : FooterPositioning footerPositioning ;
2011-09-20 05:58:05 +00:00
QSmoothedAnimation * highlightPosAnimator ;
2013-12-04 21:18:36 +00:00
QSmoothedAnimation * highlightWidthAnimator ;
QSmoothedAnimation * highlightHeightAnimator ;
2012-06-25 03:05:15 +00:00
qreal highlightMoveVelocity ;
qreal highlightResizeVelocity ;
2011-09-20 05:58:05 +00:00
int highlightResizeDuration ;
2011-10-14 08:51:42 +00:00
QQuickViewSection * sectionCriteria ;
2011-09-20 05:58:05 +00:00
QString currentSection ;
static const int sectionCacheSize = 5 ;
2011-10-14 08:51:42 +00:00
QQuickItem * sectionCache [ sectionCacheSize ] ;
QQuickItem * currentSectionItem ;
2011-09-20 05:58:05 +00:00
QString currentStickySection ;
2011-10-14 08:51:42 +00:00
QQuickItem * nextSectionItem ;
2011-09-20 05:58:05 +00:00
QString nextStickySection ;
QString lastVisibleSection ;
QString nextSection ;
qreal overshootDist ;
bool correctFlick : 1 ;
bool inFlickCorrection : 1 ;
2011-10-14 08:51:42 +00:00
QQuickListViewPrivate ( )
: orient ( QQuickListView : : Vertical )
2011-09-20 05:58:05 +00:00
, visiblePos ( 0 )
, averageSize ( 100.0 ) , spacing ( 0.0 )
2011-10-14 08:51:42 +00:00
, snapMode ( QQuickListView : : NoSnap )
2014-03-03 14:53:27 +00:00
, headerPositioning ( QQuickListView : : InlineHeader )
, footerPositioning ( QQuickListView : : InlineFooter )
2013-12-04 21:18:36 +00:00
, highlightPosAnimator ( 0 ) , highlightWidthAnimator ( 0 ) , highlightHeightAnimator ( 0 )
2012-06-25 03:05:15 +00:00
, highlightMoveVelocity ( 400 ) , highlightResizeVelocity ( 400 ) , highlightResizeDuration ( - 1 )
2011-09-20 05:58:05 +00:00
, sectionCriteria ( 0 ) , currentSectionItem ( 0 ) , nextSectionItem ( 0 )
, overshootDist ( 0.0 ) , correctFlick ( false ) , inFlickCorrection ( false )
2013-02-21 14:46:56 +00:00
{
highlightMoveDuration = - 1 ; //override default value set in base class
}
2012-02-03 02:26:37 +00:00
~ QQuickListViewPrivate ( ) {
delete highlightPosAnimator ;
2013-12-04 21:18:36 +00:00
delete highlightWidthAnimator ;
delete highlightHeightAnimator ;
2012-02-03 02:26:37 +00:00
}
2011-09-20 05:58:05 +00:00
2011-10-14 08:51:42 +00:00
friend class QQuickViewSection ;
2011-09-20 05:58:05 +00:00
} ;
//----------------------------------------------------------------------------
2011-10-14 08:51:42 +00:00
QQuickViewSection : : QQuickViewSection ( QQuickListView * parent )
2011-09-20 05:58:05 +00:00
: QObject ( parent ) , m_criteria ( FullString ) , m_delegate ( 0 ) , m_labelPositioning ( InlineLabels )
2011-10-14 08:51:42 +00:00
, m_view ( parent ? QQuickListViewPrivate : : get ( parent ) : 0 )
2011-09-20 05:58:05 +00:00
{
}
2011-10-14 08:51:42 +00:00
void QQuickViewSection : : setProperty ( const QString & property )
2011-04-27 12:13:26 +00:00
{
if ( property ! = m_property ) {
m_property = property ;
emit propertyChanged ( ) ;
2012-06-29 01:57:02 +00:00
// notify view that the contents of the sections must be recalculated
m_view - > updateSectionCriteria ( ) ;
2011-04-27 12:13:26 +00:00
}
}
2011-10-14 08:51:42 +00:00
void QQuickViewSection : : setCriteria ( QQuickViewSection : : SectionCriteria criteria )
2011-04-27 12:13:26 +00:00
{
if ( criteria ! = m_criteria ) {
m_criteria = criteria ;
emit criteriaChanged ( ) ;
2012-06-29 01:57:02 +00:00
// notify view that the contents of the sections must be recalculated
m_view - > updateSectionCriteria ( ) ;
2011-04-27 12:13:26 +00:00
}
}
2012-02-16 04:43:03 +00:00
void QQuickViewSection : : setDelegate ( QQmlComponent * delegate )
2011-04-27 12:13:26 +00:00
{
if ( delegate ! = m_delegate ) {
2012-06-26 03:13:11 +00:00
if ( m_delegate )
m_view - > releaseSectionItems ( ) ;
2011-04-27 12:13:26 +00:00
m_delegate = delegate ;
emit delegateChanged ( ) ;
2012-06-29 01:57:02 +00:00
m_view - > forceLayoutPolish ( ) ;
2011-04-27 12:13:26 +00:00
}
}
2011-10-14 08:51:42 +00:00
QString QQuickViewSection : : sectionString ( const QString & value )
2011-04-27 12:13:26 +00:00
{
if ( m_criteria = = FirstCharacter )
return value . isEmpty ( ) ? QString ( ) : value . at ( 0 ) ;
else
return value ;
}
2011-10-14 08:51:42 +00:00
void QQuickViewSection : : setLabelPositioning ( int l )
2011-09-20 05:58:05 +00:00
{
if ( m_labelPositioning ! = l ) {
m_labelPositioning = l ;
emit labelPositioningChanged ( ) ;
2012-06-29 01:57:02 +00:00
m_view - > forceLayoutPolish ( ) ;
2011-09-20 05:58:05 +00:00
}
}
2011-04-27 12:13:26 +00:00
//----------------------------------------------------------------------------
2011-07-05 05:07:05 +00:00
class FxListItemSG : public FxViewItem
2011-04-27 12:13:26 +00:00
{
public :
2013-10-07 09:55:12 +00:00
FxListItemSG ( QQuickItem * i , QQuickListView * v , bool own ) : FxViewItem ( i , v , own , static_cast < QQuickItemViewAttached * > ( qmlAttachedPropertiesObject < QQuickListView > ( i ) ) ) , view ( v )
{
2012-03-16 08:45:39 +00:00
}
2011-07-05 05:07:05 +00:00
2012-02-23 06:57:06 +00:00
inline QQuickItem * section ( ) const {
return attached ? static_cast < QQuickListViewAttached * > ( attached ) - > m_sectionItem : 0 ;
}
void setSection ( QQuickItem * s ) {
static_cast < QQuickListViewAttached * > ( attached ) - > m_sectionItem = s ;
}
2011-04-27 12:13:26 +00:00
qreal position ( ) const {
2012-02-23 06:57:06 +00:00
if ( section ( ) ) {
2011-10-14 08:51:42 +00:00
if ( view - > orientation ( ) = = QQuickListView : : Vertical )
2012-03-20 01:37:10 +00:00
return ( view - > verticalLayoutDirection ( ) = = QQuickItemView : : BottomToTop ? - section ( ) - > height ( ) - section ( ) - > y ( ) : section ( ) - > y ( ) ) ;
2011-04-27 12:13:26 +00:00
else
2012-02-23 06:57:06 +00:00
return ( view - > effectiveLayoutDirection ( ) = = Qt : : RightToLeft ? - section ( ) - > width ( ) - section ( ) - > x ( ) : section ( ) - > x ( ) ) ;
2011-04-27 12:13:26 +00:00
} else {
return itemPosition ( ) ;
}
}
qreal itemPosition ( ) const {
2011-10-14 08:51:42 +00:00
if ( view - > orientation ( ) = = QQuickListView : : Vertical )
2012-03-20 01:37:10 +00:00
return ( view - > verticalLayoutDirection ( ) = = QQuickItemView : : BottomToTop ? - item - > height ( ) - itemY ( ) : itemY ( ) ) ;
2011-04-27 12:13:26 +00:00
else
2012-02-09 07:59:44 +00:00
return ( view - > effectiveLayoutDirection ( ) = = Qt : : RightToLeft ? - item - > width ( ) - itemX ( ) : itemX ( ) ) ;
2011-04-27 12:13:26 +00:00
}
qreal size ( ) const {
2012-02-23 06:57:06 +00:00
if ( section ( ) )
return ( view - > orientation ( ) = = QQuickListView : : Vertical ? item - > height ( ) + section ( ) - > height ( ) : item - > width ( ) + section ( ) - > width ( ) ) ;
2011-04-27 12:13:26 +00:00
else
2011-10-14 08:51:42 +00:00
return ( view - > orientation ( ) = = QQuickListView : : Vertical ? item - > height ( ) : item - > width ( ) ) ;
2011-04-27 12:13:26 +00:00
}
qreal itemSize ( ) const {
2011-10-14 08:51:42 +00:00
return ( view - > orientation ( ) = = QQuickListView : : Vertical ? item - > height ( ) : item - > width ( ) ) ;
2011-04-27 12:13:26 +00:00
}
qreal sectionSize ( ) const {
2012-02-23 06:57:06 +00:00
if ( section ( ) )
return ( view - > orientation ( ) = = QQuickListView : : Vertical ? section ( ) - > height ( ) : section ( ) - > width ( ) ) ;
2011-04-27 12:13:26 +00:00
return 0.0 ;
}
qreal endPosition ( ) const {
2011-10-14 08:51:42 +00:00
if ( view - > orientation ( ) = = QQuickListView : : Vertical ) {
2012-03-20 01:37:10 +00:00
return ( view - > verticalLayoutDirection ( ) = = QQuickItemView : : BottomToTop
? - itemY ( )
: itemY ( ) + item - > height ( ) ) ;
2011-04-27 12:13:26 +00:00
} else {
return ( view - > effectiveLayoutDirection ( ) = = Qt : : RightToLeft
2012-02-09 07:59:44 +00:00
? - itemX ( )
: itemX ( ) + item - > width ( ) ) ;
2011-04-27 12:13:26 +00:00
}
}
2012-03-05 08:05:40 +00:00
void setPosition ( qreal pos , bool immediate = false ) {
2012-02-09 07:59:44 +00:00
// position the section immediately even if there is a transition
2012-02-23 06:57:06 +00:00
if ( section ( ) ) {
2012-02-09 07:59:44 +00:00
if ( view - > orientation ( ) = = QQuickListView : : Vertical ) {
2012-03-20 01:37:10 +00:00
if ( view - > verticalLayoutDirection ( ) = = QQuickItemView : : BottomToTop )
section ( ) - > setY ( - section ( ) - > height ( ) - pos ) ;
else
section ( ) - > setY ( pos ) ;
2011-04-27 12:13:26 +00:00
} else {
2012-02-09 07:59:44 +00:00
if ( view - > effectiveLayoutDirection ( ) = = Qt : : RightToLeft )
2012-02-23 06:57:06 +00:00
section ( ) - > setX ( - section ( ) - > width ( ) - pos ) ;
2012-02-09 07:59:44 +00:00
else
2012-02-23 06:57:06 +00:00
section ( ) - > setX ( pos ) ;
2011-04-27 12:13:26 +00:00
}
}
2012-03-05 08:05:40 +00:00
moveTo ( pointForPosition ( pos ) , immediate ) ;
2011-04-27 12:13:26 +00:00
}
void setSize ( qreal size ) {
2011-10-14 08:51:42 +00:00
if ( view - > orientation ( ) = = QQuickListView : : Vertical )
2011-04-27 12:13:26 +00:00
item - > setHeight ( size ) ;
else
item - > setWidth ( size ) ;
}
bool contains ( qreal x , qreal y ) const {
2012-02-09 07:59:44 +00:00
return ( x > = itemX ( ) & & x < itemX ( ) + item - > width ( ) & &
y > = itemY ( ) & & y < itemY ( ) + item - > height ( ) ) ;
}
2011-04-27 12:13:26 +00:00
2011-10-14 08:51:42 +00:00
QQuickListView * view ;
2012-02-09 07:59:44 +00:00
private :
QPointF pointForPosition ( qreal pos ) const {
if ( view - > orientation ( ) = = QQuickListView : : Vertical ) {
2012-03-20 01:37:10 +00:00
if ( view - > verticalLayoutDirection ( ) = = QQuickItemView : : BottomToTop ) {
if ( section ( ) )
pos + = section ( ) - > height ( ) ;
return QPointF ( itemX ( ) , - item - > height ( ) - pos ) ;
} else {
if ( section ( ) )
pos + = section ( ) - > height ( ) ;
return QPointF ( itemX ( ) , pos ) ;
}
2012-02-09 07:59:44 +00:00
} else {
if ( view - > effectiveLayoutDirection ( ) = = Qt : : RightToLeft ) {
2012-02-23 06:57:06 +00:00
if ( section ( ) )
pos + = section ( ) - > width ( ) ;
2012-02-09 07:59:44 +00:00
return QPointF ( - item - > width ( ) - pos , itemY ( ) ) ;
} else {
2012-02-23 06:57:06 +00:00
if ( section ( ) )
pos + = section ( ) - > width ( ) ;
2012-02-09 07:59:44 +00:00
return QPointF ( pos , itemY ( ) ) ;
}
}
}
2011-04-27 12:13:26 +00:00
} ;
//----------------------------------------------------------------------------
2011-10-14 08:51:42 +00:00
bool QQuickListViewPrivate : : isContentFlowReversed ( ) const
2011-07-05 05:07:05 +00:00
{
2012-03-20 01:37:10 +00:00
return isRightToLeft ( ) | | isBottomToTop ( ) ;
2011-07-05 05:07:05 +00:00
}
2011-04-27 12:13:26 +00:00
2011-10-14 08:51:42 +00:00
Qt : : Orientation QQuickListViewPrivate : : layoutOrientation ( ) const
2011-07-05 05:07:05 +00:00
{
return static_cast < Qt : : Orientation > ( orient ) ;
}
2011-04-27 12:13:26 +00:00
2011-10-14 08:51:42 +00:00
bool QQuickListViewPrivate : : isRightToLeft ( ) const
2011-07-05 05:07:05 +00:00
{
2011-10-14 08:51:42 +00:00
Q_Q ( const QQuickListView ) ;
return orient = = QQuickListView : : Horizontal & & q - > effectiveLayoutDirection ( ) = = Qt : : RightToLeft ;
2011-07-05 05:07:05 +00:00
}
2011-04-27 12:13:26 +00:00
2012-03-20 01:37:10 +00:00
bool QQuickListViewPrivate : : isBottomToTop ( ) const
{
return orient = = QQuickListView : : Vertical & & verticalLayoutDirection = = QQuickItemView : : BottomToTop ;
}
2011-07-05 05:07:05 +00:00
// Returns the item before modelIndex, if created.
// May return an item marked for removal.
2011-10-14 08:51:42 +00:00
FxViewItem * QQuickListViewPrivate : : itemBefore ( int modelIndex ) const
2011-07-05 05:07:05 +00:00
{
if ( modelIndex < visibleIndex )
return 0 ;
int idx = 1 ;
int lastIndex = - 1 ;
while ( idx < visibleItems . count ( ) ) {
FxViewItem * item = visibleItems . at ( idx ) ;
if ( item - > index ! = - 1 )
lastIndex = item - > index ;
if ( item - > index = = modelIndex )
return visibleItems . at ( idx - 1 ) ;
+ + idx ;
}
if ( lastIndex = = modelIndex - 1 )
return visibleItems . last ( ) ;
return 0 ;
}
2011-04-27 12:13:26 +00:00
2011-10-14 08:51:42 +00:00
void QQuickListViewPrivate : : setPosition ( qreal pos )
2011-07-05 05:07:05 +00:00
{
2011-10-14 08:51:42 +00:00
Q_Q ( QQuickListView ) ;
if ( orient = = QQuickListView : : Vertical ) {
2012-03-20 01:37:10 +00:00
if ( isBottomToTop ( ) )
q - > QQuickFlickable : : setContentY ( - pos - size ( ) ) ;
else
q - > QQuickFlickable : : setContentY ( pos ) ;
2011-07-05 05:07:05 +00:00
} else {
if ( isRightToLeft ( ) )
2011-10-14 08:51:42 +00:00
q - > QQuickFlickable : : setContentX ( - pos - size ( ) ) ;
2011-07-05 05:07:05 +00:00
else
2011-10-14 08:51:42 +00:00
q - > QQuickFlickable : : setContentX ( pos ) ;
2011-04-27 12:13:26 +00:00
}
2011-07-05 05:07:05 +00:00
}
2011-04-27 12:13:26 +00:00
2011-10-14 08:51:42 +00:00
qreal QQuickListViewPrivate : : originPosition ( ) const
2011-07-05 05:07:05 +00:00
{
qreal pos = 0 ;
if ( ! visibleItems . isEmpty ( ) ) {
pos = ( * visibleItems . constBegin ( ) ) - > position ( ) ;
if ( visibleIndex > 0 )
pos - = visibleIndex * ( averageSize + spacing ) ;
2011-04-27 12:13:26 +00:00
}
2011-07-05 05:07:05 +00:00
return pos ;
}
2011-04-27 12:13:26 +00:00
2011-10-14 08:51:42 +00:00
qreal QQuickListViewPrivate : : lastPosition ( ) const
2011-07-05 05:07:05 +00:00
{
qreal pos = 0 ;
if ( ! visibleItems . isEmpty ( ) ) {
int invisibleCount = visibleItems . count ( ) - visibleIndex ;
2011-04-27 12:13:26 +00:00
for ( int i = visibleItems . count ( ) - 1 ; i > = 0 ; - - i ) {
2011-07-05 05:07:05 +00:00
if ( visibleItems . at ( i ) - > index ! = - 1 ) {
invisibleCount = model - > count ( ) - visibleItems . at ( i ) - > index - 1 ;
2011-04-27 12:13:26 +00:00
break ;
}
}
2011-07-05 05:07:05 +00:00
pos = ( * ( - - visibleItems . constEnd ( ) ) ) - > endPosition ( ) + invisibleCount * ( averageSize + spacing ) ;
} else if ( model & & model - > count ( ) ) {
2011-07-27 04:42:48 +00:00
pos = ( model - > count ( ) * averageSize + ( model - > count ( ) - 1 ) * spacing ) ;
2011-04-27 12:13:26 +00:00
}
2011-07-05 05:07:05 +00:00
return pos ;
}
2011-04-27 12:13:26 +00:00
2011-10-14 08:51:42 +00:00
qreal QQuickListViewPrivate : : positionAt ( int modelIndex ) const
2011-07-05 05:07:05 +00:00
{
2012-02-09 07:59:44 +00:00
if ( FxViewItem * item = visibleItem ( modelIndex ) ) {
2011-07-05 05:07:05 +00:00
return item - > position ( ) ;
2012-02-09 07:59:44 +00:00
}
2011-07-05 05:07:05 +00:00
if ( ! visibleItems . isEmpty ( ) ) {
if ( modelIndex < visibleIndex ) {
int count = visibleIndex - modelIndex ;
qreal cs = 0 ;
if ( modelIndex = = currentIndex & & currentItem ) {
cs = currentItem - > size ( ) + spacing ;
- - count ;
}
return ( * visibleItems . constBegin ( ) ) - > position ( ) - count * ( averageSize + spacing ) - cs ;
} else {
int count = modelIndex - findLastVisibleIndex ( visibleIndex ) - 1 ;
2011-07-27 04:42:48 +00:00
return ( * ( - - visibleItems . constEnd ( ) ) ) - > endPosition ( ) + spacing + count * ( averageSize + spacing ) ;
2011-04-27 12:13:26 +00:00
}
}
2011-07-05 05:07:05 +00:00
return 0 ;
}
2011-04-27 12:13:26 +00:00
2011-10-14 08:51:42 +00:00
qreal QQuickListViewPrivate : : endPositionAt ( int modelIndex ) const
2011-07-05 05:07:05 +00:00
{
if ( FxViewItem * item = visibleItem ( modelIndex ) )
return item - > endPosition ( ) ;
if ( ! visibleItems . isEmpty ( ) ) {
if ( modelIndex < visibleIndex ) {
int count = visibleIndex - modelIndex ;
2011-07-27 04:42:48 +00:00
return ( * visibleItems . constBegin ( ) ) - > position ( ) - ( count - 1 ) * ( averageSize + spacing ) - spacing ;
2011-04-27 12:13:26 +00:00
} else {
2011-07-05 05:07:05 +00:00
int count = modelIndex - findLastVisibleIndex ( visibleIndex ) - 1 ;
return ( * ( - - visibleItems . constEnd ( ) ) ) - > endPosition ( ) + count * ( averageSize + spacing ) ;
2011-04-27 12:13:26 +00:00
}
}
2011-07-05 05:07:05 +00:00
return 0 ;
}
2011-04-27 12:13:26 +00:00
2011-10-14 08:51:42 +00:00
QString QQuickListViewPrivate : : sectionAt ( int modelIndex )
2011-07-05 05:07:05 +00:00
{
if ( FxViewItem * item = visibleItem ( modelIndex ) )
return item - > attached - > section ( ) ;
QString section ;
2013-11-29 01:56:49 +00:00
if ( sectionCriteria & & modelIndex > = 0 & & modelIndex < itemCount ) {
2011-07-05 05:07:05 +00:00
QString propValue = model - > stringValue ( modelIndex , sectionCriteria - > property ( ) ) ;
section = sectionCriteria - > sectionString ( propValue ) ;
2011-04-27 12:13:26 +00:00
}
2011-07-05 05:07:05 +00:00
return section ;
}
2011-10-14 08:51:42 +00:00
qreal QQuickListViewPrivate : : snapPosAt ( qreal pos )
2011-07-05 05:07:05 +00:00
{
if ( FxViewItem * snapItem = snapItemAt ( pos ) )
return snapItem - > position ( ) ;
if ( visibleItems . count ( ) ) {
qreal firstPos = ( * visibleItems . constBegin ( ) ) - > position ( ) ;
qreal endPos = ( * ( - - visibleItems . constEnd ( ) ) ) - > position ( ) ;
if ( pos < firstPos ) {
return firstPos - qRound ( ( firstPos - pos ) / averageSize ) * averageSize ;
} else if ( pos > endPos )
return endPos + qRound ( ( pos - endPos ) / averageSize ) * averageSize ;
2011-04-27 12:13:26 +00:00
}
2011-07-05 05:07:05 +00:00
return qRound ( ( pos - originPosition ( ) ) / averageSize ) * averageSize + originPosition ( ) ;
}
2011-04-27 12:13:26 +00:00
2011-10-14 08:51:42 +00:00
FxViewItem * QQuickListViewPrivate : : snapItemAt ( qreal pos )
2011-07-05 05:07:05 +00:00
{
FxViewItem * snapItem = 0 ;
2011-08-05 03:44:38 +00:00
qreal prevItemSize = 0 ;
2011-07-05 05:07:05 +00:00
for ( int i = 0 ; i < visibleItems . count ( ) ; + + i ) {
FxViewItem * item = visibleItems . at ( i ) ;
if ( item - > index = = - 1 )
continue ;
qreal itemTop = item - > position ( ) ;
2011-07-27 04:42:48 +00:00
if ( highlight & & itemTop > = pos & & item - > endPosition ( ) < = pos + highlight - > size ( ) )
2011-07-05 05:07:05 +00:00
return item ;
2011-08-05 03:44:38 +00:00
if ( itemTop + item - > size ( ) / 2 > = pos & & itemTop - prevItemSize / 2 < pos )
2011-07-05 05:07:05 +00:00
snapItem = item ;
2011-08-05 03:44:38 +00:00
prevItemSize = item - > size ( ) ;
2011-07-05 05:07:05 +00:00
}
return snapItem ;
}
2011-04-27 12:13:26 +00:00
2011-10-14 08:51:42 +00:00
void QQuickListViewPrivate : : changedVisibleIndex ( int newIndex )
2011-07-05 05:07:05 +00:00
{
visiblePos = positionAt ( newIndex ) ;
visibleIndex = newIndex ;
}
2011-04-27 12:13:26 +00:00
2011-10-14 08:51:42 +00:00
void QQuickListViewPrivate : : init ( )
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
QQuickItemViewPrivate : : init ( ) ;
: : memset ( sectionCache , 0 , sizeof ( QQuickItem * ) * sectionCacheSize ) ;
2011-04-27 12:13:26 +00:00
}
2011-10-14 08:51:42 +00:00
void QQuickListViewPrivate : : clear ( )
2011-04-27 12:13:26 +00:00
{
for ( int i = 0 ; i < sectionCacheSize ; + + i ) {
delete sectionCache [ i ] ;
sectionCache [ i ] = 0 ;
}
2011-07-14 03:55:20 +00:00
visiblePos = 0 ;
2012-03-16 07:01:11 +00:00
releaseSectionItem ( currentSectionItem ) ;
2011-09-20 05:58:05 +00:00
currentSectionItem = 0 ;
2012-03-16 07:01:11 +00:00
releaseSectionItem ( nextSectionItem ) ;
2011-09-20 05:58:05 +00:00
nextSectionItem = 0 ;
lastVisibleSection = QString ( ) ;
2011-10-14 08:51:42 +00:00
QQuickItemViewPrivate : : clear ( ) ;
2011-04-27 12:13:26 +00:00
}
2011-10-14 08:51:42 +00:00
FxViewItem * QQuickListViewPrivate : : newViewItem ( int modelIndex , QQuickItem * item )
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
Q_Q ( QQuickListView ) ;
2011-07-05 05:07:05 +00:00
2013-06-22 13:49:26 +00:00
FxListItemSG * listItem = new FxListItemSG ( item , q , false ) ;
2011-07-05 05:07:05 +00:00
listItem - > index = modelIndex ;
// initialise attached properties
if ( sectionCriteria ) {
QString propValue = model - > stringValue ( modelIndex , sectionCriteria - > property ( ) ) ;
2013-11-29 01:56:49 +00:00
QString section = sectionCriteria - > sectionString ( propValue ) ;
QString prevSection ;
QString nextSection ;
2011-07-05 05:07:05 +00:00
if ( modelIndex > 0 ) {
if ( FxViewItem * item = itemBefore ( modelIndex ) )
2013-11-29 01:56:49 +00:00
prevSection = item - > attached - > section ( ) ;
2011-07-05 05:07:05 +00:00
else
2013-11-29 01:56:49 +00:00
prevSection = sectionAt ( modelIndex - 1 ) ;
2011-04-27 12:13:26 +00:00
}
2011-07-05 05:07:05 +00:00
if ( modelIndex < model - > count ( ) - 1 ) {
2013-11-29 01:56:49 +00:00
nextSection = sectionAt ( modelIndex + 1 ) ;
2011-04-27 12:13:26 +00:00
}
2013-11-29 01:56:49 +00:00
listItem - > attached - > setSections ( prevSection , section , nextSection ) ;
2011-04-27 12:13:26 +00:00
}
return listItem ;
}
2011-10-14 08:51:42 +00:00
void QQuickListViewPrivate : : initializeViewItem ( FxViewItem * item )
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
QQuickItemViewPrivate : : initializeViewItem ( item ) ;
2011-08-02 00:53:52 +00:00
2013-06-22 13:49:26 +00:00
// need to track current items that are animating
item - > trackGeometry ( true ) ;
2011-07-05 05:07:05 +00:00
if ( sectionCriteria & & sectionCriteria - > delegate ( ) ) {
2012-03-27 23:17:02 +00:00
if ( QString : : compare ( item - > attached - > m_prevSection , item - > attached - > m_section , Qt : : CaseInsensitive ) )
2011-09-20 05:58:05 +00:00
updateInlineSection ( static_cast < FxListItemSG * > ( item ) ) ;
2011-04-27 12:13:26 +00:00
}
2011-07-05 05:07:05 +00:00
}
2012-02-23 06:57:06 +00:00
bool QQuickListViewPrivate : : releaseItem ( FxViewItem * item )
2011-07-05 05:07:05 +00:00
{
2012-02-23 06:57:06 +00:00
if ( ! item | | ! model )
return true ;
QQuickListViewAttached * att = static_cast < QQuickListViewAttached * > ( item - > attached ) ;
bool released = QQuickItemViewPrivate : : releaseItem ( item ) ;
if ( released & & att & & att - > m_sectionItem ) {
// We hold no more references to this item
int i = 0 ;
do {
if ( ! sectionCache [ i ] ) {
sectionCache [ i ] = att - > m_sectionItem ;
sectionCache [ i ] - > setVisible ( false ) ;
att - > m_sectionItem = 0 ;
break ;
}
+ + i ;
} while ( i < sectionCacheSize ) ;
delete att - > m_sectionItem ;
att - > m_sectionItem = 0 ;
2011-04-27 12:13:26 +00:00
}
2012-02-23 06:57:06 +00:00
return released ;
2011-04-27 12:13:26 +00:00
}
2012-06-14 05:11:54 +00:00
bool QQuickListViewPrivate : : addVisibleItems ( qreal fillFrom , qreal fillTo , qreal bufferFrom , qreal bufferTo , bool doBuffer )
2011-04-27 12:13:26 +00:00
{
2011-07-27 04:42:48 +00:00
qreal itemEnd = visiblePos ;
2011-07-05 05:07:05 +00:00
if ( visibleItems . count ( ) ) {
2011-04-27 12:13:26 +00:00
visiblePos = ( * visibleItems . constBegin ( ) ) - > position ( ) ;
itemEnd = ( * ( - - visibleItems . constEnd ( ) ) ) - > endPosition ( ) + spacing ;
}
2011-07-05 05:07:05 +00:00
int modelIndex = findLastVisibleIndex ( ) ;
bool haveValidItems = modelIndex > = 0 ;
modelIndex = modelIndex < 0 ? visibleIndex : modelIndex + 1 ;
2012-06-14 05:11:54 +00:00
if ( haveValidItems & & ( bufferFrom > itemEnd + averageSize + spacing
| | bufferTo < visiblePos - averageSize - spacing ) ) {
2011-05-04 07:53:51 +00:00
// We've jumped more than a page. Estimate which items are now
// visible and fill from there.
int count = ( fillFrom - itemEnd ) / ( averageSize + spacing ) ;
2012-03-07 05:26:33 +00:00
int newModelIdx = qBound ( 0 , modelIndex + count , model - > count ( ) ) ;
count = newModelIdx - modelIndex ;
if ( count ) {
for ( int i = 0 ; i < visibleItems . count ( ) ; + + i )
releaseItem ( visibleItems . at ( i ) ) ;
visibleItems . clear ( ) ;
modelIndex = newModelIdx ;
visibleIndex = modelIndex ;
visiblePos = itemEnd + count * ( averageSize + spacing ) ;
itemEnd = visiblePos ;
2011-05-04 07:53:51 +00:00
}
}
2011-04-27 12:13:26 +00:00
bool changed = false ;
FxListItemSG * item = 0 ;
2011-07-27 04:42:48 +00:00
qreal pos = itemEnd ;
2011-04-27 12:13:26 +00:00
while ( modelIndex < model - > count ( ) & & pos < = fillTo ) {
2011-11-03 05:52:13 +00:00
if ( ! ( item = static_cast < FxListItemSG * > ( createItem ( modelIndex , doBuffer ) ) ) )
2011-04-27 12:13:26 +00:00
break ;
2014-08-12 11:42:19 +00:00
qCDebug ( lcItemViewDelegateLifecycle ) < < " refill: append item " < < modelIndex < < " pos " < < pos < < " buffer " < < doBuffer < < " item " < < item - > item - > objectName ( ) ;
2012-02-21 04:44:21 +00:00
if ( ! transitioner | | ! transitioner - > canTransition ( QQuickItemViewTransitioner : : PopulateTransition , true ) ) // pos will be set by layoutVisibleItems()
2012-03-05 08:05:40 +00:00
item - > setPosition ( pos , true ) ;
2012-06-08 01:19:09 +00:00
QQuickItemPrivate : : get ( item - > item ) - > setCulled ( doBuffer ) ;
2011-04-27 12:13:26 +00:00
pos + = item - > size ( ) + spacing ;
visibleItems . append ( item ) ;
+ + modelIndex ;
changed = true ;
}
2012-01-18 06:21:50 +00:00
if ( doBuffer & & requestedIndex ! = - 1 ) // already waiting for an item
return changed ;
2011-11-03 05:52:13 +00:00
while ( visibleIndex > 0 & & visibleIndex < = model - > count ( ) & & visiblePos > fillFrom ) {
if ( ! ( item = static_cast < FxListItemSG * > ( createItem ( visibleIndex - 1 , doBuffer ) ) ) )
2011-04-27 12:13:26 +00:00
break ;
2014-08-12 11:42:19 +00:00
qCDebug ( lcItemViewDelegateLifecycle ) < < " refill: prepend item " < < visibleIndex - 1 < < " current top pos " < < visiblePos < < " buffer " < < doBuffer < < " item " < < item - > item - > objectName ( ) ;
2011-04-27 12:13:26 +00:00
- - visibleIndex ;
visiblePos - = item - > size ( ) + spacing ;
2012-02-21 04:44:21 +00:00
if ( ! transitioner | | ! transitioner - > canTransition ( QQuickItemViewTransitioner : : PopulateTransition , true ) ) // pos will be set by layoutVisibleItems()
2012-03-05 08:05:40 +00:00
item - > setPosition ( visiblePos , true ) ;
2012-06-08 01:19:09 +00:00
QQuickItemPrivate : : get ( item - > item ) - > setCulled ( doBuffer ) ;
2011-04-27 12:13:26 +00:00
visibleItems . prepend ( item ) ;
changed = true ;
}
2011-07-05 05:07:05 +00:00
return changed ;
}
2011-10-14 08:51:42 +00:00
bool QQuickListViewPrivate : : removeNonVisibleItems ( qreal bufferFrom , qreal bufferTo )
2011-07-05 05:07:05 +00:00
{
FxViewItem * item = 0 ;
bool changed = false ;
2011-11-10 04:30:08 +00:00
// Remove items from the start of the view.
// Zero-sized items shouldn't be removed unless a non-zero-sized item is also being
// removed, otherwise a zero-sized item is infinitely added and removed over and
// over by refill().
int index = 0 ;
while ( visibleItems . count ( ) > 1 & & index < visibleItems . count ( )
2011-11-03 05:52:13 +00:00
& & ( item = visibleItems . at ( index ) ) & & item - > endPosition ( ) < bufferFrom ) {
2011-07-05 05:07:05 +00:00
if ( item - > attached - > delayRemove ( ) )
break ;
2012-02-09 07:59:44 +00:00
2011-11-10 04:30:08 +00:00
if ( item - > size ( ) > 0 ) {
2014-08-12 11:42:19 +00:00
qCDebug ( lcItemViewDelegateLifecycle ) < < " refill: remove first " < < visibleIndex < < " top end pos " < < item - > endPosition ( ) ;
2011-11-10 04:30:08 +00:00
// remove this item and all zero-sized items before it
while ( item ) {
if ( item - > index ! = - 1 )
visibleIndex + + ;
visibleItems . removeAt ( index ) ;
2012-02-09 07:59:44 +00:00
if ( item - > transitionScheduledOrRunning ( ) ) {
2014-08-12 11:42:19 +00:00
qCDebug ( lcItemViewDelegateLifecycle ) < < " \t not releasing animating item " < < item - > index < < item - > item - > objectName ( ) ;
2012-02-09 07:59:44 +00:00
item - > releaseAfterTransition = true ;
releasePendingTransition . append ( item ) ;
} else {
releaseItem ( item ) ;
}
2011-11-10 04:30:08 +00:00
if ( index = = 0 )
break ;
item = visibleItems . at ( - - index ) ;
}
changed = true ;
} else {
index + + ;
}
2011-07-05 05:07:05 +00:00
}
2011-11-10 04:30:08 +00:00
2011-07-05 05:07:05 +00:00
while ( visibleItems . count ( ) > 1 & & ( item = visibleItems . last ( ) ) & & item - > position ( ) > bufferTo ) {
if ( item - > attached - > delayRemove ( ) )
break ;
2014-08-12 11:42:19 +00:00
qCDebug ( lcItemViewDelegateLifecycle ) < < " refill: remove last " < < visibleIndex + visibleItems . count ( ) - 1 < < item - > position ( ) < < item - > item - > objectName ( ) ;
2011-07-05 05:07:05 +00:00
visibleItems . removeLast ( ) ;
2012-02-09 07:59:44 +00:00
if ( item - > transitionScheduledOrRunning ( ) ) {
2014-08-12 11:42:19 +00:00
qCDebug ( lcItemViewDelegateLifecycle ) < < " \t not releasing animating item " < < item - > index < < item - > item - > objectName ( ) ;
2012-02-09 07:59:44 +00:00
item - > releaseAfterTransition = true ;
releasePendingTransition . append ( item ) ;
} else {
releaseItem ( item ) ;
}
2011-07-05 05:07:05 +00:00
changed = true ;
2011-04-27 12:13:26 +00:00
}
2011-07-05 05:07:05 +00:00
return changed ;
2011-04-27 12:13:26 +00:00
}
2011-10-14 08:51:42 +00:00
void QQuickListViewPrivate : : visibleItemsChanged ( )
2011-04-27 12:13:26 +00:00
{
2011-07-05 05:07:05 +00:00
if ( visibleItems . count ( ) )
visiblePos = ( * visibleItems . constBegin ( ) ) - > position ( ) ;
updateAverage ( ) ;
if ( currentIndex > = 0 & & currentItem & & ! visibleItem ( currentIndex ) ) {
static_cast < FxListItemSG * > ( currentItem ) - > setPosition ( positionAt ( currentIndex ) ) ;
updateHighlight ( ) ;
2011-04-27 12:13:26 +00:00
}
2011-07-05 05:07:05 +00:00
if ( sectionCriteria )
updateCurrentSection ( ) ;
updateUnrequestedPositions ( ) ;
2011-04-27 12:13:26 +00:00
}
2012-01-13 04:35:04 +00:00
void QQuickListViewPrivate : : layoutVisibleItems ( int fromModelIndex )
2011-04-27 12:13:26 +00:00
{
if ( ! visibleItems . isEmpty ( ) ) {
2013-08-29 07:48:29 +00:00
const qreal from = isContentFlowReversed ( ) ? - position ( ) - displayMarginBeginning - size ( ) : position ( ) - displayMarginBeginning ;
const qreal to = isContentFlowReversed ( ) ? - position ( ) + displayMarginEnd : position ( ) + size ( ) + displayMarginEnd ;
2011-12-09 02:55:32 +00:00
FxViewItem * firstItem = * visibleItems . constBegin ( ) ;
bool fixedCurrent = currentItem & & firstItem - > item = = currentItem - > item ;
qreal sum = firstItem - > size ( ) ;
qreal pos = firstItem - > position ( ) + firstItem - > size ( ) + spacing ;
2012-06-08 01:19:09 +00:00
firstItem - > setVisible ( firstItem - > endPosition ( ) > = from & & firstItem - > position ( ) < = to ) ;
2012-02-09 07:59:44 +00:00
2011-04-27 12:13:26 +00:00
for ( int i = 1 ; i < visibleItems . count ( ) ; + + i ) {
2011-07-05 05:07:05 +00:00
FxListItemSG * item = static_cast < FxListItemSG * > ( visibleItems . at ( i ) ) ;
2012-01-13 04:35:04 +00:00
if ( item - > index > = fromModelIndex ) {
item - > setPosition ( pos ) ;
2012-02-09 07:59:44 +00:00
item - > setVisible ( item - > endPosition ( ) > = from & & item - > position ( ) < = to ) ;
2012-01-13 04:35:04 +00:00
}
2011-04-27 12:13:26 +00:00
pos + = item - > size ( ) + spacing ;
sum + = item - > size ( ) ;
fixedCurrent = fixedCurrent | | ( currentItem & & item - > item = = currentItem - > item ) ;
}
averageSize = qRound ( sum / visibleItems . count ( ) ) ;
2011-07-05 05:07:05 +00:00
// move current item if it is not a visible item.
2012-02-09 07:59:44 +00:00
if ( currentIndex > = 0 & & currentItem & & ! fixedCurrent )
2011-07-05 05:07:05 +00:00
static_cast < FxListItemSG * > ( currentItem ) - > setPosition ( positionAt ( currentIndex ) ) ;
2012-06-29 01:57:02 +00:00
updateCurrentSection ( ) ;
updateStickySections ( ) ;
2011-04-27 12:13:26 +00:00
}
}
2012-02-09 07:59:44 +00:00
void QQuickListViewPrivate : : repositionItemAt ( FxViewItem * item , int index , qreal sizeBuffer )
{
static_cast < FxListItemSG * > ( item ) - > setPosition ( positionAt ( index ) + sizeBuffer ) ;
}
2011-10-14 08:51:42 +00:00
void QQuickListViewPrivate : : repositionPackageItemAt ( QQuickItem * item , int index )
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
Q_Q ( QQuickListView ) ;
2011-07-05 05:07:05 +00:00
qreal pos = position ( ) ;
2011-10-14 08:51:42 +00:00
if ( orient = = QQuickListView : : Vertical ) {
2012-03-20 01:37:10 +00:00
if ( item - > y ( ) + item - > height ( ) > pos & & item - > y ( ) < pos + q - > height ( ) ) {
if ( isBottomToTop ( ) )
item - > setY ( - positionAt ( index ) - item - > height ( ) ) ;
else
item - > setY ( positionAt ( index ) ) ;
}
2011-07-05 05:07:05 +00:00
} else {
if ( item - > x ( ) + item - > width ( ) > pos & & item - > x ( ) < pos + q - > width ( ) ) {
if ( isRightToLeft ( ) )
item - > setX ( - positionAt ( index ) - item - > width ( ) ) ;
else
item - > setX ( positionAt ( index ) ) ;
}
}
2011-04-27 12:13:26 +00:00
}
2012-01-13 04:35:04 +00:00
void QQuickListViewPrivate : : resetFirstItemPosition ( qreal pos )
2011-08-29 05:33:36 +00:00
{
FxListItemSG * item = static_cast < FxListItemSG * > ( visibleItems . first ( ) ) ;
2012-01-13 04:35:04 +00:00
item - > setPosition ( pos ) ;
2011-08-29 05:33:36 +00:00
}
2012-01-18 06:21:50 +00:00
void QQuickListViewPrivate : : adjustFirstItem ( qreal forwards , qreal backwards , int )
2011-08-29 05:33:36 +00:00
{
2012-01-04 23:59:30 +00:00
if ( ! visibleItems . count ( ) )
return ;
2011-10-12 04:30:18 +00:00
qreal diff = forwards - backwards ;
2012-01-04 23:59:30 +00:00
static_cast < FxListItemSG * > ( visibleItems . first ( ) ) - > setPosition ( visibleItems . first ( ) - > position ( ) + diff ) ;
2011-08-29 05:33:36 +00:00
}
2013-09-23 06:30:40 +00:00
void QQuickListViewPrivate : : updateSizeChangesBeforeVisiblePos ( FxViewItem * item , ChangeResult * removeResult )
{
if ( item ! = visibleItems . first ( ) )
QQuickItemViewPrivate : : updateSizeChangesBeforeVisiblePos ( item , removeResult ) ;
}
2011-10-14 08:51:42 +00:00
void QQuickListViewPrivate : : createHighlight ( )
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
Q_Q ( QQuickListView ) ;
2011-04-27 12:13:26 +00:00
bool changed = false ;
if ( highlight ) {
if ( trackedItem = = highlight )
trackedItem = 0 ;
delete highlight ;
highlight = 0 ;
2011-07-05 05:07:05 +00:00
2011-04-27 12:13:26 +00:00
delete highlightPosAnimator ;
2013-12-04 21:18:36 +00:00
delete highlightWidthAnimator ;
delete highlightHeightAnimator ;
2011-04-27 12:13:26 +00:00
highlightPosAnimator = 0 ;
2013-12-04 21:18:36 +00:00
highlightWidthAnimator = 0 ;
highlightHeightAnimator = 0 ;
2011-07-05 05:07:05 +00:00
2011-04-27 12:13:26 +00:00
changed = true ;
}
if ( currentItem ) {
2011-10-14 08:51:42 +00:00
QQuickItem * item = createHighlightItem ( ) ;
2011-04-27 12:13:26 +00:00
if ( item ) {
2013-06-22 13:49:26 +00:00
FxListItemSG * newHighlight = new FxListItemSG ( item , q , true ) ;
newHighlight - > trackGeometry ( true ) ;
2011-07-05 05:07:05 +00:00
if ( autoHighlight ) {
newHighlight - > setSize ( static_cast < FxListItemSG * > ( currentItem ) - > itemSize ( ) ) ;
newHighlight - > setPosition ( static_cast < FxListItemSG * > ( currentItem ) - > itemPosition ( ) ) ;
2011-04-27 12:13:26 +00:00
}
2011-10-14 08:51:42 +00:00
const QLatin1String posProp ( orient = = QQuickListView : : Vertical ? " y " : " x " ) ;
2012-02-03 02:26:37 +00:00
highlightPosAnimator = new QSmoothedAnimation ;
2012-02-16 04:43:03 +00:00
highlightPosAnimator - > target = QQmlProperty ( item , posProp ) ;
2012-06-25 03:05:15 +00:00
highlightPosAnimator - > velocity = highlightMoveVelocity ;
2011-04-27 12:13:26 +00:00
highlightPosAnimator - > userDuration = highlightMoveDuration ;
2011-07-05 05:07:05 +00:00
2013-12-04 21:18:36 +00:00
highlightWidthAnimator = new QSmoothedAnimation ;
highlightWidthAnimator - > velocity = highlightResizeVelocity ;
highlightWidthAnimator - > userDuration = highlightResizeDuration ;
2013-12-13 13:25:39 +00:00
highlightWidthAnimator - > target = QQmlProperty ( item , QStringLiteral ( " width " ) ) ;
2013-12-04 21:18:36 +00:00
highlightHeightAnimator = new QSmoothedAnimation ;
highlightHeightAnimator - > velocity = highlightResizeVelocity ;
highlightHeightAnimator - > userDuration = highlightResizeDuration ;
2013-12-13 13:25:39 +00:00
highlightHeightAnimator - > target = QQmlProperty ( item , QStringLiteral ( " height " ) ) ;
2011-07-05 05:07:05 +00:00
highlight = newHighlight ;
2011-04-27 12:13:26 +00:00
changed = true ;
}
}
if ( changed )
emit q - > highlightItemChanged ( ) ;
}
2011-10-14 08:51:42 +00:00
void QQuickListViewPrivate : : updateHighlight ( )
2011-04-27 12:13:26 +00:00
{
2011-08-29 05:33:36 +00:00
applyPendingChanges ( ) ;
2011-04-27 12:13:26 +00:00
if ( ( ! currentItem & & highlight ) | | ( currentItem & & ! highlight ) )
createHighlight ( ) ;
2011-10-14 08:51:42 +00:00
bool strictHighlight = haveHighlightRange & & highlightRange = = QQuickListView : : StrictlyEnforceRange ;
2011-08-01 05:00:30 +00:00
if ( currentItem & & autoHighlight & & highlight & & ( ! strictHighlight | | ! pressed ) ) {
2011-04-27 12:13:26 +00:00
// auto-update highlight
2011-07-05 05:07:05 +00:00
FxListItemSG * listItem = static_cast < FxListItemSG * > ( currentItem ) ;
2012-03-20 01:37:10 +00:00
highlightPosAnimator - > to = isContentFlowReversed ( )
2011-07-05 05:07:05 +00:00
? - listItem - > itemPosition ( ) - listItem - > itemSize ( )
: listItem - > itemPosition ( ) ;
2013-12-04 21:18:36 +00:00
highlightWidthAnimator - > to = listItem - > item - > width ( ) ;
highlightHeightAnimator - > to = listItem - > item - > height ( ) ;
2011-10-14 08:51:42 +00:00
if ( orient = = QQuickListView : : Vertical ) {
2011-04-27 12:13:26 +00:00
if ( highlight - > item - > width ( ) = = 0 )
highlight - > item - > setWidth ( currentItem - > item - > width ( ) ) ;
} else {
if ( highlight - > item - > height ( ) = = 0 )
highlight - > item - > setHeight ( currentItem - > item - > height ( ) ) ;
}
2011-07-05 05:07:05 +00:00
2011-04-27 12:13:26 +00:00
highlightPosAnimator - > restart ( ) ;
2013-12-04 21:18:36 +00:00
highlightWidthAnimator - > restart ( ) ;
highlightHeightAnimator - > restart ( ) ;
2011-04-27 12:13:26 +00:00
}
updateTrackedItem ( ) ;
}
2011-10-14 08:51:42 +00:00
void QQuickListViewPrivate : : resetHighlightPosition ( )
2011-07-05 05:07:05 +00:00
{
if ( highlight & & currentItem )
static_cast < FxListItemSG * > ( highlight ) - > setPosition ( static_cast < FxListItemSG * > ( currentItem ) - > itemPosition ( ) ) ;
}
2011-10-14 08:51:42 +00:00
QQuickItem * QQuickListViewPrivate : : getSectionItem ( const QString & section )
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
Q_Q ( QQuickListView ) ;
QQuickItem * sectionItem = 0 ;
2011-09-20 05:58:05 +00:00
int i = sectionCacheSize - 1 ;
while ( i > = 0 & & ! sectionCache [ i ] )
- - i ;
if ( i > = 0 ) {
sectionItem = sectionCache [ i ] ;
sectionCache [ i ] = 0 ;
sectionItem - > setVisible ( true ) ;
2012-02-16 04:43:03 +00:00
QQmlContext * context = QQmlEngine : : contextForObject ( sectionItem ) - > parentContext ( ) ;
2011-09-20 05:58:05 +00:00
context - > setContextProperty ( QLatin1String ( " section " ) , section ) ;
} else {
2012-02-16 04:43:03 +00:00
QQmlContext * creationContext = sectionCriteria - > delegate ( ) - > creationContext ( ) ;
QQmlContext * context = new QQmlContext (
2011-10-07 03:06:26 +00:00
creationContext ? creationContext : qmlContext ( q ) ) ;
2011-09-20 05:58:05 +00:00
context - > setContextProperty ( QLatin1String ( " section " ) , section ) ;
QObject * nobj = sectionCriteria - > delegate ( ) - > beginCreate ( context ) ;
if ( nobj ) {
2012-02-16 04:43:03 +00:00
QQml_setParent_noEvent ( context , nobj ) ;
2011-10-14 08:51:42 +00:00
sectionItem = qobject_cast < QQuickItem * > ( nobj ) ;
2011-09-20 05:58:05 +00:00
if ( ! sectionItem ) {
delete nobj ;
} else {
2014-03-10 14:58:10 +00:00
if ( qFuzzyIsNull ( sectionItem - > z ( ) ) )
sectionItem - > setZ ( 2 ) ;
2012-02-16 04:43:03 +00:00
QQml_setParent_noEvent ( sectionItem , contentItem ) ;
2011-09-20 05:58:05 +00:00
sectionItem - > setParentItem ( contentItem ) ;
}
2013-10-07 09:55:12 +00:00
// sections are not controlled by FxListItemSG, so apply attached properties here
QQuickItemViewAttached * attached = static_cast < QQuickItemViewAttached * > ( qmlAttachedPropertiesObject < QQuickListView > ( sectionItem ) ) ;
attached - > setView ( q ) ;
2011-09-20 05:58:05 +00:00
} else {
delete context ;
}
sectionCriteria - > delegate ( ) - > completeCreate ( ) ;
}
return sectionItem ;
}
2011-10-14 08:51:42 +00:00
void QQuickListViewPrivate : : releaseSectionItem ( QQuickItem * item )
2011-09-20 05:58:05 +00:00
{
2012-03-16 07:01:11 +00:00
if ( ! item )
return ;
2011-09-20 05:58:05 +00:00
int i = 0 ;
do {
if ( ! sectionCache [ i ] ) {
sectionCache [ i ] = item ;
sectionCache [ i ] - > setVisible ( false ) ;
return ;
}
+ + i ;
} while ( i < sectionCacheSize ) ;
delete item ;
}
2012-06-26 03:13:11 +00:00
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 ;
}
}
2011-10-14 08:51:42 +00:00
void QQuickListViewPrivate : : updateInlineSection ( FxListItemSG * listItem )
2011-09-20 05:58:05 +00:00
{
2011-04-27 12:13:26 +00:00
if ( ! sectionCriteria | | ! sectionCriteria - > delegate ( ) )
return ;
2012-03-27 23:17:02 +00:00
if ( QString : : compare ( listItem - > attached - > m_prevSection , listItem - > attached - > m_section , Qt : : CaseInsensitive )
2011-10-14 08:51:42 +00:00
& & ( sectionCriteria - > labelPositioning ( ) & QQuickViewSection : : InlineLabels
| | ( listItem - > index = = 0 & & sectionCriteria - > labelPositioning ( ) & QQuickViewSection : : CurrentLabelAtStart ) ) ) {
2012-02-23 06:57:06 +00:00
if ( ! listItem - > section ( ) ) {
2011-04-27 12:13:26 +00:00
qreal pos = listItem - > position ( ) ;
2012-02-23 06:57:06 +00:00
listItem - > setSection ( getSectionItem ( listItem - > attached - > m_section ) ) ;
2011-04-27 12:13:26 +00:00
listItem - > setPosition ( pos ) ;
} else {
2012-03-05 01:39:24 +00:00
QQmlContext * context = QQmlEngine : : contextForObject ( listItem - > section ( ) ) - > parentContext ( ) ;
2011-04-27 12:13:26 +00:00
context - > setContextProperty ( QLatin1String ( " section " ) , listItem - > attached - > m_section ) ;
}
2012-02-23 06:57:06 +00:00
} else if ( listItem - > section ( ) ) {
2011-04-27 12:13:26 +00:00
qreal pos = listItem - > position ( ) ;
2012-02-23 06:57:06 +00:00
releaseSectionItem ( listItem - > section ( ) ) ;
listItem - > setSection ( 0 ) ;
2011-04-27 12:13:26 +00:00
listItem - > setPosition ( pos ) ;
}
}
2011-10-14 08:51:42 +00:00
void QQuickListViewPrivate : : updateStickySections ( )
2011-09-20 05:58:05 +00:00
{
2013-07-29 19:50:41 +00:00
if ( ! sectionCriteria | | ! sectionCriteria - > delegate ( )
2011-09-20 05:58:05 +00:00
| | ( ! sectionCriteria - > labelPositioning ( ) & & ! currentSectionItem & & ! nextSectionItem ) )
return ;
2012-03-20 01:37:10 +00:00
bool isFlowReversed = isContentFlowReversed ( ) ;
qreal viewPos = isFlowReversed ? - position ( ) - size ( ) : position ( ) ;
2014-03-03 14:53:27 +00:00
qreal startPos = hasStickyHeader ( ) ? header - > endPosition ( ) : viewPos ;
qreal endPos = hasStickyFooter ( ) ? footer - > position ( ) : viewPos + size ( ) ;
2011-10-14 08:51:42 +00:00
QQuickItem * sectionItem = 0 ;
QQuickItem * lastSectionItem = 0 ;
2011-09-20 05:58:05 +00:00
int index = 0 ;
while ( index < visibleItems . count ( ) ) {
2012-02-23 06:57:06 +00:00
if ( QQuickItem * section = static_cast < FxListItemSG * > ( visibleItems . at ( index ) ) - > section ( ) ) {
2011-09-20 05:58:05 +00:00
// Find the current section header and last visible section header
// and hide them if they will overlap a static section header.
2011-10-14 08:51:42 +00:00
qreal sectionPos = orient = = QQuickListView : : Vertical ? section - > y ( ) : section - > x ( ) ;
qreal sectionSize = orient = = QQuickListView : : Vertical ? section - > height ( ) : section - > width ( ) ;
2011-09-20 05:58:05 +00:00
bool visTop = true ;
2011-10-14 08:51:42 +00:00
if ( sectionCriteria - > labelPositioning ( ) & QQuickViewSection : : CurrentLabelAtStart )
2014-03-03 14:53:27 +00:00
visTop = isFlowReversed ? - sectionPos - sectionSize > = startPos : sectionPos > = startPos ;
2011-09-20 05:58:05 +00:00
bool visBot = true ;
2011-10-14 08:51:42 +00:00
if ( sectionCriteria - > labelPositioning ( ) & QQuickViewSection : : NextLabelAtEnd )
2014-03-03 14:53:27 +00:00
visBot = isFlowReversed ? - sectionPos < = endPos : sectionPos + sectionSize < endPos ;
2011-09-20 05:58:05 +00:00
section - > setVisible ( visBot & & visTop ) ;
if ( visTop & & ! sectionItem )
sectionItem = section ;
2012-03-20 01:37:10 +00:00
if ( isFlowReversed ) {
2014-03-03 14:53:27 +00:00
if ( - sectionPos < = endPos )
2011-09-20 05:58:05 +00:00
lastSectionItem = section ;
} else {
2014-03-03 14:53:27 +00:00
if ( sectionPos + sectionSize < endPos )
2011-09-20 05:58:05 +00:00
lastSectionItem = section ;
}
}
+ + index ;
}
// Current section header
2012-03-16 07:01:11 +00:00
if ( sectionCriteria - > labelPositioning ( ) & QQuickViewSection : : CurrentLabelAtStart & & isValid ( ) & & visibleItems . count ( ) ) {
2011-09-20 05:58:05 +00:00
if ( ! currentSectionItem ) {
currentSectionItem = getSectionItem ( currentSection ) ;
2012-03-27 23:17:02 +00:00
} else if ( QString : : compare ( currentStickySection , currentSection , Qt : : CaseInsensitive ) ) {
2012-02-16 04:43:03 +00:00
QQmlContext * context = QQmlEngine : : contextForObject ( currentSectionItem ) - > parentContext ( ) ;
2011-09-20 05:58:05 +00:00
context - > setContextProperty ( QLatin1String ( " section " ) , currentSection ) ;
}
currentStickySection = currentSection ;
if ( ! currentSectionItem )
return ;
2011-10-14 08:51:42 +00:00
qreal sectionSize = orient = = QQuickListView : : Vertical ? currentSectionItem - > height ( ) : currentSectionItem - > width ( ) ;
2012-03-20 01:37:10 +00:00
bool atBeginning = orient = = QQuickListView : : Vertical ? ( isBottomToTop ( ) ? vData . atEnd : vData . atBeginning ) : ( isRightToLeft ( ) ? hData . atEnd : hData . atBeginning ) ;
2014-03-03 14:53:27 +00:00
currentSectionItem - > setVisible ( ! atBeginning & & ( ! header | | hasStickyHeader ( ) | | header - > endPosition ( ) < viewPos ) ) ;
qreal pos = isFlowReversed ? position ( ) + size ( ) - sectionSize : startPos ;
if ( header )
pos = isFlowReversed ? qMin ( - header - > endPosition ( ) - sectionSize , pos ) : qMax ( header - > endPosition ( ) , pos ) ;
2011-09-20 05:58:05 +00:00
if ( sectionItem ) {
2011-10-14 08:51:42 +00:00
qreal sectionPos = orient = = QQuickListView : : Vertical ? sectionItem - > y ( ) : sectionItem - > x ( ) ;
2012-03-20 01:37:10 +00:00
pos = isFlowReversed ? qMax ( pos , sectionPos + sectionSize ) : qMin ( pos , sectionPos - sectionSize ) ;
2011-09-20 05:58:05 +00:00
}
if ( footer )
2012-03-20 01:37:10 +00:00
pos = isFlowReversed ? qMax ( - footer - > position ( ) , pos ) : qMin ( footer - > position ( ) - sectionSize , pos ) ;
2011-10-14 08:51:42 +00:00
if ( orient = = QQuickListView : : Vertical )
2011-09-20 05:58:05 +00:00
currentSectionItem - > setY ( pos ) ;
else
currentSectionItem - > setX ( pos ) ;
} else if ( currentSectionItem ) {
releaseSectionItem ( currentSectionItem ) ;
currentSectionItem = 0 ;
}
// Next section footer
2012-03-16 07:01:11 +00:00
if ( sectionCriteria - > labelPositioning ( ) & QQuickViewSection : : NextLabelAtEnd & & isValid ( ) & & visibleItems . count ( ) ) {
2011-09-20 05:58:05 +00:00
if ( ! nextSectionItem ) {
nextSectionItem = getSectionItem ( nextSection ) ;
2012-03-27 23:17:02 +00:00
} else if ( QString : : compare ( nextStickySection , nextSection , Qt : : CaseInsensitive ) ) {
2012-02-16 04:43:03 +00:00
QQmlContext * context = QQmlEngine : : contextForObject ( nextSectionItem ) - > parentContext ( ) ;
2011-09-20 05:58:05 +00:00
context - > setContextProperty ( QLatin1String ( " section " ) , nextSection ) ;
}
nextStickySection = nextSection ;
if ( ! nextSectionItem )
return ;
2011-10-14 08:51:42 +00:00
qreal sectionSize = orient = = QQuickListView : : Vertical ? nextSectionItem - > height ( ) : nextSectionItem - > width ( ) ;
2011-09-20 05:58:05 +00:00
nextSectionItem - > setVisible ( ! nextSection . isEmpty ( ) ) ;
2014-03-03 14:53:27 +00:00
qreal pos = isFlowReversed ? position ( ) : endPos - sectionSize ;
if ( footer )
pos = isFlowReversed ? qMax ( - footer - > position ( ) , pos ) : qMin ( footer - > position ( ) - sectionSize , pos ) ;
2011-09-20 05:58:05 +00:00
if ( lastSectionItem ) {
2011-10-14 08:51:42 +00:00
qreal sectionPos = orient = = QQuickListView : : Vertical ? lastSectionItem - > y ( ) : lastSectionItem - > x ( ) ;
2012-03-20 01:37:10 +00:00
pos = isFlowReversed ? qMin ( pos , sectionPos - sectionSize ) : qMax ( pos , sectionPos + sectionSize ) ;
2011-09-20 05:58:05 +00:00
}
if ( header )
2014-03-03 14:53:27 +00:00
pos = isFlowReversed ? qMin ( - header - > endPosition ( ) - sectionSize , pos ) : qMax ( header - > endPosition ( ) , pos ) ;
2011-10-14 08:51:42 +00:00
if ( orient = = QQuickListView : : Vertical )
2011-09-20 05:58:05 +00:00
nextSectionItem - > setY ( pos ) ;
else
nextSectionItem - > setX ( pos ) ;
} else if ( nextSectionItem ) {
releaseSectionItem ( nextSectionItem ) ;
nextSectionItem = 0 ;
}
}
2011-10-14 08:51:42 +00:00
void QQuickListViewPrivate : : updateSections ( )
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
Q_Q ( QQuickListView ) ;
2011-09-20 05:58:05 +00:00
if ( ! q - > isComponentComplete ( ) )
return ;
2011-10-14 08:51:42 +00:00
QQuickItemViewPrivate : : updateSections ( ) ;
2011-08-02 00:53:52 +00:00
2012-03-16 07:01:11 +00:00
if ( sectionCriteria & & ! visibleItems . isEmpty ( ) & & isValid ( ) ) {
2011-04-27 12:13:26 +00:00
QString prevSection ;
if ( visibleIndex > 0 )
prevSection = sectionAt ( visibleIndex - 1 ) ;
2011-10-14 08:51:42 +00:00
QQuickListViewAttached * prevAtt = 0 ;
2011-04-27 12:13:26 +00:00
int idx = - 1 ;
for ( int i = 0 ; i < visibleItems . count ( ) ; + + i ) {
2011-10-14 08:51:42 +00:00
QQuickListViewAttached * attached = static_cast < QQuickListViewAttached * > ( visibleItems . at ( i ) - > attached ) ;
2011-04-27 12:13:26 +00:00
attached - > setPrevSection ( prevSection ) ;
if ( visibleItems . at ( i ) - > index ! = - 1 ) {
QString propValue = model - > stringValue ( visibleItems . at ( i ) - > index , sectionCriteria - > property ( ) ) ;
attached - > setSection ( sectionCriteria - > sectionString ( propValue ) ) ;
idx = visibleItems . at ( i ) - > index ;
}
2011-09-20 05:58:05 +00:00
updateInlineSection ( static_cast < FxListItemSG * > ( visibleItems . at ( i ) ) ) ;
2011-04-27 12:13:26 +00:00
if ( prevAtt )
prevAtt - > setNextSection ( attached - > section ( ) ) ;
prevSection = attached - > section ( ) ;
prevAtt = attached ;
}
if ( prevAtt ) {
if ( idx > 0 & & idx < model - > count ( ) - 1 )
prevAtt - > setNextSection ( sectionAt ( idx + 1 ) ) ;
else
prevAtt - > setNextSection ( QString ( ) ) ;
}
}
2011-09-20 05:58:05 +00:00
lastVisibleSection = QString ( ) ;
2011-04-27 12:13:26 +00:00
}
2011-10-14 08:51:42 +00:00
void QQuickListViewPrivate : : updateCurrentSection ( )
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
Q_Q ( QQuickListView ) ;
2011-04-27 12:13:26 +00:00
if ( ! sectionCriteria | | visibleItems . isEmpty ( ) ) {
if ( ! currentSection . isEmpty ( ) ) {
currentSection . clear ( ) ;
emit q - > currentSectionChanged ( ) ;
}
return ;
}
2011-10-14 08:51:42 +00:00
bool inlineSections = sectionCriteria - > labelPositioning ( ) & QQuickViewSection : : InlineLabels ;
2014-03-03 14:53:27 +00:00
qreal viewPos = isContentFlowReversed ( ) ? - position ( ) - size ( ) : position ( ) ;
qreal startPos = hasStickyHeader ( ) ? header - > endPosition ( ) : viewPos ;
2011-04-27 12:13:26 +00:00
int index = 0 ;
2011-09-20 05:58:05 +00:00
int modelIndex = visibleIndex ;
2014-03-03 14:53:27 +00:00
while ( index < visibleItems . count ( ) & & visibleItems . at ( index ) - > endPosition ( ) < = startPos ) {
2011-09-20 05:58:05 +00:00
if ( visibleItems . at ( index ) - > index ! = - 1 )
modelIndex = visibleItems . at ( index ) - > index ;
2011-04-27 12:13:26 +00:00
+ + index ;
2011-09-20 05:58:05 +00:00
}
2011-04-27 12:13:26 +00:00
QString newSection = currentSection ;
if ( index < visibleItems . count ( ) )
newSection = visibleItems . at ( index ) - > attached - > section ( ) ;
else
2011-07-05 05:07:05 +00:00
newSection = ( * visibleItems . constBegin ( ) ) - > attached - > section ( ) ;
2011-04-27 12:13:26 +00:00
if ( newSection ! = currentSection ) {
currentSection = newSection ;
2011-09-20 05:58:05 +00:00
updateStickySections ( ) ;
2011-04-27 12:13:26 +00:00
emit q - > currentSectionChanged ( ) ;
}
2011-09-20 05:58:05 +00:00
2011-10-14 08:51:42 +00:00
if ( sectionCriteria - > labelPositioning ( ) & QQuickViewSection : : NextLabelAtEnd ) {
2011-09-20 05:58:05 +00:00
// Don't want to scan for next section on every movement, so remember
// the last section in the visible area and only scan for the next
// section when that changes. Clearing lastVisibleSection will also
// force searching.
QString lastSection = currentSection ;
2014-03-03 14:53:27 +00:00
qreal endPos = hasStickyFooter ( ) ? footer - > position ( ) : viewPos + size ( ) ;
2011-09-20 05:58:05 +00:00
if ( nextSectionItem & & ! inlineSections )
2011-10-14 08:51:42 +00:00
endPos - = orient = = QQuickListView : : Vertical ? nextSectionItem - > height ( ) : nextSectionItem - > width ( ) ;
2011-09-20 05:58:05 +00:00
while ( index < visibleItems . count ( ) & & static_cast < FxListItemSG * > ( visibleItems . at ( index ) ) - > itemPosition ( ) < endPos ) {
if ( visibleItems . at ( index ) - > index ! = - 1 )
modelIndex = visibleItems . at ( index ) - > index ;
lastSection = visibleItems . at ( index ) - > attached - > section ( ) ;
+ + index ;
}
if ( lastVisibleSection ! = lastSection ) {
nextSection = QString ( ) ;
lastVisibleSection = lastSection ;
for ( int i = modelIndex ; i < itemCount ; + + i ) {
QString section = sectionAt ( i ) ;
if ( section ! = lastSection ) {
nextSection = section ;
updateStickySections ( ) ;
break ;
}
}
}
}
2011-04-27 12:13:26 +00:00
}
2011-10-14 08:51:42 +00:00
void QQuickListViewPrivate : : initializeCurrentItem ( )
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
QQuickItemViewPrivate : : initializeCurrentItem ( ) ;
2011-08-02 00:53:52 +00:00
2011-04-27 12:13:26 +00:00
if ( currentItem ) {
2011-07-05 05:07:05 +00:00
FxListItemSG * listItem = static_cast < FxListItemSG * > ( currentItem ) ;
2012-02-23 06:57:06 +00:00
// don't reposition the item if it is already in the visibleItems list
2012-02-09 07:59:44 +00:00
FxViewItem * actualItem = visibleItem ( currentIndex ) ;
2012-02-23 06:57:06 +00:00
if ( ! actualItem ) {
2012-02-09 07:59:44 +00:00
if ( currentIndex = = visibleIndex - 1 & & visibleItems . count ( ) ) {
// We can calculate exact postion in this case
listItem - > setPosition ( visibleItems . first ( ) - > position ( ) - currentItem - > size ( ) - spacing ) ;
} else {
// Create current item now and position as best we can.
// Its position will be corrected when it becomes visible.
listItem - > setPosition ( positionAt ( currentIndex ) ) ;
}
2011-04-27 12:13:26 +00:00
}
2011-07-05 05:07:05 +00:00
2011-04-27 12:13:26 +00:00
if ( visibleItems . isEmpty ( ) )
2011-07-05 05:07:05 +00:00
averageSize = listItem - > size ( ) ;
2011-04-27 12:13:26 +00:00
}
}
2011-10-14 08:51:42 +00:00
void QQuickListViewPrivate : : updateAverage ( )
2011-04-27 12:13:26 +00:00
{
if ( ! visibleItems . count ( ) )
return ;
qreal sum = 0.0 ;
for ( int i = 0 ; i < visibleItems . count ( ) ; + + i )
sum + = visibleItems . at ( i ) - > size ( ) ;
averageSize = qRound ( sum / visibleItems . count ( ) ) ;
}
2011-10-14 08:51:42 +00:00
qreal QQuickListViewPrivate : : headerSize ( ) const
2011-07-05 05:07:05 +00:00
{
return header ? header - > size ( ) : 0.0 ;
}
2011-10-14 08:51:42 +00:00
qreal QQuickListViewPrivate : : footerSize ( ) const
2011-07-05 05:07:05 +00:00
{
return footer ? footer - > size ( ) : 0.0 ;
}
2011-10-14 08:51:42 +00:00
bool QQuickListViewPrivate : : showHeaderForIndex ( int index ) const
2011-08-05 05:48:16 +00:00
{
return index = = 0 ;
}
2011-10-14 08:51:42 +00:00
bool QQuickListViewPrivate : : showFooterForIndex ( int index ) const
2011-08-05 05:48:16 +00:00
{
return index = = model - > count ( ) - 1 ;
}
2011-10-14 08:51:42 +00:00
void QQuickListViewPrivate : : updateFooter ( )
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
Q_Q ( QQuickListView ) ;
2011-07-26 05:33:58 +00:00
bool created = false ;
2011-07-05 05:07:05 +00:00
if ( ! footer ) {
2012-05-25 07:33:02 +00:00
QQuickItem * item = createComponentItem ( footerComponent , 1.0 ) ;
2011-07-05 05:07:05 +00:00
if ( ! item )
return ;
2013-06-22 13:49:26 +00:00
footer = new FxListItemSG ( item , q , true ) ;
footer - > trackGeometry ( true ) ;
2011-07-26 05:33:58 +00:00
created = true ;
2011-04-27 12:13:26 +00:00
}
2011-07-05 05:07:05 +00:00
FxListItemSG * listItem = static_cast < FxListItemSG * > ( footer ) ;
if ( visibleItems . count ( ) ) {
2014-03-03 14:53:27 +00:00
if ( footerPositioning = = QQuickListView : : OverlayFooter ) {
listItem - > setPosition ( isContentFlowReversed ( ) ? - position ( ) - footerSize ( ) : position ( ) + size ( ) - footerSize ( ) ) ;
} else if ( footerPositioning = = QQuickListView : : PullBackFooter ) {
qreal viewPos = isContentFlowReversed ( ) ? - position ( ) : position ( ) + size ( ) ;
qreal clampedPos = qBound ( originPosition ( ) - footerSize ( ) + size ( ) , listItem - > position ( ) , lastPosition ( ) ) ;
listItem - > setPosition ( qBound ( viewPos - footerSize ( ) , clampedPos , viewPos ) ) ;
2011-04-27 12:13:26 +00:00
} else {
2014-03-03 14:53:27 +00:00
qreal endPos = lastPosition ( ) ;
if ( findLastVisibleIndex ( ) = = model - > count ( ) - 1 ) {
2011-07-05 05:07:05 +00:00
listItem - > setPosition ( endPos ) ;
2014-03-03 14:53:27 +00:00
} else {
qreal visiblePos = position ( ) + q - > height ( ) ;
if ( endPos < = visiblePos | | listItem - > position ( ) < endPos )
listItem - > setPosition ( endPos ) ;
}
2011-04-27 12:13:26 +00:00
}
2011-07-05 05:07:05 +00:00
} else {
listItem - > setPosition ( visiblePos ) ;
2011-04-27 12:13:26 +00:00
}
2011-07-26 05:33:58 +00:00
if ( created )
emit q - > footerItemChanged ( ) ;
2011-04-27 12:13:26 +00:00
}
2011-10-14 08:51:42 +00:00
void QQuickListViewPrivate : : updateHeader ( )
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
Q_Q ( QQuickListView ) ;
2011-07-26 05:33:58 +00:00
bool created = false ;
2011-07-05 05:07:05 +00:00
if ( ! header ) {
2012-05-25 07:33:02 +00:00
QQuickItem * item = createComponentItem ( headerComponent , 1.0 ) ;
2011-07-05 05:07:05 +00:00
if ( ! item )
return ;
2013-06-22 13:49:26 +00:00
header = new FxListItemSG ( item , q , true ) ;
header - > trackGeometry ( true ) ;
2011-07-26 05:33:58 +00:00
created = true ;
2011-04-27 12:13:26 +00:00
}
2011-07-05 05:07:05 +00:00
FxListItemSG * listItem = static_cast < FxListItemSG * > ( header ) ;
if ( listItem ) {
2011-04-27 12:13:26 +00:00
if ( visibleItems . count ( ) ) {
2014-03-03 14:53:27 +00:00
if ( headerPositioning = = QQuickListView : : OverlayHeader ) {
listItem - > setPosition ( isContentFlowReversed ( ) ? - position ( ) - size ( ) : position ( ) ) ;
} else if ( headerPositioning = = QQuickListView : : PullBackHeader ) {
qreal viewPos = isContentFlowReversed ( ) ? - position ( ) - size ( ) : position ( ) ;
qreal clampedPos = qBound ( originPosition ( ) - headerSize ( ) , listItem - > position ( ) , lastPosition ( ) - headerSize ( ) - size ( ) ) ;
listItem - > setPosition ( qBound ( viewPos - headerSize ( ) , clampedPos , viewPos ) ) ;
2011-04-27 12:13:26 +00:00
} else {
2014-03-03 14:53:27 +00:00
qreal startPos = originPosition ( ) ;
if ( visibleIndex = = 0 ) {
2011-07-05 05:07:05 +00:00
listItem - > setPosition ( startPos - headerSize ( ) ) ;
2014-03-03 14:53:27 +00:00
} else {
if ( position ( ) < = startPos | | listItem - > position ( ) > startPos - headerSize ( ) )
listItem - > setPosition ( startPos - headerSize ( ) ) ;
}
2011-04-27 12:13:26 +00:00
}
} else {
2011-07-14 03:55:20 +00:00
listItem - > setPosition ( - headerSize ( ) ) ;
2011-07-05 05:07:05 +00:00
}
}
2011-07-26 05:33:58 +00:00
if ( created )
emit q - > headerItemChanged ( ) ;
2011-07-05 05:07:05 +00:00
}
2014-03-03 14:53:27 +00:00
bool QQuickListViewPrivate : : hasStickyHeader ( ) const
{
return header & & headerPositioning ! = QQuickListView : : InlineHeader ;
}
bool QQuickListViewPrivate : : hasStickyFooter ( ) const
{
return footer & & footerPositioning ! = QQuickListView : : InlineFooter ;
}
2011-10-14 08:51:42 +00:00
void QQuickListViewPrivate : : itemGeometryChanged ( QQuickItem * item , const QRectF & newGeometry , const QRectF & oldGeometry )
2011-07-05 05:07:05 +00:00
{
2011-10-14 08:51:42 +00:00
Q_Q ( QQuickListView ) ;
QQuickItemViewPrivate : : itemGeometryChanged ( item , newGeometry , oldGeometry ) ;
2011-07-05 05:07:05 +00:00
if ( ! q - > isComponentComplete ( ) )
return ;
2012-04-30 02:55:45 +00:00
2011-07-05 05:07:05 +00:00
if ( item ! = contentItem & & ( ! highlight | | item ! = highlight - > item ) ) {
2011-10-14 08:51:42 +00:00
if ( ( orient = = QQuickListView : : Vertical & & newGeometry . height ( ) ! = oldGeometry . height ( ) )
| | ( orient = = QQuickListView : : Horizontal & & newGeometry . width ( ) ! = oldGeometry . width ( ) ) ) {
2012-04-30 02:55:45 +00:00
// if visibleItems.first() has resized, adjust its pos since it is used to
// position all subsequent items
if ( visibleItems . count ( ) & & item = = visibleItems . first ( ) - > item ) {
FxListItemSG * listItem = static_cast < FxListItemSG * > ( visibleItems . first ( ) ) ;
2014-05-02 13:46:12 +00:00
if ( listItem - > transitionScheduledOrRunning ( ) )
return ;
2012-05-01 07:48:34 +00:00
if ( orient = = QQuickListView : : Vertical ) {
2013-05-28 08:28:56 +00:00
const qreal oldItemEndPosition = verticalLayoutDirection = = QQuickItemView : : BottomToTop ? - oldGeometry . y ( ) : oldGeometry . y ( ) + oldGeometry . height ( ) ;
2012-04-30 02:55:45 +00:00
qreal diff = newGeometry . height ( ) - oldGeometry . height ( ) ;
2013-05-28 08:28:56 +00:00
if ( verticalLayoutDirection = = QQuickListView : : TopToBottom & & oldItemEndPosition < q - > contentY ( ) )
2012-04-30 02:55:45 +00:00
listItem - > setPosition ( listItem - > position ( ) - diff , true ) ;
2013-05-28 08:28:56 +00:00
else if ( verticalLayoutDirection = = QQuickListView : : BottomToTop & & oldItemEndPosition > q - > contentY ( ) )
2012-04-30 02:55:45 +00:00
listItem - > setPosition ( listItem - > position ( ) + diff , true ) ;
} else {
2013-05-28 08:28:56 +00:00
const qreal oldItemEndPosition = q - > effectiveLayoutDirection ( ) = = Qt : : RightToLeft ? - oldGeometry . x ( ) : oldGeometry . x ( ) + oldGeometry . width ( ) ;
2012-04-30 02:55:45 +00:00
qreal diff = newGeometry . width ( ) - oldGeometry . width ( ) ;
2013-05-28 08:28:56 +00:00
if ( q - > effectiveLayoutDirection ( ) = = Qt : : LeftToRight & & oldItemEndPosition < q - > contentX ( ) )
2012-04-30 02:55:45 +00:00
listItem - > setPosition ( listItem - > position ( ) - diff , true ) ;
2013-05-28 08:28:56 +00:00
else if ( q - > effectiveLayoutDirection ( ) = = Qt : : RightToLeft & & oldItemEndPosition > q - > contentX ( ) )
2012-04-30 02:55:45 +00:00
listItem - > setPosition ( listItem - > position ( ) + diff , true ) ;
}
}
2012-06-29 01:57:02 +00:00
forceLayoutPolish ( ) ;
2011-04-27 12:13:26 +00:00
}
}
}
2011-10-14 08:51:42 +00:00
void QQuickListViewPrivate : : fixupPosition ( )
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
if ( ( haveHighlightRange & & highlightRange = = QQuickListView : : StrictlyEnforceRange )
| | snapMode ! = QQuickListView : : NoSnap )
2011-04-27 12:13:26 +00:00
moveReason = Other ;
2011-10-14 08:51:42 +00:00
if ( orient = = QQuickListView : : Vertical )
2011-04-27 12:13:26 +00:00
fixupY ( ) ;
else
fixupX ( ) ;
}
2011-10-14 08:51:42 +00:00
void QQuickListViewPrivate : : fixup ( AxisData & data , qreal minExtent , qreal maxExtent )
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
if ( ( orient = = QQuickListView : : Horizontal & & & data = = & vData )
| | ( orient = = QQuickListView : : Vertical & & & data = = & hData ) )
2011-04-27 12:13:26 +00:00
return ;
correctFlick = false ;
fixupMode = moveReason = = Mouse ? fixupMode : Immediate ;
2011-10-14 08:51:42 +00:00
bool strictHighlightRange = haveHighlightRange & & highlightRange = = QQuickListView : : StrictlyEnforceRange ;
2011-04-27 12:13:26 +00:00
2012-03-20 01:37:10 +00:00
qreal viewPos = isContentFlowReversed ( ) ? - position ( ) - size ( ) : position ( ) ;
2011-04-27 12:13:26 +00:00
2011-10-14 08:51:42 +00:00
if ( snapMode ! = QQuickListView : : NoSnap & & moveReason ! = QQuickListViewPrivate : : SetIndex ) {
2012-03-20 01:37:10 +00:00
qreal tempPosition = isContentFlowReversed ( ) ? - position ( ) - size ( ) : position ( ) ;
2011-10-14 08:51:42 +00:00
if ( snapMode = = QQuickListView : : SnapOneItem & & moveReason = = Mouse ) {
2011-09-26 03:13:02 +00:00
// if we've been dragged < averageSize/2 then bias towards the next item
qreal dist = data . move . value ( ) - ( data . pressPos - data . dragStartOffset ) ;
qreal bias = 0 ;
if ( data . velocity > 0 & & dist > QML_FLICK_SNAPONETHRESHOLD & & dist < averageSize / 2 )
bias = averageSize / 2 ;
else if ( data . velocity < 0 & & dist < - QML_FLICK_SNAPONETHRESHOLD & & dist > - averageSize / 2 )
bias = - averageSize / 2 ;
2012-03-20 01:37:10 +00:00
if ( isContentFlowReversed ( ) )
2011-09-26 03:13:02 +00:00
bias = - bias ;
tempPosition - = bias ;
}
2011-10-13 07:41:51 +00:00
FxViewItem * topItem = snapItemAt ( tempPosition + highlightRangeStart ) ;
2011-09-26 03:13:02 +00:00
if ( ! topItem & & strictHighlightRange & & currentItem ) {
// StrictlyEnforceRange always keeps an item in range
updateHighlight ( ) ;
topItem = currentItem ;
}
2011-10-13 07:41:51 +00:00
FxViewItem * bottomItem = snapItemAt ( tempPosition + highlightRangeEnd ) ;
2011-09-26 03:13:02 +00:00
if ( ! bottomItem & & strictHighlightRange & & currentItem ) {
// StrictlyEnforceRange always keeps an item in range
updateHighlight ( ) ;
bottomItem = currentItem ;
}
2011-04-27 12:13:26 +00:00
qreal pos ;
2011-09-26 03:13:02 +00:00
bool isInBounds = - position ( ) > maxExtent & & - position ( ) < = minExtent ;
if ( topItem & & ( isInBounds | | strictHighlightRange ) ) {
2011-10-13 07:41:51 +00:00
if ( topItem - > index = = 0 & & header & & tempPosition + highlightRangeStart < header - > position ( ) + header - > size ( ) / 2 & & ! strictHighlightRange ) {
2012-03-20 01:37:10 +00:00
pos = isContentFlowReversed ( ) ? - header - > position ( ) + highlightRangeStart - size ( ) : header - > position ( ) - highlightRangeStart ;
2011-04-27 12:13:26 +00:00
} else {
2012-03-20 01:37:10 +00:00
if ( isContentFlowReversed ( ) )
2011-10-13 07:41:51 +00:00
pos = qMax ( qMin ( - topItem - > position ( ) + highlightRangeStart - size ( ) , - maxExtent ) , - minExtent ) ;
2011-04-27 12:13:26 +00:00
else
2011-10-13 07:41:51 +00:00
pos = qMax ( qMin ( topItem - > position ( ) - highlightRangeStart , - maxExtent ) , - minExtent ) ;
2011-04-27 12:13:26 +00:00
}
} else if ( bottomItem & & isInBounds ) {
2012-03-20 01:37:10 +00:00
if ( isContentFlowReversed ( ) )
2011-10-13 07:41:51 +00:00
pos = qMax ( qMin ( - bottomItem - > position ( ) + highlightRangeEnd - size ( ) , - maxExtent ) , - minExtent ) ;
2011-04-27 12:13:26 +00:00
else
2011-10-13 07:41:51 +00:00
pos = qMax ( qMin ( bottomItem - > position ( ) - highlightRangeEnd , - maxExtent ) , - minExtent ) ;
2011-04-27 12:13:26 +00:00
} else {
2011-10-14 08:51:42 +00:00
QQuickItemViewPrivate : : fixup ( data , minExtent , maxExtent ) ;
2011-04-27 12:13:26 +00:00
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 ( ) ;
}
2011-10-14 08:51:42 +00:00
} else if ( currentItem & & strictHighlightRange & & moveReason ! = QQuickListViewPrivate : : SetIndex ) {
2011-09-26 03:13:02 +00:00
updateHighlight ( ) ;
qreal pos = static_cast < FxListItemSG * > ( currentItem ) - > itemPosition ( ) ;
2011-10-13 07:41:51 +00:00
if ( viewPos < pos + static_cast < FxListItemSG * > ( currentItem ) - > itemSize ( ) - highlightRangeEnd )
viewPos = pos + static_cast < FxListItemSG * > ( currentItem ) - > itemSize ( ) - highlightRangeEnd ;
if ( viewPos > pos - highlightRangeStart )
viewPos = pos - highlightRangeStart ;
2012-03-20 01:37:10 +00:00
if ( isContentFlowReversed ( ) )
2011-09-26 03:13:02 +00:00
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 ( ) ;
2011-04-27 12:13:26 +00:00
} else {
2011-10-14 08:51:42 +00:00
QQuickItemViewPrivate : : fixup ( data , minExtent , maxExtent ) ;
2011-04-27 12:13:26 +00:00
}
2011-05-04 07:53:51 +00:00
data . inOvershoot = false ;
2011-04-27 12:13:26 +00:00
fixupMode = Normal ;
}
2012-06-04 03:34:57 +00:00
bool QQuickListViewPrivate : : flick ( AxisData & data , qreal minExtent , qreal maxExtent , qreal vSize ,
2012-02-16 04:43:03 +00:00
QQuickTimeLineCallback : : Callback fixupCallback , qreal velocity )
2011-04-27 12:13:26 +00:00
{
data . fixingUp = false ;
moveReason = Mouse ;
2011-10-14 08:51:42 +00:00
if ( ( ! haveHighlightRange | | highlightRange ! = QQuickListView : : StrictlyEnforceRange ) & & snapMode = = QQuickListView : : NoSnap ) {
2011-04-27 12:13:26 +00:00
correctFlick = true ;
2012-06-04 03:34:57 +00:00
return QQuickItemViewPrivate : : flick ( data , minExtent , maxExtent , vSize , fixupCallback , velocity ) ;
2011-04-27 12:13:26 +00:00
}
qreal maxDistance = 0 ;
2012-03-20 01:37:10 +00:00
qreal dataValue = isContentFlowReversed ( ) ? - data . move . value ( ) + size ( ) : data . move . value ( ) ;
2011-10-13 07:41:51 +00:00
2011-04-27 12:13:26 +00:00
// -ve velocity means list is moving up/left
if ( velocity > 0 ) {
if ( data . move . value ( ) < minExtent ) {
2011-10-14 08:51:42 +00:00
if ( snapMode = = QQuickListView : : SnapOneItem & & ! hData . flicking & & ! vData . flicking ) {
2011-09-26 03:13:02 +00:00
// 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 < averageSize / 2 ? averageSize / 2 : 0 ;
2012-03-20 01:37:10 +00:00
if ( isContentFlowReversed ( ) )
2011-09-26 03:13:02 +00:00
bias = - bias ;
2011-10-13 07:41:51 +00:00
data . flickTarget = - snapPosAt ( - ( dataValue - highlightRangeStart ) - bias ) + highlightRangeStart ;
2011-09-26 03:13:02 +00:00
maxDistance = qAbs ( data . flickTarget - data . move . value ( ) ) ;
velocity = maxVelocity ;
2011-04-27 12:13:26 +00:00
} else {
maxDistance = qAbs ( minExtent - data . move . value ( ) ) ;
}
}
2011-10-14 08:51:42 +00:00
if ( snapMode = = QQuickListView : : NoSnap & & highlightRange ! = QQuickListView : : StrictlyEnforceRange )
2011-04-27 12:13:26 +00:00
data . flickTarget = minExtent ;
} else {
if ( data . move . value ( ) > maxExtent ) {
2011-10-14 08:51:42 +00:00
if ( snapMode = = QQuickListView : : SnapOneItem & & ! hData . flicking & & ! vData . flicking ) {
2011-09-26 03:13:02 +00:00
// 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 < averageSize / 2 ? averageSize / 2 : 0 ;
2012-03-20 01:37:10 +00:00
if ( isContentFlowReversed ( ) )
2011-09-26 03:13:02 +00:00
bias = - bias ;
2011-10-13 07:41:51 +00:00
data . flickTarget = - snapPosAt ( - ( dataValue - highlightRangeStart ) + bias ) + highlightRangeStart ;
2011-09-26 03:13:02 +00:00
maxDistance = qAbs ( data . flickTarget - data . move . value ( ) ) ;
velocity = - maxVelocity ;
2011-04-27 12:13:26 +00:00
} else {
maxDistance = qAbs ( maxExtent - data . move . value ( ) ) ;
}
}
2011-10-14 08:51:42 +00:00
if ( snapMode = = QQuickListView : : NoSnap & & highlightRange ! = QQuickListView : : StrictlyEnforceRange )
2011-04-27 12:13:26 +00:00
data . flickTarget = maxExtent ;
}
2011-10-14 08:51:42 +00:00
bool overShoot = boundsBehavior = = QQuickFlickable : : DragAndOvershootBounds ;
2011-04-27 12:13:26 +00:00
if ( maxDistance > 0 | | overShoot ) {
// These modes require the list to stop exactly on an item boundary.
// The initial flick will estimate the boundary to stop on.
// Since list items can have variable sizes, the boundary will be
// reevaluated and adjusted as we approach the boundary.
qreal v = velocity ;
if ( maxVelocity ! = - 1 & & maxVelocity < qAbs ( v ) ) {
if ( v < 0 )
v = - maxVelocity ;
else
v = maxVelocity ;
}
2011-09-26 03:13:02 +00:00
if ( ! hData . flicking & & ! vData . flicking ) {
2011-04-27 12:13:26 +00:00
// the initial flick - estimate boundary
qreal accel = deceleration ;
qreal v2 = v * v ;
overshootDist = 0.0 ;
// + averageSize/4 to encourage moving at least one item in the flick direction
qreal dist = v2 / ( accel * 2.0 ) + averageSize / 4 ;
if ( maxDistance > 0 )
dist = qMin ( dist , maxDistance ) ;
if ( v > 0 )
dist = - dist ;
2011-10-14 08:51:42 +00:00
if ( ( maxDistance > 0.0 & & v2 / ( 2.0f * maxDistance ) < accel ) | | snapMode = = QQuickListView : : SnapOneItem ) {
if ( snapMode ! = QQuickListView : : SnapOneItem ) {
2012-03-20 01:37:10 +00:00
qreal distTemp = isContentFlowReversed ( ) ? - dist : dist ;
2011-10-13 07:41:51 +00:00
data . flickTarget = - snapPosAt ( - ( dataValue - highlightRangeStart ) + distTemp ) + highlightRangeStart ;
2011-09-26 03:13:02 +00:00
}
2012-03-20 01:37:10 +00:00
data . flickTarget = isContentFlowReversed ( ) ? - data . flickTarget + size ( ) : data . flickTarget ;
2011-04-27 12:13:26 +00:00
if ( overShoot ) {
if ( data . flickTarget > = minExtent ) {
2011-05-04 07:53:51 +00:00
overshootDist = overShootDistance ( vSize ) ;
2011-04-27 12:13:26 +00:00
data . flickTarget + = overshootDist ;
} else if ( data . flickTarget < = maxExtent ) {
2011-05-04 07:53:51 +00:00
overshootDist = overShootDistance ( vSize ) ;
2011-04-27 12:13:26 +00:00
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 if ( overShoot ) {
data . flickTarget = data . move . value ( ) - dist ;
if ( data . flickTarget > = minExtent ) {
2011-05-04 07:53:51 +00:00
overshootDist = overShootDistance ( vSize ) ;
2011-04-27 12:13:26 +00:00
data . flickTarget + = overshootDist ;
} else if ( data . flickTarget < = maxExtent ) {
2011-05-04 07:53:51 +00:00
overshootDist = overShootDistance ( vSize ) ;
2011-04-27 12:13:26 +00:00
data . flickTarget - = overshootDist ;
}
}
timeline . reset ( data . move ) ;
timeline . accel ( data . move , v , accel , maxDistance + overshootDist ) ;
2012-02-16 04:43:03 +00:00
timeline . callback ( QQuickTimeLineCallback ( & data . move , fixupCallback , this ) ) ;
2011-04-27 12:13:26 +00:00
correctFlick = true ;
2012-06-04 03:34:57 +00:00
return true ;
2011-04-27 12:13:26 +00:00
} else {
// reevaluate the target boundary.
qreal newtarget = data . flickTarget ;
2011-10-14 08:51:42 +00:00
if ( snapMode ! = QQuickListView : : NoSnap | | highlightRange = = QQuickListView : : StrictlyEnforceRange ) {
2012-03-20 01:37:10 +00:00
qreal tempFlickTarget = isContentFlowReversed ( ) ? - data . flickTarget + size ( ) : data . flickTarget ;
2011-10-13 07:41:51 +00:00
newtarget = - snapPosAt ( - ( tempFlickTarget - highlightRangeStart ) ) + highlightRangeStart ;
2012-03-20 01:37:10 +00:00
newtarget = isContentFlowReversed ( ) ? - newtarget + size ( ) : newtarget ;
2011-04-27 12:13:26 +00:00
}
if ( velocity < 0 & & newtarget < = maxExtent )
newtarget = maxExtent - overshootDist ;
else if ( velocity > 0 & & newtarget > = minExtent )
newtarget = minExtent + overshootDist ;
if ( newtarget = = data . flickTarget ) { // boundary unchanged - nothing to do
if ( qAbs ( velocity ) < MinimumFlickVelocity )
correctFlick = false ;
2012-06-04 03:34:57 +00:00
return false ;
2011-04-27 12:13:26 +00:00
}
data . flickTarget = newtarget ;
qreal dist = - newtarget + data . move . value ( ) ;
if ( ( v < 0 & & dist < 0 ) | | ( v > 0 & & dist > 0 ) ) {
correctFlick = false ;
timeline . reset ( data . move ) ;
fixup ( data , minExtent , maxExtent ) ;
2012-06-04 03:34:57 +00:00
return false ;
2011-04-27 12:13:26 +00:00
}
timeline . reset ( data . move ) ;
timeline . accelDistance ( data . move , v , - dist ) ;
2012-02-16 04:43:03 +00:00
timeline . callback ( QQuickTimeLineCallback ( & data . move , fixupCallback , this ) ) ;
2012-06-04 03:34:57 +00:00
return false ;
2011-04-27 12:13:26 +00:00
}
} else {
correctFlick = false ;
timeline . reset ( data . move ) ;
fixup ( data , minExtent , maxExtent ) ;
2012-06-04 03:34:57 +00:00
return false ;
2011-07-05 05:07:05 +00:00
}
2011-04-27 12:13:26 +00:00
}
2011-07-05 05:07:05 +00:00
//----------------------------------------------------------------------------
2011-08-08 08:03:31 +00:00
/*!
2012-07-27 15:18:12 +00:00
\ qmltype ListView
\ instantiates QQuickListView
2013-09-24 14:41:12 +00:00
\ inqmlmodule QtQuick
2012-05-28 17:40:02 +00:00
\ ingroup qtquick - views
2011-08-08 08:03:31 +00:00
\ inherits Flickable
2012-05-18 13:19:55 +00:00
\ brief Provides a list view of items provided by a model
2011-08-08 08:03:31 +00:00
2012-07-11 06:29:42 +00:00
A ListView displays data from models created from built - in QML types like ListModel
2011-08-08 08:03:31 +00:00
and XmlListModel , or custom model classes defined in C + + that inherit from
2013-05-08 05:14:25 +00:00
QAbstractItemModel or QAbstractListModel .
2011-08-08 08:03:31 +00:00
A ListView 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
ListView are laid out horizontally or vertically . List views are inherently
flickable because ListView 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 :
2012-05-28 01:56:24 +00:00
\ snippet qml / listview / ContactModel . qml 0
2011-08-08 08:03:31 +00:00
Another component can display this model data in a ListView , like this :
2012-05-28 01:56:24 +00:00
\ snippet qml / listview / listview . qml import
2011-08-08 08:03:31 +00:00
\ codeline
2012-05-28 01:56:24 +00:00
\ snippet qml / listview / listview . qml classdocs simple
2011-08-08 08:03:31 +00:00
\ image listview - simple . png
2012-07-11 06:29:42 +00:00
Here , the ListView creates a \ c ContactModel component for its model , and a \ l Text item
2011-08-08 08:03:31 +00:00
for its delegate . The view will create a new \ l Text component for each item in the model . Notice
the delegate is able to access the model ' s \ c name and \ c number data directly .
An improved list view is shown below . The delegate is visually improved and is moved
into a separate \ c contactDelegate component .
2012-05-28 01:56:24 +00:00
\ snippet qml / listview / listview . qml classdocs advanced
2011-08-08 08:03:31 +00:00
\ image listview - highlight . png
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 list view .
2012-08-02 03:06:09 +00:00
The list view itself is a focus scope ( see \ l { Keyboard Focus in Qt Quick } for more details ) .
2011-08-08 08:03:31 +00:00
Delegates are instantiated as needed and may be destroyed at any time .
2013-08-04 10:12:26 +00:00
They are parented to ListView ' s \ l { Flickable : : contentItem } { contentItem } , not to the view itself .
2011-08-08 08:03:31 +00:00
State should \ e never be stored in a delegate .
ListView attaches a number of properties to the root item of the delegate , for example
2012-08-02 03:06:09 +00:00
\ c { ListView : isCurrentItem } . In the following example , the root delegate item can access
2011-08-08 08:03:31 +00:00
this attached property directly as \ c ListView . isCurrentItem , while the child
\ c contactInfo object must refer to this property as \ c wrapper . ListView . isCurrentItem .
2012-05-28 01:56:24 +00:00
\ snippet qml / listview / listview . qml isCurrentItem
2011-08-08 08:03:31 +00:00
\ note Views do not enable \ e clip automatically . If the view
is not clipped by another item or the screen , it will be necessary
to set \ e { clip : true } in order to have the out of view items clipped
nicely .
2012-03-20 01:37:10 +00:00
\ section1 ListView layouts
The layout of the items in a ListView can be controlled by these properties :
\ list
\ li \ l orientation - controls whether items flow horizontally or vertically .
This value can be either Qt . Horizontal or Qt . Vertical .
\ li \ l layoutDirection - controls the horizontal layout direction for a
horizontally - oriented view : that is , whether items are laid out from the left side of
the view to the right , or vice - versa . This value can be either Qt . LeftToRight or Qt . RightToLeft .
\ li \ l verticalLayoutDirection - controls the vertical layout direction for a vertically - oriented
view : that is , whether items are laid out from the top of the view down towards the bottom of
the view , or vice - versa . This value can be either ListView . TopToBottom or ListView . BottomToTop .
\ endlist
By default , a ListView has a vertical orientation , and items are laid out from top to bottom . The
table below shows the different layouts that a ListView can have , depending on the values of
the properties listed above .
\ table
\ header
\ li { 2 , 1 }
2012-08-01 04:03:49 +00:00
\ b ListViews with Qt . Vertical orientation
2012-03-20 01:37:10 +00:00
\ row
\ li Top to bottom
\ image listview - layout - toptobottom . png
\ li Bottom to top
\ image listview - layout - bottomtotop . png
\ header
\ li { 2 , 1 }
2012-08-01 04:03:49 +00:00
\ b ListViews with Qt . Horizontal orientation
2012-03-20 01:37:10 +00:00
\ row
\ li Left to right
\ image listview - layout - lefttoright . png
\ li Right to left
\ image listview - layout - righttoleft . png
\ endtable
2013-11-05 12:17:06 +00:00
\ sa { QML Data Models } , GridView , PathView , { Qt Quick Examples - Views }
2011-08-08 08:03:31 +00:00
*/
2011-10-14 08:51:42 +00:00
QQuickListView : : QQuickListView ( QQuickItem * parent )
: QQuickItemView ( * ( new QQuickListViewPrivate ) , parent )
2011-04-27 12:13:26 +00:00
{
}
2011-10-14 08:51:42 +00:00
QQuickListView : : ~ QQuickListView ( )
2011-04-27 12:13:26 +00:00
{
}
2011-08-08 08:03:31 +00:00
/*!
2013-10-01 11:03:28 +00:00
\ qmlattachedproperty bool QtQuick : : ListView : : isCurrentItem
2011-08-08 08:03:31 +00:00
This attached property is true if this delegate is the current item ; otherwise false .
It is attached to each instance of the delegate .
This property may be used to adjust the appearance of the current item , for example :
2012-05-28 01:56:24 +00:00
\ snippet qml / listview / listview . qml isCurrentItem
2011-08-08 08:03:31 +00:00
*/
/*!
2013-10-01 11:03:28 +00:00
\ qmlattachedproperty ListView QtQuick : : ListView : : view
2011-08-08 08:03:31 +00:00
This attached property holds the view that manages this delegate instance .
2013-10-07 09:55:12 +00:00
It is attached to each instance of the delegate and also to the header , the footer ,
the section and the highlight delegates .
2011-08-08 08:03:31 +00:00
*/
/*!
2013-10-01 11:03:28 +00:00
\ qmlattachedproperty string QtQuick : : ListView : : previousSection
2011-08-08 08:03:31 +00:00
This attached property holds the section of the previous element .
It is attached to each instance of the delegate .
The section is evaluated using the \ l { ListView : : section . property } { section } properties .
*/
/*!
2013-10-01 11:03:28 +00:00
\ qmlattachedproperty string QtQuick : : ListView : : nextSection
2011-08-08 08:03:31 +00:00
This attached property holds the section of the next element .
It is attached to each instance of the delegate .
The section is evaluated using the \ l { ListView : : section . property } { section } properties .
*/
/*!
2013-10-01 11:03:28 +00:00
\ qmlattachedproperty string QtQuick : : ListView : : section
2011-08-08 08:03:31 +00:00
This attached property holds the section of this element .
It is attached to each instance of the delegate .
The section is evaluated using the \ l { ListView : : section . property } { section } properties .
*/
/*!
2013-10-01 11:03:28 +00:00
\ qmlattachedproperty bool QtQuick : : ListView : : delayRemove
2011-08-08 08:03:31 +00:00
2012-02-09 07:59:44 +00:00
This attached property holds whether the delegate may be destroyed . It
is attached to each instance of the delegate . The default value is false .
2011-08-08 08:03:31 +00:00
It is sometimes necessary to delay the destruction of an item
2012-02-09 07:59:44 +00:00
until an animation completes . The example delegate below ensures that the
animation completes before the item is removed from the list .
2011-08-08 08:03:31 +00:00
2012-05-28 01:56:24 +00:00
\ snippet qml / listview / listview . qml delayRemove
2012-02-09 07:59:44 +00:00
If a \ l remove transition has been specified , it will not be applied until
delayRemove is returned to \ c false .
2011-08-08 08:03:31 +00:00
*/
/*!
2014-03-20 13:57:03 +00:00
\ qmlattachedsignal QtQuick : : ListView : : add ( )
This attached signal is emitted immediately after an item is added to the view .
2012-02-09 07:59:44 +00:00
If an \ l add transition is specified , it is applied immediately after
2014-03-20 13:57:03 +00:00
this signal is handled .
The corresponding handler is \ c onAdd .
2011-08-08 08:03:31 +00:00
*/
/*!
2014-03-20 13:57:03 +00:00
\ qmlattachedsignal QtQuick : : ListView : : remove ( )
This attached signal is emitted immediately before an item is removed from the view .
2012-02-09 07:59:44 +00:00
If a \ l remove transition has been specified , it is applied after
2014-03-20 13:57:03 +00:00
this signal is handled , providing that \ l delayRemove is false .
The corresponding handler is \ c onRemove .
2011-08-08 08:03:31 +00:00
*/
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty model QtQuick : : ListView : : model
2011-08-08 08:03:31 +00:00
This property holds the model providing data for the list .
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 .
2012-08-02 03:06:09 +00:00
\ sa { qml - data - models } { Data Models }
2011-08-08 08:03:31 +00:00
*/
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty Component QtQuick : : ListView : : delegate
2011-08-08 08:03:31 +00:00
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
2012-08-02 03:06:09 +00:00
model are also available depending upon the type of \ l { qml - data - models } { Data Model } .
2011-08-08 08:03:31 +00:00
2012-07-11 06:29:42 +00:00
The number of objects and bindings in the delegate has a direct effect on the
2011-08-08 08:03:31 +00:00
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
2012-07-11 06:29:42 +00:00
can load additional components when needed .
2011-08-08 08:03:31 +00:00
The ListView will lay out the items based on the size of the root item
in the delegate .
2011-11-04 05:32:58 +00:00
It is recommended that the delegate ' s size be a whole number to avoid sub - pixel
2011-08-08 08:03:31 +00:00
alignment of items .
2014-03-10 14:58:10 +00:00
The default \ l { QQuickItem : : z } { stacking order } of delegate instances is \ c 1.
2011-08-08 08:03:31 +00:00
\ note Delegates are instantiated as needed and may be destroyed at any time .
2013-08-04 10:12:26 +00:00
They are parented to ListView ' s \ l { Flickable : : contentItem } { contentItem } , not to the view itself .
2011-08-08 08:03:31 +00:00
State should \ e never be stored in a delegate .
*/
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty int QtQuick : : ListView : : currentIndex
\ qmlproperty Item QtQuick : : ListView : : currentItem
2011-08-08 08:03:31 +00:00
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 ListView 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 .
*/
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty Item QtQuick : : ListView : : highlightItem
2011-08-08 08:03:31 +00:00
This holds the highlight item created from the \ l highlight component .
The \ c highlightItem is managed by the view unless
\ l highlightFollowsCurrentItem is set to false .
2014-03-10 14:58:10 +00:00
The default \ l { QQuickItem : : z } { stacking order }
of the highlight item is \ c 0.
2011-08-08 08:03:31 +00:00
\ sa highlight , highlightFollowsCurrentItem
*/
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty int QtQuick : : ListView : : count
2011-08-08 08:03:31 +00:00
This property holds the number of items in the view .
*/
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty Component QtQuick : : ListView : : highlight
2011-08-08 08:03:31 +00:00
This property holds the component to use as the highlight .
An instance of the highlight component is created for each list .
The geometry of the resulting component instance is managed by the list
so as to stay with the current item , unless the highlightFollowsCurrentItem
2014-03-10 14:58:10 +00:00
property is false . The default \ l { QQuickItem : : z } { stacking order } of the
highlight item is \ c 0.
2011-08-08 08:03:31 +00:00
2013-11-05 12:17:06 +00:00
\ sa highlightItem , highlightFollowsCurrentItem ,
2014-04-08 11:24:42 +00:00
{ Qt Quick Examples - Views # Highlight } { ListView highlight example }
2011-08-08 08:03:31 +00:00
*/
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty bool QtQuick : : ListView : : highlightFollowsCurrentItem
2011-08-08 08:03:31 +00:00
This property holds 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 :
2012-05-28 01:56:24 +00:00
\ snippet qml / listview / listview . qml highlightFollowsCurrentItem
2011-08-08 08:03:31 +00:00
Note that the highlight animation also affects the way that the view
is scrolled . This is because the view moves to maintain the
highlight within the preferred highlight range ( or visible viewport ) .
2012-06-25 03:05:15 +00:00
\ sa highlight , highlightMoveVelocity
2011-08-08 08:03:31 +00:00
*/
//###Possibly rename these properties, since they are very useful even without a highlight?
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty real QtQuick : : ListView : : preferredHighlightBegin
\ qmlproperty real QtQuick : : ListView : : preferredHighlightEnd
\ qmlproperty enumeration QtQuick : : ListView : : highlightRangeMode
2011-08-08 08:03:31 +00:00
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 list is scrolled .
For example , if the currently selected item should stay in the middle of the
list when the view 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 list 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
2012-03-01 17:05:16 +00:00
\ li ListView . ApplyRange - the view attempts to maintain the highlight within the range .
2011-08-08 08:03:31 +00:00
However , the highlight can move outside of the range at the ends of the list or due
to mouse interaction .
2012-03-01 17:05:16 +00:00
\ li ListView . StrictlyEnforceRange - the highlight never moves outside of the range .
2011-08-08 08:03:31 +00:00
The current item changes if a keyboard or mouse action would cause the highlight to move
outside of the range .
2012-03-01 17:05:16 +00:00
\ li ListView . NoHighlightRange - this is the default value .
2011-08-08 08:03:31 +00:00
\ endlist
*/
2011-10-14 08:51:42 +00:00
void QQuickListView : : setHighlightFollowsCurrentItem ( bool autoHighlight )
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
Q_D ( QQuickListView ) ;
2011-07-05 05:07:05 +00:00
if ( d - > autoHighlight ! = autoHighlight ) {
if ( ! autoHighlight ) {
if ( d - > highlightPosAnimator )
d - > highlightPosAnimator - > stop ( ) ;
2013-12-04 21:18:36 +00:00
if ( d - > highlightWidthAnimator )
d - > highlightWidthAnimator - > stop ( ) ;
if ( d - > highlightHeightAnimator )
d - > highlightHeightAnimator - > stop ( ) ;
2011-07-05 05:07:05 +00:00
}
2011-10-14 08:51:42 +00:00
QQuickItemView : : setHighlightFollowsCurrentItem ( autoHighlight ) ;
2011-07-05 05:07:05 +00:00
}
2011-04-27 12:13:26 +00:00
}
2011-08-08 08:03:31 +00:00
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty real QtQuick : : ListView : : spacing
2011-08-08 08:03:31 +00:00
This property holds the spacing between items .
The default value is 0.
*/
2011-10-14 08:51:42 +00:00
qreal QQuickListView : : spacing ( ) const
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
Q_D ( const QQuickListView ) ;
2011-04-27 12:13:26 +00:00
return d - > spacing ;
}
2011-10-14 08:51:42 +00:00
void QQuickListView : : setSpacing ( qreal spacing )
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
Q_D ( QQuickListView ) ;
2011-04-27 12:13:26 +00:00
if ( spacing ! = d - > spacing ) {
d - > spacing = spacing ;
2012-06-29 01:57:02 +00:00
d - > forceLayoutPolish ( ) ;
2011-04-27 12:13:26 +00:00
emit spacingChanged ( ) ;
}
}
2011-08-08 08:03:31 +00:00
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty enumeration QtQuick : : ListView : : orientation
2011-08-08 08:03:31 +00:00
This property holds the orientation of the list .
Possible values :
\ list
2012-03-01 17:05:16 +00:00
\ li ListView . Horizontal - Items are laid out horizontally
\ li ListView . Vertical ( default ) - Items are laid out vertically
2011-08-08 08:03:31 +00:00
\ endlist
\ table
\ row
2012-03-01 17:05:16 +00:00
\ li Horizontal orientation :
2011-08-08 08:03:31 +00:00
\ image ListViewHorizontal . png
\ row
2012-03-01 17:05:16 +00:00
\ li Vertical orientation :
2011-08-08 08:03:31 +00:00
\ image listview - highlight . png
\ endtable
*/
2011-10-14 08:51:42 +00:00
QQuickListView : : Orientation QQuickListView : : orientation ( ) const
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
Q_D ( const QQuickListView ) ;
2011-04-27 12:13:26 +00:00
return d - > orient ;
}
2011-10-14 08:51:42 +00:00
void QQuickListView : : setOrientation ( QQuickListView : : Orientation orientation )
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
Q_D ( QQuickListView ) ;
2011-04-27 12:13:26 +00:00
if ( d - > orient ! = orientation ) {
d - > orient = orientation ;
2011-07-05 05:07:05 +00:00
if ( d - > orient = = Vertical ) {
2011-04-27 12:13:26 +00:00
setContentWidth ( - 1 ) ;
setFlickableDirection ( VerticalFlick ) ;
2011-05-04 07:53:51 +00:00
setContentX ( 0 ) ;
2011-04-27 12:13:26 +00:00
} else {
setContentHeight ( - 1 ) ;
setFlickableDirection ( HorizontalFlick ) ;
2011-05-04 07:53:51 +00:00
setContentY ( 0 ) ;
2011-04-27 12:13:26 +00:00
}
2014-07-23 07:51:37 +00:00
d - > regenerate ( true ) ;
2011-04-27 12:13:26 +00:00
emit orientationChanged ( ) ;
}
}
2011-08-08 08:03:31 +00:00
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty enumeration QtQuick : : ListView : : layoutDirection
2012-03-20 01:37:10 +00:00
This property holds the layout direction of a horizontally - oriented list .
2011-08-08 08:03:31 +00:00
Possible values :
\ list
2012-03-01 17:05:16 +00:00
\ li Qt . LeftToRight ( default ) - Items will be laid out from left to right .
\ li Qt . RightToLeft - Items will be laid out from right to let .
2011-08-08 08:03:31 +00:00
\ endlist
2012-03-20 01:37:10 +00:00
Setting this property has no effect if the \ l orientation is Qt . Vertical .
\ sa ListView : : effectiveLayoutDirection , ListView : : verticalLayoutDirection
2011-08-08 08:03:31 +00:00
*/
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty enumeration QtQuick : : ListView : : effectiveLayoutDirection
2012-03-20 01:37:10 +00:00
This property holds the effective layout direction of a horizontally - oriented list .
2011-08-08 08:03:31 +00:00
When using the attached property \ l { LayoutMirroring : : enabled } { LayoutMirroring : : enabled } for locale layouts ,
the visual layout direction of the horizontal list will be mirrored . However , the
property \ l { ListView : : layoutDirection } { layoutDirection } will remain unchanged .
\ sa ListView : : layoutDirection , { LayoutMirroring } { LayoutMirroring }
*/
2012-03-20 01:37:10 +00:00
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty enumeration QtQuick : : ListView : : verticalLayoutDirection
2012-03-20 01:37:10 +00:00
This property holds the layout direction of a vertically - oriented list .
Possible values :
\ list
\ li ListView . TopToBottom ( default ) - Items are laid out from the top of the view down to the bottom of the view .
\ li ListView . BottomToTop - Items are laid out from the bottom of the view up to the top of the view .
\ endlist
Setting this property has no effect if the \ l orientation is Qt . Horizontal .
\ sa ListView : : layoutDirection
*/
2011-08-08 08:03:31 +00:00
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty bool QtQuick : : ListView : : keyNavigationWraps
2011-08-08 08:03:31 +00:00
This property holds whether the list wraps key navigation .
If this is true , key navigation that would move the current item selection
past the end of the list instead wraps around and moves the selection to
the start of the list , and vice - versa .
By default , key navigation is not wrapped .
*/
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty int QtQuick : : ListView : : cacheBuffer
2011-08-08 08:03:31 +00:00
This property determines whether delegates are retained outside the
visible area of the view .
2014-05-06 10:22:32 +00:00
If this value is greater than zero , the view may keep as many delegates
2011-08-08 08:03:31 +00:00
instantiated as it can 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
2011-11-03 05:52:13 +00:00
area may be created / retained . The buffered delegates are created asynchronously ,
allowing creation to occur across multiple frames and reducing the
likelihood of skipping frames . In order to improve painting performance
2012-06-11 23:19:35 +00:00
delegates outside the visible area are not painted .
The default value of this property is platform dependent , but will usually
2014-05-06 10:22:32 +00:00
be a value greater than zero . Negative values are ignored .
2011-08-08 08:03:31 +00:00
Note that cacheBuffer is not a pixel buffer - it only maintains additional
instantiated delegates .
Setting this value can improve the smoothness of scrolling behavior at the expense
of additional memory usage . It is not a substitute for creating efficient
2012-07-11 06:29:42 +00:00
delegates ; the fewer objects and bindings in a delegate , the faster a view can be
2011-08-08 08:03:31 +00:00
scrolled .
2013-08-29 07:48:29 +00:00
The cacheBuffer operates outside of any display margins specified by
displayMarginBeginning or displayMarginEnd .
2011-08-08 08:03:31 +00:00
*/
2013-08-29 07:48:29 +00:00
/*!
\ qmlproperty int QtQuick : : ListView : : displayMarginBeginning
\ qmlproperty int QtQuick : : ListView : : displayMarginEnd
\ since QtQuick 2.3
This property allows delegates to be displayed outside of the view geometry .
If this value is non - zero , the view will create extra delegates before the
start of the view , or after the end . The view will create as many delegates
as it can fit into the pixel size specified .
For example , if in a vertical view the delegate is 20 pixels high and
\ c displayMarginBeginning and \ c displayMarginEnd are both set to 40 ,
then 2 delegates above and 2 delegates below will be created and shown .
The default value is 0.
This property is meant for allowing certain UI configurations ,
and not as a performance optimization . If you wish to create delegates
outside of the view geometry for performance reasons , you probably
want to use the cacheBuffer property instead .
*/
2011-08-08 08:03:31 +00:00
/*!
2013-12-18 16:45:52 +00:00
\ qmlpropertygroup QtQuick : : ListView : : section
2013-10-01 11:03:28 +00:00
\ qmlproperty string QtQuick : : ListView : : section . property
\ qmlproperty enumeration QtQuick : : ListView : : section . criteria
\ qmlproperty Component QtQuick : : ListView : : section . delegate
\ qmlproperty enumeration QtQuick : : ListView : : section . labelPositioning
2011-08-08 08:03:31 +00:00
2011-09-20 05:58:05 +00:00
These properties determine the expression to be evaluated and appearance
of the section labels .
2011-08-08 08:03:31 +00:00
\ c section . property holds the name of the property that is the basis
of each section .
\ c section . criteria holds the criteria for forming each section based on
\ c section . property . This value can be one of :
\ list
2012-03-01 17:05:16 +00:00
\ li ViewSection . FullString ( default ) - sections are created based on the
2011-08-08 08:03:31 +00:00
\ c section . property value .
2012-03-01 17:05:16 +00:00
\ li ViewSection . FirstCharacter - sections are created based on the first
2011-08-08 08:03:31 +00:00
character of the \ c section . property value ( for example , ' A ' , ' B ' , ' C '
sections , etc . for an address book )
\ endlist
2012-03-27 23:17:02 +00:00
A case insensitive comparison is used when determining section
boundaries .
2014-03-10 14:58:10 +00:00
\ c section . delegate holds the delegate component for each section . The
default \ l { QQuickItem : : z } { stacking order } of section delegate instances
is \ c 2.
2011-08-08 08:03:31 +00:00
2011-09-20 05:58:05 +00:00
\ c section . labelPositioning determines whether the current and / or
next section labels stick to the start / end of the view , and whether
the labels are shown inline . This value can be a combination of :
\ list
2012-03-01 17:05:16 +00:00
\ li ViewSection . InlineLabels - section labels are shown inline between
2011-09-20 05:58:05 +00:00
the item delegates separating sections ( default ) .
2012-03-01 17:05:16 +00:00
\ li ViewSection . CurrentLabelAtStart - the current section label sticks to the
2011-09-20 05:58:05 +00:00
start of the view as it is moved .
2012-03-01 17:05:16 +00:00
\ li ViewSection . NextLabelAtEnd - the next section label ( beyond all visible
2011-09-20 05:58:05 +00:00
sections ) sticks to the end of the view as it is moved . \ note Enabling
\ c ViewSection . NextLabelAtEnd requires the view to scan ahead for the next
section , which has performance implications , especially for slower models .
\ endlist
2011-08-08 08:03:31 +00:00
Each item in the list has attached properties named \ c ListView . section ,
2011-09-20 05:58:05 +00:00
\ c ListView . previousSection and \ c ListView . nextSection .
2011-08-08 08:03:31 +00:00
For example , here is a ListView that displays a list of animals , separated
into sections . Each item in the ListView is placed in a different section
depending on the " size " property of the model item . The \ c sectionHeading
delegate component provides the light blue bar that marks the beginning of
each section .
2013-05-05 00:08:41 +00:00
\ snippet views / listview / sections . qml 0
2011-08-08 08:03:31 +00:00
\ image qml - listview - sections - example . png
\ note Adding sections to a ListView does not automatically re - order the
list items by the section criteria .
If the model is not ordered by section , then it is possible that
the sections created will not be unique ; each boundary between
differing sections will result in a section header being created
even if that section exists elsewhere .
2014-04-08 11:24:42 +00:00
\ sa { Qt Quick Examples - Views } { ListView examples }
2011-08-08 08:03:31 +00:00
*/
2011-10-14 08:51:42 +00:00
QQuickViewSection * QQuickListView : : sectionCriteria ( )
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
Q_D ( QQuickListView ) ;
2012-06-29 01:57:02 +00:00
if ( ! d - > sectionCriteria )
2011-10-14 08:51:42 +00:00
d - > sectionCriteria = new QQuickViewSection ( this ) ;
2011-04-27 12:13:26 +00:00
return d - > sectionCriteria ;
}
2011-08-08 08:03:31 +00:00
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty string QtQuick : : ListView : : currentSection
2011-08-08 08:03:31 +00:00
This property holds the section that is currently at the beginning of the view .
*/
2011-10-14 08:51:42 +00:00
QString QQuickListView : : currentSection ( ) const
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
Q_D ( const QQuickListView ) ;
2011-04-27 12:13:26 +00:00
return d - > currentSection ;
}
2011-08-08 08:03:31 +00:00
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty real QtQuick : : ListView : : highlightMoveVelocity
\ qmlproperty int QtQuick : : ListView : : highlightMoveDuration
\ qmlproperty real QtQuick : : ListView : : highlightResizeVelocity
\ qmlproperty int QtQuick : : ListView : : highlightResizeDuration
2011-08-08 08:03:31 +00:00
2012-06-25 03:05:15 +00:00
These properties control the speed of the move and resize animations for the
highlight delegate .
2011-08-08 08:03:31 +00:00
\ l highlightFollowsCurrentItem must be true for these properties
to have effect .
2012-06-25 03:05:15 +00:00
The default value for the velocity properties is 400 pixels / second .
2012-06-25 01:30:01 +00:00
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 .
2011-08-08 08:03:31 +00:00
\ sa highlightFollowsCurrentItem
*/
2012-06-25 03:05:15 +00:00
qreal QQuickListView : : highlightMoveVelocity ( ) const
2012-06-25 01:30:01 +00:00
{
Q_D ( const QQuickListView ) ;
2012-06-25 03:05:15 +00:00
return d - > highlightMoveVelocity ;
2012-06-25 01:30:01 +00:00
}
2012-06-25 03:05:15 +00:00
void QQuickListView : : setHighlightMoveVelocity ( qreal speed )
2012-06-25 01:30:01 +00:00
{
Q_D ( QQuickListView ) ;
2012-06-25 03:05:15 +00:00
if ( d - > highlightMoveVelocity ! = speed ) {
d - > highlightMoveVelocity = speed ;
2012-06-25 01:30:01 +00:00
if ( d - > highlightPosAnimator )
2012-06-25 03:05:15 +00:00
d - > highlightPosAnimator - > velocity = d - > highlightMoveVelocity ;
emit highlightMoveVelocityChanged ( ) ;
2012-06-25 01:30:01 +00:00
}
}
2011-10-14 08:51:42 +00:00
void QQuickListView : : setHighlightMoveDuration ( int duration )
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
Q_D ( QQuickListView ) ;
2011-04-27 12:13:26 +00:00
if ( d - > highlightMoveDuration ! = duration ) {
if ( d - > highlightPosAnimator )
2011-07-05 05:07:05 +00:00
d - > highlightPosAnimator - > userDuration = duration ;
2011-10-14 08:51:42 +00:00
QQuickItemView : : setHighlightMoveDuration ( duration ) ;
2011-04-27 12:13:26 +00:00
}
}
2012-06-25 03:05:15 +00:00
qreal QQuickListView : : highlightResizeVelocity ( ) const
2012-06-25 01:30:01 +00:00
{
Q_D ( const QQuickListView ) ;
2012-06-25 03:05:15 +00:00
return d - > highlightResizeVelocity ;
2012-06-25 01:30:01 +00:00
}
2012-06-25 03:05:15 +00:00
void QQuickListView : : setHighlightResizeVelocity ( qreal speed )
2012-06-25 01:30:01 +00:00
{
Q_D ( QQuickListView ) ;
2012-06-25 03:05:15 +00:00
if ( d - > highlightResizeVelocity ! = speed ) {
d - > highlightResizeVelocity = speed ;
2013-12-04 21:18:36 +00:00
if ( d - > highlightWidthAnimator )
d - > highlightWidthAnimator - > velocity = d - > highlightResizeVelocity ;
if ( d - > highlightHeightAnimator )
d - > highlightHeightAnimator - > velocity = d - > highlightResizeVelocity ;
2012-06-25 03:05:15 +00:00
emit highlightResizeVelocityChanged ( ) ;
2012-06-25 01:30:01 +00:00
}
}
2011-10-14 08:51:42 +00:00
int QQuickListView : : highlightResizeDuration ( ) const
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
Q_D ( const QQuickListView ) ;
2011-04-27 12:13:26 +00:00
return d - > highlightResizeDuration ;
}
2011-10-14 08:51:42 +00:00
void QQuickListView : : setHighlightResizeDuration ( int duration )
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
Q_D ( QQuickListView ) ;
2011-04-27 12:13:26 +00:00
if ( d - > highlightResizeDuration ! = duration ) {
d - > highlightResizeDuration = duration ;
2013-12-04 21:18:36 +00:00
if ( d - > highlightWidthAnimator )
d - > highlightWidthAnimator - > userDuration = d - > highlightResizeDuration ;
if ( d - > highlightHeightAnimator )
d - > highlightHeightAnimator - > userDuration = d - > highlightResizeDuration ;
2011-04-27 12:13:26 +00:00
emit highlightResizeDurationChanged ( ) ;
}
}
2011-08-08 08:03:31 +00:00
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty enumeration QtQuick : : ListView : : snapMode
2011-08-08 08:03:31 +00:00
This property determines how the view scrolling will settle following a drag or flick .
The possible values are :
\ list
2012-03-01 17:05:16 +00:00
\ li ListView . NoSnap ( default ) - the view stops anywhere within the visible area .
\ li ListView . SnapToItem - the view settles with an item aligned with the start of
2011-08-08 08:03:31 +00:00
the view .
2012-03-01 17:05:16 +00:00
\ li ListView . SnapOneItem - the view settles no more than one item away from the first
2011-08-08 08:03:31 +00:00
visible item at the time the mouse button is released . This mode is particularly
useful for moving one page at a time .
\ endlist
\ c snapMode does not affect the \ l currentIndex . To update the
\ l currentIndex as the list is moved , set \ l highlightRangeMode
to \ c ListView . StrictlyEnforceRange .
\ sa highlightRangeMode
*/
2011-10-14 08:51:42 +00:00
QQuickListView : : SnapMode QQuickListView : : snapMode ( ) const
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
Q_D ( const QQuickListView ) ;
2011-04-27 12:13:26 +00:00
return d - > snapMode ;
}
2011-10-14 08:51:42 +00:00
void QQuickListView : : setSnapMode ( SnapMode mode )
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
Q_D ( QQuickListView ) ;
2011-04-27 12:13:26 +00:00
if ( d - > snapMode ! = mode ) {
d - > snapMode = mode ;
emit snapModeChanged ( ) ;
2013-07-05 08:49:55 +00:00
d - > fixupPosition ( ) ;
2011-04-27 12:13:26 +00:00
}
}
2011-08-08 08:03:31 +00:00
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty Component QtQuick : : ListView : : footer
2011-08-08 08:03:31 +00:00
This property holds the component to use as the footer .
An instance of the footer component is created for each view . The
2014-03-10 14:58:10 +00:00
footer is positioned at the end of the view , after any items . The
default \ l { QQuickItem : : z } { stacking order } of the footer is \ c 1.
2011-08-08 08:03:31 +00:00
2011-12-05 05:40:31 +00:00
\ sa header , footerItem
2011-08-08 08:03:31 +00:00
*/
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty Component QtQuick : : ListView : : header
2011-08-08 08:03:31 +00:00
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 .
2014-03-10 14:58:10 +00:00
The default \ l { QQuickItem : : z } { stacking order } of the header is \ c 1.
2011-08-08 08:03:31 +00:00
2012-08-02 03:06:09 +00:00
\ sa footer , headerItem
2011-12-05 05:40:31 +00:00
*/
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty Item QtQuick : : ListView : : headerItem
2011-12-05 05:40:31 +00:00
This holds the header item created from the \ l header component .
An instance of the header component is created for each view . The
header is positioned at the beginning of the view , before any items .
2014-03-10 14:58:10 +00:00
The default \ l { QQuickItem : : z } { stacking order } of the header is \ c 1.
2011-12-05 05:40:31 +00:00
\ sa header , footerItem
*/
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty Item QtQuick : : ListView : : footerItem
2011-12-05 05:40:31 +00:00
This holds the footer item created from the \ l footer component .
An instance of the footer component is created for each view . The
2014-03-10 14:58:10 +00:00
footer is positioned at the end of the view , after any items . The
default \ l { QQuickItem : : z } { stacking order } of the footer is \ c 1.
2011-12-05 05:40:31 +00:00
\ sa footer , headerItem
2011-08-08 08:03:31 +00:00
*/
2014-03-03 14:53:27 +00:00
/*!
\ qmlproperty enumeration QtQuick : : ListView : : headerPositioning
\ since Qt 5.4
This property determines the positioning of the \ l { headerItem } { header item } .
The possible values are :
\ list
\ li ListView . InlineHeader ( default ) - the header is positioned in the beginning
of the content and moves together with the content like an ordinary item .
\ li ListView . OverlayHeader - the header is positioned in the beginning of the view .
\ li ListView . PullBackHeader - the header is positioned in the beginning of the view .
The header can be pushed away by moving the content forwards , and pulled back by
moving the content backwards .
\ endlist
*/
QQuickListView : : HeaderPositioning QQuickListView : : headerPositioning ( ) const
{
Q_D ( const QQuickListView ) ;
return d - > headerPositioning ;
}
void QQuickListView : : setHeaderPositioning ( QQuickListView : : HeaderPositioning positioning )
{
Q_D ( QQuickListView ) ;
if ( d - > headerPositioning ! = positioning ) {
d - > applyPendingChanges ( ) ;
d - > headerPositioning = positioning ;
if ( isComponentComplete ( ) ) {
d - > updateHeader ( ) ;
d - > updateViewport ( ) ;
d - > fixupPosition ( ) ;
}
emit headerPositioningChanged ( ) ;
}
}
/*!
\ qmlproperty enumeration QtQuick : : ListView : : footerPositioning
\ since Qt 5.4
This property determines the positioning of the \ l { footerItem } { footer item } .
The possible values are :
\ list
\ li ListView . InlineFooter ( default ) - the footer is positioned in the end
of the content and moves together with the content like an ordinary item .
\ li ListView . OverlayFooter - the footer is positioned in the end of the view .
\ li ListView . PullBackFooter - the footer is positioned in the end of the view .
The footer can be pushed away by moving the content backwards , and pulled back by
moving the content forwards .
\ endlist
*/
QQuickListView : : FooterPositioning QQuickListView : : footerPositioning ( ) const
{
Q_D ( const QQuickListView ) ;
return d - > footerPositioning ;
}
void QQuickListView : : setFooterPositioning ( QQuickListView : : FooterPositioning positioning )
{
Q_D ( QQuickListView ) ;
if ( d - > footerPositioning ! = positioning ) {
d - > applyPendingChanges ( ) ;
d - > footerPositioning = positioning ;
if ( isComponentComplete ( ) ) {
d - > updateFooter ( ) ;
d - > updateViewport ( ) ;
d - > fixupPosition ( ) ;
}
emit footerPositioningChanged ( ) ;
}
}
2012-02-09 07:59:44 +00:00
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty Transition QtQuick : : ListView : : populate
2012-02-09 07:59:44 +00:00
2012-02-23 01:51:31 +00:00
This property holds the transition to apply to the items that are initially created
for a view .
It is applied to all items that are created when :
2012-02-09 07:59:44 +00:00
\ list
2012-03-01 17:05:16 +00:00
\ li The view is first created
\ li The view ' s \ l model changes
2012-08-02 03:06:09 +00:00
\ li The view ' s \ l model is \ l { QAbstractItemModel : : reset ( ) } { reset } , if the model is a QAbstractItemModel subclass
2012-02-09 07:59:44 +00:00
\ endlist
For example , here is a view that specifies such a transition :
\ code
ListView {
. . .
populate : Transition {
NumberAnimation { properties : " x,y " ; duration : 1000 }
}
}
\ endcode
When the view is initialized , the view will create all the necessary items for the view ,
then animate them to their correct positions within the view over one second .
For more details and examples on how to use view transitions , see the ViewTransition
documentation .
\ sa add , ViewTransition
*/
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty Transition QtQuick : : ListView : : add
2012-02-09 07:59:44 +00:00
2012-02-23 01:51:31 +00:00
This property holds the transition to apply to items that are added to the view .
For example , here is a view that specifies such a transition :
2012-02-09 07:59:44 +00:00
\ code
ListView {
. . .
add : Transition {
NumberAnimation { properties : " x,y " ; from : 100 ; duration : 1000 }
}
}
\ endcode
Whenever an item is added to the above view , the item will be animated from the position ( 100 , 100 )
to its final x , y position within the view , over one second . The transition only applies to
the new items that are added to the view ; it does not apply to the items below that are
2012-02-22 07:23:47 +00:00
displaced by the addition of the new items . To animate the displaced items , set the \ l displaced
or \ l addDisplaced properties .
2012-02-09 07:59:44 +00:00
For more details and examples on how to use view transitions , see the ViewTransition
documentation .
\ note This transition is not applied to the items that are created when the view is initially
2012-08-03 07:18:57 +00:00
populated , or when the view ' s \ l model changes . ( In those cases , the \ l populate transition is
applied instead . ) Additionally , this transition should \ e not animate the height of the new item ;
doing so will cause any items beneath the new item to be laid out at the wrong position . Instead ,
2014-03-20 13:57:03 +00:00
the height can be animated within the \ l { add } { onAdd } handler in the delegate .
2012-02-09 07:59:44 +00:00
\ sa addDisplaced , populate , ViewTransition
*/
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty Transition QtQuick : : ListView : : addDisplaced
2012-02-09 07:59:44 +00:00
2012-02-23 01:51:31 +00:00
This property holds the transition to apply to items within the view that are displaced by
the addition of other items to the view .
For example , here is a view that specifies such a transition :
2012-02-09 07:59:44 +00:00
\ code
ListView {
. . .
addDisplaced : Transition {
NumberAnimation { properties : " x,y " ; duration : 1000 }
}
}
\ endcode
Whenever an item is added to the above view , all items beneath the new item are displaced , causing
them to move down ( or sideways , if horizontally orientated ) within the view . As this
displacement occurs , the items ' movement to their new x , y positions within the view will be
animated by a NumberAnimation over one second , as specified . This transition is not applied to
the new item that has been added to the view ; to animate the added items , set the \ l add
property .
2012-02-22 07:23:47 +00:00
If an item is displaced by multiple types of operations at the same time , it is not defined as to
whether the addDisplaced , moveDisplaced or removeDisplaced transition will be applied . Additionally ,
if it is not necessary to specify different transitions depending on whether an item is displaced
by an add , move or remove operation , consider setting the \ l displaced property instead .
2012-02-21 04:44:21 +00:00
2012-02-09 07:59:44 +00:00
For more details and examples on how to use view transitions , see the ViewTransition
documentation .
\ note This transition is not applied to the items that are created when the view is initially
populated , or when the view ' s \ l model changes . In those cases , the \ l populate transition is
applied instead .
2012-02-22 07:23:47 +00:00
\ sa displaced , add , populate , ViewTransition
2012-02-09 07:59:44 +00:00
*/
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty Transition QtQuick : : ListView : : move
2012-02-09 07:59:44 +00:00
2012-02-23 01:51:31 +00:00
This property holds the transition to apply to items in the view that are being moved due
to a move operation in the view ' s \ l model .
For example , here is a view that specifies such a transition :
2012-02-09 07:59:44 +00:00
\ code
ListView {
. . .
move : Transition {
NumberAnimation { properties : " x,y " ; duration : 1000 }
}
}
\ endcode
2012-02-23 01:51:31 +00:00
Whenever the \ l model performs a move operation to move a particular set of indexes , the
respective items in the view will be animated to their new positions in the view over one
second . The transition only applies to the items that are the subject of the move operation
in the model ; it does not apply to items below them that are displaced by the move operation .
2012-02-22 07:23:47 +00:00
To animate the displaced items , set the \ l displaced or \ l moveDisplaced properties .
2012-02-09 07:59:44 +00:00
For more details and examples on how to use view transitions , see the ViewTransition
documentation .
\ sa moveDisplaced , ViewTransition
*/
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty Transition QtQuick : : ListView : : moveDisplaced
2012-02-09 07:59:44 +00:00
2012-02-23 01:51:31 +00:00
This property holds the transition to apply to items that are displaced by a move operation in
the view ' s \ l model .
For example , here is a view that specifies such a transition :
2012-02-09 07:59:44 +00:00
\ code
ListView {
. . .
moveDisplaced : Transition {
NumberAnimation { properties : " x,y " ; duration : 1000 }
}
}
\ endcode
2012-02-23 01:51:31 +00:00
Whenever the \ l model performs a move operation to move a particular set of indexes , the items
between the source and destination indexes of the move operation are displaced , causing them
to move upwards or downwards ( or sideways , if horizontally orientated ) within the view . As this
displacement occurs , the items ' movement to their new x , y positions within the view will be
animated by a NumberAnimation over one second , as specified . This transition is not applied to
the items that are the actual subjects of the move operation ; to animate the moved items , set
the \ l move property .
2012-02-09 07:59:44 +00:00
2012-02-22 07:23:47 +00:00
If an item is displaced by multiple types of operations at the same time , it is not defined as to
whether the addDisplaced , moveDisplaced or removeDisplaced transition will be applied . Additionally ,
if it is not necessary to specify different transitions depending on whether an item is displaced
by an add , move or remove operation , consider setting the \ l displaced property instead .
2012-02-09 07:59:44 +00:00
For more details and examples on how to use view transitions , see the ViewTransition
documentation .
2012-02-22 07:23:47 +00:00
\ sa displaced , move , ViewTransition
2012-02-09 07:59:44 +00:00
*/
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty Transition QtQuick : : ListView : : remove
2012-02-23 01:51:31 +00:00
2012-02-09 07:59:44 +00:00
This property holds the transition to apply to items that are removed from the view .
2012-02-23 01:51:31 +00:00
For example , here is a view that specifies such a transition :
2012-02-09 07:59:44 +00:00
\ code
ListView {
. . .
remove : Transition {
ParallelAnimation {
NumberAnimation { property : " opacity " ; to : 0 ; duration : 1000 }
NumberAnimation { properties : " x,y " ; to : 100 ; duration : 1000 }
}
}
}
\ endcode
Whenever an item is removed from the above view , the item will be animated to the position ( 100 , 100 )
over one second , and in parallel will also change its opacity to 0. The transition
only applies to the items that are removed from the view ; it does not apply to the items below
2012-02-22 07:23:47 +00:00
them that are displaced by the removal of the items . To animate the displaced items , set the
\ l displaced or \ l removeDisplaced properties .
2012-02-09 07:59:44 +00:00
Note that by the time the transition is applied , the item has already been removed from the
model ; any references to the model data for the removed index will not be valid .
Additionally , if the \ l delayRemove attached property has been set for a delegate item , the
remove transition will not be applied until \ l delayRemove becomes false again .
For more details and examples on how to use view transitions , see the ViewTransition
documentation .
\ sa removeDisplaced , ViewTransition
*/
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty Transition QtQuick : : ListView : : removeDisplaced
2012-02-23 01:51:31 +00:00
2012-02-09 07:59:44 +00:00
This property holds the transition to apply to items in the view that are displaced by the
removal of other items in the view .
2012-02-23 01:51:31 +00:00
For example , here is a view that specifies such a transition :
2012-02-09 07:59:44 +00:00
\ code
ListView {
. . .
removeDisplaced : Transition {
NumberAnimation { properties : " x,y " ; duration : 1000 }
}
}
\ endcode
Whenever an item is removed from the above view , all items beneath it are displaced , causing
them to move upwards ( or sideways , if horizontally orientated ) within the view . As this
displacement occurs , the items ' movement to their new x , y positions within the view will be
animated by a NumberAnimation over one second , as specified . This transition is not applied to
the item that has actually been removed from the view ; to animate the removed items , set the
\ l remove property .
2012-02-22 07:23:47 +00:00
If an item is displaced by multiple types of operations at the same time , it is not defined as to
whether the addDisplaced , moveDisplaced or removeDisplaced transition will be applied . Additionally ,
if it is not necessary to specify different transitions depending on whether an item is displaced
by an add , move or remove operation , consider setting the \ l displaced property instead .
2012-02-21 04:44:21 +00:00
2012-02-09 07:59:44 +00:00
For more details and examples on how to use view transitions , see the ViewTransition
documentation .
2012-02-22 07:23:47 +00:00
\ sa displaced , remove , ViewTransition
2012-02-09 07:59:44 +00:00
*/
2012-02-22 07:23:47 +00:00
/*!
2013-10-01 11:03:28 +00:00
\ qmlproperty Transition QtQuick : : ListView : : displaced
2012-02-22 07:23:47 +00:00
This property holds the generic transition to apply to items that have been displaced by
any model operation that affects the view .
This is a convenience for specifying the generic transition to be applied to any items
that are displaced by an add , move or remove operation , without having to specify the
individual addDisplaced , moveDisplaced and removeDisplaced properties . For example , here
is a view that specifies a displaced transition :
\ code
ListView {
. . .
displaced : Transition {
NumberAnimation { properties : " x,y " ; duration : 1000 }
}
}
\ endcode
When any item is added , moved or removed within the above view , the items below it are
displaced , causing them to move down ( or sideways , if horizontally orientated ) within the
view . As this displacement occurs , the items ' movement to their new x , y positions within
the view will be animated by a NumberAnimation over one second , as specified .
If a view specifies this generic displaced transition as well as a specific addDisplaced ,
moveDisplaced or removeDisplaced transition , the more specific transition will be used
instead of the generic displaced transition when the relevant operation occurs , providing that
the more specific transition has not been disabled ( by setting \ l { Transition : : enabled } { enabled }
to false ) . If it has indeed been disabled , the generic displaced transition is applied instead .
For more details and examples on how to use view transitions , see the ViewTransition
documentation .
\ sa addDisplaced , moveDisplaced , removeDisplaced , ViewTransition
*/
2012-02-09 07:59:44 +00:00
2012-06-13 01:17:44 +00:00
void QQuickListView : : viewportMoved ( Qt : : Orientations orient )
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
Q_D ( QQuickListView ) ;
2012-06-13 01:17:44 +00:00
QQuickItemView : : viewportMoved ( orient ) ;
2011-04-27 12:13:26 +00:00
if ( ! d - > itemCount )
return ;
// Recursion can occur due to refill changing the content size.
if ( d - > inViewportMoved )
return ;
d - > inViewportMoved = true ;
2011-11-03 05:52:13 +00:00
2012-03-20 01:37:10 +00:00
if ( yflick ( ) ) {
if ( d - > isBottomToTop ( ) )
d - > bufferMode = d - > vData . smoothVelocity < 0 ? QQuickListViewPrivate : : BufferAfter : QQuickListViewPrivate : : BufferBefore ;
else
d - > bufferMode = d - > vData . smoothVelocity < 0 ? QQuickListViewPrivate : : BufferBefore : QQuickListViewPrivate : : BufferAfter ;
} else {
if ( d - > isRightToLeft ( ) )
d - > bufferMode = d - > hData . smoothVelocity < 0 ? QQuickListViewPrivate : : BufferAfter : QQuickListViewPrivate : : BufferBefore ;
else
d - > bufferMode = d - > hData . smoothVelocity < 0 ? QQuickListViewPrivate : : BufferBefore : QQuickListViewPrivate : : BufferAfter ;
}
2011-11-03 05:52:13 +00:00
2012-04-11 06:22:52 +00:00
d - > refillOrLayout ( ) ;
2012-01-18 06:21:50 +00:00
// Set visibility of items to eliminate cost of items outside the visible area.
2013-08-29 07:48:29 +00:00
qreal from = d - > isContentFlowReversed ( ) ? - d - > position ( ) - d - > displayMarginBeginning - d - > size ( ) : d - > position ( ) - d - > displayMarginBeginning ;
qreal to = d - > isContentFlowReversed ( ) ? - d - > position ( ) + d - > displayMarginEnd : d - > position ( ) + d - > size ( ) + d - > displayMarginEnd ;
2012-01-18 06:21:50 +00:00
for ( int i = 0 ; i < d - > visibleItems . count ( ) ; + + i ) {
FxViewItem * item = static_cast < FxListItemSG * > ( d - > visibleItems . at ( i ) ) ;
2012-06-08 01:19:09 +00:00
QQuickItemPrivate : : get ( item - > item ) - > setCulled ( item - > endPosition ( ) < from | | item - > position ( ) > to ) ;
2012-01-18 06:21:50 +00:00
}
2012-03-07 05:26:33 +00:00
if ( d - > currentItem )
2012-06-08 01:19:09 +00:00
QQuickItemPrivate : : get ( d - > currentItem - > item ) - > setCulled ( d - > currentItem - > endPosition ( ) < from | | d - > currentItem - > position ( ) > to ) ;
2012-01-18 06:21:50 +00:00
2011-09-26 03:13:02 +00:00
if ( d - > hData . flicking | | d - > vData . flicking | | d - > hData . moving | | d - > vData . moving )
2011-10-14 08:51:42 +00:00
d - > moveReason = QQuickListViewPrivate : : Mouse ;
if ( d - > moveReason ! = QQuickListViewPrivate : : SetIndex ) {
2011-04-27 12:13:26 +00:00
if ( d - > haveHighlightRange & & d - > highlightRange = = StrictlyEnforceRange & & d - > highlight ) {
// reposition highlight
qreal pos = d - > highlight - > position ( ) ;
2012-03-20 01:37:10 +00:00
qreal viewPos = d - > isContentFlowReversed ( ) ? - d - > position ( ) - d - > size ( ) : d - > position ( ) ;
2011-10-13 07:41:51 +00:00
if ( pos > viewPos + d - > highlightRangeEnd - d - > highlight - > size ( ) )
pos = viewPos + d - > highlightRangeEnd - d - > highlight - > size ( ) ;
if ( pos < viewPos + d - > highlightRangeStart )
pos = viewPos + d - > highlightRangeStart ;
2011-08-01 05:00:30 +00:00
if ( pos ! = d - > highlight - > position ( ) ) {
d - > highlightPosAnimator - > stop ( ) ;
static_cast < FxListItemSG * > ( d - > highlight ) - > setPosition ( pos ) ;
} else {
d - > updateHighlight ( ) ;
}
2011-04-27 12:13:26 +00:00
// update current index
2011-07-05 05:07:05 +00:00
if ( FxViewItem * snapItem = d - > snapItemAt ( d - > highlight - > position ( ) ) ) {
2011-04-27 12:13:26 +00:00
if ( snapItem - > index > = 0 & & snapItem - > index ! = d - > currentIndex )
d - > updateCurrent ( snapItem - > index ) ;
}
}
}
2011-09-26 03:13:02 +00:00
if ( ( d - > hData . flicking | | d - > vData . flicking ) & & d - > correctFlick & & ! d - > inFlickCorrection ) {
2011-04-27 12:13:26 +00:00
d - > inFlickCorrection = true ;
// Near an end and it seems that the extent has changed?
// Recalculate the flick so that we don't end up in an odd position.
2011-05-04 07:53:51 +00:00
if ( yflick ( ) & & ! d - > vData . inOvershoot ) {
2011-04-27 12:13:26 +00:00
if ( d - > vData . velocity > 0 ) {
const qreal minY = minYExtent ( ) ;
if ( ( minY - d - > vData . move . value ( ) < height ( ) / 2 | | d - > vData . flickTarget - d - > vData . move . value ( ) < height ( ) / 2 )
& & minY ! = d - > vData . flickTarget )
d - > flickY ( - d - > vData . smoothVelocity . value ( ) ) ;
} else if ( d - > vData . velocity < 0 ) {
const qreal maxY = maxYExtent ( ) ;
if ( ( d - > vData . move . value ( ) - maxY < height ( ) / 2 | | d - > vData . move . value ( ) - d - > vData . flickTarget < height ( ) / 2 )
& & maxY ! = d - > vData . flickTarget )
d - > flickY ( - d - > vData . smoothVelocity . value ( ) ) ;
}
}
2011-05-04 07:53:51 +00:00
if ( xflick ( ) & & ! d - > hData . inOvershoot ) {
2011-04-27 12:13:26 +00:00
if ( d - > hData . velocity > 0 ) {
const qreal minX = minXExtent ( ) ;
if ( ( minX - d - > hData . move . value ( ) < width ( ) / 2 | | d - > hData . flickTarget - d - > hData . move . value ( ) < width ( ) / 2 )
& & minX ! = d - > hData . flickTarget )
d - > flickX ( - d - > hData . smoothVelocity . value ( ) ) ;
} else if ( d - > hData . velocity < 0 ) {
const qreal maxX = maxXExtent ( ) ;
if ( ( d - > hData . move . value ( ) - maxX < width ( ) / 2 | | d - > hData . move . value ( ) - d - > hData . flickTarget < width ( ) / 2 )
& & maxX ! = d - > hData . flickTarget )
d - > flickX ( - d - > hData . smoothVelocity . value ( ) ) ;
}
}
d - > inFlickCorrection = false ;
}
2014-03-03 14:53:27 +00:00
if ( d - > hasStickyHeader ( ) )
d - > updateHeader ( ) ;
if ( d - > hasStickyFooter ( ) )
d - > updateFooter ( ) ;
2011-09-20 05:58:05 +00:00
if ( d - > sectionCriteria ) {
d - > updateCurrentSection ( ) ;
d - > updateStickySections ( ) ;
}
2011-04-27 12:13:26 +00:00
d - > inViewportMoved = false ;
}
2011-10-14 08:51:42 +00:00
void QQuickListView : : keyPressEvent ( QKeyEvent * event )
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
Q_D ( QQuickListView ) ;
2011-04-27 12:13:26 +00:00
if ( d - > model & & d - > model - > count ( ) & & d - > interactive ) {
2011-10-14 08:51:42 +00:00
if ( ( d - > orient = = QQuickListView : : Horizontal & & ! d - > isRightToLeft ( ) & & event - > key ( ) = = Qt : : Key_Left )
| | ( d - > orient = = QQuickListView : : Horizontal & & d - > isRightToLeft ( ) & & event - > key ( ) = = Qt : : Key_Right )
2012-03-20 01:37:10 +00:00
| | ( d - > orient = = QQuickListView : : Vertical & & ! d - > isBottomToTop ( ) & & event - > key ( ) = = Qt : : Key_Up )
| | ( d - > orient = = QQuickListView : : Vertical & & d - > isBottomToTop ( ) & & event - > key ( ) = = Qt : : Key_Down ) ) {
2011-04-27 12:13:26 +00:00
if ( currentIndex ( ) > 0 | | ( d - > wrap & & ! event - > isAutoRepeat ( ) ) ) {
decrementCurrentIndex ( ) ;
event - > accept ( ) ;
return ;
} else if ( d - > wrap ) {
event - > accept ( ) ;
return ;
}
2011-10-14 08:51:42 +00:00
} else if ( ( d - > orient = = QQuickListView : : Horizontal & & ! d - > isRightToLeft ( ) & & event - > key ( ) = = Qt : : Key_Right )
| | ( d - > orient = = QQuickListView : : Horizontal & & d - > isRightToLeft ( ) & & event - > key ( ) = = Qt : : Key_Left )
2012-03-20 01:37:10 +00:00
| | ( d - > orient = = QQuickListView : : Vertical & & ! d - > isBottomToTop ( ) & & event - > key ( ) = = Qt : : Key_Down )
| | ( d - > orient = = QQuickListView : : Vertical & & d - > isBottomToTop ( ) & & event - > key ( ) = = Qt : : Key_Up ) ) {
2011-04-27 12:13:26 +00:00
if ( currentIndex ( ) < d - > model - > count ( ) - 1 | | ( d - > wrap & & ! event - > isAutoRepeat ( ) ) ) {
incrementCurrentIndex ( ) ;
event - > accept ( ) ;
return ;
} else if ( d - > wrap ) {
event - > accept ( ) ;
return ;
}
}
}
event - > ignore ( ) ;
2011-10-14 08:51:42 +00:00
QQuickItemView : : keyPressEvent ( event ) ;
2011-04-27 12:13:26 +00:00
}
2011-10-14 08:51:42 +00:00
void QQuickListView : : geometryChanged ( const QRectF & newGeometry , const QRectF & oldGeometry )
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
Q_D ( QQuickListView ) ;
2012-03-20 01:37:10 +00:00
if ( d - > isRightToLeft ( ) ) {
2011-04-27 12:13:26 +00:00
// maintain position relative to the right edge
2014-04-04 08:42:37 +00:00
qreal dx = newGeometry . width ( ) - oldGeometry . width ( ) ;
2011-04-27 12:13:26 +00:00
setContentX ( contentX ( ) - dx ) ;
2012-03-20 01:37:10 +00:00
} else if ( d - > isBottomToTop ( ) ) {
// maintain position relative to the bottom edge
2014-04-04 08:42:37 +00:00
qreal dy = newGeometry . height ( ) - oldGeometry . height ( ) ;
2012-03-20 01:37:10 +00:00
setContentY ( contentY ( ) - dy ) ;
2011-04-27 12:13:26 +00:00
}
2011-10-14 08:51:42 +00:00
QQuickItemView : : geometryChanged ( newGeometry , oldGeometry ) ;
2011-04-27 12:13:26 +00:00
}
2013-01-15 22:26:59 +00:00
void QQuickListView : : initItem ( int index , QObject * object )
2012-06-14 05:11:54 +00:00
{
2013-01-15 22:26:59 +00:00
QQuickItemView : : initItem ( index , object ) ;
2013-10-07 09:55:12 +00:00
// setting the view from the FxViewItem wrapper is too late if the delegate
// needs access to the view in Component.onCompleted
2013-01-15 22:26:59 +00:00
QQuickItem * item = qmlobject_cast < QQuickItem * > ( object ) ;
if ( item ) {
QQuickListViewAttached * attached = static_cast < QQuickListViewAttached * > (
qmlAttachedPropertiesObject < QQuickListView > ( item ) ) ;
if ( attached )
attached - > setView ( this ) ;
}
2012-06-14 05:11:54 +00:00
}
2011-04-27 12:13:26 +00:00
2011-08-08 08:03:31 +00:00
/*!
2013-10-01 11:03:28 +00:00
\ qmlmethod QtQuick : : ListView : : incrementCurrentIndex ( )
2011-08-08 08:03:31 +00:00
Increments the current index . 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 .
2012-03-01 17:05:16 +00:00
\ b Note : methods should only be called after the Component has completed .
2011-08-08 08:03:31 +00:00
*/
2011-10-14 08:51:42 +00:00
void QQuickListView : : incrementCurrentIndex ( )
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
Q_D ( QQuickListView ) ;
2011-04-27 12:13:26 +00:00
int count = d - > model ? d - > model - > count ( ) : 0 ;
if ( count & & ( currentIndex ( ) < count - 1 | | d - > wrap ) ) {
2011-10-14 08:51:42 +00:00
d - > moveReason = QQuickListViewPrivate : : SetIndex ;
2011-04-27 12:13:26 +00:00
int index = currentIndex ( ) + 1 ;
setCurrentIndex ( ( index > = 0 & & index < count ) ? index : 0 ) ;
}
}
2011-08-08 08:03:31 +00:00
/*!
2013-10-01 11:03:28 +00:00
\ qmlmethod QtQuick : : ListView : : decrementCurrentIndex ( )
2011-08-08 08:03:31 +00:00
Decrements the current index . The current index will wrap
if keyNavigationWraps is true and it is currently at the beginning .
This method has no effect if the \ l count is zero .
2012-03-01 17:05:16 +00:00
\ b Note : methods should only be called after the Component has completed .
2011-08-08 08:03:31 +00:00
*/
2011-10-14 08:51:42 +00:00
void QQuickListView : : decrementCurrentIndex ( )
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
Q_D ( QQuickListView ) ;
2011-04-27 12:13:26 +00:00
int count = d - > model ? d - > model - > count ( ) : 0 ;
if ( count & & ( currentIndex ( ) > 0 | | d - > wrap ) ) {
2011-10-14 08:51:42 +00:00
d - > moveReason = QQuickListViewPrivate : : SetIndex ;
2011-04-27 12:13:26 +00:00
int index = currentIndex ( ) - 1 ;
setCurrentIndex ( ( index > = 0 & & index < count ) ? index : count - 1 ) ;
}
}
2012-06-29 01:57:02 +00:00
void QQuickListViewPrivate : : updateSectionCriteria ( )
2011-04-27 12:13:26 +00:00
{
2012-06-29 01:57:02 +00:00
Q_Q ( QQuickListView ) ;
if ( q - > isComponentComplete ( ) & & model ) {
2011-04-27 12:13:26 +00:00
QList < QByteArray > roles ;
2012-06-29 01:57:02 +00:00
if ( sectionCriteria & & ! sectionCriteria - > property ( ) . isEmpty ( ) )
roles < < sectionCriteria - > property ( ) . toUtf8 ( ) ;
model - > setWatchedRoles ( roles ) ;
updateSections ( ) ;
if ( itemCount )
forceLayoutPolish ( ) ;
2011-04-27 12:13:26 +00:00
}
}
2014-04-30 18:29:39 +00:00
bool QQuickListViewPrivate : : applyInsertionChange ( const QQmlChangeSet : : Change & change , ChangeResult * insertResult , QList < FxViewItem * > * addedItems , QList < MovedItem > * movingIntoView )
2011-04-27 12:13:26 +00:00
{
2011-08-29 05:33:36 +00:00
int modelIndex = change . index ;
int count = change . count ;
2012-03-20 01:37:10 +00:00
qreal tempPos = isContentFlowReversed ( ) ? - position ( ) - size ( ) : position ( ) ;
2011-08-29 05:33:36 +00:00
int index = visibleItems . count ( ) ? mapFromModel ( modelIndex ) : 0 ;
2011-04-27 12:13:26 +00:00
if ( index < 0 ) {
2011-08-29 05:33:36 +00:00
int i = visibleItems . count ( ) - 1 ;
while ( i > 0 & & visibleItems . at ( i ) - > index = = - 1 )
2011-04-27 12:13:26 +00:00
- - i ;
2011-08-29 05:33:36 +00:00
if ( i = = 0 & & visibleItems . first ( ) - > index = = - 1 ) {
2011-04-27 12:13:26 +00:00
// there are no visible items except items marked for removal
2011-08-29 05:33:36 +00:00
index = visibleItems . count ( ) ;
} else if ( visibleItems . at ( i ) - > index + 1 = = modelIndex
2013-08-29 07:48:29 +00:00
& & visibleItems . at ( i ) - > endPosition ( ) < = buffer + displayMarginEnd + tempPos + size ( ) ) {
2011-04-27 12:13:26 +00:00
// Special case of appending an item to the model.
2011-08-29 05:33:36 +00:00
index = visibleItems . count ( ) ;
2011-04-27 12:13:26 +00:00
} else {
2011-08-29 05:33:36 +00:00
if ( modelIndex < visibleIndex ) {
2011-04-27 12:13:26 +00:00
// Insert before visible items
2011-08-29 05:33:36 +00:00
visibleIndex + = count ;
for ( int i = 0 ; i < visibleItems . count ( ) ; + + i ) {
FxViewItem * item = visibleItems . at ( i ) ;
2011-07-05 05:07:05 +00:00
if ( item - > index ! = - 1 & & item - > index > = modelIndex )
item - > index + = count ;
2011-04-27 12:13:26 +00:00
}
}
2011-08-29 05:33:36 +00:00
return true ;
2011-04-27 12:13:26 +00:00
}
}
// index can be the next item past the end of the visible items list (i.e. appended)
2014-04-04 08:42:37 +00:00
qreal pos = 0 ;
2011-08-29 05:33:36 +00:00
if ( visibleItems . count ( ) ) {
pos = index < visibleItems . count ( ) ? visibleItems . at ( index ) - > position ( )
: visibleItems . last ( ) - > endPosition ( ) + spacing ;
2011-04-27 12:13:26 +00:00
}
2012-01-04 23:59:30 +00:00
int prevVisibleCount = visibleItems . count ( ) ;
if ( insertResult - > visiblePos . isValid ( ) & & pos < insertResult - > visiblePos ) {
2011-04-27 12:13:26 +00:00
// Insert items before the visible item.
int insertionIdx = index ;
int i = 0 ;
2014-04-04 08:42:37 +00:00
qreal from = tempPos - displayMarginBeginning - buffer ;
2011-08-29 05:33:36 +00:00
2011-10-12 04:30:18 +00:00
for ( i = count - 1 ; i > = 0 ; - - i ) {
2011-11-18 02:04:56 +00:00
if ( pos > from & & insertionIdx < visibleIndex ) {
// item won't be visible, just note the size for repositioning
2012-01-04 23:59:30 +00:00
insertResult - > sizeChangesBeforeVisiblePos + = averageSize + spacing ;
2011-11-18 02:04:56 +00:00
pos - = averageSize + spacing ;
2011-10-12 04:30:18 +00:00
} else {
2011-11-18 02:04:56 +00:00
// item is before first visible e.g. in cache buffer
2011-10-12 04:30:18 +00:00
FxViewItem * item = 0 ;
2012-01-04 23:59:30 +00:00
if ( change . isMove ( ) & & ( item = currentChanges . removedItems . take ( change . moveKey ( modelIndex + i ) ) ) )
2011-10-12 04:30:18 +00:00
item - > index = modelIndex + i ;
if ( ! item )
item = createItem ( modelIndex + i ) ;
2011-11-03 05:52:13 +00:00
if ( ! item )
return false ;
2011-08-29 05:33:36 +00:00
2011-10-12 04:30:18 +00:00
visibleItems . insert ( insertionIdx , item ) ;
2012-01-04 23:59:30 +00:00
if ( insertionIdx = = 0 )
2012-01-13 04:35:04 +00:00
insertResult - > changedFirstItem = true ;
2012-02-09 07:59:44 +00:00
if ( ! change . isMove ( ) ) {
2012-01-04 23:59:30 +00:00
addedItems - > append ( item ) ;
2012-03-07 03:29:20 +00:00
item - > transitionNextReposition ( transitioner , QQuickItemViewTransitioner : : AddTransition , true ) ;
2012-02-09 07:59:44 +00:00
}
2012-01-04 23:59:30 +00:00
insertResult - > sizeChangesBeforeVisiblePos + = item - > size ( ) + spacing ;
2011-10-12 04:30:18 +00:00
pos - = item - > size ( ) + spacing ;
}
2011-04-27 12:13:26 +00:00
index + + ;
}
} else {
int i = 0 ;
2014-04-04 08:42:37 +00:00
qreal to = buffer + displayMarginEnd + tempPos + size ( ) ;
2011-04-27 12:13:26 +00:00
for ( i = 0 ; i < count & & pos < = to ; + + i ) {
2011-08-29 05:33:36 +00:00
FxViewItem * item = 0 ;
2012-01-04 23:59:30 +00:00
if ( change . isMove ( ) & & ( item = currentChanges . removedItems . take ( change . moveKey ( modelIndex + i ) ) ) )
2011-08-29 05:33:36 +00:00
item - > index = modelIndex + i ;
2012-02-09 07:59:44 +00:00
bool newItem = ! item ;
2011-08-29 05:33:36 +00:00
if ( ! item )
item = createItem ( modelIndex + i ) ;
2011-11-03 05:52:13 +00:00
if ( ! item )
return false ;
2011-04-27 12:13:26 +00:00
2011-08-29 05:33:36 +00:00
visibleItems . insert ( index , item ) ;
2012-01-04 23:59:30 +00:00
if ( index = = 0 )
2012-01-13 04:35:04 +00:00
insertResult - > changedFirstItem = true ;
2012-02-09 07:59:44 +00:00
if ( change . isMove ( ) ) {
// we know this is a move target, since move displaced items that are
// shuffled into view due to a move would be added in refill()
2012-02-21 04:44:21 +00:00
if ( newItem & & transitioner & & transitioner - > canTransition ( QQuickItemViewTransitioner : : MoveTransition , true ) )
2012-02-09 07:59:44 +00:00
movingIntoView - > append ( MovedItem ( item , change . moveKey ( item - > index ) ) ) ;
} else {
2012-01-04 23:59:30 +00:00
addedItems - > append ( item ) ;
2012-03-07 03:29:20 +00:00
item - > transitionNextReposition ( transitioner , QQuickItemViewTransitioner : : AddTransition , true ) ;
2012-02-09 07:59:44 +00:00
}
2012-01-04 23:59:30 +00:00
insertResult - > sizeChangesAfterVisiblePos + = item - > size ( ) + spacing ;
2011-08-29 05:33:36 +00:00
pos + = item - > size ( ) + spacing ;
+ + index ;
2011-04-27 12:13:26 +00:00
}
}
2011-08-29 05:33:36 +00:00
for ( ; index < visibleItems . count ( ) ; + + index ) {
FxViewItem * item = visibleItems . at ( index ) ;
2012-03-07 03:29:20 +00:00
if ( item - > index ! = - 1 ) {
2011-08-29 05:33:36 +00:00
item - > index + = count ;
2012-02-21 04:44:21 +00:00
if ( change . isMove ( ) )
2012-03-07 03:29:20 +00:00
item - > transitionNextReposition ( transitioner , QQuickItemViewTransitioner : : MoveTransition , false ) ;
2012-02-21 04:44:21 +00:00
else
2012-03-07 03:29:20 +00:00
item - > transitionNextReposition ( transitioner , QQuickItemViewTransitioner : : AddTransition , false ) ;
2012-02-21 04:44:21 +00:00
}
2011-04-27 12:13:26 +00:00
}
2011-10-12 04:30:18 +00:00
updateVisibleIndex ( ) ;
2012-01-04 23:59:30 +00:00
return visibleItems . count ( ) > prevVisibleCount ;
2011-04-27 12:13:26 +00:00
}
2012-02-09 07:59:44 +00:00
void QQuickListViewPrivate : : translateAndTransitionItemsAfter ( int afterModelIndex , const ChangeResult & insertionResult , const ChangeResult & removalResult )
{
Q_UNUSED ( insertionResult ) ;
2012-02-21 04:44:21 +00:00
if ( ! transitioner )
return ;
2012-02-09 07:59:44 +00:00
int markerItemIndex = - 1 ;
for ( int i = 0 ; i < visibleItems . count ( ) ; i + + ) {
if ( visibleItems [ i ] - > index = = afterModelIndex ) {
markerItemIndex = i ;
break ;
}
}
if ( markerItemIndex < 0 )
return ;
const qreal viewEndPos = isContentFlowReversed ( ) ? - position ( ) : position ( ) + size ( ) ;
qreal sizeRemoved = - removalResult . sizeChangesAfterVisiblePos
- ( removalResult . countChangeAfterVisibleItems * ( averageSize + spacing ) ) ;
for ( int i = markerItemIndex + 1 ; i < visibleItems . count ( ) & & visibleItems . at ( i ) - > position ( ) < viewEndPos ; i + + ) {
FxListItemSG * listItem = static_cast < FxListItemSG * > ( visibleItems [ i ] ) ;
if ( ! listItem - > transitionScheduledOrRunning ( ) ) {
qreal pos = listItem - > position ( ) ;
listItem - > setPosition ( pos - sizeRemoved ) ;
2012-03-07 03:29:20 +00:00
listItem - > transitionNextReposition ( transitioner , QQuickItemViewTransitioner : : RemoveTransition , false ) ;
2012-02-09 07:59:44 +00:00
listItem - > setPosition ( pos ) ;
}
}
}
2011-04-27 12:13:26 +00:00
2011-08-08 08:03:31 +00:00
/*!
2013-10-01 11:03:28 +00:00
\ qmlmethod QtQuick : : ListView : : positionViewAtIndex ( int index , PositionMode mode )
2011-08-08 08:03:31 +00:00
Positions the view such that the \ a index is at the position specified by
\ a mode :
\ list
2012-03-01 17:05:16 +00:00
\ li ListView . Beginning - position item at the top ( or left for horizontal orientation ) of the view .
\ li ListView . Center - position item in the center of the view .
\ li ListView . End - position item at bottom ( or right for horizontal orientation ) of the view .
\ li ListView . Visible - if any part of the item is visible then take no action , otherwise
2011-08-08 08:03:31 +00:00
bring the item into view .
2012-03-01 17:05:16 +00:00
\ li ListView . Contain - ensure the entire item is visible . If the item is larger than
2011-08-08 08:03:31 +00:00
the view the item is positioned at the top ( or left for horizontal orientation ) of the view .
2012-07-26 03:14:50 +00:00
\ li ListView . SnapPosition - position the item at \ l preferredHighlightBegin . This mode
is only valid if \ l highlightRangeMode is StrictlyEnforceRange or snapping is enabled
via \ l snapMode .
2011-08-08 08:03:31 +00:00
\ endlist
If positioning the view at \ a 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 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 .
The correct way to bring an item into view is with \ c positionViewAtIndex .
2012-03-01 17:05:16 +00:00
\ b Note : methods should only be called after the Component has completed . To position
2011-08-08 08:03:31 +00:00
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 , ListView . Beginning )
\ endcode
*/
/*!
2013-10-01 11:03:28 +00:00
\ qmlmethod QtQuick : : ListView : : positionViewAtBeginning ( )
\ qmlmethod QtQuick : : ListView : : positionViewAtEnd ( )
2011-08-08 08:03:31 +00:00
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 .
2012-03-01 17:05:16 +00:00
\ b Note : methods should only be called after the Component has completed . To position
2011-08-08 08:03:31 +00:00
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
*/
/*!
2013-10-01 11:03:28 +00:00
\ qmlmethod int QtQuick : : ListView : : indexAt ( int x , int y )
2011-08-08 08:03:31 +00:00
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 .
2012-03-01 17:05:16 +00:00
\ b Note : methods should only be called after the Component has completed .
2011-08-08 08:03:31 +00:00
*/
2011-04-27 12:13:26 +00:00
2012-01-05 23:58:27 +00:00
/*!
2013-10-01 11:03:28 +00:00
\ qmlmethod Item QtQuick : : ListView : : itemAt ( int x , int y )
2012-01-05 23:58:27 +00:00
Returns 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 null is returned .
If the item is outside the visible area , null is returned , regardless of
whether an item will exist at that point when scrolled into view .
2012-03-01 17:05:16 +00:00
\ b Note : methods should only be called after the Component has completed .
2012-01-05 23:58:27 +00:00
*/
2013-04-11 23:57:19 +00:00
/*!
2013-10-01 11:03:28 +00:00
\ qmlmethod QtQuick : : ListView : : forceLayout ( )
2013-04-11 23:57:19 +00:00
Responding to changes in the model is usually batched to happen only once
per frame . This means that inside script blocks it is possible for the
underlying model to have changed , but the ListView has not caught up yet .
This method forces the ListView to immediately respond to any outstanding
changes in the model .
2013-09-24 13:23:45 +00:00
\ since 5.1
2013-04-11 23:57:19 +00:00
\ b Note : methods should only be called after the Component has completed .
*/
2011-10-14 08:51:42 +00:00
QQuickListViewAttached * QQuickListView : : qmlAttachedProperties ( QObject * obj )
2011-04-27 12:13:26 +00:00
{
2011-10-14 08:51:42 +00:00
return new QQuickListViewAttached ( obj ) ;
2011-04-27 12:13:26 +00:00
}
QT_END_NAMESPACE