17 #include "abstractdashview.h"
19 static const qreal bufferRatio = 0.5;
21 AbstractDashView::AbstractDashView()
22 : m_delegateModel(nullptr)
23 , m_asyncRequestedIndex(-1)
26 , m_delegateCreationBegin(0)
27 , m_delegateCreationEnd(0)
28 , m_delegateCreationBeginValid(false)
29 , m_delegateCreationEndValid(false)
30 , m_needsRelayout(false)
31 , m_delegateValidated(false)
32 , m_implicitHeightDirty(false)
34 connect(
this, SIGNAL(widthChanged()),
this, SLOT(relayout()));
35 connect(
this, SIGNAL(heightChanged()),
this, SLOT(onHeightChanged()));
38 QAbstractItemModel *AbstractDashView::model()
const
40 return m_delegateModel ? m_delegateModel->model().value<QAbstractItemModel *>() :
nullptr;
43 void AbstractDashView::setModel(QAbstractItemModel *model)
45 if (model != this->model()) {
46 if (!m_delegateModel) {
47 createDelegateModel();
49 #if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
50 disconnect(m_delegateModel, SIGNAL(modelUpdated(QQuickChangeSet,
bool)),
this, SLOT(onModelUpdated(QQuickChangeSet,
bool)));
52 m_delegateModel->setModel(QVariant::fromValue<QAbstractItemModel *>(model));
53 connect(m_delegateModel, SIGNAL(modelUpdated(QQuickChangeSet,
bool)),
this, SLOT(onModelUpdated(QQuickChangeSet,
bool)));
55 disconnect(m_delegateModel, SIGNAL(modelUpdated(QQmlChangeSet,
bool)),
this, SLOT(onModelUpdated(QQmlChangeSet,
bool)));
57 m_delegateModel->setModel(QVariant::fromValue<QAbstractItemModel *>(model));
58 connect(m_delegateModel, SIGNAL(modelUpdated(QQmlChangeSet,
bool)),
this, SLOT(onModelUpdated(QQmlChangeSet,
bool)));
61 cleanupExistingItems();
63 Q_EMIT modelChanged();
68 QQmlComponent *AbstractDashView::delegate()
const
70 return m_delegateModel ? m_delegateModel->delegate() :
nullptr;
73 void AbstractDashView::setDelegate(QQmlComponent *delegate)
75 if (delegate != this->delegate()) {
76 if (!m_delegateModel) {
77 createDelegateModel();
80 cleanupExistingItems();
82 m_delegateModel->setDelegate(delegate);
84 Q_EMIT delegateChanged();
85 m_delegateValidated =
false;
90 qreal AbstractDashView::columnSpacing()
const
92 return m_columnSpacing;
95 void AbstractDashView::setColumnSpacing(qreal columnSpacing)
97 if (columnSpacing != m_columnSpacing) {
98 m_columnSpacing = columnSpacing;
99 Q_EMIT columnSpacingChanged();
101 if (isComponentComplete()) {
107 qreal AbstractDashView::rowSpacing()
const
112 void AbstractDashView::setRowSpacing(qreal rowSpacing)
114 if (rowSpacing != m_rowSpacing) {
115 m_rowSpacing = rowSpacing;
116 Q_EMIT rowSpacingChanged();
118 if (isComponentComplete()) {
124 qreal AbstractDashView::delegateCreationBegin()
const
126 return m_delegateCreationBegin;
129 void AbstractDashView::setDelegateCreationBegin(qreal begin)
131 m_delegateCreationBeginValid =
true;
132 if (m_delegateCreationBegin == begin)
134 m_delegateCreationBegin = begin;
135 if (isComponentComplete()) {
138 emit delegateCreationBeginChanged();
141 void AbstractDashView::resetDelegateCreationBegin()
143 m_delegateCreationBeginValid =
false;
144 if (m_delegateCreationBegin == 0)
146 m_delegateCreationBegin = 0;
147 if (isComponentComplete()) {
150 emit delegateCreationBeginChanged();
153 qreal AbstractDashView::delegateCreationEnd()
const
155 return m_delegateCreationEnd;
158 void AbstractDashView::setDelegateCreationEnd(qreal end)
160 m_delegateCreationEndValid =
true;
161 if (m_delegateCreationEnd == end)
163 m_delegateCreationEnd = end;
164 if (isComponentComplete()) {
167 emit delegateCreationEndChanged();
170 void AbstractDashView::resetDelegateCreationEnd()
172 m_delegateCreationEndValid =
false;
173 if (m_delegateCreationEnd == 0)
175 m_delegateCreationEnd = 0;
176 if (isComponentComplete()) {
179 emit delegateCreationEndChanged();
182 void AbstractDashView::createDelegateModel()
184 #if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
185 m_delegateModel =
new QQuickVisualDataModel(qmlContext(
this),
this);
186 connect(m_delegateModel, SIGNAL(createdItem(
int,QQuickItem*)),
this, SLOT(itemCreated(
int,QQuickItem*)));
188 m_delegateModel =
new QQmlDelegateModel(qmlContext(
this),
this);
189 connect(m_delegateModel, SIGNAL(createdItem(
int,QObject*)),
this, SLOT(itemCreated(
int,QObject*)));
191 if (isComponentComplete())
192 m_delegateModel->componentComplete();
195 void AbstractDashView::refill()
197 if (!isComponentComplete() || height() < 0) {
201 const bool delegateRangesValid = m_delegateCreationBeginValid && m_delegateCreationEndValid;
202 const qreal from = delegateRangesValid ? m_delegateCreationBegin : 0;
203 const qreal to = delegateRangesValid ? m_delegateCreationEnd : from + height();
204 const qreal buffer = (to - from) * bufferRatio;
205 const qreal bufferFrom = from - buffer;
206 const qreal bufferTo = to + buffer;
208 bool added = addVisibleItems(from, to,
false);
209 bool removed = removeNonVisibleItems(bufferFrom, bufferTo);
210 added |= addVisibleItems(bufferFrom, bufferTo,
true);
212 if (added || removed) {
213 m_implicitHeightDirty =
true;
218 bool AbstractDashView::addVisibleItems(qreal fillFromY, qreal fillToY,
bool asynchronous)
223 if (m_delegateModel->count() == 0)
228 findBottomModelIndexToAdd(&modelIndex, &yPos);
229 bool changed =
false;
230 while (modelIndex < m_delegateModel->count() && yPos <= fillToY) {
231 if (!createItem(modelIndex, asynchronous))
235 findBottomModelIndexToAdd(&modelIndex, &yPos);
238 findTopModelIndexToAdd(&modelIndex, &yPos);
239 while (modelIndex >= 0 && yPos > fillFromY) {
240 if (!createItem(modelIndex, asynchronous))
244 findTopModelIndexToAdd(&modelIndex, &yPos);
250 QQuickItem *AbstractDashView::createItem(
int modelIndex,
bool asynchronous)
252 if (asynchronous && m_asyncRequestedIndex != -1)
255 m_asyncRequestedIndex = -1;
256 #if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
257 QQuickItem *item = m_delegateModel->item(modelIndex, asynchronous);
259 QObject*
object = m_delegateModel->object(modelIndex, asynchronous);
260 QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
263 #if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
264 m_asyncRequestedIndex = modelIndex;
267 m_delegateModel->release(
object);
268 if (!m_delegateValidated) {
269 m_delegateValidated =
true;
270 QObject* delegateObj = delegate();
271 qmlInfo(delegateObj ? delegateObj :
this) <<
"Delegate must be of Item type";
274 m_asyncRequestedIndex = modelIndex;
279 addItemToView(modelIndex, item);
284 void AbstractDashView::releaseItem(QQuickItem *item)
286 #if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
287 QQuickVisualModel::ReleaseFlags flags = m_delegateModel->release(item);
288 if (flags & QQuickVisualModel::Destroyed) {
290 QQmlDelegateModel::ReleaseFlags flags = m_delegateModel->release(item);
291 if (flags & QQmlDelegateModel::Destroyed) {
293 item->setParentItem(
nullptr);
297 void AbstractDashView::setImplicitHeightDirty()
299 m_implicitHeightDirty =
true;
302 #if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
303 void AbstractDashView::itemCreated(
int modelIndex, QQuickItem *item)
306 void AbstractDashView::itemCreated(
int modelIndex, QObject *
object)
308 QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
310 qWarning() <<
"AbstractDashView::itemCreated got a non item for index" << modelIndex;
314 item->setParentItem(
this);
321 if (modelIndex == m_asyncRequestedIndex) {
322 createItem(modelIndex,
false);
323 m_implicitHeightDirty =
true;
328 #if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
329 void AbstractDashView::onModelUpdated(
const QQuickChangeSet &changeSet,
bool reset)
331 void AbstractDashView::onModelUpdated(
const QQmlChangeSet &changeSet,
bool reset)
335 cleanupExistingItems();
337 processModelRemoves(changeSet.removes());
343 void AbstractDashView::relayout()
345 m_needsRelayout =
true;
349 void AbstractDashView::onHeightChanged()
354 void AbstractDashView::updatePolish()
359 if (m_needsRelayout) {
361 m_needsRelayout =
false;
362 m_implicitHeightDirty =
true;
367 const bool delegateRangesValid = m_delegateCreationBeginValid && m_delegateCreationEndValid;
368 const qreal from = delegateRangesValid ? m_delegateCreationBegin : 0;
369 const qreal to = delegateRangesValid ? m_delegateCreationEnd : from + height();
370 updateItemCulling(from, to);
372 if (m_implicitHeightDirty) {
373 calculateImplicitHeight();
374 m_implicitHeightDirty =
false;
378 void AbstractDashView::componentComplete()
381 m_delegateModel->componentComplete();
383 QQuickItem::componentComplete();
385 m_needsRelayout =
true;