From cbde1fa757dbffaa71c2f0c40216809860cf3818 Mon Sep 17 00:00:00 2001 From: Marius Bugge Monsen Date: Thu, 26 Nov 2009 18:47:32 +0100 Subject: Add support for highlight item in QtGraphicsListView. This allows us to set a graphics item to show the highlighted item in the view. --- examples/listModel/main.cpp | 14 +++++++++++++ src/qgraphicslistview.cpp | 49 ++++++++++++++++++++++++++++++++++++++++----- src/qgraphicslistview_p.h | 15 +++++++++++++- 3 files changed, 72 insertions(+), 6 deletions(-) diff --git a/examples/listModel/main.cpp b/examples/listModel/main.cpp index 3ee686d..397dba0 100644 --- a/examples/listModel/main.cpp +++ b/examples/listModel/main.cpp @@ -24,13 +24,27 @@ #include #include #include +#include #include "model.h" +class Highlight : public QGraphicsWidget +{ +public: + Highlight(QGraphicsWidget *parent = 0) : QGraphicsWidget(parent) {} + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget) + { + Q_UNUSED(option); + Q_UNUSED(widget); + painter->fillRect(0, 0, size().width(), size().height(), Qt::green); + } +}; + int main(int argc, char *argv[]) { QApplication app(argc, argv); QtListWidgetNG widget; widget.controller()->setModel(new Model(&widget)); + widget.controller()->view()->setHighlight(new Highlight); widget.resize(QSize(240, 320)); widget.show(); return app.exec(); diff --git a/src/qgraphicslistview.cpp b/src/qgraphicslistview.cpp index 1e3b8fd..162d691 100644 --- a/src/qgraphicslistview.cpp +++ b/src/qgraphicslistview.cpp @@ -208,7 +208,7 @@ void QtGraphicsListViewItem::initStyleOption(QStyleOptionViewItemV4 *option) con else option->state &= ~QStyle::State_HasFocus; // selectionManager - if (d->view->selectionManager()->isSelected(d->index)) + if (!d->view->highlight() && d->view->selectionManager()->isSelected(d->index)) option->state |= QStyle::State_Selected; else option->state &= ~QStyle::State_Selected; @@ -370,7 +370,7 @@ void QtGraphicsListViewItemCreatorBase::recycle(QGraphicsObject *item) QtGraphicsListViewPrivate::QtGraphicsListViewPrivate() : q_ptr(0), controller(0), model(0), selectionManager(0), orientation(Qt::Horizontal), textElideMode(Qt::ElideMiddle), - highlight(0), firstIndex(0), offset(0), + highlight(0), firstIndex(0), offset(0), transform(0), #if CACHING_ENABLED cachedIndexOffset(0), cachedCoordinateOffset(0), #endif @@ -491,7 +491,7 @@ void QtGraphicsListViewPrivate::_q_currentChanged(int current, int previous) return; //qDebug() << "QtGraphicsListViewPrivate::_q_currentChanged" << current << previous; if (highlight) { - // FIXME: update highlight geometry + updateHighlightGeometry(); } else { const int from = items.first().first; const int to = items.last().first; @@ -502,6 +502,29 @@ void QtGraphicsListViewPrivate::_q_currentChanged(int current, int previous) } } +/*! + \internal +*/ +void QtGraphicsListViewPrivate::updateHighlightGeometry() +{ + const int from = items.first().first; + const int to = items.last().first; + const int current = currentItem(); + if (from <= current && current <= to) { + highlight->show(); + highlight->setZValue(-1); + const QGraphicsObject *currentObject = items.at(current - from).second; + if (highlight->isWidget() && currentObject->isWidget()) { + const QRectF geometry = static_cast(currentObject)->geometry(); + static_cast(highlight)->setGeometry(geometry); + } else { + highlight->setPos(currentObject->pos()); + } + } else { + highlight->hide(); + } +} + /*! \internal */ @@ -605,6 +628,7 @@ QtGraphicsListView::QtGraphicsListView(Qt::Orientation orientation, QGraphicsWid //setFlag(QGraphicsItem::ItemClipsChildrenToShape); d->q_ptr = this; d->orientation = orientation; + d->transform = new QtGraphicsTransform(this); } /*! @@ -617,6 +641,7 @@ QtGraphicsListView::QtGraphicsListView(QtGraphicsListViewPrivate &dd, Qt::Orient //setFlag(QGraphicsItem::ItemClipsChildrenToShape); d->q_ptr = this; d->orientation = orientation; + d->transform = new QtGraphicsTransform(this); } /*! @@ -788,6 +813,7 @@ void QtGraphicsListView::setHighlight(QGraphicsObject *highlight) Q_D(QtGraphicsListView); d->highlight = highlight; // update the highlight geometry + highlight->setParentItem(this); } /*! @@ -905,15 +931,24 @@ void QtGraphicsListView::doLayout() qreal coordinate = -d->offset; int index = d->firstIndex; + qDebug() << "coordinate" << coordinate; + qDebug() << "index" << index; + // find the visible items; caching helps us skip this most of the time - if (coordinate <= 0 && !d->items.isEmpty()) { + if (coordinate <= 0 && !d->items.isEmpty()) { // ### disabled #if CACHING_ENABLED // optimization: use the cached index and offset as starting points // The cached values are offsets from the start of the _contents_ // and the to index found at that offset. index += d->cachedIndexOffset; coordinate += d->cachedCoordinateOffset; + + qDebug() << "cachedIndexOffset" << d->cachedIndexOffset; + qDebug() << "index" << index; #endif + //index = d->items.first().first; + //coordinate = d->items.first().second->pos().y(); // ### vertical only + // the visible area starts at coordinate == 0 if (coordinate < 0) { // the cached offset was above or to the left of the visible area while (index < count) { @@ -1028,6 +1063,10 @@ void QtGraphicsListView::doLayout() const int visibleCount = index - firstVisibleIndex; while (visibleCount < d->items.count()) d->creator->recycle(d->items.takeLast().second); + + // update highlight + if (d->highlight) + d->updateHighlightGeometry(); } /*! @@ -1110,7 +1149,7 @@ qreal QtGraphicsListView::maximumOffset() const void QtGraphicsListView::setFirstIndex(int index) { Q_D(QtGraphicsListView); - if (d->firstIndex == index) + if (d->firstIndex == index || index < 0) return; d->firstIndex = index; emit firstIndexChanged(index); diff --git a/src/qgraphicslistview_p.h b/src/qgraphicslistview_p.h index fe87578..af5fdc2 100644 --- a/src/qgraphicslistview_p.h +++ b/src/qgraphicslistview_p.h @@ -54,6 +54,16 @@ public: QtGraphicsListViewItem *q_ptr; }; +class QtGraphicsTransform : public QGraphicsItem +{ +public: + QtGraphicsTransform(QGraphicsItem *parent) : QGraphicsItem(parent) + { setFlag(QGraphicsItem::ItemHasNoContents); } + ~QtGraphicsTransform() {} + void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) {} + QRectF boundingRect() const { return QRectF(pos(), QSizeF()); } +}; + // QtGraphicsListViewPrivate class QtGraphicsListViewPrivate //: public QGraphicsWidgetPrivate @@ -75,9 +85,11 @@ public: void _q_selectionsChanged(const QtListSelectionChange &change); void _q_currentChanged(int current, int previous); - void checkCache(int index, int count); + void updateHighlightGeometry(); + void checkCache(int index, int count); QVariant cachedData(int index, const QByteArray &role) const; + bool isSelected(int index) const; int currentItem() const; @@ -105,6 +117,7 @@ public: mutable QHash cachedDataHash; mutable int cachedDataIndex; + QGraphicsItem *transform; // non-visible transform node QList > items; QtGraphicsListViewItemCreatorBase *creator; QBasicTimer layoutTimer; -- cgit v1.2.3