X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fgui%2Fqt4%2Fcomponents%2Fplaylist%2Ficon_view.cpp;h=9b8d1f183322df734d558044429b0d1af233729b;hb=05d736eac9cb11e55fca0552ff4150cb48004ed8;hp=b3101e9a6f292708a59712370d632df4af0c62ef;hpb=91d00d909f5ab02b1ffc6073500667cfb6679b7d;p=vlc diff --git a/modules/gui/qt4/components/playlist/icon_view.cpp b/modules/gui/qt4/components/playlist/icon_view.cpp index b3101e9a6f..9b8d1f1833 100644 --- a/modules/gui/qt4/components/playlist/icon_view.cpp +++ b/modules/gui/qt4/components/playlist/icon_view.cpp @@ -23,98 +23,282 @@ #include "components/playlist/icon_view.hpp" #include "components/playlist/playlist_model.hpp" +#include "components/playlist/sorting.h" #include "input_manager.hpp" +#include #include #include #include -#include +#include +#include #include "assert.h" -#define RECT_SIZE 100 -#define ART_SIZE 64 -#define OFFSET (100-64)/2 -#define ITEMS_SPACING 10 +#define ART_SIZE_W 110 +#define ART_SIZE_H 80 #define ART_RADIUS 5 +#define SPACER 5 -void PlListViewItemDelegate::paint( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const +QString AbstractPlViewItemDelegate::getMeta( const QModelIndex & index, int meta ) const { - painter->setRenderHints( QPainter::Antialiasing | QPainter::SmoothPixmapTransform ); + return index.model()->index( index.row(), + PLModel::columnFromMeta( meta ), + index.parent() ) + .data().toString(); +} - /*if( option.state & QStyle::State_Selected ) - painter->fillRect(option.rect, option.palette.highlight());*/ - QApplication::style()->drawPrimitive( QStyle::PE_PanelItemViewItem, &option, painter ); +void AbstractPlViewItemDelegate::paintPlayingItemBg( QPainter *painter, const QStyleOptionViewItem & option ) const +{ + painter->save(); + painter->setOpacity( 0.5 ); + painter->setBrush( QBrush( Qt::gray ) ); + painter->fillRect( option.rect, option.palette.color( QPalette::Dark ) ); + painter->restore(); +} - PLItem *currentItem = static_cast( index.internalPointer() ); - assert( currentItem ); +QPixmap AbstractPlViewItemDelegate::getArtPixmap( const QModelIndex & index, const QSize & size ) const +{ + PLItem *item = static_cast( index.internalPointer() ); + assert( item ); - QPixmap pix; - QString url = InputManager::decodeArtURL( currentItem->inputItem() ); + QString artUrl = InputManager::decodeArtURL( item->inputItem() ); - if( !url.isEmpty() && pix.load( url ) ) + if( artUrl.isEmpty() ) { - pix = pix.scaled( ART_SIZE, ART_SIZE, Qt::KeepAspectRatioByExpanding ); + for( int i = 0; i < item->childCount(); i++ ) + { + artUrl = InputManager::decodeArtURL( item->child( i )->inputItem() ); + if( !artUrl.isEmpty() ) + break; + } } - else + + QPixmap artPix; + + QString key = artUrl + QString("%1%2").arg(size.width()).arg(size.height()); + + if( !QPixmapCache::find( key, artPix )) { - pix = QPixmap( ":/noart64" ); + if( artUrl.isEmpty() || !artPix.load( artUrl ) ) + { + artPix = QPixmap( ":/noart" ).scaled( size, Qt::KeepAspectRatio, Qt::SmoothTransformation ); + } + else + { + artPix = artPix.scaled( size, Qt::KeepAspectRatio, Qt::SmoothTransformation ); + QPixmapCache::insert( key, artPix ); + } } - QRect artRect = option.rect.adjusted( OFFSET - 1, 0, - OFFSET, - OFFSET *2 ); - QPainterPath artRectPath; - artRectPath.addRoundedRect( artRect, ART_RADIUS, ART_RADIUS ); + return artPix; +} + +void PlIconViewItemDelegate::paint( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const +{ + QString title = getMeta( index, COLUMN_TITLE ); + QString artist = getMeta( index, COLUMN_ARTIST ); + + QPixmap artPix = getArtPixmap( index, QSize( ART_SIZE_W, ART_SIZE_H ) ); + + QApplication::style()->drawPrimitive( QStyle::PE_PanelItemViewItem, &option, + painter ); + + painter->save(); + + if( index.data( PLModel::IsCurrentRole ).toBool() ) + { + painter->save(); + painter->setOpacity( 0.2 ); + painter->setBrush( QBrush( Qt::gray ) ); + painter->drawRoundedRect( option.rect.adjusted( 0, 0, -1, -1 ), ART_RADIUS, ART_RADIUS ); + painter->restore(); + } + + QRect artRect( option.rect.x() + 5 + ( ART_SIZE_W - artPix.width() ) / 2, + option.rect.y() + 5 + ( ART_SIZE_H - artPix.height() ) / 2, + artPix.width(), artPix.height() ); // Draw the drop shadow painter->save(); painter->setOpacity( 0.7 ); - painter->setBrush( QBrush( Qt::gray ) ); - painter->drawRoundedRect( artRect.adjusted( 2, 2, 2, 2 ), ART_RADIUS, ART_RADIUS ); + painter->setBrush( QBrush( Qt::darkGray ) ); + painter->setPen( Qt::NoPen ); + painter->drawRoundedRect( artRect.adjusted( 0, 0, 2, 2 ), ART_RADIUS, ART_RADIUS ); painter->restore(); // Draw the art pixmap + QPainterPath artRectPath; + artRectPath.addRoundedRect( artRect, ART_RADIUS, ART_RADIUS ); painter->setClipPath( artRectPath ); - painter->drawPixmap( artRect, pix ); + painter->drawPixmap( artRect, artPix ); painter->setClipping( false ); - painter->setFont( QFont( "Verdana", 7 ) ); + if( option.state & QStyle::State_Selected ) + painter->setPen( option.palette.color( QPalette::HighlightedText ) ); - QRect textRect = option.rect.adjusted( 1, ART_SIZE + 2, -1, -1 ); - painter->drawText( textRect, qfu( input_item_GetTitleFbName( currentItem->inputItem() ) ), - QTextOption( Qt::AlignCenter ) ); + QFont font( index.data( Qt::FontRole ).value() ); + font.setPointSize( 7 ); + // Draw title + font.setItalic( true ); + painter->setFont( font ); + + QFontMetrics fm = painter->fontMetrics(); + QRect textRect = option.rect.adjusted( 1, ART_SIZE_H + 10, 0, -1 ); + textRect.setHeight( fm.height() ); + + painter->drawText( textRect, + fm.elidedText( title, Qt::ElideRight, textRect.width() ), + QTextOption( Qt::AlignCenter ) ); + + // Draw artist + painter->setPen( painter->pen().color().lighter( 150 ) ); + font.setItalic( false ); + painter->setFont( font ); + fm = painter->fontMetrics(); + + textRect.moveTop( textRect.bottom() + 1 ); + + painter->drawText( textRect, + fm.elidedText( artist, Qt::ElideRight, textRect.width() ), + QTextOption( Qt::AlignCenter ) ); + + painter->restore(); } -QSize PlListViewItemDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const +QSize PlIconViewItemDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const { - return QSize( RECT_SIZE, RECT_SIZE); + QFont f; + f.setPointSize( 7 ); + f.setBold( true ); + QFontMetrics fm( f ); + int textHeight = fm.height(); + QSize sz ( ART_SIZE_W + 2 * SPACER, + ART_SIZE_H + 3 * SPACER + 2 * textHeight + 1 ); + return sz; } +#define LISTVIEW_ART_SIZE 45 + +void PlListViewItemDelegate::paint( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const +{ + QModelIndex parent = index.parent(); + QModelIndex i; + + QString title = getMeta( index, COLUMN_TITLE ); + QString duration = getMeta( index, COLUMN_DURATION ); + if( !duration.isEmpty() ) title += QString(" [%1]").arg( duration ); + + QString artist = getMeta( index, COLUMN_ARTIST ); + QString album = getMeta( index, COLUMN_ALBUM ); + QString trackNum = getMeta( index, COLUMN_TRACK_NUMBER ); + QString artistAlbum = artist + + ( artist.isEmpty() ? QString() : QString( ": " ) ) + + album + + ( album.isEmpty() || trackNum.isEmpty() ? + QString() : QString( " [#%1]" ).arg( trackNum ) ); + + QPixmap artPix = getArtPixmap( index, QSize( LISTVIEW_ART_SIZE, LISTVIEW_ART_SIZE ) ); + + //Draw selection rectangle + QApplication::style()->drawPrimitive( QStyle::PE_PanelItemViewItem, &option, painter ); + + //Paint background if item is playing + if( index.data( PLModel::IsCurrentRole ).toBool() ) + paintPlayingItemBg( painter, option ); + + QRect artRect( artPix.rect() ); + artRect.moveCenter( QPoint( artRect.center().x() + 3, + option.rect.center().y() ) ); + //Draw album art + painter->drawPixmap( artRect, artPix ); + + //Start drawing text + painter->save(); + + if( option.state & QStyle::State_Selected ) + painter->setPen( option.palette.color( QPalette::HighlightedText ) ); + + QTextOption textOpt( Qt::AlignVCenter | Qt::AlignLeft ); + textOpt.setWrapMode( QTextOption::NoWrap ); + + QFont f( index.data( Qt::FontRole ).value() ); + + //Draw title info + f.setItalic( true ); + painter->setFont( f ); + QFontMetrics fm( painter->fontMetrics() ); + + QRect textRect = option.rect.adjusted( LISTVIEW_ART_SIZE + 10, 0, -10, 0 ); + if( !artistAlbum.isEmpty() ) + { + textRect.setHeight( fm.height() ); + textRect.moveBottom( option.rect.center().y() - 1 ); + } + + painter->drawText( textRect, + fm.elidedText( title, Qt::ElideRight, textRect.width() ), + textOpt ); + + // Draw artist and album info + if( !artistAlbum.isEmpty() ) + { + f.setItalic( false ); + painter->setFont( f ); + fm = painter->fontMetrics(); + + textRect.moveTop( textRect.bottom() + 2 ); + + painter->drawText( textRect, + fm.elidedText( artistAlbum, Qt::ElideRight, textRect.width() ), + textOpt ); + } + + painter->restore(); +} + +QSize PlListViewItemDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const +{ + QFont f; + f.setBold( true ); + QFontMetrics fm( f ); + int height = qMax( LISTVIEW_ART_SIZE, 2 * fm.height() + 2 ) + 6; + return QSize( 0, height ); +} + PlIconView::PlIconView( PLModel *model, QWidget *parent ) : QListView( parent ) { + PlIconViewItemDelegate *delegate = new PlIconViewItemDelegate( this ); + setModel( model ); setViewMode( QListView::IconMode ); setMovement( QListView::Static ); setResizeMode( QListView::Adjust ); - setGridSize( QSize( 100, 100 ) ); - setSpacing( ITEMS_SPACING ); + setGridSize( delegate->sizeHint() ); setWrapping( true ); + setUniformItemSizes( true ); + setSelectionMode( QAbstractItemView::ExtendedSelection ); + setDragEnabled(true); + /* dropping in QListView::IconMode does not seem to work */ + //setAcceptDrops( true ); + //setDropIndicatorShown(true); - PlListViewItemDelegate *pl = new PlListViewItemDelegate(); - setItemDelegate( pl ); - - CONNECT( this, activated( const QModelIndex & ), this, activate( const QModelIndex & ) ); + setItemDelegate( delegate ); } -void PlIconView::activate( const QModelIndex & index ) +PlListView::PlListView( PLModel *model, QWidget *parent ) : QListView( parent ) { - if( model()->hasChildren( index ) ) - setRootIndex( index ); - else - { - PLModel *plModel = qobject_cast( model() ); - if( !plModel ) return; - plModel->activateItem( index ); - } + setModel( model ); + setViewMode( QListView::ListMode ); + setUniformItemSizes( true ); + setSelectionMode( QAbstractItemView::ExtendedSelection ); + setAlternatingRowColors( true ); + setDragEnabled(true); + setAcceptDrops( true ); + setDropIndicatorShown(true); + + PlListViewItemDelegate *delegate = new PlListViewItemDelegate( this ); + setItemDelegate( delegate ); }