summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarius Bugge Monsen <mmonsen@trolltech.com>2009-06-04 15:28:06 +0200
committerMarius Bugge Monsen <mmonsen@trolltech.com>2009-06-04 15:28:06 +0200
commit2d40b2a2b38a9c55ffe1aedc3d936c05a387b60d (patch)
tree99dd67c37ea19900942acc9ba6a7d9c419fc76ba
parenta56e814afea012d4892ee23e518df8ade7f0d788 (diff)
Update the QtGraphicsTreeView::doLayout() to a slightly improved algorithm. It is still not optimal and is still a work-in-progress.
-rw-r--r--src/qgraphicstreeview.cpp75
-rw-r--r--src/qgraphicstreeview.h2
-rw-r--r--src/qgraphicstreeview_p.h5
3 files changed, 33 insertions, 49 deletions
diff --git a/src/qgraphicstreeview.cpp b/src/qgraphicstreeview.cpp
index cc24969..85490cd 100644
--- a/src/qgraphicstreeview.cpp
+++ b/src/qgraphicstreeview.cpp
@@ -335,18 +335,17 @@ void QtGraphicsTreeViewPrivate::_q_reset()
void QtGraphicsTreeViewPrivate::_q_selectionsChanged(const QtTreeSelection &selection)
{
//qDebug() << "QtGraphicsTreeViewPrivate::_q_selectionsChanged" << selection;
- for (int i = 0; i < items.count(); ++i)
- if (selection.contains(items.at(i)->iterator()))
- items.at(i)->update();
+ // ### FIXME: it might be more efficient to iterate over the items instead
+ QtTreeSelection::const_iterator it = selection.constBegin();
+ for (; it != selection.constEnd(); ++it)
+ updateItem(*it);
}
void QtGraphicsTreeViewPrivate::_q_currentChanged(const QtTreeModelBase::iterator_base &current, const QtTreeModelBase::iterator_base &previous)
{
- //Q_Q(QtGraphicsTreeView);
- Q_UNUSED(current);
- Q_UNUSED(previous);
//qDebug() << "QtGraphicsTreeViewPrivate::_q_currentChanged" << current << previous;
- //q->update(); // ### FIXME: remove when converted to items
+ updateItem(current);
+ updateItem(previous);
}
/*!
@@ -712,29 +711,10 @@ void QtGraphicsTreeViewPrivate::_q_mapIndexesToItems()
/*!
\internal
*/
-void QtGraphicsTreeViewPrivate::scrollItems(QtTreeModelBase::iterator_base it, QStack<QtTreeModelBase::iterator_base> stack, int index)
-{
- // shift items around
- Q_ASSERT(it.isValid());
- if (!items.isEmpty()) {
- // scrolling down - move from first to last
- while (items.first()->index() < index) {
- const QtGraphicsTreeViewItem *last = items.last();
- QtTreeModelIterator iterator = last->iterator();
- next(iterator, stack);
- Q_ASSERT(iterator.isValid());
- items.append(creator->reassign(iterator, last->index() + 1, items.takeFirst()));
- }
- // scrolling up - move from last to first
- const int firstNonVisibleIndex = index + items.count();
- while (items.last()->index() >= firstNonVisibleIndex) {
- const QtGraphicsTreeViewItem *first = items.first();
- QtTreeModelIterator iterator = first->iterator();
- previous(iterator, stack);
- Q_ASSERT(iterator.isValid());
- items.prepend(creator->reassign(iterator, first->index() - 1, items.takeLast()));
- }
- }
+void QtGraphicsTreeViewPrivate::updateItem(const QtTreeModelBase::iterator_base &it) const
+{
+ if (QtGraphicsTreeViewItem *item = items.value(it))
+ item->update();
}
// QtGraphicsTreeView
@@ -1156,21 +1136,25 @@ void QtGraphicsTreeView::doLayout()
if (!it.isValid())
return;
+ // collect unused items for reassignment
+ QHash<QtTreeModelBase::iterator_base, QtGraphicsTreeViewItem*> unused = d->items;
+ d->items.clear(); // ### FIXME: find a solution that updates in-place
+
// position the visible items
- const int firstVisibleIndex = index;
+ const qreal x = -horizontalOffset;
while (y < area.height() && it.isValid()) {
- qreal x = -horizontalOffset;
-
- // ### FIXME: scroll the items properly
- QtGraphicsTreeViewItem *item = 0;
- const int i = index - firstVisibleIndex;
- if (i >= d->items.count()) {
- item = d->creator->create(it, index, this);
- d->items.append(item);
- } else {
- item = d->creator->reassign(it, index, d->items.at(i));
+ // update item geometry
+ QtGraphicsTreeViewItem *item = unused.take(it);
+ if (!item) { // if the item did not exist
+ if (unused.isEmpty()) {
+ item = d->creator->create(it, index, this);
+ } else { // take another random item (idealy we should take from the bottom, since this kicks in early when scolling up)
+ QHash<QtTreeModelBase::iterator_base, QtGraphicsTreeViewItem*>::iterator random = unused.begin();
+ item = d->creator->reassign(it, index, random.value());
+ unused.erase(random);
+ }
}
-
+ d->items.insert(it, item);
QSizeF size = item->sizeHint(it, &option, Qt::PreferredSize, constraint);
item->setGeometry(x, y, w, size.height());
// next item
@@ -1179,9 +1163,10 @@ void QtGraphicsTreeView::doLayout()
++index;
} // while
- // clean up view items
- while ((index - firstVisibleIndex) < d->items.count())
- d->creator->recycle(d->items.takeLast());
+ // recycle any unused items left
+ QHash<QtTreeModelBase::iterator_base, QtGraphicsTreeViewItem*>::iterator it2 = unused.begin();
+ for (; it2 != unused.end(); ++it2)
+ d->creator->recycle(it2.value());
}
/*!
diff --git a/src/qgraphicstreeview.h b/src/qgraphicstreeview.h
index 6a7fdbc..3ed889c 100644
--- a/src/qgraphicstreeview.h
+++ b/src/qgraphicstreeview.h
@@ -147,8 +147,6 @@ public:
QtGraphicsTreeViewItemCreatorBase *itemCreator() const;
void setItemCreator(QtGraphicsTreeViewItemCreatorBase *creator);
- //const QList<QtGraphicsTreeViewItem*> &visibleItems() const;
-
virtual void doLayout();
virtual QtTreeModelIterator itemAt(const QPointF &position, int *index = 0, QRectF *rect = 0) const;
virtual int indexOf(const QtTreeModelIterator &it) const;
diff --git a/src/qgraphicstreeview_p.h b/src/qgraphicstreeview_p.h
index cf64ef8..dfdc3f6 100644
--- a/src/qgraphicstreeview_p.h
+++ b/src/qgraphicstreeview_p.h
@@ -142,7 +142,7 @@ public:
void _q_mapIndexesToItems();
#endif
- void scrollItems(QtTreeModelBase::iterator_base it, QStack<QtTreeModelBase::iterator_base> stack, int index);
+ void updateItem(const QtTreeModelBase::iterator_base &it) const;
QtGraphicsTreeView *q_ptr;
QtTreeController *controller;
@@ -177,7 +177,8 @@ public:
static inline qreal indentation() { return 20; } // ### hardcoded value; make styleHint
- QList<QtGraphicsTreeViewItem*> items;
+ QHash<QtTreeModelBase::iterator_base, QtGraphicsTreeViewItem*> items;
+
QtGraphicsTreeViewItemCreatorBase *creator;
QBasicTimer layoutTimer;
};