diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index 150da0642..a7cd9f8c1 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -170,9 +170,8 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, Q_ASSERT( m_loadingSpinners[ index ] ); if ( m_loadingSpinners[ index ] ) { - painter->setOpacity( 1.0 ); const QPixmap pm = m_loadingSpinners[index]->pixmap(); - painter->drawPixmap( checkRect.adjusted( -2, -2, 2, 2 ), pm ); + painter->drawPixmap( checkRect, pm ); } } @@ -681,7 +680,10 @@ void AccountDelegate::startInstalling( const QPersistentModelIndex& idx ) { qDebug() << "START INSTALLING:" << idx.data( Qt::DisplayRole ).toString(); - AnimatedSpinner* anim = new AnimatedSpinner( 0 ); + QStyleOptionViewItemV4 opt; + initStyleOption( &opt, idx ); + + AnimatedSpinner* anim = new AnimatedSpinner( checkRectForIndex( opt, idx ).size(), true ); _detail::Closure* closure = NewClosure( anim, SIGNAL( requestUpdate() ), this, SLOT( doUpdateIndex( const QPersistentModelIndex& ) ), idx ); closure->setAutoDelete( false ); diff --git a/src/libtomahawk/utils/AnimatedSpinner.cpp b/src/libtomahawk/utils/AnimatedSpinner.cpp index 0f98bc69a..25b0dc497 100644 --- a/src/libtomahawk/utils/AnimatedSpinner.cpp +++ b/src/libtomahawk/utils/AnimatedSpinner.cpp @@ -28,17 +28,67 @@ #include #include -AnimatedSpinner::AnimatedSpinner(QWidget *parent) - : QWidget(parent) +AnimatedSpinner::AnimatedSpinner( QWidget *parent ) + : QWidget( parent ) , m_showHide( new QTimeLine ) , m_animation( new QTimeLine ) , m_currentIndex( -1 ) { + init(); + m_radius = 10; + m_armLength = sizeHint().width()/2 - m_radius; + m_armWidth = 5; + m_border = 3; + m_armRect = QRect( m_radius, 0, m_armLength, m_armWidth ); +} + + +AnimatedSpinner::AnimatedSpinner( const QSize size, bool autoStart ) + : QWidget() + , m_showHide( new QTimeLine ) + , m_animation( new QTimeLine ) + , m_currentIndex( -1 ) +{ + m_pixmap = QPixmap( size ); + m_pixmap.fill( Qt::transparent ); + + init(); + + if ( size.width() < 30 ) + { + m_radius = 4; + m_armLength = size.width()/2 - m_radius; + m_armWidth = 2; + m_border = 2; + m_armRect = QRect( m_radius, 0, m_armLength, m_armWidth ); + } + else + { + m_radius = 10; + m_armLength = size.width()/2 - m_radius; + m_armWidth = 5; + m_border = 3; + m_armRect = QRect( m_radius, 0, m_armLength, m_armWidth ); + } + + if ( autoStart ) + fadeIn(); +} + + +void +AnimatedSpinner::init() +{ + m_showHide->setDuration( 300 ); m_showHide->setStartFrame( 0 ); m_showHide->setEndFrame( 100 ); m_showHide->setUpdateInterval( 20 ); - connect( m_showHide, SIGNAL( frameChanged( int ) ), this, SLOT( update() ) ); + if( parentWidget() ) + connect( m_showHide, SIGNAL( frameChanged( int ) ), this, SLOT( update() ) ); + else + connect( m_showHide, SIGNAL( frameChanged( int ) ), this, SLOT( updatePixmap() ) ); + connect( m_showHide, SIGNAL( finished() ), this, SLOT( hideFinished() ) ); m_animation->setDuration( 1000 ); @@ -53,12 +103,6 @@ AnimatedSpinner::AnimatedSpinner(QWidget *parent) m_colors.resize( segmentCount() ); hide(); - - if ( !parentWidget() ) - { - m_pixmap = QPixmap( sizeHint() ); - } - } @@ -66,7 +110,6 @@ void AnimatedSpinner::paintEvent(QPaintEvent *event) { Q_UNUSED(event); - if ( parentWidget() ) { QPoint center( ( parentWidget()->width() / 2 ) - ( width() / 2 ), ( parentWidget()->height() / 2 ) - ( height() / 2 ) ); @@ -77,43 +120,47 @@ AnimatedSpinner::paintEvent(QPaintEvent *event) } } - QPainter p; - if ( parentWidget() ) - { - p.begin(this); - } - else - { - m_pixmap.fill( Qt::transparent ); + QPainter p(this); + drawFrame( &p, rect() ); +} - p.begin(&m_pixmap); - } +void +AnimatedSpinner::updatePixmap() +{ + Q_ASSERT( !m_pixmap.isNull() ); + + QPainter p( &m_pixmap ); + m_pixmap.fill( Qt::transparent ); + drawFrame( &p, m_pixmap.rect() ); + p.end(); + + emit requestUpdate(); +} + + +void +AnimatedSpinner::drawFrame( QPainter* p, const QRect& rect ) +{ if ( m_showHide->state() == QTimeLine::Running ) { // showing or hiding - p.setOpacity( (qreal)m_showHide->currentValue() ); + p->setOpacity( (qreal)m_showHide->currentValue() ); } - const int radius = 10; - const int armLength = width()/2 - radius; - const int armWidth = 5; - const int border = 3; - const QRectF armRect( radius, 0, armLength, armWidth ); + p->setRenderHint(QPainter::Antialiasing, true); - p.setRenderHint(QPainter::Antialiasing, true); + p->translate( rect.center() ); // center - p.translate(width() / 2, height() / 2); // center - - const qreal stepRadius = (360 + 2*armWidth) / segmentCount(); - p.rotate( stepRadius ); + const qreal stepRadius = (360 + 2*m_armWidth) / segmentCount(); + p->rotate( stepRadius ); for (int segment = 0; segment < segmentCount(); ++segment) { - p.rotate(stepRadius); + p->rotate(stepRadius); QPainterPath arm; - arm.addRoundedRect( armRect.adjusted( 0, -armWidth/2., 0, -armWidth/2 ), border, border ); + arm.addRoundedRect( m_armRect.adjusted( 0, -m_armWidth/2., 0, -m_armWidth/2 ), m_border, m_border ); - p.fillPath( arm, colorForSegment( segment ) ); + p->fillPath( arm, colorForSegment( segment ) ); } } @@ -121,17 +168,20 @@ AnimatedSpinner::paintEvent(QPaintEvent *event) void AnimatedSpinner::fadeIn() { - if ( isVisible() ) + if ( parentWidget() && isVisible() ) return; - show(); - m_animation->start(); m_showHide->setDirection( QTimeLine::Forward ); if ( m_showHide->state() != QTimeLine::Running ) m_showHide->start(); + + if ( parentWidget() ) + show(); + else + updatePixmap(); } @@ -150,8 +200,11 @@ AnimatedSpinner::hideFinished() { if ( m_showHide->direction() == QTimeLine::Backward ) { - hide(); m_animation->stop(); + if ( parentWidget() ) + hide(); + else + updatePixmap(); } } @@ -188,7 +241,11 @@ AnimatedSpinner::frameChanged( int frame ) ++running; cur = --cur < 0 ? m_colors.size() - 1 : cur; } - update(); + + if ( parentWidget() ) + update(); + else + updatePixmap(); } diff --git a/src/libtomahawk/utils/AnimatedSpinner.h b/src/libtomahawk/utils/AnimatedSpinner.h index cfe76d388..e738d9bb0 100644 --- a/src/libtomahawk/utils/AnimatedSpinner.h +++ b/src/libtomahawk/utils/AnimatedSpinner.h @@ -25,6 +25,7 @@ #include #include #include +#include class QTimeLine; class QHideEvent; @@ -32,18 +33,21 @@ class QShowEvent; class QPaintEvent; class QTimerEvent; +/** + If you don't pass a parent QWidget, this spinner will + draw into the pixmap instead. If you do, the pixmap will + be invalid. + + */ class DLLEXPORT AnimatedSpinner : public QWidget { Q_OBJECT public: - AnimatedSpinner( QWidget *parent = 0 ); + explicit AnimatedSpinner( QWidget *parent = 0 ); // widget mode + AnimatedSpinner( const QSize size, bool autoStart ); // pixmap mode QSize sizeHint() const; - /** - If you don't pass a parent QWidget, this spinner will - draw into the pixmap instead. If you do, this will be invalid. - */ QPixmap pixmap() const { return m_pixmap; } public slots: @@ -57,17 +61,24 @@ protected: void paintEvent(QPaintEvent *event); private slots: + void updatePixmap(); void hideFinished(); void frameChanged( int ); private: + void init(); + void drawFrame( QPainter* p, const QRect& rect ); int segmentCount() const; QColor colorForSegment( int segment ) const; QTimeLine* m_showHide; QTimeLine* m_animation; + // to tweak + int m_radius, m_armLength, m_armWidth, m_border; + QRect m_armRect; + int m_currentIndex; QVector m_colors; QPixmap m_pixmap;