1 /***************************************************************************
2 * copyright : (C) 2007 Ian Monroe <ian@monroe.nu> *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License version 2 *
6 * as published by the Free Software Foundation. *
7 ***************************************************************************/
10 #include "meta/MetaUtility.h"
11 #include "PlaylistGraphicsItem.h"
12 #include "PlaylistModel.h"
13 #include "TheInstances.h"
16 #include <QFontMetricsF>
17 #include <QGraphicsScene>
18 #include <QGraphicsTextItem>
19 #include <QGraphicsPixmapItem>
20 #include <QGraphicsRectItem>
21 #include <QGraphicsSceneMouseEvent>
22 #include <QGraphicsView>
25 #include <QRadialGradient>
27 #include <QStyleOptionGraphicsItem>
29 struct PlaylistNS::GraphicsItem::ActiveItems
35 , bottomRightText( 0 )
44 delete bottomLeftText
;
46 delete bottomRightText
;
50 QGraphicsPixmapItem
* albumArt
;
51 QGraphicsTextItem
* topLeftText
;
52 QGraphicsTextItem
* bottomLeftText
;
53 QGraphicsTextItem
* topRightText
;
54 QGraphicsTextItem
* bottomRightText
;
55 QGraphicsRectItem
* background
;
56 QGraphicsRectItem
* foreground
;
61 const qreal
PlaylistNS::GraphicsItem::ALBUM_WIDTH
= 50.0;
62 const qreal
PlaylistNS::GraphicsItem::MARGIN
= 2.0;
63 qreal
PlaylistNS::GraphicsItem::s_height
= -1.0;
64 QFontMetricsF
* PlaylistNS::GraphicsItem::s_fm
= 0;
66 PlaylistNS::GraphicsItem::GraphicsItem()
70 , m_verticalOffset( 2.0 )
74 s_fm
= new QFontMetricsF( QFont() );
75 s_height
= qMax( ALBUM_WIDTH
, s_fm
->height() * 2 ) + 2 * m_verticalOffset
;
77 // setHandlesChildEvents( true );
78 setFlag( QGraphicsItem::ItemIsSelectable
);
79 setAcceptDrops( true );
82 PlaylistNS::GraphicsItem::~GraphicsItem()
88 PlaylistNS::GraphicsItem::paint( QPainter
* painter
, const QStyleOptionGraphicsItem
* option
, QWidget
* widget
)
90 Q_UNUSED( painter
); Q_UNUSED( widget
);
91 const int row
= getRow();
92 const QModelIndex index
= The::playlistModel()->index( row
, 0 );
94 if( not m_items
|| ( option
->rect
.width() != m_items
->lastWidth
) )
99 const Meta::TrackPtr track
= index
.data( ItemRole
).value
< PlaylistNS::Item
* >()->track();
100 m_items
= new PlaylistNS::GraphicsItem::ActiveItems();
101 m_items
->track
= track
;
104 resize( m_items
->track
, option
->rect
.width() );
107 if( not m_items
->background
)
109 m_items
->background
= new QGraphicsRectItem( option
->rect
, this );
110 m_items
->background
->setPos( 0.0, 0.0 );
111 m_items
->background
->setPen( QPen( Qt::NoPen
) );
112 m_items
->background
->setBrush( option
->palette
.highlight() );
113 m_items
->background
->setZValue( -5.0 );
117 if( option
->state
& QStyle::State_Selected
)
119 m_items
->background
->setBrush( option
->palette
.highlight() );
120 m_items
->background
->show();
124 //alternate color of background
126 m_items
->background
->setBrush( option
->palette
.base() );
128 m_items
->background
->setBrush( option
->palette
.alternateBase() );
130 m_items
->background
->show();
133 if( index
.data( ActiveTrackRole
).toBool() )
135 if( not m_items
->foreground
)
137 m_items
->foreground
= new QGraphicsRectItem( option
->rect
, this );
138 m_items
->foreground
->setPos( 0.0, m_verticalOffset
);
139 m_items
->foreground
->setZValue( 5.0 );
140 QRadialGradient
gradient(option
->rect
.width() / 2.0, option
->rect
.height() / 2.0, option
->rect
.width() / 2.0, 20 + option
->rect
.width() / 2.0, option
->rect
.height() / 2.0 );
141 QColor start
= option
->palette
.highlight().color().light();
142 start
.setAlpha( 51 );
143 QColor end
= option
->palette
.highlight().color().dark();
145 gradient
.setColorAt( 0.0, start
);
146 gradient
.setColorAt( 1.0, end
);
147 QBrush
brush( gradient
);
148 m_items
->foreground
->setBrush( brush
);
149 m_items
->foreground
->setPen( QPen( Qt::NoPen
) );
152 m_items
->background
->hide();
153 m_items
->foreground
->show();
155 else if( m_items
->foreground
)
156 m_items
->foreground
->hide();
158 m_items
->albumArt
->show();
162 PlaylistNS::GraphicsItem::init( Meta::TrackPtr track
)
168 albumPixmap
= track
->album()->image( int( ALBUM_WIDTH
) );
170 m_items
->albumArt
= new QGraphicsPixmapItem( albumPixmap
, this );
171 m_items
->albumArt
->setPos( 0.0, m_verticalOffset
);
175 font
.setPointSize( font
.pointSize() - 1 );
176 #define NewText( X ) \
177 X = new QGraphicsTextItem( this ); \
178 X->setTextInteractionFlags( Qt::TextEditorInteraction ); \
180 NewText( m_items
->topLeftText
)
181 NewText( m_items
->bottomLeftText
)
182 NewText( m_items
->topRightText
)
183 NewText( m_items
->bottomRightText
)
189 PlaylistNS::GraphicsItem::resize( Meta::TrackPtr track
, int totalWidth
)
191 if( totalWidth
== -1 || totalWidth
== m_items
->lastWidth
) //no change needed
193 if( m_items
->lastWidth
!= -5 ) //this isn't the first "resize"
194 prepareGeometryChange();
195 m_items
->lastWidth
= totalWidth
;
196 QString prettyLength
= Meta::secToPrettyTime( track
->length() );
199 album
= track
->album()->name();
201 const qreal lineTwoY
= s_height
/ 2 + m_verticalOffset
;
202 const qreal textWidth
= ( ( qreal( totalWidth
) - ALBUM_WIDTH
) / 2.0 );
203 const qreal leftAlignX
= ALBUM_WIDTH
+ MARGIN
;
206 qreal middle
= textWidth
+ ALBUM_WIDTH
+ ( MARGIN
* 2.0 );
207 qreal rightWidth
= totalWidth
- qMax( s_fm
->width( album
)
208 , s_fm
->width( prettyLength
) );
209 rightAlignX
= qMax( middle
, rightWidth
);
211 m_items
->topRightText
->setPos( rightAlignX
, m_verticalOffset
);
212 m_items
->bottomRightText
->setPos( rightAlignX
, lineTwoY
);
213 m_items
->topRightText
->setPlainText( s_fm
->elidedText( album
, Qt::ElideRight
, totalWidth
- rightAlignX
) );
214 m_items
->bottomRightText
->setPlainText( s_fm
->elidedText( prettyLength
, Qt::ElideRight
, totalWidth
- rightAlignX
) );
217 qreal spaceForLeft
= totalWidth
- ( totalWidth
- rightAlignX
) - leftAlignX
;
220 if( track
->artist() )
221 artist
= track
->artist()->name();
222 m_items
->topLeftText
->setPlainText( s_fm
->elidedText( artist
, Qt::ElideRight
, spaceForLeft
) );
223 m_items
->topLeftText
->setPos( leftAlignX
, m_verticalOffset
);
226 m_items
->bottomLeftText
->setPlainText( s_fm
->elidedText( QString("%1 - %2").arg( QString::number( track
->trackNumber() ), track
->name() )
227 , Qt::ElideRight
, spaceForLeft
) );
228 m_items
->bottomLeftText
->setPos( leftAlignX
, lineTwoY
);
232 PlaylistNS::GraphicsItem::boundingRect() const
234 // the viewport()->size() takes scrollbars into account
235 return QRectF( 0.0, 0.0, scene()->views().at(0)->viewport()->size().width(), s_height
);
239 PlaylistNS::GraphicsItem::mouseDoubleClickEvent( QGraphicsSceneMouseEvent
* event
)
243 The::playlistModel()->play( getRow() );
247 QGraphicsItem::mouseDoubleClickEvent( event
);
251 PlaylistNS::GraphicsItem::dragEnterEvent( QGraphicsSceneDragDropEvent
*event
)
253 foreach( QString mime
, The::playlistModel()->mimeTypes() )
254 if( event
->mimeData()->hasFormat( mime
) )
259 PlaylistNS::GraphicsItem::dropEvent( QGraphicsSceneDragDropEvent
* event
)
261 The::playlistModel()->dropMimeData( event
->mimeData(), Qt::CopyAction
, getRow(), 0, QModelIndex() );
265 PlaylistNS::GraphicsItem::refresh()
271 if( m_track
->album() )
272 albumPixmap
= m_track
->album()->image( int( ALBUM_WIDTH
) );
274 m_items
->albumArt
->hide();
275 delete ( m_items
->albumArt
);
276 m_items
->albumArt
= new QGraphicsPixmapItem( albumPixmap
, this );
277 m_items
->albumArt
->setPos( 0.0, m_verticalOffset
);