1 /*****************************************************************************
2 * icon_view.cpp : Icon view for the Playlist
3 ****************************************************************************
4 * Copyright © 2010 the VideoLAN team
7 * Authors: Jean-Baptiste Kempf <jb@videolan.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 #include "components/playlist/icon_view.hpp"
25 #include "components/playlist/playlist_model.hpp"
26 #include "components/playlist/sorting.h"
27 #include "input_manager.hpp"
29 #include <QApplication>
32 #include <QStyleOptionViewItem>
33 #include <QFontMetrics>
34 #include <QPixmapCache>
38 #define RECT_SIZE_W 120
39 #define RECT_SIZE_H 120
40 #define ART_SIZE_W 110
42 //#define OFFSET (RECT_SIZE_W-ART_SIZE_W)/2
43 //#define ITEMS_SPACING 10
46 QString AbstractPlViewItemDelegate::getMeta( const QModelIndex & index, int meta ) const
48 return index.model()->index( index.row(),
49 PLModel::columnFromMeta( meta ),
54 void AbstractPlViewItemDelegate::paintPlayingItemBg( QPainter *painter, const QStyleOptionViewItem & option ) const
57 painter->setOpacity( 0.5 );
58 painter->setBrush( QBrush( Qt::gray ) );
59 painter->fillRect( option.rect, option.palette.color( QPalette::Dark ) );
63 QPixmap AbstractPlViewItemDelegate::getArtPixmap( const QModelIndex & index, const QSize & size ) const
65 PLItem *item = static_cast<PLItem*>( index.internalPointer() );
68 QString artUrl = InputManager::decodeArtURL( item->inputItem() );
70 if( artUrl.isEmpty() )
72 for( int i = 0; i < item->childCount(); i++ )
74 artUrl = InputManager::decodeArtURL( item->child( i )->inputItem() );
75 if( !artUrl.isEmpty() )
82 QString key = artUrl + QString("%1%2").arg(size.width()).arg(size.height());
84 if( !QPixmapCache::find( key, artPix ))
86 if( artUrl.isEmpty() || !artPix.load( artUrl ) )
88 artPix = QPixmap( ":/noart" ).scaled( size, Qt::KeepAspectRatio, Qt::SmoothTransformation );
92 artPix = artPix.scaled( size, Qt::KeepAspectRatio, Qt::SmoothTransformation );
93 QPixmapCache::insert( key, artPix );
100 void PlIconViewItemDelegate::paint( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
102 QString title = getMeta( index, COLUMN_TITLE );
103 QString artist = getMeta( index, COLUMN_ARTIST );
105 QPixmap artPix = getArtPixmap( index, QSize( ART_SIZE_W, ART_SIZE_H ) );
107 QApplication::style()->drawPrimitive( QStyle::PE_PanelItemViewItem, &option,
112 if( index.data( PLModel::IsCurrentRole ).toBool() )
115 painter->setOpacity( 0.2 );
116 painter->setBrush( QBrush( Qt::gray ) );
117 painter->drawRoundedRect( option.rect.adjusted( 0, 0, -1, -1 ), ART_RADIUS, ART_RADIUS );
121 QRect artRect( option.rect.x() + 5 + ( ART_SIZE_W - artPix.width() ) / 2,
122 option.rect.y() + 5 + ( ART_SIZE_H - artPix.height() ) / 2,
123 artPix.width(), artPix.height() );
125 // Draw the drop shadow
127 painter->setOpacity( 0.7 );
128 painter->setBrush( QBrush( Qt::darkGray ) );
129 painter->setPen( Qt::NoPen );
130 painter->drawRoundedRect( artRect.adjusted( 0, 0, 2, 2 ), ART_RADIUS, ART_RADIUS );
133 // Draw the art pixmap
134 QPainterPath artRectPath;
135 artRectPath.addRoundedRect( artRect, ART_RADIUS, ART_RADIUS );
136 painter->setClipPath( artRectPath );
137 painter->drawPixmap( artRect, artPix );
138 painter->setClipping( false );
140 if( option.state & QStyle::State_Selected )
141 painter->setPen( option.palette.color( QPalette::HighlightedText ) );
144 font.setPointSize( 7 );
145 font.setBold( index.data( Qt::FontRole ).value<QFont>().bold() );
148 font.setItalic( true );
149 painter->setFont( font );
151 QFontMetrics fm = painter->fontMetrics();
152 QRect textRect = option.rect.adjusted( 1, ART_SIZE_H + 10, 0, -1 );
153 textRect.setHeight( fm.height() + 1 );
155 painter->drawText( textRect,
156 fm.elidedText( title, Qt::ElideRight, textRect.width() ),
157 QTextOption( Qt::AlignCenter ) );
160 painter->setPen( painter->pen().color().lighter( 150 ) );
161 font.setItalic( false );
162 painter->setFont( font );
163 fm = painter->fontMetrics();
165 textRect = textRect.adjusted( 0, textRect.height(),
166 0, textRect.height() );
167 painter->drawText( textRect,
168 fm.elidedText( artist, Qt::ElideRight, textRect.width() ),
169 QTextOption( Qt::AlignCenter ) );
174 QSize PlIconViewItemDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const
176 return QSize( RECT_SIZE_W, RECT_SIZE_H );
179 #define LISTVIEW_ART_SIZE 45
181 void PlListViewItemDelegate::paint( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
183 QModelIndex parent = index.parent();
186 QString title = getMeta( index, COLUMN_TITLE );
187 QString duration = getMeta( index, COLUMN_DURATION );
188 if( !duration.isEmpty() ) title += QString(" [%1]").arg( duration );
190 QString artist = getMeta( index, COLUMN_ARTIST );
191 QString album = getMeta( index, COLUMN_ALBUM );
192 QString trackNum = getMeta( index, COLUMN_TRACK_NUMBER );
193 QString artistAlbum = artist
194 + ( artist.isEmpty() ? QString() : QString( ": " ) )
196 + ( album.isEmpty() || trackNum.isEmpty() ?
197 QString() : QString( " [#%1]" ).arg( trackNum ) );
199 QPixmap artPix = getArtPixmap( index, QSize( LISTVIEW_ART_SIZE, LISTVIEW_ART_SIZE ) );
201 QApplication::style()->drawPrimitive( QStyle::PE_PanelItemViewItem, &option, painter );
203 if( index.data( PLModel::IsCurrentRole ).toBool() )
204 paintPlayingItemBg( painter, option );
206 painter->drawPixmap( option.rect.topLeft() + QPoint(3,3)
207 + QPoint( (LISTVIEW_ART_SIZE - artPix.width()) / 2,
208 (LISTVIEW_ART_SIZE - artPix.height()) / 2 ),
212 int textH = option.fontMetrics.height() + 2;
213 int marginY = ( option.rect.height() / 2 ) - textH;
215 QRect textRect = option.rect.adjusted( LISTVIEW_ART_SIZE + 10,
218 marginY * -1 - ( artistAlbum.isEmpty() ? 0 : textH ) );
222 if( option.state & QStyle::State_Selected )
223 painter->setPen( option.palette.color( QPalette::HighlightedText ) );
225 QTextOption textOpt( Qt::AlignVCenter | Qt::AlignLeft );
226 textOpt.setWrapMode( QTextOption::NoWrap );
228 QFont f( option.font );
229 if( index.data( PLModel::IsCurrentRole ).toBool() ) f.setBold( true );
232 painter->setFont( f );
234 painter->drawText( textRect, title, textOpt );
236 f.setItalic( false );
237 painter->setFont( f );
238 textRect.moveTop( textRect.top() + textH );
240 painter->drawText( textRect, artistAlbum, textOpt );
245 QSize PlListViewItemDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const
247 return QSize( LISTVIEW_ART_SIZE + 6, LISTVIEW_ART_SIZE + 6 );
250 PlIconView::PlIconView( PLModel *model, QWidget *parent ) : QListView( parent )
253 setViewMode( QListView::IconMode );
254 setMovement( QListView::Static );
255 setResizeMode( QListView::Adjust );
256 setGridSize( QSize( RECT_SIZE_W, RECT_SIZE_H ) );
258 setUniformItemSizes( true );
259 setSelectionMode( QAbstractItemView::ExtendedSelection );
260 setDragEnabled(true);
261 /* dropping in QListView::IconMode does not seem to work */
262 //setAcceptDrops( true );
263 //setDropIndicatorShown(true);
265 PlIconViewItemDelegate *delegate = new PlIconViewItemDelegate( this );
266 setItemDelegate( delegate );
269 PlListView::PlListView( PLModel *model, QWidget *parent ) : QListView( parent )
272 setViewMode( QListView::ListMode );
273 setUniformItemSizes( true );
274 setSelectionMode( QAbstractItemView::ExtendedSelection );
275 setAlternatingRowColors( true );
276 setDragEnabled(true);
277 setAcceptDrops( true );
278 setDropIndicatorShown(true);
280 PlListViewItemDelegate *delegate = new PlListViewItemDelegate( this );
281 setItemDelegate( delegate );