17 #include "abstractdashview.h"
19 AbstractDashView::AbstractDashView()
20 : m_delegateModel(nullptr)
21 , m_asyncRequestedIndex(-1)
25 , m_displayMarginBeginning(0)
26 , m_displayMarginEnd(0)
27 , m_needsRelayout(false)
28 , m_delegateValidated(false)
29 , m_implicitHeightDirty(false)
31 connect(
this, &AbstractDashView::widthChanged,
this, &AbstractDashView::relayout);
32 connect(
this, &AbstractDashView::heightChanged,
this, &AbstractDashView::onHeightChanged);
35 QAbstractItemModel *AbstractDashView::model()
const
37 return m_delegateModel ? m_delegateModel->model().value<QAbstractItemModel *>() :
nullptr;
40 void AbstractDashView::setModel(QAbstractItemModel *model)
42 if (model != this->model()) {
43 if (!m_delegateModel) {
44 createDelegateModel();
46 disconnect(m_delegateModel, &QQmlDelegateModel::modelUpdated,
this, &AbstractDashView::onModelUpdated);
48 m_delegateModel->setModel(QVariant::fromValue<QAbstractItemModel *>(model));
49 connect(m_delegateModel, &QQmlDelegateModel::modelUpdated,
this, &AbstractDashView::onModelUpdated);
51 cleanupExistingItems();
53 Q_EMIT modelChanged();
58 QQmlComponent *AbstractDashView::delegate()
const
60 return m_delegateModel ? m_delegateModel->delegate() :
nullptr;
63 void AbstractDashView::setDelegate(QQmlComponent *delegate)
65 if (delegate != this->delegate()) {
66 if (!m_delegateModel) {
67 createDelegateModel();
70 cleanupExistingItems();
72 m_delegateModel->setDelegate(delegate);
74 Q_EMIT delegateChanged();
75 m_delegateValidated =
false;
80 qreal AbstractDashView::columnSpacing()
const
82 return m_columnSpacing;
85 void AbstractDashView::setColumnSpacing(qreal columnSpacing)
87 if (columnSpacing != m_columnSpacing) {
88 m_columnSpacing = columnSpacing;
89 Q_EMIT columnSpacingChanged();
91 if (isComponentComplete()) {
97 qreal AbstractDashView::rowSpacing()
const
102 void AbstractDashView::setRowSpacing(qreal rowSpacing)
104 if (rowSpacing != m_rowSpacing) {
105 m_rowSpacing = rowSpacing;
106 Q_EMIT rowSpacingChanged();
108 if (isComponentComplete()) {
114 int AbstractDashView::cacheBuffer()
const
119 void AbstractDashView::setCacheBuffer(
int buffer)
122 qmlInfo(
this) <<
"Cannot set a negative cache buffer";
126 if (m_buffer != buffer) {
128 if (isComponentComplete()) {
131 emit cacheBufferChanged();
135 qreal AbstractDashView::displayMarginBeginning()
const
137 return m_displayMarginBeginning;
140 void AbstractDashView::setDisplayMarginBeginning(qreal begin)
142 if (m_displayMarginBeginning == begin)
144 m_displayMarginBeginning = begin;
145 if (isComponentComplete()) {
148 emit displayMarginBeginningChanged();
151 qreal AbstractDashView::displayMarginEnd()
const
153 return m_displayMarginEnd;
156 void AbstractDashView::setDisplayMarginEnd(qreal end)
158 if (m_displayMarginEnd == end)
160 m_displayMarginEnd = end;
161 if (isComponentComplete()) {
164 emit displayMarginEndChanged();
167 void AbstractDashView::createDelegateModel()
169 m_delegateModel =
new QQmlDelegateModel(qmlContext(
this),
this);
170 connect(m_delegateModel, &QQmlDelegateModel::createdItem,
this, &AbstractDashView::itemCreated);
171 if (isComponentComplete())
172 m_delegateModel->componentComplete();
175 void AbstractDashView::refill()
177 if (!isComponentComplete() || height() < 0) {
181 const qreal from = -m_displayMarginBeginning;
182 const qreal to = height() + m_displayMarginEnd;
183 const qreal bufferFrom = from - m_buffer;
184 const qreal bufferTo = to + m_buffer;
186 bool added = addVisibleItems(from, to,
false);
187 bool removed = removeNonVisibleItems(bufferFrom, bufferTo);
188 added |= addVisibleItems(bufferFrom, bufferTo,
true);
190 if (added || removed) {
191 m_implicitHeightDirty =
true;
196 bool AbstractDashView::addVisibleItems(qreal fillFromY, qreal fillToY,
bool asynchronous)
198 if (fillToY <= fillFromY)
204 if (m_delegateModel->count() == 0)
209 findBottomModelIndexToAdd(&modelIndex, &yPos);
210 bool changed =
false;
211 while (modelIndex < m_delegateModel->count() && yPos <= fillToY) {
212 if (!createItem(modelIndex, asynchronous))
216 findBottomModelIndexToAdd(&modelIndex, &yPos);
219 findTopModelIndexToAdd(&modelIndex, &yPos);
220 while (modelIndex >= 0 && yPos > fillFromY) {
221 if (!createItem(modelIndex, asynchronous))
225 findTopModelIndexToAdd(&modelIndex, &yPos);
231 QQuickItem *AbstractDashView::createItem(
int modelIndex,
bool asynchronous)
233 if (asynchronous && m_asyncRequestedIndex != -1)
236 m_asyncRequestedIndex = -1;
237 QObject*
object = m_delegateModel->object(modelIndex, asynchronous);
238 QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
241 m_delegateModel->release(
object);
242 if (!m_delegateValidated) {
243 m_delegateValidated =
true;
244 QObject* delegateObj = delegate();
245 qmlInfo(delegateObj ? delegateObj :
this) <<
"Delegate must be of Item type";
248 m_asyncRequestedIndex = modelIndex;
252 addItemToView(modelIndex, item);
257 void AbstractDashView::releaseItem(QQuickItem *item)
259 QQmlDelegateModel::ReleaseFlags flags = m_delegateModel->release(item);
260 if (flags & QQmlDelegateModel::Destroyed) {
261 item->setParentItem(
nullptr);
265 void AbstractDashView::setImplicitHeightDirty()
267 m_implicitHeightDirty =
true;
270 void AbstractDashView::itemCreated(
int modelIndex, QObject *
object)
272 QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
274 qWarning() <<
"AbstractDashView::itemCreated got a non item for index" << modelIndex;
277 item->setParentItem(
this);
284 if (modelIndex == m_asyncRequestedIndex) {
285 createItem(modelIndex,
false);
286 m_implicitHeightDirty =
true;
291 void AbstractDashView::onModelUpdated(
const QQmlChangeSet &changeSet,
bool reset)
294 cleanupExistingItems();
296 processModelRemoves(changeSet.removes());
302 void AbstractDashView::relayout()
304 m_needsRelayout =
true;
308 void AbstractDashView::onHeightChanged()
313 void AbstractDashView::updatePolish()
318 if (m_needsRelayout) {
320 m_needsRelayout =
false;
321 m_implicitHeightDirty =
true;
326 const qreal from = -m_displayMarginBeginning;
327 const qreal to = height() + m_displayMarginEnd;
328 updateItemCulling(from, to);
330 if (m_implicitHeightDirty) {
331 calculateImplicitHeight();
332 m_implicitHeightDirty =
false;
336 void AbstractDashView::componentComplete()
339 m_delegateModel->componentComplete();
341 QQuickItem::componentComplete();
343 m_needsRelayout =
true;