From 5c70221296cd309dfb8cac641db52c35f174940b Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 19 May 2012 01:29:10 +0200 Subject: [PATCH] * Show proper play buttons / spinners overlaying album items. --- src/libtomahawk/Typedefs.h | 1 + src/libtomahawk/audio/AudioEngine.cpp | 1 - .../playlist/AlbumItemDelegate.cpp | 99 +++++++++++++++---- src/libtomahawk/playlist/AlbumItemDelegate.h | 8 ++ src/libtomahawk/playlist/AlbumModel.cpp | 2 +- src/libtomahawk/playlist/AlbumView.cpp | 8 ++ src/libtomahawk/playlist/AlbumView.h | 2 + src/libtomahawk/utils/AnimatedSpinner.cpp | 15 +-- src/libtomahawk/utils/AnimatedSpinner.h | 3 + 9 files changed, 112 insertions(+), 27 deletions(-) diff --git a/src/libtomahawk/Typedefs.h b/src/libtomahawk/Typedefs.h index cce94d236..54e705e7c 100644 --- a/src/libtomahawk/Typedefs.h +++ b/src/libtomahawk/Typedefs.h @@ -93,6 +93,7 @@ inline static QString uuid() return q; } +Q_DECLARE_METATYPE( QModelIndex ) Q_DECLARE_METATYPE( QPersistentModelIndex ) #endif // TYPEDEFS_H diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index d4238513d..dbde95469 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -579,7 +579,6 @@ AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk: void AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk::query_ptr& query ) { - tDebug() << query->toString(); if ( !query.isNull() && query->numResults() ) playItem( playlist, query->results().first() ); } diff --git a/src/libtomahawk/playlist/AlbumItemDelegate.cpp b/src/libtomahawk/playlist/AlbumItemDelegate.cpp index 3caa38c26..24d810b04 100644 --- a/src/libtomahawk/playlist/AlbumItemDelegate.cpp +++ b/src/libtomahawk/playlist/AlbumItemDelegate.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include "Artist.h" #include "Query.h" @@ -35,8 +36,9 @@ #include "playlist/AlbumItem.h" #include "playlist/AlbumProxyModel.h" #include "AlbumView.h" -#include -#include +#include "ViewManager.h" +#include "utils/AnimatedSpinner.h" +#include "widgets/ImageButton.h" AlbumItemDelegate::AlbumItemDelegate( QAbstractItemView* parent, AlbumProxyModel* proxy ) @@ -46,6 +48,8 @@ AlbumItemDelegate::AlbumItemDelegate( QAbstractItemView* parent, AlbumProxyModel { if ( m_view && m_view->metaObject()->indexOfSignal( "modelChanged()" ) > -1 ) connect( m_view, SIGNAL( modelChanged() ), this, SLOT( modelChanged() ) ); + + connect( m_view, SIGNAL( scrolledContents( int, int ) ), SLOT( onScrolled( int, int ) ) ); } @@ -156,7 +160,7 @@ AlbumItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, painter->drawPixmap( r, cover.scaled( r.size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) ); - if ( m_hoverIndex == index ) +/* if ( m_hoverIndex == index ) { painter->save(); @@ -172,7 +176,7 @@ AlbumItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, painter->drawPixmap( m_playButtonRect, playButton ); painter->restore(); - } + }*/ painter->save(); @@ -250,6 +254,37 @@ AlbumItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, } +void +AlbumItemDelegate::onPlayClicked( const QPersistentModelIndex& index ) +{ + AlbumItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( index ) ); + if ( item ) + { + if ( !item->query().isNull() ) + AudioEngine::instance()->playItem( Tomahawk::playlistinterface_ptr(), item->query() ); + else if ( !item->album().isNull() ) + AudioEngine::instance()->playItem( item->album() ); + else if ( !item->artist().isNull() ) + AudioEngine::instance()->playItem( item->artist() ); + } + + QPoint pos = m_button[ index ]->pos(); + foreach ( ImageButton* button, m_button ) + button->deleteLater(); + m_button.clear(); + + _detail::Closure* closure = NewClosure( AudioEngine::instance(), SIGNAL( loading( Tomahawk::result_ptr ) ), + const_cast(this), SLOT( onPlaybackStarted( QPersistentModelIndex ) ), QPersistentModelIndex( index ) ); + + AnimatedSpinner* spinner = new AnimatedSpinner( m_view ); + spinner->setAutoCenter( false ); + spinner->fadeIn(); + spinner->move( pos ); + + m_subWidgets[ index ] = spinner; +} + + bool AlbumItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ) { @@ -263,27 +298,31 @@ AlbumItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const return false; if ( event->type() == QEvent::MouseMove ) - m_hoverIndex = index; - - QMouseEvent* ev = static_cast< QMouseEvent* >( event ); - if ( event->type() == QEvent::MouseButtonRelease ) { - if ( m_playButtonRect.contains( ev->pos() ) ) + if ( !m_button.contains( index ) && !m_subWidgets.contains( index ) ) { - AlbumItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( index ) ); + foreach ( ImageButton* button, m_button ) + button->deleteLater(); + m_button.clear(); - if ( !item->query().isNull() ) - AudioEngine::instance()->playItem( Tomahawk::playlistinterface_ptr(), item->query() ); - else if ( !item->album().isNull() ) - AudioEngine::instance()->playItem( item->album() ); - else if ( !item->artist().isNull() ) - AudioEngine::instance()->playItem( item->artist() ); + ImageButton* button = new ImageButton( m_view ); + button->setPixmap( RESPATH "images/play-rest.png" ); + button->setPixmap( RESPATH "images/play-pressed.png", QIcon::Off, QIcon::Active ); + button->setFixedSize( 48, 48 ); + button->move( option.rect.center() - QPoint( 23, 23 ) ); + button->setContentsMargins( 0, 0, 0, 0 ); + button->show(); + + _detail::Closure* closure = NewClosure( button, SIGNAL( clicked( bool ) ), + const_cast(this), SLOT( onPlayClicked( QPersistentModelIndex ) ), QPersistentModelIndex( index ) ); - event->accept(); - return true; + m_button[ index ] = button; } + + m_hoverIndex = index; } + QMouseEvent* ev = static_cast< QMouseEvent* >( event ); if ( m_artistNameRects.contains( index ) ) { QRect artistNameRect = m_artistNameRects[ index ]; @@ -359,3 +398,27 @@ AlbumItemDelegate::doUpdateIndex( const QPersistentModelIndex& idx ) emit updateIndex( idx ); } + +void +AlbumItemDelegate::onScrolled( int dx, int dy ) +{ + foreach ( QWidget* widget, m_subWidgets.values() ) + { + widget->move( widget->pos() + QPoint( dx, dy ) ); + } + foreach ( ImageButton* button, m_button.values() ) + { + button->move( button->pos() + QPoint( dx, dy ) ); + } +} + + +void +AlbumItemDelegate::onPlaybackStarted( const QPersistentModelIndex& index ) +{ + foreach ( QWidget* widget, m_subWidgets.values() ) + { + delete widget; + } + m_subWidgets.clear(); +} diff --git a/src/libtomahawk/playlist/AlbumItemDelegate.h b/src/libtomahawk/playlist/AlbumItemDelegate.h index e2a78468d..f33fc47df 100644 --- a/src/libtomahawk/playlist/AlbumItemDelegate.h +++ b/src/libtomahawk/playlist/AlbumItemDelegate.h @@ -30,6 +30,7 @@ namespace Tomahawk { class QEvent; class AlbumProxyModel; +class ImageButton; class DLLEXPORT AlbumItemDelegate : public QStyledItemDelegate { @@ -52,6 +53,11 @@ signals: private slots: void modelChanged(); void doUpdateIndex( const QPersistentModelIndex& idx ); + + void onScrolled( int dx, int dy ); + void onPlaybackStarted( const QPersistentModelIndex& index ); + + void onPlayClicked( const QPersistentModelIndex& index ); private: QAbstractItemView* m_view; @@ -65,6 +71,8 @@ private: mutable QRect m_playButtonRect; QPixmap m_shadowPixmap; + mutable QHash< QPersistentModelIndex, QWidget* > m_subWidgets; + mutable QHash< QPersistentModelIndex, ImageButton* > m_button; }; #endif // ALBUMITEMDELEGATE_H diff --git a/src/libtomahawk/playlist/AlbumModel.cpp b/src/libtomahawk/playlist/AlbumModel.cpp index 98ad354e0..d09734beb 100644 --- a/src/libtomahawk/playlist/AlbumModel.cpp +++ b/src/libtomahawk/playlist/AlbumModel.cpp @@ -158,7 +158,7 @@ AlbumModel::flags( const QModelIndex& index ) const Qt::ItemFlags defaultFlags = QAbstractItemModel::flags( index ); if ( index.isValid() && index.column() == 0 ) - return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags; + return Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags; else return defaultFlags; } diff --git a/src/libtomahawk/playlist/AlbumView.cpp b/src/libtomahawk/playlist/AlbumView.cpp index a3442c9a0..e279c4bc2 100644 --- a/src/libtomahawk/playlist/AlbumView.cpp +++ b/src/libtomahawk/playlist/AlbumView.cpp @@ -170,6 +170,14 @@ AlbumView::onItemCountChanged( unsigned int items ) } +void +AlbumView::scrollContentsBy( int dx, int dy ) +{ + QListView::scrollContentsBy( dx, dy ); + emit scrolledContents( dx, dy ); +} + + void AlbumView::paintEvent( QPaintEvent* event ) { diff --git a/src/libtomahawk/playlist/AlbumView.h b/src/libtomahawk/playlist/AlbumView.h index cb2a069ea..d9b35213a 100644 --- a/src/libtomahawk/playlist/AlbumView.h +++ b/src/libtomahawk/playlist/AlbumView.h @@ -68,9 +68,11 @@ public slots: signals: void modelChanged(); + void scrolledContents( int dx, int dy ); protected: virtual void startDrag( Qt::DropActions supportedActions ); + virtual void scrollContentsBy( int dx, int dy ); void paintEvent( QPaintEvent* event ); void resizeEvent( QResizeEvent* event ); diff --git a/src/libtomahawk/utils/AnimatedSpinner.cpp b/src/libtomahawk/utils/AnimatedSpinner.cpp index 7cdb7dda0..7939eab80 100644 --- a/src/libtomahawk/utils/AnimatedSpinner.cpp +++ b/src/libtomahawk/utils/AnimatedSpinner.cpp @@ -57,12 +57,14 @@ AnimatedSpinner::AnimatedSpinner( const QSize size, bool autoStart ) void AnimatedSpinner::init() { + m_autoCenter = true; m_showHide->setDuration( 300 ); m_showHide->setStartFrame( 0 ); m_showHide->setEndFrame( 100 ); m_showHide->setUpdateInterval( 20 ); - if( parentWidget() ) + + if ( parentWidget() ) connect( m_showHide, SIGNAL( frameChanged( int ) ), this, SLOT( update() ) ); else connect( m_showHide, SIGNAL( frameChanged( int ) ), this, SLOT( updatePixmap() ) ); @@ -86,7 +88,6 @@ AnimatedSpinner::init() else size = m_pixmap.size(); - /// Radius is best-fit line with points (13x13, 2), (28x28, 5), (48x48, 10) m_radius = qRound( ( 23. * ( size.width() - 5.) ) / 100. ); m_armLength = size.width()/2 - m_radius; @@ -101,12 +102,12 @@ AnimatedSpinner::init() void -AnimatedSpinner::paintEvent(QPaintEvent *event) +AnimatedSpinner::paintEvent( QPaintEvent* event ) { - Q_UNUSED(event); - if ( parentWidget() ) + Q_UNUSED( event ); + if ( m_autoCenter && parentWidget() ) { - QPoint center( ( parentWidget()->width() / 2 ) - ( width() / 2 ), ( parentWidget()->height() / 2 ) - ( height() / 2 ) ); + QPoint center = parentWidget()->contentsRect().center(); if ( center != pos() ) { move( center ); @@ -114,7 +115,7 @@ AnimatedSpinner::paintEvent(QPaintEvent *event) } } - QPainter p(this); + QPainter p( this ); drawFrame( &p, rect() ); } diff --git a/src/libtomahawk/utils/AnimatedSpinner.h b/src/libtomahawk/utils/AnimatedSpinner.h index e738d9bb0..0bf502246 100644 --- a/src/libtomahawk/utils/AnimatedSpinner.h +++ b/src/libtomahawk/utils/AnimatedSpinner.h @@ -49,6 +49,8 @@ public: QSize sizeHint() const; QPixmap pixmap() const { return m_pixmap; } + + void setAutoCenter( bool enabled ) { m_autoCenter = enabled; } public slots: void fadeIn(); @@ -82,6 +84,7 @@ private: int m_currentIndex; QVector m_colors; QPixmap m_pixmap; + bool m_autoCenter; }; #endif