1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtQuick module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #ifndef QQUICKITEMVIEW_P_H
41 #define QQUICKITEMVIEW_P_H
42 
43 //
44 //  W A R N I N G
45 //  -------------
46 //
47 // This file is not part of the Qt API.  It exists purely as an
48 // implementation detail.  This header file may change from version to
49 // version without notice, or even be removed.
50 //
51 // We mean it.
52 //
53 
54 #include <QtQuick/private/qtquickglobal_p.h>
55 
56 QT_REQUIRE_CONFIG(quick_itemview);
57 
58 #include "qquickflickable_p.h"
59 #include <qpointer.h>
60 #include <QtCore/QLoggingCategory>
61 
62 QT_BEGIN_NAMESPACE
63 
64 Q_DECLARE_LOGGING_CATEGORY(lcItemViewDelegateLifecycle)
65 
66 class QQmlChangeSet;
67 
68 class QQuickItemViewPrivate;
69 
70 class Q_QUICK_PRIVATE_EXPORT QQuickItemView : public QQuickFlickable
71 {
72     Q_OBJECT
73 
74     Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged)
75     Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
76     Q_PROPERTY(int count READ count NOTIFY countChanged)
77 
78     Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
79     Q_PROPERTY(QQuickItem *currentItem READ currentItem NOTIFY currentItemChanged)
80 
81     Q_PROPERTY(bool keyNavigationWraps READ isWrapEnabled WRITE setWrapEnabled NOTIFY keyNavigationWrapsChanged)
82     Q_PROPERTY(bool keyNavigationEnabled READ isKeyNavigationEnabled WRITE setKeyNavigationEnabled NOTIFY keyNavigationEnabledChanged REVISION 7)
83     Q_PROPERTY(int cacheBuffer READ cacheBuffer WRITE setCacheBuffer NOTIFY cacheBufferChanged)
84     Q_PROPERTY(int displayMarginBeginning READ displayMarginBeginning WRITE setDisplayMarginBeginning NOTIFY displayMarginBeginningChanged REVISION 3)
85     Q_PROPERTY(int displayMarginEnd READ displayMarginEnd WRITE setDisplayMarginEnd NOTIFY displayMarginEndChanged REVISION 3)
86 
87     Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
88     Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged)
89     Q_PROPERTY(VerticalLayoutDirection verticalLayoutDirection READ verticalLayoutDirection WRITE setVerticalLayoutDirection NOTIFY verticalLayoutDirectionChanged)
90 
91     Q_PROPERTY(QQmlComponent *header READ header WRITE setHeader NOTIFY headerChanged)
92     Q_PROPERTY(QQuickItem *headerItem READ headerItem NOTIFY headerItemChanged)
93     Q_PROPERTY(QQmlComponent *footer READ footer WRITE setFooter NOTIFY footerChanged)
94     Q_PROPERTY(QQuickItem *footerItem READ footerItem NOTIFY footerItemChanged)
95 
96     Q_PROPERTY(QQuickTransition *populate READ populateTransition WRITE setPopulateTransition NOTIFY populateTransitionChanged)
97     Q_PROPERTY(QQuickTransition *add READ addTransition WRITE setAddTransition NOTIFY addTransitionChanged)
98     Q_PROPERTY(QQuickTransition *addDisplaced READ addDisplacedTransition WRITE setAddDisplacedTransition NOTIFY addDisplacedTransitionChanged)
99     Q_PROPERTY(QQuickTransition *move READ moveTransition WRITE setMoveTransition NOTIFY moveTransitionChanged)
100     Q_PROPERTY(QQuickTransition *moveDisplaced READ moveDisplacedTransition WRITE setMoveDisplacedTransition NOTIFY moveDisplacedTransitionChanged)
101     Q_PROPERTY(QQuickTransition *remove READ removeTransition WRITE setRemoveTransition NOTIFY removeTransitionChanged)
102     Q_PROPERTY(QQuickTransition *removeDisplaced READ removeDisplacedTransition WRITE setRemoveDisplacedTransition NOTIFY removeDisplacedTransitionChanged)
103     Q_PROPERTY(QQuickTransition *displaced READ displacedTransition WRITE setDisplacedTransition NOTIFY displacedTransitionChanged)
104 
105     Q_PROPERTY(QQmlComponent *highlight READ highlight WRITE setHighlight NOTIFY highlightChanged)
106     Q_PROPERTY(QQuickItem *highlightItem READ highlightItem NOTIFY highlightItemChanged)
107     Q_PROPERTY(bool highlightFollowsCurrentItem READ highlightFollowsCurrentItem WRITE setHighlightFollowsCurrentItem NOTIFY highlightFollowsCurrentItemChanged)
108     Q_PROPERTY(HighlightRangeMode highlightRangeMode READ highlightRangeMode WRITE setHighlightRangeMode NOTIFY highlightRangeModeChanged)
109     Q_PROPERTY(qreal preferredHighlightBegin READ preferredHighlightBegin WRITE setPreferredHighlightBegin NOTIFY preferredHighlightBeginChanged RESET resetPreferredHighlightBegin)
110     Q_PROPERTY(qreal preferredHighlightEnd READ preferredHighlightEnd WRITE setPreferredHighlightEnd NOTIFY preferredHighlightEndChanged RESET resetPreferredHighlightEnd)
111     Q_PROPERTY(int highlightMoveDuration READ highlightMoveDuration WRITE setHighlightMoveDuration NOTIFY highlightMoveDurationChanged)
112 
113     Q_PROPERTY(bool reuseItems READ reuseItems WRITE setReuseItems NOTIFY reuseItemsChanged REVISION 15)
114 
115     QML_NAMED_ELEMENT(ItemView)
116     QML_UNCREATABLE("ItemView is an abstract base class.")
117     QML_ADDED_IN_MINOR_VERSION(1)
118 
119 public:
120     // this holds all layout enum values so they can be referred to by other enums
121     // to ensure consistent values - e.g. QML references to GridView.TopToBottom flow
122     // and GridView.TopToBottom vertical layout direction should have same value
123     enum LayoutDirection {
124         LeftToRight = Qt::LeftToRight,
125         RightToLeft = Qt::RightToLeft,
126         VerticalTopToBottom,
127         VerticalBottomToTop
128     };
129     Q_ENUM(LayoutDirection)
130 
131     enum VerticalLayoutDirection {
132         TopToBottom = VerticalTopToBottom,
133         BottomToTop = VerticalBottomToTop
134     };
135     Q_ENUM(VerticalLayoutDirection)
136 
137     QQuickItemView(QQuickFlickablePrivate &dd, QQuickItem *parent = nullptr);
138     ~QQuickItemView();
139 
140     QVariant model() const;
141     void setModel(const QVariant &);
142 
143     QQmlComponent *delegate() const;
144     void setDelegate(QQmlComponent *);
145 
146     int count() const;
147 
148     int currentIndex() const;
149     void setCurrentIndex(int idx);
150 
151     QQuickItem *currentItem() const;
152 
153     bool isWrapEnabled() const;
154     void setWrapEnabled(bool);
155 
156     bool isKeyNavigationEnabled() const;
157     void setKeyNavigationEnabled(bool);
158 
159     int cacheBuffer() const;
160     void setCacheBuffer(int);
161 
162     int displayMarginBeginning() const;
163     void setDisplayMarginBeginning(int);
164 
165     int displayMarginEnd() const;
166     void setDisplayMarginEnd(int);
167 
168     Qt::LayoutDirection layoutDirection() const;
169     void setLayoutDirection(Qt::LayoutDirection);
170     Qt::LayoutDirection effectiveLayoutDirection() const;
171 
172     VerticalLayoutDirection verticalLayoutDirection() const;
173     void setVerticalLayoutDirection(VerticalLayoutDirection layoutDirection);
174 
175     QQmlComponent *footer() const;
176     void setFooter(QQmlComponent *);
177     QQuickItem *footerItem() const;
178 
179     QQmlComponent *header() const;
180     void setHeader(QQmlComponent *);
181     QQuickItem *headerItem() const;
182 
183     QQuickTransition *populateTransition() const;
184     void setPopulateTransition(QQuickTransition *transition);
185 
186     QQuickTransition *addTransition() const;
187     void setAddTransition(QQuickTransition *transition);
188 
189     QQuickTransition *addDisplacedTransition() const;
190     void setAddDisplacedTransition(QQuickTransition *transition);
191 
192     QQuickTransition *moveTransition() const;
193     void setMoveTransition(QQuickTransition *transition);
194 
195     QQuickTransition *moveDisplacedTransition() const;
196     void setMoveDisplacedTransition(QQuickTransition *transition);
197 
198     QQuickTransition *removeTransition() const;
199     void setRemoveTransition(QQuickTransition *transition);
200 
201     QQuickTransition *removeDisplacedTransition() const;
202     void setRemoveDisplacedTransition(QQuickTransition *transition);
203 
204     QQuickTransition *displacedTransition() const;
205     void setDisplacedTransition(QQuickTransition *transition);
206 
207     QQmlComponent *highlight() const;
208     void setHighlight(QQmlComponent *);
209 
210     QQuickItem *highlightItem() const;
211 
212     bool highlightFollowsCurrentItem() const;
213     virtual void setHighlightFollowsCurrentItem(bool);
214 
215     enum HighlightRangeMode { NoHighlightRange, ApplyRange, StrictlyEnforceRange };
216     Q_ENUM(HighlightRangeMode)
217     HighlightRangeMode highlightRangeMode() const;
218     void setHighlightRangeMode(HighlightRangeMode mode);
219 
220     qreal preferredHighlightBegin() const;
221     void setPreferredHighlightBegin(qreal);
222     void resetPreferredHighlightBegin();
223 
224     qreal preferredHighlightEnd() const;
225     void setPreferredHighlightEnd(qreal);
226     void resetPreferredHighlightEnd();
227 
228     int highlightMoveDuration() const;
229     virtual void setHighlightMoveDuration(int);
230 
231     bool reuseItems() const;
232     void setReuseItems(bool reuse);
233 
234     enum PositionMode { Beginning, Center, End, Visible, Contain, SnapPosition };
235     Q_ENUM(PositionMode)
236 
237     Q_INVOKABLE void positionViewAtIndex(int index, int mode);
238     Q_INVOKABLE int indexAt(qreal x, qreal y) const;
239     Q_INVOKABLE QQuickItem *itemAt(qreal x, qreal y) const;
240     Q_REVISION(13) Q_INVOKABLE QQuickItem *itemAtIndex(int index) const;
241     Q_INVOKABLE void positionViewAtBeginning();
242     Q_INVOKABLE void positionViewAtEnd();
243     Q_REVISION(1) Q_INVOKABLE void forceLayout();
244 
245     void setContentX(qreal pos) override;
246     void setContentY(qreal pos) override;
247     qreal originX() const override;
248     qreal originY() const override;
249 
250 Q_SIGNALS:
251     void modelChanged();
252     void delegateChanged();
253     void countChanged();
254     void currentIndexChanged();
255     void currentItemChanged();
256 
257     void keyNavigationWrapsChanged();
258     Q_REVISION(7) void keyNavigationEnabledChanged();
259     void cacheBufferChanged();
260     void displayMarginBeginningChanged();
261     void displayMarginEndChanged();
262 
263     void layoutDirectionChanged();
264     void effectiveLayoutDirectionChanged();
265     void verticalLayoutDirectionChanged();
266 
267     void headerChanged();
268     void footerChanged();
269     void headerItemChanged();
270     void footerItemChanged();
271 
272     void populateTransitionChanged();
273     void addTransitionChanged();
274     void addDisplacedTransitionChanged();
275     void moveTransitionChanged();
276     void moveDisplacedTransitionChanged();
277     void removeTransitionChanged();
278     void removeDisplacedTransitionChanged();
279     void displacedTransitionChanged();
280 
281     void highlightChanged();
282     void highlightItemChanged();
283     void highlightFollowsCurrentItemChanged();
284     void highlightRangeModeChanged();
285     void preferredHighlightBeginChanged();
286     void preferredHighlightEndChanged();
287     void highlightMoveDurationChanged();
288 
289     Q_REVISION(15) void reuseItemsChanged();
290 
291 protected:
292     void updatePolish() override;
293     void componentComplete() override;
294     void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
295     qreal minYExtent() const override;
296     qreal maxYExtent() const override;
297     qreal minXExtent() const override;
298     qreal maxXExtent() const override;
299 
300 protected Q_SLOTS:
301     void destroyRemoved();
302     void createdItem(int index, QObject *item);
303     virtual void initItem(int index, QObject *item);
304     void modelUpdated(const QQmlChangeSet &changeSet, bool reset);
305     void destroyingItem(QObject *item);
306     Q_REVISION(15) void onItemPooled(int modelIndex, QObject *object);
307     Q_REVISION(15) void onItemReused(int modelIndex, QObject *object);
308     void animStopped();
309     void trackedPositionChanged();
310 
311 private:
312     Q_DECLARE_PRIVATE(QQuickItemView)
313 };
314 
315 
316 class Q_QUICK_PRIVATE_EXPORT QQuickItemViewAttached : public QObject
317 {
318     Q_OBJECT
319 
Q_PROPERTY(QQuickItemView * view READ view NOTIFY viewChanged)320     Q_PROPERTY(QQuickItemView *view READ view NOTIFY viewChanged)
321     Q_PROPERTY(bool isCurrentItem READ isCurrentItem NOTIFY currentItemChanged)
322     Q_PROPERTY(bool delayRemove READ delayRemove WRITE setDelayRemove NOTIFY delayRemoveChanged)
323 
324     Q_PROPERTY(QString section READ section NOTIFY sectionChanged)
325     Q_PROPERTY(QString previousSection READ prevSection NOTIFY prevSectionChanged)
326     Q_PROPERTY(QString nextSection READ nextSection NOTIFY nextSectionChanged)
327 
328 public:
329     QQuickItemViewAttached(QObject *parent)
330         : QObject(parent), m_isCurrent(false), m_delayRemove(false) {}
~QQuickItemViewAttached()331     ~QQuickItemViewAttached() {}
332 
view()333     QQuickItemView *view() const { return m_view; }
setView(QQuickItemView * view)334     void setView(QQuickItemView *view) {
335         if (view != m_view) {
336             m_view = view;
337             Q_EMIT viewChanged();
338         }
339     }
340 
isCurrentItem()341     bool isCurrentItem() const { return m_isCurrent; }
setIsCurrentItem(bool c)342     void setIsCurrentItem(bool c) {
343         if (m_isCurrent != c) {
344             m_isCurrent = c;
345             Q_EMIT currentItemChanged();
346         }
347     }
348 
delayRemove()349     bool delayRemove() const { return m_delayRemove; }
setDelayRemove(bool delay)350     void setDelayRemove(bool delay) {
351         if (m_delayRemove != delay) {
352             m_delayRemove = delay;
353             Q_EMIT delayRemoveChanged();
354         }
355     }
356 
section()357     QString section() const { return m_section; }
setSection(const QString & sect)358     void setSection(const QString &sect) {
359         if (m_section != sect) {
360             m_section = sect;
361             Q_EMIT sectionChanged();
362         }
363     }
364 
prevSection()365     QString prevSection() const { return m_prevSection; }
setPrevSection(const QString & sect)366     void setPrevSection(const QString &sect) {
367         if (m_prevSection != sect) {
368             m_prevSection = sect;
369             Q_EMIT prevSectionChanged();
370         }
371     }
372 
nextSection()373     QString nextSection() const { return m_nextSection; }
setNextSection(const QString & sect)374     void setNextSection(const QString &sect) {
375         if (m_nextSection != sect) {
376             m_nextSection = sect;
377             Q_EMIT nextSectionChanged();
378         }
379     }
380 
setSections(const QString & prev,const QString & sect,const QString & next)381     void setSections(const QString &prev, const QString &sect, const QString &next) {
382         bool prevChanged = prev != m_prevSection;
383         bool sectChanged = sect != m_section;
384         bool nextChanged = next != m_nextSection;
385         m_prevSection = prev;
386         m_section = sect;
387         m_nextSection = next;
388         if (prevChanged)
389             Q_EMIT prevSectionChanged();
390         if (sectChanged)
391             Q_EMIT sectionChanged();
392         if (nextChanged)
393             Q_EMIT nextSectionChanged();
394     }
395 
emitAdd()396     void emitAdd() { Q_EMIT add(); }
emitRemove()397     void emitRemove() { Q_EMIT remove(); }
398 
399 Q_SIGNALS:
400     void viewChanged();
401     void currentItemChanged();
402     void delayRemoveChanged();
403 
404     void add();
405     void remove();
406 
407     void sectionChanged();
408     void prevSectionChanged();
409     void nextSectionChanged();
410 
411     void pooled();
412     void reused();
413 
414 public:
415     QPointer<QQuickItemView> m_view;
416     bool m_isCurrent : 1;
417     bool m_delayRemove : 1;
418 
419     // current only used by list view
420     mutable QString m_section;
421     QString m_prevSection;
422     QString m_nextSection;
423 };
424 
425 
426 QT_END_NAMESPACE
427 
428 #endif // QQUICKITEMVIEW_P_H
429 
430