File indexing completed on 2024-04-28 15:27:41
0001 /* 0002 * SPDX-FileCopyrightText: 2018 Marco Martin <mart@kde.org> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #ifndef DELEGATERECYCLER_H 0008 #define DELEGATERECYCLER_H 0009 0010 #include <QPointer> 0011 #include <QQuickItem> 0012 #include <QVariant> 0013 0014 class DelegateRecyclerAttached : public QObject 0015 { 0016 Q_OBJECT 0017 0018 public: 0019 DelegateRecyclerAttached(QObject *parent = nullptr); 0020 ~DelegateRecyclerAttached() override; 0021 0022 Q_SIGNALS: 0023 void pooled(); 0024 void reused(); 0025 }; 0026 0027 /** 0028 * This class may be used as a delegate of a QtQuick.ListView or a QtQuick.GridView 0029 * in the case the intended delegate is a bit heavy, with many objects inside. 0030 * This will ensure the delegate instances will be put back in a common pool after 0031 * destruction, so when scrolling a big list, the delegates from old delete items will 0032 * be taken from the pool and reused, minimizing the need of instantiating new objects 0033 * and deleting old ones. It ensures scrolling of lists with heavy delegates is 0034 * smoother and helps with memory fragmentations as well. 0035 * 0036 * @note org::kde::kirigami::CardsListView and org::kde::kirigami::CardsGridView 0037 * are already using this recycler, so do NOT use it as a delegate for those 2 views. 0038 * Also, do NOT use this with a QtQuick.Repeater. 0039 * 0040 * @since org.kde.kirigami 2.4 0041 */ 0042 class DelegateRecycler : public QQuickItem 0043 { 0044 Q_OBJECT 0045 0046 /** 0047 * The Component the actual delegates will be built from. 0048 * 0049 * @note the component may not be a child of this object, therefore it can't be 0050 * declared inside the DelegateRecycler declaration. 0051 * 0052 * The DelegateRecycler will not take ownership of the delegate Component, so it's up 0053 * to the caller to delete it (usually with the normal child/parent relationship) 0054 */ 0055 Q_PROPERTY(QQmlComponent *sourceComponent READ sourceComponent WRITE setSourceComponent RESET resetSourceComponent NOTIFY sourceComponentChanged) 0056 0057 public: 0058 DelegateRecycler(QQuickItem *parent = nullptr); 0059 ~DelegateRecycler() override; 0060 0061 QQmlComponent *sourceComponent() const; 0062 void setSourceComponent(QQmlComponent *component); 0063 void resetSourceComponent(); 0064 0065 static DelegateRecyclerAttached *qmlAttachedProperties(QObject *object); 0066 0067 protected: 0068 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0069 void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; 0070 #else 0071 void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; 0072 #endif 0073 void focusInEvent(QFocusEvent *event) override; 0074 0075 void updateHints(); 0076 void updateSize(bool parentResized); 0077 0078 Q_SIGNALS: 0079 void sourceComponentChanged(); 0080 0081 private Q_SLOTS: 0082 void syncIndex(); 0083 void syncModel(); 0084 void syncModelProperties(); 0085 void syncModelData(); 0086 0087 private: 0088 QPointer<QQmlComponent> m_sourceComponent; 0089 QPointer<QQuickItem> m_item; 0090 QObject *m_propertiesTracker = nullptr; 0091 bool m_updatingSize = false; 0092 bool m_widthFromItem = false; 0093 bool m_heightFromItem = false; 0094 }; 0095 0096 QML_DECLARE_TYPEINFO(DelegateRecycler, QML_HAS_ATTACHED_PROPERTIES) 0097 0098 #endif