2 * Copyright (C) 2013 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17#ifndef LISTVIEWWITHPAGEHEADER_H
18#define LISTVIEWWITHPAGEHEADER_H
20#include <private/qquickitemchangelistener_p.h>
21#include <private/qquickflickable_p.h>
23class QAbstractItemModel;
24class QQuickNumberAnimation;
26class QQmlDelegateModel;
30 Note for users of this class
32 ListViewWithPageHeader already loads delegates async when appropiate so if
33 your delegate uses a Loader you should not enable the asynchronous feature since
34 that will need to introduce sizing problems
36 With the double async it may happen what while we are scrolling down
37 we reach to a point where given the size of the just created delegate with loader not yet loaded (which will be very close to 0)
38 we are already "at the end" of the list, but then a few milliseconds later the loader finishes loading and we could
39 have kept scrolling. This is specially visible at the end of the list where you realize
40 that scrolling ended a bit before the end of the list but the speed of the flicking was good
43 By not having the second async we get a better sizing when the delegate is created and things work better
46class ListViewWithPageHeader : public QQuickFlickable, public QQuickItemChangeListener
49 Q_PROPERTY(QAbstractItemModel *model READ model WRITE setModel NOTIFY modelChanged)
50 Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
51 Q_PROPERTY(QQuickItem *pageHeader READ header WRITE setHeader NOTIFY headerChanged)
52 Q_PROPERTY(QQmlComponent *sectionDelegate READ sectionDelegate WRITE setSectionDelegate NOTIFY sectionDelegateChanged)
53 Q_PROPERTY(QString sectionProperty READ sectionProperty WRITE setSectionProperty NOTIFY sectionPropertyChanged)
54 Q_PROPERTY(bool forceNoClip READ forceNoClip WRITE setForceNoClip NOTIFY forceNoClipChanged)
55 Q_PROPERTY(int stickyHeaderHeight READ stickyHeaderHeight NOTIFY stickyHeaderHeightChanged)
56 Q_PROPERTY(qreal headerItemShownHeight READ headerItemShownHeight NOTIFY headerItemShownHeightChanged)
57 Q_PROPERTY(int cacheBuffer READ cacheBuffer WRITE setCacheBuffer NOTIFY cacheBufferChanged)
59 friend class ListViewWithPageHeaderTest;
60 friend class ListViewWithPageHeaderTestSection;
61 friend class ListViewWithPageHeaderTestExternalModel;
64 ListViewWithPageHeader();
65 ~ListViewWithPageHeader();
67 QAbstractItemModel *model() const;
68 void setModel(QAbstractItemModel *model);
70 QQmlComponent *delegate() const;
71 void setDelegate(QQmlComponent *delegate);
73 QQuickItem *header() const;
74 void setHeader(QQuickItem *header);
76 QQmlComponent *sectionDelegate() const;
77 void setSectionDelegate(QQmlComponent *delegate);
79 QString sectionProperty() const;
80 void setSectionProperty(const QString &property);
82 bool forceNoClip() const;
83 void setForceNoClip(bool noClip);
85 int stickyHeaderHeight() const;
86 qreal headerItemShownHeight() const;
88 int cacheBuffer() const;
89 void setCacheBuffer(int cacheBuffer);
91 Q_INVOKABLE void positionAtBeginning();
92 Q_INVOKABLE void showHeader();
93 Q_INVOKABLE int firstCreatedIndex() const;
94 Q_INVOKABLE int createdItemCount() const;
95 Q_INVOKABLE QQuickItem *item(int modelIndex) const;
97 // The index has to be created for this to try to do something
98 // Created items are those visible and the precached ones
99 // Returns if the item existed or not
100 Q_INVOKABLE bool maximizeVisibleArea(int modelIndex);
101 Q_INVOKABLE bool maximizeVisibleArea(int modelIndex, int itemHeight);
105 void delegateChanged();
106 void headerChanged();
107 void sectionDelegateChanged();
108 void sectionPropertyChanged();
109 void forceNoClipChanged();
110 void stickyHeaderHeightChanged();
111 void headerItemShownHeightChanged();
112 void cacheBufferChanged();
115 void componentComplete() override;
116 void viewportMoved(Qt::Orientations orient) override;
117 qreal minYExtent() const override;
118 void itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) override;
119 void itemImplicitHeightChanged(QQuickItem *item) override;
120 void updatePolish() override;
123 void itemCreated(int modelIndex, QObject *object);
124 void onContentHeightChanged();
125 void onContentWidthChanged();
126 void onHeightChanged();
127 void onModelUpdated(const QQmlChangeSet &changeSet, bool reset);
128 void contentYAnimationRunningChanged(bool running);
134 qreal height() const;
137 void setY(qreal newY);
140 void setCulled(bool culled);
142 QQuickItem *sectionItem() const { return m_sectionItem; }
143 void setSectionItem(QQuickItem *sectionItem);
147 QQuickItem *m_sectionItem;
150 bool maximizeVisibleArea(ListItem *listItem, int listItemHeight);
152 void createDelegateModel();
156 bool addVisibleItems(qreal fillFrom, qreal fillTo, bool asynchronous);
157 bool removeNonVisibleItems(qreal bufferFrom, qreal bufferTo);
158 ListItem *createItem(int modelIndex, bool asynchronous);
160 void adjustHeader(qreal diff);
161 void adjustMinYExtent();
162 void updateClipItem();
163 void headerHeightChanged(qreal newHeaderHeight, qreal oldHeaderHeight, qreal oldHeaderY);
164 ListItem *itemAtIndex(int modelIndex) const; // Returns the item at modelIndex if has been created
165 void releaseItem(ListItem *item);
166 void reallyReleaseItem(ListItem *item);
167 void updateWatchedRoles();
168 QQuickItem *getSectionItem(int modelIndex, bool alreadyInserted);
169 QQuickItem *getSectionItem(const QString §ionText);
170 void updateSectionItem(int modelIndex);
171 void initializeValuesForEmptyList();
173 QQmlDelegateModel *m_delegateModel;
175 // Index we are waiting because we requested it asynchronously
176 int m_asyncRequestedIndex;
178 // Used to only give a warning once if the delegate does not return objects
179 bool m_delegateValidated;
181 // Visible indexes, [0] is m_firstValidIndex, [0+1] is m_firstValidIndex +1, ...
182 QList<ListItem *> m_visibleItems;
183 int m_firstVisibleIndex;
187 QQuickItem *m_clipItem;
189 // If any of the heights has changed
190 // or new items have been added/removed
191 bool m_contentHeightDirty;
193 QQuickItem *m_headerItem;
194 qreal m_previousContentY;
195 qreal m_previousHeaderImplicitHeight;
196 qreal m_headerItemShownHeight; // The height of header shown when the header is shown outside its topmost position
197 // i.e. it's being shown after dragging down in the middle of the list
198 enum ContentYAnimationType { ContentYAnimationShowHeader, ContentYAnimationMaximizeVisibleArea };
199 ContentYAnimationType contentYAnimationType;
200 QQuickNumberAnimation *m_contentYAnimation;
202 QQmlComponent *m_sectionDelegate;
203 QString m_sectionProperty;
204 QQuickItem *m_topSectionItem;
208 bool m_inContentHeightKeepHeaderShown;
211 // Qt 5.0 doesn't like releasing the items just after itemCreated
212 // so we delay the releasing until the next updatePolish
213 QList<ListItem *> m_itemsToRelease;
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list