diff --git a/modules/gui/qt4/components/playlist/icon_view.cpp b/modules/gui/qt4/components/playlist/icon_view.cpp index 72a9ca2cae62..9b8d1f183322 100644 --- a/modules/gui/qt4/components/playlist/icon_view.cpp +++ b/modules/gui/qt4/components/playlist/icon_view.cpp @@ -35,13 +35,10 @@ #include "assert.h" -#define RECT_SIZE_W 120 -#define RECT_SIZE_H 120 #define ART_SIZE_W 110 #define ART_SIZE_H 80 -//#define OFFSET (RECT_SIZE_W-ART_SIZE_W)/2 -//#define ITEMS_SPACING 10 #define ART_RADIUS 5 +#define SPACER 5 QString AbstractPlViewItemDelegate::getMeta( const QModelIndex & index, int meta ) const { @@ -140,9 +137,8 @@ void PlIconViewItemDelegate::paint( QPainter * painter, const QStyleOptionViewIt if( option.state & QStyle::State_Selected ) painter->setPen( option.palette.color( QPalette::HighlightedText ) ); - QFont font; + QFont font( index.data( Qt::FontRole ).value() ); font.setPointSize( 7 ); - font.setBold( index.data( Qt::FontRole ).value().bold() ); // Draw title font.setItalic( true ); @@ -150,7 +146,7 @@ void PlIconViewItemDelegate::paint( QPainter * painter, const QStyleOptionViewIt QFontMetrics fm = painter->fontMetrics(); QRect textRect = option.rect.adjusted( 1, ART_SIZE_H + 10, 0, -1 ); - textRect.setHeight( fm.height() + 1 ); + textRect.setHeight( fm.height() ); painter->drawText( textRect, fm.elidedText( title, Qt::ElideRight, textRect.width() ), @@ -162,8 +158,8 @@ void PlIconViewItemDelegate::paint( QPainter * painter, const QStyleOptionViewIt painter->setFont( font ); fm = painter->fontMetrics(); - textRect = textRect.adjusted( 0, textRect.height(), - 0, textRect.height() ); + textRect.moveTop( textRect.bottom() + 1 ); + painter->drawText( textRect, fm.elidedText( artist, Qt::ElideRight, textRect.width() ), QTextOption( Qt::AlignCenter ) ); @@ -173,9 +169,17 @@ void PlIconViewItemDelegate::paint( QPainter * painter, const QStyleOptionViewIt QSize PlIconViewItemDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const { - return QSize( RECT_SIZE_W, RECT_SIZE_H ); + 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 @@ -198,25 +202,20 @@ void PlListViewItemDelegate::paint( QPainter * painter, const QStyleOptionViewIt 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 ); - painter->drawPixmap( option.rect.topLeft() + QPoint(3,3) - + QPoint( (LISTVIEW_ART_SIZE - artPix.width()) / 2, - (LISTVIEW_ART_SIZE - artPix.height()) / 2 ), - artPix ); - - - int textH = option.fontMetrics.height() + 2; - int marginY = ( option.rect.height() / 2 ) - textH; - - QRect textRect = option.rect.adjusted( LISTVIEW_ART_SIZE + 10, - marginY, - -10, - marginY * -1 - ( artistAlbum.isEmpty() ? 0 : textH ) ); + 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 ) @@ -225,35 +224,59 @@ void PlListViewItemDelegate::paint( QPainter * painter, const QStyleOptionViewIt QTextOption textOpt( Qt::AlignVCenter | Qt::AlignLeft ); textOpt.setWrapMode( QTextOption::NoWrap ); - QFont f( option.font ); - if( index.data( PLModel::IsCurrentRole ).toBool() ) f.setBold( true ); + QFont f( index.data( Qt::FontRole ).value() ); + //Draw title info f.setItalic( true ); painter->setFont( f ); + QFontMetrics fm( painter->fontMetrics() ); - painter->drawText( textRect, title, textOpt ); + 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 ); + } - f.setItalic( false ); - painter->setFont( f ); - textRect.moveTop( textRect.top() + textH ); + 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, artistAlbum, textOpt ); + painter->drawText( textRect, + fm.elidedText( artistAlbum, Qt::ElideRight, textRect.width() ), + textOpt ); + } painter->restore(); } QSize PlListViewItemDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const { - return QSize( LISTVIEW_ART_SIZE + 6, LISTVIEW_ART_SIZE + 6 ); + 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( RECT_SIZE_W, RECT_SIZE_H ) ); + setGridSize( delegate->sizeHint() ); setWrapping( true ); setUniformItemSizes( true ); setSelectionMode( QAbstractItemView::ExtendedSelection ); @@ -262,7 +285,6 @@ PlIconView::PlIconView( PLModel *model, QWidget *parent ) : QListView( parent ) //setAcceptDrops( true ); //setDropIndicatorShown(true); - PlIconViewItemDelegate *delegate = new PlIconViewItemDelegate( this ); setItemDelegate( delegate ); } diff --git a/modules/gui/qt4/components/playlist/icon_view.hpp b/modules/gui/qt4/components/playlist/icon_view.hpp index cd723d133f7b..f300142dee3c 100644 --- a/modules/gui/qt4/components/playlist/icon_view.hpp +++ b/modules/gui/qt4/components/playlist/icon_view.hpp @@ -44,10 +44,10 @@ class PlIconViewItemDelegate : public AbstractPlViewItemDelegate Q_OBJECT public: - PlIconViewItemDelegate(QWidget *parent = 0) : AbstractPlViewItemDelegate(parent) {} - + PlIconViewItemDelegate(QWidget *parent = 0) : AbstractPlViewItemDelegate( parent ) {} void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const; - QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const; + QSize sizeHint ( const QStyleOptionViewItem & option = QStyleOptionViewItem(), + const QModelIndex & index = QModelIndex() ) const; }; class PlListViewItemDelegate : public AbstractPlViewItemDelegate diff --git a/modules/gui/qt4/components/playlist/selector.cpp b/modules/gui/qt4/components/playlist/selector.cpp index 44a1999c3177..2b42401046d1 100644 --- a/modules/gui/qt4/components/playlist/selector.cpp +++ b/modules/gui/qt4/components/playlist/selector.cpp @@ -65,13 +65,14 @@ PLSelItem::PLSelItem ( QTreeWidgetItem *i, const QString& text ) layout->setContentsMargins(0,0,0,0); layout->addSpacing( 3 ); - lbl = new QLabel( text ); + lbl = new QVLCElidingLabel( text ); layout->addWidget(lbl, 1); setLayout( layout ); - setMinimumHeight( 22 ); //Action icon height plus 6 + int height = qMax( 22, fontMetrics().height() + 8 ); + setMinimumHeight( height ); } void PLSelItem::addAction( ItemAction act, const QString& tooltip ) diff --git a/modules/gui/qt4/components/playlist/standardpanel.cpp b/modules/gui/qt4/components/playlist/standardpanel.cpp index 351803c4f3c1..bf81375978f5 100644 --- a/modules/gui/qt4/components/playlist/standardpanel.cpp +++ b/modules/gui/qt4/components/playlist/standardpanel.cpp @@ -477,7 +477,7 @@ void LocationBar::setIndex( const QModelIndex &index ) free(fb_name); QAbstractButton *btn = new LocationButton( text, bold, i.isValid() ); btn->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Fixed ); - box->insertWidget( 0, btn, bold ? 1 : 0 ); + box->insertWidget( 0, btn ); buttons.append( btn ); mapper->setMapping( btn, item->id() ); @@ -524,9 +524,14 @@ void LocationButton::paintEvent ( QPaintEvent * event ) int margin = style()->pixelMetric(QStyle::PM_DefaultFrameWidth,0,this) + PADDING; - QRect rect = option.rect.adjusted( b_arrow ? 15 + margin : margin, 0, margin * -1, 0 ); - p.drawText( rect, Qt::AlignVCenter, - fontMetrics().elidedText( text(), Qt::ElideRight, rect.width() ) ); + QRect rect = option.rect.adjusted( b_arrow ? 15 + margin : margin, 0, -margin, 0 ); + + QString str( text() ); + /* This check is absurd, but either it is not done properly inside elidedText(), + or boundingRect() is wrong */ + if( rect.width() < fontMetrics().boundingRect( text() ).width() ) + str = fontMetrics().elidedText( text(), Qt::ElideRight, rect.width() ); + p.drawText( rect, Qt::AlignVCenter | Qt::AlignLeft, str ); if( b_arrow ) { @@ -540,7 +545,9 @@ QSize LocationButton::sizeHint() const { int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth,0,this); QSize s( fontMetrics().boundingRect( text() ).size() ); - s.setWidth( s.width() + ( 2 * frameWidth ) + ( 2 * PADDING ) + ( b_arrow ? 15 : 0 ) ); + /* Add two pixels to width: font metrics are buggy, if you pass text through elidation + with exactly the width of its bounding rect, sometimes it still elides */ + s.setWidth( s.width() + ( 2 * frameWidth ) + ( 2 * PADDING ) + ( b_arrow ? 15 : 0 ) + 2 ); s.setHeight( QPushButton::sizeHint().height() ); return s; } diff --git a/modules/gui/qt4/util/customwidgets.cpp b/modules/gui/qt4/util/customwidgets.cpp index a99456d4dbf5..26e808f9411c 100644 --- a/modules/gui/qt4/util/customwidgets.cpp +++ b/modules/gui/qt4/util/customwidgets.cpp @@ -208,6 +208,25 @@ void SearchLineEdit::paintEvent( QPaintEvent *event ) painter.drawText( rect, Qt::AlignLeft | Qt::AlignVCenter, qtr( I_PL_FILTER ) ); } + +QVLCElidingLabel::QVLCElidingLabel( const QString &s, Qt::TextElideMode mode, QWidget * parent ) + : elideMode( mode ), QLabel( s, parent ) +{ } + +void QVLCElidingLabel::setElideMode( Qt::TextElideMode mode ) +{ + elideMode = mode; + repaint(); +} + +void QVLCElidingLabel::paintEvent( QPaintEvent * event ) +{ + QPainter p( this ); + int space = frameWidth() + margin(); + QRect r = rect().adjusted( space, space, -space, -space ); + p.drawText( r, fontMetrics().elidedText( text(), elideMode, r.width() ), alignment() ); +} + /*************************************************************************** * Hotkeys converters ***************************************************************************/ diff --git a/modules/gui/qt4/util/customwidgets.hpp b/modules/gui/qt4/util/customwidgets.hpp index 77d57651a673..266d95449385 100644 --- a/modules/gui/qt4/util/customwidgets.hpp +++ b/modules/gui/qt4/util/customwidgets.hpp @@ -29,6 +29,7 @@ #include #include +#include /** This class provides a QLineEdit which contains a greyed-out hinting @@ -67,8 +68,6 @@ class QVLCFramelessButton : public QPushButton virtual void paintEvent( QPaintEvent * event ); }; -class QLabel; - class SearchLineEdit : public QLineEdit { Q_OBJECT @@ -92,6 +91,18 @@ private slots: void updateText( const QString& ); }; +class QVLCElidingLabel : public QLabel +{ +public: + QVLCElidingLabel( const QString &s = QString(), + Qt::TextElideMode mode = Qt::ElideRight, + QWidget * parent = NULL ); + void setElideMode( Qt::TextElideMode ); +private: + void paintEvent( QPaintEvent * event ); + Qt::TextElideMode elideMode; +}; + /* VLC Key/Wheel hotkeys interactions */ class QKeyEvent;