26 #include "horizontaljournal.h"
28 #include <qqmlengine.h>
29 #pragma GCC diagnostic push
30 #pragma GCC diagnostic ignored "-pedantic"
31 #if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
32 #include <private/qquickvisualdatamodel_p.h>
34 #include <private/qqmldelegatemodel_p.h>
37 #include <private/qquickitem_p.h>
38 #pragma GCC diagnostic pop
40 static const qreal bufferRatio = 0.5;
42 HorizontalJournal::HorizontalJournal()
43 : m_firstVisibleIndex(-1)
48 qreal HorizontalJournal::rowHeight()
const
53 void HorizontalJournal::setRowHeight(qreal rowHeight)
55 if (rowHeight != m_rowHeight) {
56 m_rowHeight = rowHeight;
57 Q_EMIT rowHeightChanged();
59 if (isComponentComplete()) {
60 Q_FOREACH(QQuickItem *item, m_visibleItems) {
61 item->setHeight(rowHeight);
68 void HorizontalJournal::findBottomModelIndexToAdd(
int *modelIndex, qreal *yPos)
70 if (m_visibleItems.isEmpty()) {
74 *modelIndex = m_firstVisibleIndex + m_visibleItems.count();
75 if (m_lastInRowIndexPosition.contains(*modelIndex - 1)) {
76 *yPos = m_visibleItems.last()->y() + m_rowHeight + rowSpacing();
78 *yPos = m_visibleItems.last()->y();
83 void HorizontalJournal::findTopModelIndexToAdd(
int *modelIndex, qreal *yPos)
85 if (m_visibleItems.isEmpty()) {
89 *modelIndex = m_firstVisibleIndex - 1;
90 if (m_lastInRowIndexPosition.contains(*modelIndex)) {
91 *yPos = m_visibleItems.first()->y() - rowSpacing() - m_rowHeight;
93 *yPos = m_visibleItems.first()->y();
98 bool HorizontalJournal::removeNonVisibleItems(qreal bufferFromY, qreal bufferToY)
100 bool changed =
false;
102 while (!m_visibleItems.isEmpty() && m_visibleItems.first()->y() + m_rowHeight < bufferFromY) {
103 releaseItem(m_visibleItems.takeFirst());
105 m_firstVisibleIndex++;
108 while (!m_visibleItems.isEmpty() && m_visibleItems.last()->y() > bufferToY) {
109 releaseItem(m_visibleItems.takeLast());
111 m_lastInRowIndexPosition.remove(m_firstVisibleIndex + m_visibleItems.count());
114 if (m_visibleItems.isEmpty()) {
115 m_firstVisibleIndex = -1;
121 void HorizontalJournal::addItemToView(
int modelIndex, QQuickItem *item)
123 if (item->height() != m_rowHeight) {
124 qWarning() <<
"Item" << modelIndex <<
"height is not the one that the rowHeight mandates, resetting it";
125 item->setHeight(m_rowHeight);
128 if (m_visibleItems.isEmpty()) {
129 Q_ASSERT(modelIndex == 0);
132 m_visibleItems << item;
133 m_firstVisibleIndex = 0;
136 if (modelIndex == m_firstVisibleIndex + m_visibleItems.count()) {
137 QQuickItem *lastItem = m_visibleItems.last();
138 if (lastItem->x() + lastItem->width() + columnSpacing() + item->width() <= width()) {
140 item->setY(lastItem->y());
141 item->setX(lastItem->x() + lastItem->width() + columnSpacing());
144 item->setY(lastItem->y() + m_rowHeight + rowSpacing());
146 m_lastInRowIndexPosition[modelIndex - 1] = lastItem->x();
148 m_visibleItems << item;
149 }
else if (modelIndex == m_firstVisibleIndex - 1) {
150 QQuickItem *firstItem = m_visibleItems.first();
151 if (m_lastInRowIndexPosition.contains(modelIndex)) {
153 item->setY(firstItem->y() - rowSpacing() - m_rowHeight);
154 item->setX(m_lastInRowIndexPosition[modelIndex]);
156 item->setY(firstItem->y());
157 item->setX(firstItem->x() - columnSpacing() - item->width());
159 m_firstVisibleIndex = modelIndex;
160 m_visibleItems.prepend(item);
162 qWarning() <<
"HorizontalJournal::addItemToView - Got unexpected modelIndex"
163 << modelIndex << m_firstVisibleIndex << m_visibleItems.count();
168 void HorizontalJournal::cleanupExistingItems()
171 Q_FOREACH(QQuickItem *item, m_visibleItems)
173 m_visibleItems.clear();
174 m_lastInRowIndexPosition.clear();
175 m_firstVisibleIndex = -1;
176 setImplicitHeightDirty();
181 if (m_firstVisibleIndex >= 0) {
182 const int nIndexes = m_firstVisibleIndex + m_visibleItems.count();
183 const double bottomMostY = m_visibleItems.last()->y() + m_rowHeight;
184 const double averageHeight = bottomMostY / nIndexes;
185 setImplicitHeight(bottomMostY + averageHeight * (model()->rowCount() - nIndexes));
187 setImplicitHeight(0);
191 #if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
192 void HorizontalJournal::processModelRemoves(
const QVector<QQuickChangeSet::Remove> &removes)
194 void HorizontalJournal::processModelRemoves(
const QVector<QQmlChangeSet::Remove> &removes)
197 #if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
198 Q_FOREACH(
const QQuickChangeSet::Remove &
remove, removes) {
200 Q_FOREACH(
const QQmlChangeSet::Remove &
remove, removes) {
202 for (
int i =
remove.count - 1; i >= 0; --i) {
203 const int indexToRemove =
remove.index + i;
206 const int lastIndex = m_firstVisibleIndex + m_visibleItems.count() - 1;
207 if (indexToRemove == lastIndex) {
208 releaseItem(m_visibleItems.takeLast());
209 m_lastInRowIndexPosition.remove(indexToRemove);
211 if (indexToRemove < lastIndex) {
212 qFatal(
"HorizontalJournal only supports removal from the end of the model");
214 setImplicitHeightDirty();
219 if (m_visibleItems.isEmpty()) {
220 m_firstVisibleIndex = -1;
225 void HorizontalJournal::doRelayout()
230 if (m_firstVisibleIndex == 0) {
232 const QList<QQuickItem*> allItems = m_visibleItems;
233 m_visibleItems.clear();
234 m_lastInRowIndexPosition.clear();
235 Q_FOREACH(QQuickItem *item, allItems) {
236 addItemToView(i, item);
240 Q_FOREACH(QQuickItem *item, m_visibleItems) {
243 m_visibleItems.clear();
244 m_lastInRowIndexPosition.clear();
245 m_firstVisibleIndex = -1;
249 void HorizontalJournal::updateItemCulling(qreal visibleFromY, qreal visibleToY)
251 Q_FOREACH(QQuickItem *item, m_visibleItems) {
252 QQuickItemPrivate::get(item)->setCulled(item->y() + m_rowHeight <= visibleFromY || item->y() >= visibleToY);