26 #include "horizontaljournal.h"
28 #include <qqmlengine.h>
29 #pragma GCC diagnostic push
30 #pragma GCC diagnostic ignored "-pedantic"
31 #include <private/qqmldelegatemodel_p.h>
33 #include <private/qquickitem_p.h>
34 #pragma GCC diagnostic pop
36 static const qreal bufferRatio = 0.5;
38 HorizontalJournal::HorizontalJournal()
39 : m_firstVisibleIndex(-1)
44 qreal HorizontalJournal::rowHeight()
const
49 void HorizontalJournal::setRowHeight(qreal rowHeight)
51 if (rowHeight != m_rowHeight) {
52 m_rowHeight = rowHeight;
53 Q_EMIT rowHeightChanged();
55 if (isComponentComplete()) {
56 Q_FOREACH(QQuickItem *item, m_visibleItems) {
57 item->setHeight(rowHeight);
64 void HorizontalJournal::findBottomModelIndexToAdd(
int *modelIndex, qreal *yPos)
66 if (m_visibleItems.isEmpty()) {
70 *modelIndex = m_firstVisibleIndex + m_visibleItems.count();
71 if (m_lastInRowIndexPosition.contains(*modelIndex - 1)) {
72 *yPos = m_visibleItems.last()->y() + m_rowHeight + rowSpacing();
74 *yPos = m_visibleItems.last()->y();
79 void HorizontalJournal::findTopModelIndexToAdd(
int *modelIndex, qreal *yPos)
81 if (m_visibleItems.isEmpty()) {
85 *modelIndex = m_firstVisibleIndex - 1;
86 if (m_lastInRowIndexPosition.contains(*modelIndex)) {
87 *yPos = m_visibleItems.first()->y() - rowSpacing() - m_rowHeight;
89 *yPos = m_visibleItems.first()->y();
94 bool HorizontalJournal::removeNonVisibleItems(qreal bufferFromY, qreal bufferToY)
98 while (!m_visibleItems.isEmpty() && m_visibleItems.first()->y() + m_rowHeight < bufferFromY) {
99 releaseItem(m_visibleItems.takeFirst());
101 m_firstVisibleIndex++;
104 while (!m_visibleItems.isEmpty() && m_visibleItems.last()->y() > bufferToY) {
105 releaseItem(m_visibleItems.takeLast());
107 m_lastInRowIndexPosition.remove(m_firstVisibleIndex + m_visibleItems.count());
110 if (m_visibleItems.isEmpty()) {
111 m_firstVisibleIndex = -1;
117 void HorizontalJournal::addItemToView(
int modelIndex, QQuickItem *item)
119 if (item->height() != m_rowHeight) {
120 qWarning() <<
"Item" << modelIndex <<
"height is not the one that the rowHeight mandates, resetting it";
121 item->setHeight(m_rowHeight);
124 if (m_visibleItems.isEmpty()) {
125 Q_ASSERT(modelIndex == 0);
128 m_visibleItems << item;
129 m_firstVisibleIndex = 0;
132 if (modelIndex == m_firstVisibleIndex + m_visibleItems.count()) {
133 QQuickItem *lastItem = m_visibleItems.last();
134 if (lastItem->x() + lastItem->width() + columnSpacing() + item->width() <= width()) {
136 item->setY(lastItem->y());
137 item->setX(lastItem->x() + lastItem->width() + columnSpacing());
140 item->setY(lastItem->y() + m_rowHeight + rowSpacing());
142 m_lastInRowIndexPosition[modelIndex - 1] = lastItem->x();
144 m_visibleItems << item;
145 }
else if (modelIndex == m_firstVisibleIndex - 1) {
146 QQuickItem *firstItem = m_visibleItems.first();
147 if (m_lastInRowIndexPosition.contains(modelIndex)) {
149 item->setY(firstItem->y() - rowSpacing() - m_rowHeight);
150 item->setX(m_lastInRowIndexPosition[modelIndex]);
152 item->setY(firstItem->y());
153 item->setX(firstItem->x() - columnSpacing() - item->width());
155 m_firstVisibleIndex = modelIndex;
156 m_visibleItems.prepend(item);
158 qWarning() <<
"HorizontalJournal::addItemToView - Got unexpected modelIndex"
159 << modelIndex << m_firstVisibleIndex << m_visibleItems.count();
164 void HorizontalJournal::cleanupExistingItems()
167 Q_FOREACH(QQuickItem *item, m_visibleItems)
169 m_visibleItems.clear();
170 m_lastInRowIndexPosition.clear();
171 m_firstVisibleIndex = -1;
172 setImplicitHeightDirty();
177 if (m_firstVisibleIndex >= 0) {
178 const int nIndexes = m_firstVisibleIndex + m_visibleItems.count();
179 const double bottomMostY = m_visibleItems.last()->y() + m_rowHeight;
180 const double averageHeight = bottomMostY / nIndexes;
181 setImplicitHeight(bottomMostY + averageHeight * (model()->rowCount() - nIndexes));
183 setImplicitHeight(0);
187 #if (QT_VERSION < QT_VERSION_CHECK(5, 4, 0))
188 void HorizontalJournal::processModelRemoves(
const QVector<QQmlChangeSet::Remove> &removes)
190 void HorizontalJournal::processModelRemoves(
const QVector<QQmlChangeSet::Change> &removes)
193 Q_FOREACH(
const QQmlChangeSet::Change &
remove, removes) {
194 for (
int i =
remove.count - 1; i >= 0; --i) {
195 const int indexToRemove =
remove.index + i;
198 const int lastIndex = m_firstVisibleIndex + m_visibleItems.count() - 1;
199 if (indexToRemove == lastIndex) {
200 releaseItem(m_visibleItems.takeLast());
201 m_lastInRowIndexPosition.remove(indexToRemove);
203 if (indexToRemove < lastIndex) {
204 qFatal(
"HorizontalJournal only supports removal from the end of the model");
206 setImplicitHeightDirty();
211 if (m_visibleItems.isEmpty()) {
212 m_firstVisibleIndex = -1;
217 void HorizontalJournal::doRelayout()
222 if (m_firstVisibleIndex == 0) {
224 const QList<QQuickItem*> allItems = m_visibleItems;
225 m_visibleItems.clear();
226 m_lastInRowIndexPosition.clear();
227 Q_FOREACH(QQuickItem *item, allItems) {
228 addItemToView(i, item);
232 Q_FOREACH(QQuickItem *item, m_visibleItems) {
235 m_visibleItems.clear();
236 m_lastInRowIndexPosition.clear();
237 m_firstVisibleIndex = -1;
241 void HorizontalJournal::updateItemCulling(qreal visibleFromY, qreal visibleToY)
243 Q_FOREACH(QQuickItem *item, m_visibleItems) {
244 QQuickItemPrivate::get(item)->setCulled(item->y() + m_rowHeight <= visibleFromY || item->y() >= visibleToY);