Update the rating stars in the currently playing item properly, and the fix the bug that would cause the currently playing item pixmap cache to not be updated with the whole row.

This commit is contained in:
David Sansome 2010-10-23 20:58:20 +00:00
parent eba3332a5d
commit 3a32c41c7e
5 changed files with 67 additions and 21 deletions

View File

@ -1194,3 +1194,12 @@ QDataStream& operator >>(QDataStream& s, Playlist*& p) {
s.readRawData(reinterpret_cast<char*>(&p), sizeof(p));
return s;
}
void Playlist::ItemChanged(PlaylistItemPtr item) {
for (int row=0 ; row<items_.count() ; ++row) {
if (items_[row] == item) {
emit dataChanged(index(row, 0), index(row, ColumnCount-1));
return;
}
}
}

View File

@ -177,6 +177,7 @@ class Playlist : public QAbstractListModel {
void ClearStreamMetadata();
void SetStreamMetadata(const QUrl& url, const Song& song);
void ItemChanged(PlaylistItemPtr item);
void Clear();
void Shuffle();

View File

@ -268,6 +268,7 @@ void PlaylistManager::SongsDiscovered(const SongList& songs) {
if (item->Metadata().directory_id() != song.directory_id())
continue;
static_cast<LibraryPlaylistItem*>(item.get())->SetMetadata(song);
data.p->ItemChanged(item);
}
}
}

View File

@ -236,6 +236,12 @@ QList<QPixmap> PlaylistView::LoadBarPixmap(const QString& filename) {
return ret;
}
void PlaylistView::drawTree(QPainter* painter, const QRegion& region) const {
const_cast<PlaylistView*>(this)->current_paint_region_ = region;
QTreeView::drawTree(painter, region);
const_cast<PlaylistView*>(this)->current_paint_region_ = QRegion();
}
void PlaylistView::drawRow(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
QStyleOptionViewItemV4 opt(option);
@ -286,13 +292,26 @@ void PlaylistView::drawRow(QPainter* painter, const QStyleOptionViewItem& option
// Draw the actual row data on top. We cache this, because it's fairly
// expensive (1-2ms), and we do it many times per second.
if (cached_current_row_rect_ != opt.rect ||
cached_current_row_row_ != index.row() ||
cached_current_row_.isNull()) {
const_cast<PlaylistView*>(this)->UpdateCachedCurrentRowPixmap(opt, index);
}
const bool cache_dirty = cached_current_row_rect_ != opt.rect ||
cached_current_row_row_ != index.row() ||
cached_current_row_.isNull();
painter->drawPixmap(opt.rect, cached_current_row_);
// We can't update the cache if we're not drawing the entire region,
// QTreeView clips its drawing to only the columns in the region, so it
// wouldn't update the whole pixmap properly.
const bool whole_region =
current_paint_region_.boundingRect().width() == viewport()->width();
if (!cache_dirty) {
painter->drawPixmap(opt.rect, cached_current_row_);
} else {
if (whole_region) {
const_cast<PlaylistView*>(this)->UpdateCachedCurrentRowPixmap(opt, index);
painter->drawPixmap(opt.rect, cached_current_row_);
} else {
QTreeView::drawRow(painter, opt, index);
}
}
} else {
QTreeView::drawRow(painter, opt, index);
}
@ -309,7 +328,6 @@ void PlaylistView::UpdateCachedCurrentRowPixmap(QStyleOptionViewItemV4 option,
QPainter p(&cached_current_row_);
QTreeView::drawRow(&p, option, index);
p.end();
}
void PlaylistView::InvalidateCachedCurrentPixmap() {
@ -461,31 +479,43 @@ void PlaylistView::closeEditor(QWidget* editor, QAbstractItemDelegate::EndEditHi
void PlaylistView::mouseMoveEvent(QMouseEvent* event) {
QModelIndex index = indexAt(event->pos());
if (index.isValid() && index.data(Playlist::Role_CanSetRating).toBool()) {
// Little hack to get hover effects on the rating column
rating_delegate_->set_mouse_over(index, event->pos());
update(index);
setCursor(Qt::PointingHandCursor);
RatingHoverIn(index, event->pos());
} else if (rating_delegate_->is_mouse_over()) {
QModelIndex old_index = rating_delegate_->mouse_over_index();
rating_delegate_->set_mouse_out();
update(old_index);
setCursor(QCursor());
RatingHoverOut();
}
QTreeView::mouseMoveEvent(event);
}
void PlaylistView::leaveEvent(QEvent* e) {
if (rating_delegate_->is_mouse_over()) {
QModelIndex old_index = rating_delegate_->mouse_over_index();
rating_delegate_->set_mouse_out();
update(old_index);
setCursor(QCursor());
RatingHoverOut();
}
QTreeView::leaveEvent(e);
}
void PlaylistView::RatingHoverIn(const QModelIndex& index, const QPoint& pos) {
const QModelIndex old_index = rating_delegate_->mouse_over_index();
rating_delegate_->set_mouse_over(index, pos);
update(index);
setCursor(Qt::PointingHandCursor);
if (index.data(Playlist::Role_IsCurrent).toBool() ||
old_index.data(Playlist::Role_IsCurrent).toBool()) {
InvalidateCachedCurrentPixmap();
}
}
void PlaylistView::RatingHoverOut() {
const QModelIndex old_index = rating_delegate_->mouse_over_index();
rating_delegate_->set_mouse_out();
update(old_index);
setCursor(QCursor());
if (old_index.data(Playlist::Role_IsCurrent).toBool()) {
InvalidateCachedCurrentPixmap();
}
}
void PlaylistView::mousePressEvent(QMouseEvent* event) {
QModelIndex index = indexAt(event->pos());
if (event->button() == Qt::LeftButton && index.isValid() &&

View File

@ -65,6 +65,7 @@ class PlaylistView : public QTreeView {
void RemoveSelected();
// QTreeView
void drawTree(QPainter* painter, const QRegion& region) const;
void drawRow(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
void keyPressEvent(QKeyEvent* event);
void setModel(QAbstractItemModel *model);
@ -116,6 +117,9 @@ class PlaylistView : public QTreeView {
void UpdateCachedCurrentRowPixmap(QStyleOptionViewItemV4 option,
const QModelIndex& index);
void RatingHoverIn(const QModelIndex& index, const QPoint& pos);
void RatingHoverOut();
private:
static const int kGlowIntensitySteps;
static const int kAutoscrollGraceTimeout;
@ -151,6 +155,7 @@ class PlaylistView : public QTreeView {
QPixmap currenttrack_play_;
QPixmap currenttrack_pause_;
QRegion current_paint_region_;
QPixmap cached_current_row_;
QRect cached_current_row_rect_;
int cached_current_row_row_;