17 #include "abstractdashview.h" 19 #include <private/qquickitem_p.h> 21 AbstractDashView::AbstractDashView()
22 : m_delegateModel(nullptr)
23 , m_asyncRequestedIndex(-1)
27 , m_displayMarginBeginning(0)
28 , m_displayMarginEnd(0)
29 , m_needsRelayout(false)
30 , m_delegateValidated(false)
31 , m_implicitHeightDirty(false)
33 connect(
this, &AbstractDashView::widthChanged,
this, &AbstractDashView::relayout);
34 connect(
this, &AbstractDashView::heightChanged,
this, &AbstractDashView::onHeightChanged);
37 QAbstractItemModel *AbstractDashView::model()
const 39 return m_delegateModel ? m_delegateModel->model().value<QAbstractItemModel *>() :
nullptr;
42 void AbstractDashView::setModel(QAbstractItemModel *model)
44 if (model != this->model()) {
45 if (!m_delegateModel) {
46 createDelegateModel();
48 disconnect(m_delegateModel, &QQmlDelegateModel::modelUpdated,
this, &AbstractDashView::onModelUpdated);
50 m_delegateModel->setModel(QVariant::fromValue<QAbstractItemModel *>(model));
51 connect(m_delegateModel, &QQmlDelegateModel::modelUpdated,
this, &AbstractDashView::onModelUpdated);
53 cleanupExistingItems();
55 Q_EMIT modelChanged();
60 QQmlComponent *AbstractDashView::delegate()
const 62 return m_delegateModel ? m_delegateModel->delegate() :
nullptr;
65 void AbstractDashView::setDelegate(QQmlComponent *delegate)
67 if (delegate != this->delegate()) {
68 if (!m_delegateModel) {
69 createDelegateModel();
72 cleanupExistingItems();
74 m_delegateModel->setDelegate(delegate);
76 Q_EMIT delegateChanged();
77 m_delegateValidated =
false;
82 qreal AbstractDashView::columnSpacing()
const 84 return m_columnSpacing;
87 void AbstractDashView::setColumnSpacing(qreal columnSpacing)
89 if (columnSpacing != m_columnSpacing) {
90 m_columnSpacing = columnSpacing;
91 Q_EMIT columnSpacingChanged();
93 if (isComponentComplete()) {
99 qreal AbstractDashView::rowSpacing()
const 104 void AbstractDashView::setRowSpacing(qreal rowSpacing)
106 if (rowSpacing != m_rowSpacing) {
107 m_rowSpacing = rowSpacing;
108 Q_EMIT rowSpacingChanged();
110 if (isComponentComplete()) {
116 int AbstractDashView::cacheBuffer()
const 121 void AbstractDashView::setCacheBuffer(
int buffer)
124 qmlInfo(
this) <<
"Cannot set a negative cache buffer";
128 if (m_buffer != buffer) {
130 if (isComponentComplete()) {
133 emit cacheBufferChanged();
137 qreal AbstractDashView::displayMarginBeginning()
const 139 return m_displayMarginBeginning;
142 void AbstractDashView::setDisplayMarginBeginning(qreal begin)
144 if (m_displayMarginBeginning == begin)
146 m_displayMarginBeginning = begin;
147 if (isComponentComplete()) {
150 emit displayMarginBeginningChanged();
153 qreal AbstractDashView::displayMarginEnd()
const 155 return m_displayMarginEnd;
158 void AbstractDashView::setDisplayMarginEnd(qreal end)
160 if (m_displayMarginEnd == end)
162 m_displayMarginEnd = end;
163 if (isComponentComplete()) {
166 emit displayMarginEndChanged();
169 void AbstractDashView::createDelegateModel()
171 m_delegateModel =
new QQmlDelegateModel(qmlContext(
this),
this);
172 connect(m_delegateModel, &QQmlDelegateModel::createdItem,
this, &AbstractDashView::itemCreated);
173 if (isComponentComplete())
174 m_delegateModel->componentComplete();
177 void AbstractDashView::refill()
179 if (!isComponentComplete() || height() < 0) {
183 const qreal from = -m_displayMarginBeginning;
184 const qreal to = height() + m_displayMarginEnd;
185 const qreal bufferFrom = from - m_buffer;
186 const qreal bufferTo = to + m_buffer;
188 bool added = addVisibleItems(from, to,
false);
189 bool removed = removeNonVisibleItems(bufferFrom, bufferTo);
190 added |= addVisibleItems(bufferFrom, bufferTo,
true);
192 if (added || removed) {
193 m_implicitHeightDirty =
true;
198 bool AbstractDashView::addVisibleItems(qreal fillFromY, qreal fillToY,
bool asynchronous)
200 if (fillToY <= fillFromY)
206 if (m_delegateModel->count() == 0)
211 findBottomModelIndexToAdd(&modelIndex, &yPos);
212 bool changed =
false;
213 while (modelIndex < m_delegateModel->count() && yPos <= fillToY) {
214 if (!createItem(modelIndex, asynchronous))
218 findBottomModelIndexToAdd(&modelIndex, &yPos);
221 findTopModelIndexToAdd(&modelIndex, &yPos);
222 while (modelIndex >= 0 && yPos > fillFromY) {
223 if (!createItem(modelIndex, asynchronous))
227 findTopModelIndexToAdd(&modelIndex, &yPos);
233 QQuickItem *AbstractDashView::createItem(
int modelIndex,
bool asynchronous)
235 if (asynchronous && m_asyncRequestedIndex != -1)
238 m_asyncRequestedIndex = -1;
239 QObject*
object = m_delegateModel->object(modelIndex, asynchronous);
240 QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
243 m_delegateModel->release(
object);
244 if (!m_delegateValidated) {
245 m_delegateValidated =
true;
246 QObject* delegateObj = delegate();
247 qmlInfo(delegateObj ? delegateObj :
this) <<
"Delegate must be of Item type";
250 m_asyncRequestedIndex = modelIndex;
254 QQuickItemPrivate::get(item)->addItemChangeListener(
this, QQuickItemPrivate::Geometry);
255 addItemToView(modelIndex, item);
260 void AbstractDashView::releaseItem(QQuickItem *item)
262 QQuickItemPrivate::get(item)->removeItemChangeListener(
this, QQuickItemPrivate::Geometry);
263 QQmlDelegateModel::ReleaseFlags flags = m_delegateModel->release(item);
264 if (flags & QQmlDelegateModel::Destroyed) {
265 item->setParentItem(
nullptr);
269 void AbstractDashView::setImplicitHeightDirty()
271 m_implicitHeightDirty =
true;
274 void AbstractDashView::itemCreated(
int modelIndex, QObject *
object)
276 QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
278 qWarning() <<
"AbstractDashView::itemCreated got a non item for index" << modelIndex;
281 item->setParentItem(
this);
288 if (modelIndex == m_asyncRequestedIndex) {
289 createItem(modelIndex,
false);
290 m_implicitHeightDirty =
true;
295 void AbstractDashView::onModelUpdated(
const QQmlChangeSet &changeSet,
bool reset)
298 cleanupExistingItems();
300 processModelRemoves(changeSet.removes());
304 Q_FOREACH(
const QQmlChangeSet::Change insert, changeSet.inserts()) {
305 if (insert.index < m_delegateModel->count() - 1) {
306 cleanupExistingItems();
315 void AbstractDashView::relayout()
317 m_needsRelayout =
true;
321 void AbstractDashView::onHeightChanged()
326 void AbstractDashView::updatePolish()
331 if (m_needsRelayout) {
333 m_needsRelayout =
false;
334 m_implicitHeightDirty =
true;
339 const qreal from = -m_displayMarginBeginning;
340 const qreal to = height() + m_displayMarginEnd;
341 updateItemCulling(from, to);
343 if (m_implicitHeightDirty) {
344 calculateImplicitHeight();
345 m_implicitHeightDirty =
false;
349 void AbstractDashView::componentComplete()
352 m_delegateModel->componentComplete();
354 QQuickItem::componentComplete();
356 m_needsRelayout =
true;