QmlMaterial 0.1.0
Loading...
Searching...
No Matches
item_source.hpp
1#pragma once
2
3#include <QObject>
4#include <QHash>
5#include <QVariant>
6#include <QVector>
7#include <QtQml/qqmlregistration.h>
8#include <memory>
9#include "qml_material/export.hpp"
10
11namespace qml_material
12{
13struct ItemRecord {
14 QString key;
15 QString reuseType;
16 QVariant value;
17 // Zero asks the publisher to infer a version from stable identity and value equality.
18 quint64 contentRevision = 0;
19};
20
21struct ItemSnapshot {
22 quint64 revision = 0;
23 QVector<ItemRecord> rows;
24 QHash<QString, int> indexes;
25 QString error;
26 bool stableKeys = false;
27
28 int indexOfKey(const QString& key) const { return indexes.value(key, -1); }
29};
30using ItemSnapshotPtr = std::shared_ptr<const ItemSnapshot>;
31
32struct ItemChange {
33 enum Kind
34 {
35 Insert,
36 Remove,
37 Move,
38 Update
39 };
40 Kind kind = Update;
41 int index = 0;
42 int count = 0;
43 // Move destination is an index after the moved range has been removed.
44 int destination = 0;
45};
46
47struct ItemChangeSet {
48 ItemSnapshotPtr before;
49 ItemSnapshotPtr after;
50 QVector<ItemChange> changes;
51 bool reset = false;
52};
53
54class QML_MATERIAL_API ItemSource : public QObject {
55 Q_OBJECT
56 QML_NAMED_ELEMENT(ItemSource)
57 QML_UNCREATABLE("Use an item source adapter")
58 Q_PROPERTY(int count READ count NOTIFY stateChanged FINAL)
59 Q_PROPERTY(quint64 revision READ revision NOTIFY stateChanged FINAL)
60 Q_PROPERTY(bool stableKeys READ stableKeys NOTIFY stateChanged FINAL)
61 Q_PROPERTY(QString errorString READ errorString NOTIFY stateChanged FINAL)
62public:
63 explicit ItemSource(QObject* parent = nullptr);
64 ItemSnapshotPtr snapshot() const { return m_snapshot; }
65 int count() const { return int(m_snapshot->rows.size()); }
66 quint64 revision() const { return m_snapshot->revision; }
67 bool stableKeys() const { return m_snapshot->stableKeys; }
68 QString errorString() const { return m_snapshot->error; }
69 Q_INVOKABLE int indexOfKey(const QString& key) const { return m_snapshot->indexOfKey(key); }
70 Q_INVOKABLE virtual void requestMore();
71 Q_SIGNAL void stateChanged();
72 Q_SIGNAL void fetchStateChanged();
73 Q_SIGNAL void committed(const qml_material::ItemChangeSet& change);
74
75protected:
76 void publish(QVector<ItemRecord>, bool stableKeys, QVector<ItemChange> changes = {},
77 bool reset = true, QString error = {});
78
79private:
80 ItemSnapshotPtr m_snapshot;
81 QList<ItemChangeSet> m_pending;
82 bool m_publishing = false;
83};
84
85class QML_MATERIAL_API ListSnapshotSource : public ItemSource {
86 Q_OBJECT
87 QML_ELEMENT
88 Q_PROPERTY(QVariantList items READ items WRITE setItems NOTIFY itemsChanged FINAL)
89 Q_PROPERTY(QString keyRole READ keyRole WRITE setKeyRole NOTIFY keyRoleChanged FINAL)
90 Q_PROPERTY(QString typeRole READ typeRole WRITE setTypeRole NOTIFY typeRoleChanged FINAL)
91public:
92 using ItemSource::ItemSource;
93 QVariantList items() const { return m_items; }
94 QString keyRole() const { return m_keyRole; }
95 QString typeRole() const { return m_typeRole; }
96 void setItems(const QVariantList&);
97 void setKeyRole(const QString&);
98 void setTypeRole(const QString&);
99 Q_SIGNAL void itemsChanged();
100 Q_SIGNAL void keyRoleChanged();
101 Q_SIGNAL void typeRoleChanged();
102
103private:
104 void rebuild();
105 QVariantList m_items;
106 QString m_keyRole, m_typeRole;
107};
108} // namespace qml_material
109Q_DECLARE_METATYPE(qml_material::ItemChangeSet)