@@ -24,108 +24,9 @@
2424static const qreal bufferRatio = 0.5;
2525
2626OrganicGrid::OrganicGrid()
27− : m_delegateModel(nullptr)
28− , m_asyncRequestedIndex(-1)
29− , m_columnSpacing(0)
30− , m_rowSpacing(0)
31− , m_delegateCreationBegin(0)
32− , m_delegateCreationEnd(0)
33− , m_delegateCreationBeginValid(false)
34− , m_delegateCreationEndValid(false)
35− , m_needsRelayout(false)
36− , m_delegateValidated(false)
37− , m_implicitHeightDirty(false)
38− , m_firstVisibleIndex(-1)
27+ : m_firstVisibleIndex(-1)
3928 , m_numberOfModulesPerRow(-1)
4029{
41− connect(this, SIGNAL(widthChanged()), this, SLOT(relayout()));
42− connect(this, SIGNAL(heightChanged()), this, SLOT(onHeightChanged()));
43−}
44−
45−QAbstractItemModel *OrganicGrid::model() const
46−{
47− return m_delegateModel ? m_delegateModel->model().value<QAbstractItemModel *>() : nullptr;
48−}
49−
50−void OrganicGrid::setModel(QAbstractItemModel *model)
51−{
52− if (model != this->model()) {
53− if (!m_delegateModel) {
54− createDelegateModel();
55− } else {
56−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
57− disconnect(m_delegateModel, SIGNAL(modelUpdated(QQuickChangeSet,bool)), this, SLOT(onModelUpdated(QQuickChangeSet,bool)));
58− }
59− m_delegateModel->setModel(QVariant::fromValue<QAbstractItemModel *>(model));
60− connect(m_delegateModel, SIGNAL(modelUpdated(QQuickChangeSet,bool)), this, SLOT(onModelUpdated(QQuickChangeSet,bool)));
61−#else
62− disconnect(m_delegateModel, SIGNAL(modelUpdated(QQmlChangeSet,bool)), this, SLOT(onModelUpdated(QQmlChangeSet,bool)));
63− }
64− m_delegateModel->setModel(QVariant::fromValue<QAbstractItemModel *>(model));
65− connect(m_delegateModel, SIGNAL(modelUpdated(QQmlChangeSet,bool)), this, SLOT(onModelUpdated(QQmlChangeSet,bool)));
66−#endif
67−
68− cleanupExistingItems();
69−
70− Q_EMIT modelChanged();
71− polish();
72− }
73−}
74−
75−QQmlComponent *OrganicGrid::delegate() const
76−{
77− return m_delegateModel ? m_delegateModel->delegate() : nullptr;
78−}
79−
80−void OrganicGrid::setDelegate(QQmlComponent *delegate)
81−{
82− if (delegate != this->delegate()) {
83− if (!m_delegateModel) {
84− createDelegateModel();
85− }
86−
87− cleanupExistingItems();
88−
89− m_delegateModel->setDelegate(delegate);
90−
91− Q_EMIT delegateChanged();
92− m_delegateValidated = false;
93− polish();
94− }
95−}
96−
97−qreal OrganicGrid::columnSpacing() const
98−{
99− return m_columnSpacing;
100−}
101−
102−void OrganicGrid::setColumnSpacing(qreal columnSpacing)
103−{
104− if (columnSpacing != m_columnSpacing) {
105− m_columnSpacing = columnSpacing;
106− Q_EMIT columnSpacingChanged();
107−
108− if (isComponentComplete()) {
109− relayout();
110− }
111− }
112−}
113−
114−qreal OrganicGrid::rowSpacing() const
115−{
116− return m_rowSpacing;
117−}
118−
119−void OrganicGrid::setRowSpacing(qreal rowSpacing)
120−{
121− if (rowSpacing != m_rowSpacing) {
122− m_rowSpacing = rowSpacing;
123− Q_EMIT rowSpacingChanged();
124−
125− if (isComponentComplete()) {
126− relayout();
127− }
128− }
12930}
13031
13132QSizeF OrganicGrid::smallDelegateSize() const
@@ -162,272 +63,6 @@ void OrganicGrid::setBigDelegateSize(const QSizeF &size)
16263 }
16364}
16465
165−qreal OrganicGrid::delegateCreationBegin() const
166−{
167− return m_delegateCreationBegin;
168−}
169−
170−void OrganicGrid::setDelegateCreationBegin(qreal begin)
171−{
172− m_delegateCreationBeginValid = true;
173− if (m_delegateCreationBegin == begin)
174− return;
175− m_delegateCreationBegin = begin;
176− if (isComponentComplete()) {
177− polish();
178− }
179− emit delegateCreationBeginChanged();
180−}
181−
182−void OrganicGrid::resetDelegateCreationBegin()
183−{
184− m_delegateCreationBeginValid = false;
185− if (m_delegateCreationBegin == 0)
186− return;
187− m_delegateCreationBegin = 0;
188− if (isComponentComplete()) {
189− polish();
190− }
191− emit delegateCreationBeginChanged();
192−}
193−
194−qreal OrganicGrid::delegateCreationEnd() const
195−{
196− return m_delegateCreationEnd;
197−}
198−
199−void OrganicGrid::setDelegateCreationEnd(qreal end)
200−{
201− m_delegateCreationEndValid = true;
202− if (m_delegateCreationEnd == end)
203− return;
204− m_delegateCreationEnd = end;
205− if (isComponentComplete()) {
206− polish();
207− }
208− emit delegateCreationEndChanged();
209−}
210−
211−void OrganicGrid::resetDelegateCreationEnd()
212−{
213− m_delegateCreationEndValid = false;
214− if (m_delegateCreationEnd == 0)
215− return;
216− m_delegateCreationEnd = 0;
217− if (isComponentComplete()) {
218− polish();
219− }
220− emit delegateCreationEndChanged();
221−}
222−
223−void OrganicGrid::createDelegateModel()
224−{
225−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
226− m_delegateModel = new QQuickVisualDataModel(qmlContext(this), this);
227− connect(m_delegateModel, SIGNAL(createdItem(int,QQuickItem*)), this, SLOT(itemCreated(int,QQuickItem*)));
228−#else
229− m_delegateModel = new QQmlDelegateModel(qmlContext(this), this);
230− connect(m_delegateModel, SIGNAL(createdItem(int,QObject*)), this, SLOT(itemCreated(int,QObject*)));
231−#endif
232− if (isComponentComplete())
233− m_delegateModel->componentComplete();
234−}
235−
236−void OrganicGrid::refill()
237−{
238− if (!isComponentComplete()) {
239− return;
240− }
241−
242− const bool delegateRangesValid = m_delegateCreationBeginValid && m_delegateCreationEndValid;
243− const qreal from = delegateRangesValid ? m_delegateCreationBegin : 0;
244− const qreal to = delegateRangesValid ? m_delegateCreationEnd : from + height();
245− const qreal buffer = (to - from) * bufferRatio;
246− const qreal bufferFrom = from - buffer;
247− const qreal bufferTo = to + buffer;
248−
249− bool added = addVisibleItems(from, to, false);
250− bool removed = removeNonVisibleItems(bufferFrom, bufferTo);
251− added |= addVisibleItems(bufferFrom, bufferTo, true);
252−
253− if (added || removed) {
254− m_implicitHeightDirty = true;
255− polish();
256− }
257−}
258−
259−bool OrganicGrid::addVisibleItems(qreal fillFromY, qreal fillToY, bool asynchronous)
260−{
261− if (!delegate())
262− return false;
263−
264− if (m_delegateModel->count() == 0)
265− return false;
266−
267− int modelIndex;
268− qreal yPos;
269− findBottomModelIndexToAdd(&modelIndex, &yPos);
270− bool changed = false;
271− while (modelIndex < m_delegateModel->count() && yPos <= fillToY) {
272− if (!createItem(modelIndex, asynchronous))
273− break;
274−
275− changed = true;
276− findBottomModelIndexToAdd(&modelIndex, &yPos);
277− }
278−
279− findTopModelIndexToAdd(&modelIndex, &yPos);
280− while (modelIndex >= 0 && yPos > fillFromY) {
281− if (!createItem(modelIndex, asynchronous))
282− break;
283−
284− changed = true;
285− findTopModelIndexToAdd(&modelIndex, &yPos);
286− }
287−
288− return changed;
289−}
290−
291−QQuickItem *OrganicGrid::createItem(int modelIndex, bool asynchronous)
292−{
293− if (asynchronous && m_asyncRequestedIndex != -1)
294− return nullptr;
295−
296− m_asyncRequestedIndex = -1;
297−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
298− QQuickItem *item = m_delegateModel->item(modelIndex, asynchronous);
299−#else
300− QObject* object = m_delegateModel->object(modelIndex, asynchronous);
301− QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
302−#endif
303− if (!item) {
304−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
305− m_asyncRequestedIndex = modelIndex;
306−#else
307− if (object) {
308− m_delegateModel->release(object);
309− if (!m_delegateValidated) {
310− m_delegateValidated = true;
311− QObject* delegateObj = delegate();
312− qmlInfo(delegateObj ? delegateObj : this) << "Delegate must be of Item type";
313− }
314− } else {
315− m_asyncRequestedIndex = modelIndex;
316− }
317−#endif
318− return nullptr;
319− } else {
320− positionItem(modelIndex, item);
321− return item;
322− }
323−}
324−
325−void OrganicGrid::releaseItem(QQuickItem *item)
326−{
327−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
328− QQuickVisualModel::ReleaseFlags flags = m_delegateModel->release(item);
329− if (flags & QQuickVisualModel::Destroyed) {
330−#else
331− QQmlDelegateModel::ReleaseFlags flags = m_delegateModel->release(item);
332− if (flags & QQmlDelegateModel::Destroyed) {
333−#endif
334− item->setParentItem(nullptr);
335− }
336−}
337−
338−void OrganicGrid::setImplicitHeightDirty()
339−{
340− m_implicitHeightDirty = true;
341−}
342−
343−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
344−void OrganicGrid::itemCreated(int modelIndex, QQuickItem *item)
345−{
346−#else
347−void OrganicGrid::itemCreated(int modelIndex, QObject *object)
348−{
349− QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
350− if (!item) {
351− qWarning() << "OrganicGrid::itemCreated got a non item for index" << modelIndex;
352− return;
353− }
354−#endif
355− item->setParentItem(this);
356−
357− // We only need to call createItem if we are here because of an asynchronous generation
358− // otherwise we are in this slot because createItem is creating the item sync
359− // and thus we don't need to call createItem again, nor need to set m_implicitHeightDirty
360− // and call polish because the sync createItem was called from addVisibleItems that
361− // is called from refill that will already do those if an item was added
362− if (modelIndex == m_asyncRequestedIndex) {
363− createItem(modelIndex, false);
364− m_implicitHeightDirty = true;
365− polish();
366− }
367−}
368−
369−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
370−void OrganicGrid::onModelUpdated(const QQuickChangeSet &changeSet, bool reset)
371−#else
372−void OrganicGrid::onModelUpdated(const QQmlChangeSet &changeSet, bool reset)
373−#endif
374−{
375− if (reset) {
376− cleanupExistingItems();
377− } else {
378− processModelRemoves(changeSet.removes());
379− }
380− polish();
381−}
382−
383−
384−void OrganicGrid::relayout()
385−{
386− m_needsRelayout = true;
387− polish();
388−}
389−
390−void OrganicGrid::onHeightChanged()
391−{
392− polish();
393−}
394−
395−void OrganicGrid::updatePolish()
396−{
397− if (!model())
398− return;
399−
400− if (m_needsRelayout) {
401− doRelayout();
402− m_needsRelayout = false;
403− m_implicitHeightDirty = true;
404− }
405−
406− refill();
407−
408− const bool delegateRangesValid = m_delegateCreationBeginValid && m_delegateCreationEndValid;
409− const qreal from = delegateRangesValid ? m_delegateCreationBegin : 0;
410− const qreal to = delegateRangesValid ? m_delegateCreationEnd : from + height();
411− updateItemCulling(from, to);
412−
413− if (m_implicitHeightDirty) {
414− calculateImplicitHeight();
415− m_implicitHeightDirty = false;
416− }
417−}
418−
419−void OrganicGrid::componentComplete()
420−{
421− if (m_delegateModel)
422− m_delegateModel->componentComplete();
423−
424− QQuickItem::componentComplete();
425−
426− m_needsRelayout = true;
427−
428− polish();
429−}
430−
43166QPointF OrganicGrid::positionForIndex(int modelIndex) const
43267{
43368 const qreal moduleHeight = m_smallDelegateSize.height() + rowSpacing() + m_bigDelegateSize.height();
@@ -559,7 +194,7 @@ void OrganicGrid::cleanupExistingItems()
559194 releaseItem(item);
560195 m_visibleItems.clear();
561196 m_firstVisibleIndex = -1;
562− m_implicitHeightDirty = true;
197+ setImplicitHeightDirty();
563198}
564199
565200void OrganicGrid::doRelayout()
@@ -587,7 +222,7 @@ void OrganicGrid::updateItemCulling(qreal visibleFromY, qreal visibleToY)
587222void OrganicGrid::calculateImplicitHeight()
588223{
589224 const qreal moduleHeight = m_smallDelegateSize.height() + rowSpacing() + m_bigDelegateSize.height();
590− const int itemCount = !m_delegateModel ? 0 : m_delegateModel->count();
225+ const int itemCount = !model() ? 0 : model()->rowCount();
591226 const int fullRows = floor(itemCount / (m_numberOfModulesPerRow * 6));
592227 const qreal fullRowsHeight = fullRows == 0 ? 0 : fullRows * moduleHeight + rowSpacing() * (fullRows - 1);
593228