playlistitem.cpp
来自「Amarok是一款在LINUX或其他类UNIX操作系统中运行的音频播放器软件。 」· C++ 代码 · 共 1,153 行 · 第 1/3 页
CPP
1,153 行
static const QPixmap pixstop = Amarok::getPNG( "currenttrack_stop_small" ), pixrepeat = Amarok::getPNG( "currenttrack_repeat_small" ); //figure out if we are in the actual physical first column if( column == listView()->m_firstColumn && num ) { //margin, height const uint m = 2, h = height() - m; const QString str = QString::number( queue ); const uint qw = painter->fontMetrics().width( str ), sw = pixstop.width(), rw = pixrepeat.width(), qh = painter->fontMetrics().height(), sh = pixstop.height(), rh = pixrepeat.height(); //maxwidth const uint mw = kMax( qw, kMax( rw, sw ) ); //width of first & second column of pixmaps const uint w1 = ( num == 3 ) ? kMax( qw, rw ) : ( num == 2 && isCurrent ) ? kMax( repeat ? rw : 0, kMax( stop ? sw : 0, queue ? qw : 0 ) ) : ( num == 2 ) ? qw : queue ? qw : repeat ? rw : stop ? sw : 0, w2 = ( num == 3 ) ? sw : ( num == 2 && !isCurrent ) ? sw : 0; //phew //ellipse width, total width const uint ew = 16, tw = w1 + w2 + m * ( w2 ? 2 : 1 ); p.setBrush( cg.highlight() ); p.setPen( cg.highlight().dark() ); //TODO blend with background color p.drawEllipse( width - tw - ew/2, m / 2, ew, h ); p.drawRect( width - tw, m / 2, tw, h ); p.setPen( cg.highlight() ); p.drawLine( width - tw, m/2 + 1, width - tw, h - m/2 ); int x = width - m - mw, y = height() / 2, tmp = 0; const bool multi = ( isCurrent && num >= 2 ); if( queue ) { //draw the shadowed inner text //NOTE we can't set an arbituary font size or family, these settings are already optional //and user defaults should also take presidence if no playlist font has been selected //const QFont smallFont( "Arial", (playNext > 9) ? 9 : 12 ); //p->setFont( smallFont ); //TODO the shadow is hard to do well when using a dark font color //TODO it also looks cluttered for small font sizes //p->setPen( cg.highlightedText().dark() ); //p->drawText( width - w + 2, 3, w, h-1, Qt::AlignCenter, str ); if( !multi ) tmp = -(qh / 2); y += tmp; p.setPen( cg.highlightedText() ); p.drawText( x, y, -x + width, multi ? h/2 : qh, Qt::AlignCenter, str ); y -= tmp; if( isCurrent ) y -= height() / 2; else x -= m + w2; } if( repeat ) { if( multi ) tmp = (h/2 - rh)/2 + ( num == 2 && stop ? 0 : 1 ); else tmp = -(rh / 2); y += tmp; p.drawPixmap( x, y, pixrepeat ); y -= tmp; if( num == 3 ) { x -= m + w2 + 2; y = height() / 2; } else y -= height() / 2; } if( stop ) { if( multi && num != 3 ) tmp = m + (h/2 - sh)/2; else tmp = -(sh / 2); y += tmp; p.drawPixmap( x, y, pixstop ); y -= tmp; } } if( this != listView()->currentTrack() && !isSelected() ) { p.setPen( QPen( cg.mid(), 0, Qt::SolidLine ) ); p.drawLine( width - 1, 0, width - 1, height() - 1 ); } p.end(); painter->drawPixmap( 0, 0, buf );}void PlaylistItem::drawRating( QPainter *p ){ int gray = 0; if( this == listView()->m_hoveredRating || ( isSelected() && listView()->m_selCount > 1 && listView()->m_hoveredRating && listView()->m_hoveredRating->isSelected() ) ) { const int pos = listView()->viewportToContents( listView()->viewport()->mapFromGlobal( QCursor::pos() ) ).x(); gray = ratingAtPoint( pos ); } drawRating( p, ( rating() + 1 ) / 2, gray / 2, rating() % 2 );}void PlaylistItem::drawRating( QPainter *p, int stars, int greystars, bool half ){ int i = 1, x = 1; const int y = height() / 2 - StarManager::instance()->getGreyStar()->height() / 2; if( half ) i++; //We use multiple pre-colored stars instead of coloring here to keep things speedy for(; i <= stars; ++i ) { bitBlt( p->device(), x, y, StarManager::instance()->getStar( stars ) ); x += StarManager::instance()->getGreyStar()->width() + listView()->itemMargin(); } if( half ) { bitBlt( p->device(), x, y, StarManager::instance()->getHalfStar( stars ) ); x += StarManager::instance()->getGreyStar()->width() + listView()->itemMargin(); } for(; i <= greystars; ++i ) { bitBlt( p->device(), x, y, StarManager::instance()->getGreyStar() ); x += StarManager::instance()->getGreyStar()->width() + listView()->itemMargin(); }}#define MOODBAR_SPACING 2 // The distance from the moodbar pixmap to each sidevoid PlaylistItem::drawMood( QPainter *p, int width, int height ){ // In theory, if AmarokConfig::showMoodbar() == false, then the // moodbar column should be hidden and we shouldn't be here. if( !AmarokConfig::showMoodbar() ) return; // Due to the logic of the calling code, this should always return true if( moodbar().dataExists() ) { QPixmap mood = moodbar().draw( width - MOODBAR_SPACING*2, height - MOODBAR_SPACING*2 ); p->drawPixmap( MOODBAR_SPACING, MOODBAR_SPACING, mood ); } else moodbar().load(); // This only has any effect the first time it's run // We don't have to listen for the jobEvent() signal since we // inherit MetaBundle, and the moodbar lets the MetaBundle know // about new data directly via moodbarJobEvent() below.}// This is run when a job starts or finishesvoid PlaylistItem::moodbarJobEvent( int newState ){ (void) newState; // want to redraw nomatter what the new state is if( AmarokConfig::showMoodbar() ) repaint(); // Don't automatically resort because it's annoying}void PlaylistItem::setup(){ KListViewItem::setup(); // We make the current track item a bit taller than ordinary items if( this == listView()->currentTrack() ) setHeight( int( float( listView()->fontMetrics().height() ) * 1.53 ) );}void PlaylistItem::paintFocus( QPainter* p, const QColorGroup& cg, const QRect& r ){ if( this != listView()->currentTrack() ) KListViewItem::paintFocus( p, cg, r );}const QString &PlaylistItem::editingText(){ static const QString text = i18n( "Writing tag..." ); return text;}/** * Changes the transparency (alpha component) of an image. * @param image Image to be manipulated. Must be true color (8 bit per channel). * @param factor > 1.0 == more transparency, < 1.0 == less transparency. */void PlaylistItem::imageTransparency( QImage& image, float factor ) //static{ uint *data = reinterpret_cast<unsigned int *>( image.bits() ); const int pixels = image.width() * image.height(); uint table[256]; register int c; // Precalculate lookup table for( int i = 0; i < 256; ++i ) { c = int( double( i ) * factor ); if( c > 255 ) c = 255; table[i] = c; } // Process all pixels. Highly optimized. for( int i = 0; i < pixels; ++i ) { c = data[i]; // Memory access is slow, so do it only once data[i] = qRgba( qRed( c ), qGreen( c ), qBlue( c ), table[qAlpha( c )] ); }}AtomicString PlaylistItem::artist_album() const{ static const AtomicString various_artist = QString( "Various Artists (INTERNAL) [ASDF!]" ); if( compilation() == CompilationYes ) return various_artist; else return artist();}void PlaylistItem::refAlbum(){ if( Amarok::entireAlbums() ) { if( listView()->m_albums[artist_album()].find( album() ) == listView()->m_albums[artist_album()].end() ) listView()->m_albums[artist_album()][album()] = new PlaylistAlbum; m_album = listView()->m_albums[artist_album()][album()]; m_album->refcount++; }}void PlaylistItem::derefAlbum(){ if( Amarok::entireAlbums() && m_album ) { m_album->refcount--; if( !m_album->refcount ) { if (!listView()->m_prevAlbums.removeRef( m_album )) warning() << "Unable to remove album reference from " << "listView.m_prevAlbums" << endl; listView()->m_albums[artist_album()].remove( album() ); if( listView()->m_albums[artist_album()].isEmpty() ) listView()->m_albums.remove( artist_album() ); delete m_album; } }}void PlaylistItem::incrementTotals(){ if( Amarok::entireAlbums() && m_album ) { const uint prevCount = m_album->tracks.count(); // Multiple tracks with same track number are possible; // e.g. with "various_artist" albums or albums with multiple disks. // We are trying to keep m_album->tracks sorted first by discNumber() and then by track(). // It seems that the following assumption is made for the following: // ``Either all the tracks in an album have their track()'s set (to nonzero) or none of them have.'' if( !track() || !m_album->tracks.count() || ( m_album->tracks.getLast()->track() && ( ( m_album->tracks.getLast()->discNumber() < discNumber() ) || ( m_album->tracks.getLast()->discNumber() == discNumber() && m_album->tracks.getLast()->track() < track() ) ) ) ) m_album->tracks.append( this ); else for( int i = 0, n = m_album->tracks.count(); i < n; ++i ) if(!m_album->tracks.at(i)->track() || m_album->tracks.at(i)->discNumber() > discNumber() || ( m_album->tracks.at(i)->discNumber() == discNumber() && m_album->tracks.at(i)->track() > track() ) ) { m_album->tracks.insert( i, this ); break; } const Q_INT64 prevTotal = m_album->total; Q_INT64 total = m_album->total * prevCount; total += totalIncrementAmount(); m_album->total = Q_INT64( double( total + 0.5 ) / m_album->tracks.count() ); if( listView()->m_prevAlbums.findRef( m_album ) == -1 ) listView()->m_total = listView()->m_total - prevTotal + m_album->total; } else if( listView()->m_prevTracks.findRef( this ) == -1 ) listView()->m_total += totalIncrementAmount();}void PlaylistItem::decrementTotals(){ if( Amarok::entireAlbums() && m_album ) { const Q_INT64 prevTotal = m_album->total; Q_INT64 total = m_album->total * m_album->tracks.count(); if (!m_album->tracks.removeRef( this )) warning() << "Unable to remove myself from m_album" << endl; total -= totalIncrementAmount(); m_album->total = Q_INT64( double( total + 0.5 ) / m_album->tracks.count() ); if( listView()->m_prevAlbums.findRef( m_album ) == -1 ) listView()->m_total = listView()->m_total - prevTotal + m_album->total; } else if( listView()->m_prevTracks.findRef( this ) == -1 ) listView()->m_total -= totalIncrementAmount();}int PlaylistItem::totalIncrementAmount() const{ switch( AmarokConfig::favorTracks() ) { case AmarokConfig::EnumFavorTracks::Off: return 0; case AmarokConfig::EnumFavorTracks::HigherScores: return score() > 0.f ? static_cast<int>( score() ) : 50; case AmarokConfig::EnumFavorTracks::HigherRatings: return rating() ? rating() : 5; // 2.5 case AmarokConfig::EnumFavorTracks::LessRecentlyPlayed: { if( lastPlay() ) return listView()->m_startupTime_t - lastPlay(); else if( listView()->m_oldestTime_t ) return ( listView()->m_startupTime_t - listView()->m_oldestTime_t ) * 2; else return listView()->m_startupTime_t - 1058652000; //july 20, 2003, when Amarok was first released. } default: return 0; }}void PlaylistItem::incrementCounts(){ listView()->m_totalCount++; if( isSelected() ) { listView()->m_selCount++; } if( isVisible() ) { listView()->m_visCount++; incrementTotals(); }}void PlaylistItem::decrementCounts(){ listView()->m_totalCount--; if( isSelected() ) { listView()->m_selCount--; } if( isVisible() ) { listView()->m_visCount--; decrementTotals(); }}void PlaylistItem::incrementLengths(){ listView()->m_totalLength += length(); if( isSelected() ) { listView()->m_selLength += length(); } if( isVisible() ) { listView()->m_visLength += length(); }}void PlaylistItem::decrementLengths(){ listView()->m_totalLength -= length(); if( isSelected() ) { listView()->m_selLength -= length(); } if( isVisible() ) { listView()->m_visLength -= length(); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?