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 ART_SIZE_W 110
43 QString
AbstractPlViewItemDelegate::getMeta( const QModelIndex
& index
, int meta
) const
45 return index
.model()->index( index
.row(),
46 PLModel::columnFromMeta( meta
),
51 void AbstractPlViewItemDelegate::paintPlayingItemBg( QPainter
*painter
, const QStyleOptionViewItem
& option
) const
54 painter
->setOpacity( 0.5 );
55 painter
->setBrush( QBrush( Qt::gray
) );
56 painter
->fillRect( option
.rect
, option
.palette
.color( QPalette::Dark
) );
60 QPixmap
AbstractPlViewItemDelegate::getArtPixmap( const QModelIndex
& index
, const QSize
& size
) const
62 PLItem
*item
= static_cast<PLItem
*>( index
.internalPointer() );
65 QString artUrl
= InputManager::decodeArtURL( item
->inputItem() );
67 if( artUrl
.isEmpty() )
69 for( int i
= 0; i
< item
->childCount(); i
++ )
71 artUrl
= InputManager::decodeArtURL( item
->child( i
)->inputItem() );
72 if( !artUrl
.isEmpty() )
79 QString key
= artUrl
+ QString("%1%2").arg(size
.width()).arg(size
.height());
81 if( !QPixmapCache::find( key
, artPix
))
83 if( artUrl
.isEmpty() || !artPix
.load( artUrl
) )
85 artPix
= QPixmap( ":/noart" ).scaled( size
, Qt::KeepAspectRatio
, Qt::SmoothTransformation
);
89 artPix
= artPix
.scaled( size
, Qt::KeepAspectRatio
, Qt::SmoothTransformation
);
90 QPixmapCache::insert( key
, artPix
);
97 void PlIconViewItemDelegate::paint( QPainter
* painter
, const QStyleOptionViewItem
& option
, const QModelIndex
& index
) const
99 QString title
= getMeta( index
, COLUMN_TITLE
);
100 QString artist
= getMeta( index
, COLUMN_ARTIST
);
102 QPixmap artPix
= getArtPixmap( index
, QSize( ART_SIZE_W
, ART_SIZE_H
) );
104 QApplication::style()->drawPrimitive( QStyle::PE_PanelItemViewItem
, &option
,
109 if( index
.data( PLModel::IsCurrentRole
).toBool() )
112 painter
->setOpacity( 0.2 );
113 painter
->setBrush( QBrush( Qt::gray
) );
114 painter
->drawRoundedRect( option
.rect
.adjusted( 0, 0, -1, -1 ), ART_RADIUS
, ART_RADIUS
);
118 QRect
artRect( option
.rect
.x() + 5 + ( ART_SIZE_W
- artPix
.width() ) / 2,
119 option
.rect
.y() + 5 + ( ART_SIZE_H
- artPix
.height() ) / 2,
120 artPix
.width(), artPix
.height() );
122 // Draw the drop shadow
124 painter
->setOpacity( 0.7 );
125 painter
->setBrush( QBrush( Qt::darkGray
) );
126 painter
->setPen( Qt::NoPen
);
127 painter
->drawRoundedRect( artRect
.adjusted( 0, 0, 2, 2 ), ART_RADIUS
, ART_RADIUS
);
130 // Draw the art pixmap
131 QPainterPath artRectPath
;
132 artRectPath
.addRoundedRect( artRect
, ART_RADIUS
, ART_RADIUS
);
133 painter
->setClipPath( artRectPath
);
134 painter
->drawPixmap( artRect
, artPix
);
135 painter
->setClipping( false );
137 if( option
.state
& QStyle::State_Selected
)
138 painter
->setPen( option
.palette
.color( QPalette::HighlightedText
) );
140 QFont
font( index
.data( Qt::FontRole
).value
<QFont
>() );
141 font
.setPointSize( 7 );
144 font
.setItalic( true );
145 painter
->setFont( font
);
147 QFontMetrics fm
= painter
->fontMetrics();
148 QRect textRect
= option
.rect
.adjusted( 1, ART_SIZE_H
+ 10, 0, -1 );
149 textRect
.setHeight( fm
.height() );
151 painter
->drawText( textRect
,
152 fm
.elidedText( title
, Qt::ElideRight
, textRect
.width() ),
153 QTextOption( Qt::AlignCenter
) );
156 painter
->setPen( painter
->pen().color().lighter( 150 ) );
157 font
.setItalic( false );
158 painter
->setFont( font
);
159 fm
= painter
->fontMetrics();
161 textRect
.moveTop( textRect
.bottom() + 1 );
163 painter
->drawText( textRect
,
164 fm
.elidedText( artist
, Qt::ElideRight
, textRect
.width() ),
165 QTextOption( Qt::AlignCenter
) );
170 QSize
PlIconViewItemDelegate::sizeHint ( const QStyleOptionViewItem
& option
, const QModelIndex
& index
) const
175 QFontMetrics
fm( f
);
176 int textHeight
= fm
.height();
177 QSize
sz ( ART_SIZE_W
+ 2 * SPACER
,
178 ART_SIZE_H
+ 3 * SPACER
+ 2 * textHeight
+ 1 );
183 #define LISTVIEW_ART_SIZE 45
185 void PlListViewItemDelegate::paint( QPainter
* painter
, const QStyleOptionViewItem
& option
, const QModelIndex
& index
) const
187 QModelIndex parent
= index
.parent();
190 QString title
= getMeta( index
, COLUMN_TITLE
);
191 QString duration
= getMeta( index
, COLUMN_DURATION
);
192 if( !duration
.isEmpty() ) title
+= QString(" [%1]").arg( duration
);
194 QString artist
= getMeta( index
, COLUMN_ARTIST
);
195 QString album
= getMeta( index
, COLUMN_ALBUM
);
196 QString trackNum
= getMeta( index
, COLUMN_TRACK_NUMBER
);
197 QString artistAlbum
= artist
198 + ( artist
.isEmpty() ? QString() : QString( ": " ) )
200 + ( album
.isEmpty() || trackNum
.isEmpty() ?
201 QString() : QString( " [#%1]" ).arg( trackNum
) );
203 QPixmap artPix
= getArtPixmap( index
, QSize( LISTVIEW_ART_SIZE
, LISTVIEW_ART_SIZE
) );
205 //Draw selection rectangle
206 QApplication::style()->drawPrimitive( QStyle::PE_PanelItemViewItem
, &option
, painter
);
208 //Paint background if item is playing
209 if( index
.data( PLModel::IsCurrentRole
).toBool() )
210 paintPlayingItemBg( painter
, option
);
212 QRect
artRect( artPix
.rect() );
213 artRect
.moveCenter( QPoint( artRect
.center().x() + 3,
214 option
.rect
.center().y() ) );
216 painter
->drawPixmap( artRect
, artPix
);
221 if( option
.state
& QStyle::State_Selected
)
222 painter
->setPen( option
.palette
.color( QPalette::HighlightedText
) );
224 QTextOption
textOpt( Qt::AlignVCenter
| Qt::AlignLeft
);
225 textOpt
.setWrapMode( QTextOption::NoWrap
);
227 QFont
f( index
.data( Qt::FontRole
).value
<QFont
>() );
231 painter
->setFont( f
);
232 QFontMetrics
fm( painter
->fontMetrics() );
234 QRect textRect
= option
.rect
.adjusted( LISTVIEW_ART_SIZE
+ 10, 0, -10, 0 );
235 if( !artistAlbum
.isEmpty() )
237 textRect
.setHeight( fm
.height() );
238 textRect
.moveBottom( option
.rect
.center().y() - 1 );
241 painter
->drawText( textRect
,
242 fm
.elidedText( title
, Qt::ElideRight
, textRect
.width() ),
245 // Draw artist and album info
246 if( !artistAlbum
.isEmpty() )
248 f
.setItalic( false );
249 painter
->setFont( f
);
250 fm
= painter
->fontMetrics();
252 textRect
.moveTop( textRect
.bottom() + 2 );
254 painter
->drawText( textRect
,
255 fm
.elidedText( artistAlbum
, Qt::ElideRight
, textRect
.width() ),
262 QSize
PlListViewItemDelegate::sizeHint ( const QStyleOptionViewItem
& option
, const QModelIndex
& index
) const
266 QFontMetrics
fm( f
);
267 int height
= qMax( LISTVIEW_ART_SIZE
, 2 * fm
.height() + 2 ) + 6;
268 return QSize( 0, height
);
271 PlIconView::PlIconView( PLModel
*model
, QWidget
*parent
) : QListView( parent
)
273 PlIconViewItemDelegate
*delegate
= new PlIconViewItemDelegate( this );
276 setViewMode( QListView::IconMode
);
277 setMovement( QListView::Static
);
278 setResizeMode( QListView::Adjust
);
279 setGridSize( delegate
->sizeHint() );
281 setUniformItemSizes( true );
282 setSelectionMode( QAbstractItemView::ExtendedSelection
);
283 setDragEnabled(true);
284 /* dropping in QListView::IconMode does not seem to work */
285 //setAcceptDrops( true );
286 //setDropIndicatorShown(true);
288 setItemDelegate( delegate
);
291 PlListView::PlListView( PLModel
*model
, QWidget
*parent
) : QListView( parent
)
294 setViewMode( QListView::ListMode
);
295 setUniformItemSizes( true );
296 setSelectionMode( QAbstractItemView::ExtendedSelection
);
297 setAlternatingRowColors( true );
298 setDragEnabled(true);
299 setAcceptDrops( true );
300 setDropIndicatorShown(true);
302 PlListViewItemDelegate
*delegate
= new PlListViewItemDelegate( this );
303 setItemDelegate( delegate
);