1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-03-13 20:39:57 +01:00

* Added QueryLabel, a QLabel-like widget which displays any combination of a query/result's Artist, Album and Track.

* Paints a nice rounded-rect around the artist / album / track item when hovered with the mouse.
* Drag and drop / detailed click signal support coming up.
This commit is contained in:
Christian Muehlhaeuser 2011-01-12 13:18:32 +01:00
parent 2edd93ab3c
commit 80269932ad
10 changed files with 578 additions and 15 deletions

View File

@ -54,6 +54,7 @@ SET( tomahawkSources ${tomahawkSources}
SET( tomahawkSourcesGui ${tomahawkSourcesGui}
xspfloader.cpp
utils/querylabel.cpp
utils/elidedlabel.cpp
utils/imagebutton.cpp
utils/progresstreeview.cpp
@ -133,6 +134,7 @@ SET( tomahawkHeaders ${tomahawkHeaders}
SET( tomahawkHeadersGui ${tomahawkHeadersGui}
xspfloader.h
utils/querylabel.h
utils/elidedlabel.h
utils/animatedcounterlabel.h
utils/imagebutton.h

View File

@ -27,13 +27,14 @@ AudioControls::AudioControls( QWidget* parent )
QFont font( ui->artistTrackLabel->font() );
font.setPixelSize( 12 );
/* ui->artistTrackLabel->setMinimumSize( ui->artistTrackLabel->minimumSizeHint() );
ui->albumLabel->setMinimumSize( ui->albumLabel->minimumSizeHint() );*/
ui->artistTrackLabel->setFont( font );
ui->artistTrackLabel->setElideMode( Qt::ElideMiddle );
ui->artistTrackLabel->setType( QueryLabel::ArtistAndTrack );
ui->albumLabel->setFont( font );
ui->albumLabel->setType( QueryLabel::Album );
ui->timeLabel->setFont( font );
ui->timeLeftLabel->setFont( font );
@ -229,8 +230,8 @@ AudioControls::onPlaybackLoading( const Tomahawk::result_ptr& result )
m_currentTrack = result;
ui->artistTrackLabel->setText( QString( "%1 - %2" ).arg( result->artist()->name() ).arg( result->track() ) );
ui->albumLabel->setText( result->album()->name() );
ui->artistTrackLabel->setResult( result );
ui->albumLabel->setResult( result );
ui->ownerLabel->setText( result->collection()->source()->friendlyName() );
ui->coverImage->setPixmap( m_defaultCover );

View File

@ -184,7 +184,7 @@
<number>0</number>
</property>
<item>
<widget class="ElidedLabel" name="artistTrackLabel">
<widget class="QueryLabel" name="artistTrackLabel">
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
@ -194,7 +194,7 @@
</widget>
</item>
<item>
<widget class="ElidedLabel" name="albumLabel">
<widget class="QueryLabel" name="albumLabel">
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
@ -459,9 +459,9 @@
<header>imagebutton.h</header>
</customwidget>
<customwidget>
<class>ElidedLabel</class>
<class>QueryLabel</class>
<extends>QLabel</extends>
<header location="global">elidedlabel.h</header>
<header>querylabel.h</header>
</customwidget>
</customwidgets>
<resources/>

View File

@ -5,7 +5,7 @@
#include <QSqlQuery>
#include <QTime>
#define TOMAHAWK_QUERY_THRESHOLD 20
#define TOMAHAWK_QUERY_THRESHOLD 60
class TomahawkSqlQuery : public QSqlQuery
{
@ -16,7 +16,7 @@ public:
: QSqlQuery()
{}
TomahawkSqlQuery( QSqlDatabase db )
TomahawkSqlQuery( const QSqlDatabase& db )
: QSqlQuery( db )
{}

View File

@ -21,6 +21,7 @@ SourceTreeItemWidget::SourceTreeItemWidget( const source_ptr& source, QWidget* p
ui->setupUi( this );
ui->verticalLayout->setSpacing( 3 );
ui->activityLabel->setType( QueryLabel::ArtistAndTrack );
QString displayname;
if ( source.isNull() )
@ -132,7 +133,8 @@ void
SourceTreeItemWidget::onPlaybackStarted( const Tomahawk::query_ptr& query )
{
qDebug() << Q_FUNC_INFO << query->toString();
ui->activityLabel->setText( tr( "Playing: %1 by %2" ).arg( query->track() ).arg( query->artist() ) );
// ui->activityLabel->setText( tr( "Playing: %1 by %2" ).arg( query->track() ).arg( query->artist() ) );
ui->activityLabel->setQuery( query );
}

View File

@ -127,7 +127,7 @@
</widget>
</item>
<item>
<widget class="ElidedLabel" name="activityLabel">
<widget class="QueryLabel" name="activityLabel">
<property name="text">
<string>TextLabel</string>
</property>
@ -201,6 +201,11 @@
<extends>QLabel</extends>
<header>elidedlabel.h</header>
</customwidget>
<customwidget>
<class>QueryLabel</class>
<extends>QLabel</extends>
<header>querylabel.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>

View File

@ -1,6 +1,5 @@
#include "elidedlabel.h"
#include <QTime>
#include <QEvent>
#include <QPainter>
#include <QFontMetrics>

View File

@ -30,10 +30,10 @@ public:
void init( const QString& txt = QString() );
void updateLabel();
public Q_SLOTS:
public slots:
void setText( const QString& text );
Q_SIGNALS:
signals:
void clicked();
void textChanged( const QString& text );

464
src/utils/querylabel.cpp Normal file
View File

@ -0,0 +1,464 @@
#include "querylabel.h"
#include <QApplication>
#include <QEvent>
#include <QFontMetrics>
#include <QMouseEvent>
#include <QPainter>
QueryLabel::QueryLabel( QWidget* parent, Qt::WindowFlags flags )
: QFrame( parent, flags )
, m_type( Complete )
{
init();
}
QueryLabel::QueryLabel( DisplayType type, QWidget* parent, Qt::WindowFlags flags )
: QFrame( parent, flags )
, m_type( type )
{
init();
}
QueryLabel::QueryLabel( const Tomahawk::result_ptr& result, DisplayType type, QWidget* parent, Qt::WindowFlags flags )
: QFrame( parent, flags )
, m_type( type )
, m_result( result )
{
init();
}
QueryLabel::QueryLabel( const Tomahawk::query_ptr& query, DisplayType type, QWidget* parent, Qt::WindowFlags flags )
: QFrame( parent, flags )
, m_type( type )
, m_query( query )
{
init();
}
QueryLabel::~QueryLabel()
{
}
void
QueryLabel::init()
{
setContentsMargins( 0, 0, 0, 0 );
setMouseTracking( true );
align = Qt::AlignLeft;
mode = Qt::ElideMiddle;
}
QString
QueryLabel::text() const
{
QString text;
if ( m_result.isNull() && m_query.isNull() )
return m_text;
if ( !m_result.isNull() )
{
if ( m_type & Artist )
{
text += m_result->artist()->name();
}
if ( m_type & Album )
{
smartAppend( text, m_result->album()->name() );
}
if ( m_type & Track )
{
smartAppend( text, m_result->track() );
}
}
else
{
if ( m_type & Artist )
{
text += m_query->artist();
}
if ( m_type & Album )
{
smartAppend( text, m_query->album() );
}
if ( m_type & Track )
{
smartAppend( text, m_query->track() );
}
}
return text;
}
QString
QueryLabel::artist() const
{
if ( m_result.isNull() && m_query.isNull() )
return QString();
if ( !m_result.isNull() )
return m_result->artist()->name();
else
return m_query->artist();
}
QString
QueryLabel::album() const
{
if ( m_result.isNull() && m_query.isNull() )
return QString();
if ( !m_result.isNull() )
return m_result->album()->name();
else
return m_query->album();
}
QString
QueryLabel::track() const
{
if ( m_result.isNull() && m_query.isNull() )
return QString();
if ( !m_result.isNull() )
return m_result->track();
else
return m_query->track();
}
void
QueryLabel::setText( const QString& text )
{
setContentsMargins( 0, 0, 0, 0 );
m_result.clear();
m_query.clear();
m_text = text;
updateLabel();
emit textChanged( m_text );
emit resultChanged( m_result );
}
void
QueryLabel::setResult( const Tomahawk::result_ptr& result )
{
if ( result.isNull() )
return;
setContentsMargins( 2, 0, 2, 0 );
if ( m_result.isNull() || m_result.data() != result.data() )
{
m_result = result;
m_query.clear();
updateLabel();
emit textChanged( text() );
emit resultChanged( m_result );
}
}
void
QueryLabel::setQuery( const Tomahawk::query_ptr& query )
{
if ( query.isNull() )
return;
setContentsMargins( 2, 0, 2, 0 );
if ( m_query.isNull() || m_query.data() != query.data() )
{
m_query = query;
m_result.clear();
updateLabel();
emit textChanged( text() );
emit queryChanged( m_query );
}
}
Qt::Alignment
QueryLabel::alignment() const
{
return align;
}
void
QueryLabel::setAlignment( Qt::Alignment alignment )
{
if ( this->align != alignment )
{
this->align = alignment;
update(); // no geometry change, repaint is sufficient
}
}
Qt::TextElideMode
QueryLabel::elideMode() const
{
return mode;
}
void
QueryLabel::setElideMode( Qt::TextElideMode mode )
{
if ( this->mode != mode )
{
this->mode = mode;
updateLabel();
}
}
void
QueryLabel::updateLabel()
{
updateGeometry();
update();
}
QSize
QueryLabel::sizeHint() const
{
const QFontMetrics& fm = fontMetrics();
QSize size( fm.width( text() ) + contentsMargins().left() * 2, fm.height() );
return size;
}
QSize
QueryLabel::minimumSizeHint() const
{
switch ( mode )
{
case Qt::ElideNone:
return sizeHint();
default:
{
const QFontMetrics& fm = fontMetrics();
QSize size( fm.width( "..." ), fm.height() );
return size;
}
}
}
void
QueryLabel::paintEvent( QPaintEvent* event )
{
QFrame::paintEvent( event );
QPainter p( this );
QRect r = contentsRect();
QString s = text();
const QString elidedText = fontMetrics().elidedText( s, mode, r.width() );
p.save();
p.setRenderHint( QPainter::Antialiasing );
if ( elidedText == s && m_hoverArea.width() )
{
p.setPen( palette().highlight().color() );
p.setBrush( palette().highlight() );
p.drawRoundedRect( m_hoverArea, 4.0, 4.0 );
}
if ( elidedText != s || ( m_result.isNull() && m_query.isNull() ) )
{
p.setBrush( palette().window() );
p.setPen( palette().text().color() );
p.drawText( r, align, elidedText );
}
else
{
const QFontMetrics& fm = fontMetrics();
int dashX = fm.width( " - " );
int artistX = m_type & Artist ? fm.width( artist() ) : 0;
int albumX = m_type & Album ? fm.width( album() ) : 0;
int trackX = m_type & Track ? fm.width( track() ) : 0;
if ( m_type & Artist )
{
p.setBrush( palette().window() );
p.setPen( palette().text().color() );
if ( m_hoverArea.width() && m_hoverArea.left() + contentsMargins().left() == r.left() )
{
p.setPen( palette().highlightedText().color() );
p.setBrush( palette().highlight() );
}
p.drawText( r, align, artist() );
r.adjust( artistX, 0, 0, 0 );
}
if ( m_type & Album )
{
p.setBrush( palette().window() );
p.setPen( palette().text().color() );
if ( m_type & Artist )
{
p.drawText( r, align, " - " );
r.adjust( dashX, 0, 0, 0 );
}
if ( m_hoverArea.width() && m_hoverArea.left() + contentsMargins().left() == r.left() )
{
p.setPen( palette().highlightedText().color() );
p.setBrush( palette().highlight() );
}
p.drawText( r, align, album() );
r.adjust( albumX, 0, 0, 0 );
}
if ( m_type & Track )
{
p.setBrush( palette().window() );
p.setPen( palette().text().color() );
if ( m_type & Artist || m_type & Album )
{
p.drawText( r, align, " - " );
r.adjust( dashX, 0, 0, 0 );
}
if ( m_hoverArea.width() && m_hoverArea.left() + contentsMargins().left() == r.left() )
{
p.setPen( palette().highlightedText().color() );
p.setBrush( palette().highlight() );
}
p.drawText( r, align, track() );
r.adjust( trackX, 0, 0, 0 );
}
}
p.restore();
}
void
QueryLabel::changeEvent( QEvent* event )
{
QFrame::changeEvent( event );
switch ( event->type() )
{
case QEvent::FontChange:
case QEvent::ApplicationFontChange:
updateLabel();
break;
default:
break;
}
}
void
QueryLabel::mousePressEvent( QMouseEvent* event )
{
QFrame::mousePressEvent( event );
time.start();
}
void
QueryLabel::mouseReleaseEvent( QMouseEvent* event )
{
QFrame::mouseReleaseEvent( event );
if ( time.elapsed() < qApp->doubleClickInterval() )
emit clicked();
}
void
QueryLabel::mouseMoveEvent( QMouseEvent* event )
{
QFrame::mouseMoveEvent( event );
int x = event->x();
const QFontMetrics& fm = fontMetrics();
int dashX = fm.width( " - " );
int artistX = m_type & Artist ? fm.width( artist() ) : 0;
int albumX = m_type & Album ? fm.width( album() ) : 0;
int trackX = m_type & Track ? fm.width( track() ) : 0;
if ( m_type & Album )
{
trackX += albumX + dashX;
}
if ( m_type & Artist )
{
albumX += artistX + dashX;
trackX += artistX + dashX;
}
QRect hoverArea;
if ( m_type & Artist && x < artistX )
{
hoverArea.setLeft( 0 );
hoverArea.setRight( artistX + contentsMargins().left() );
}
else if ( m_type & Album && x < albumX )
{
int spacing = ( m_type & Artist ) ? dashX : 0;
hoverArea.setLeft( artistX + spacing );
hoverArea.setRight( albumX + spacing + contentsMargins().left() );
}
else if ( m_type & Track && x < trackX )
{
int spacing = ( m_type & Album ) ? dashX : 0;
hoverArea.setLeft( albumX + spacing );
hoverArea.setRight( trackX + contentsMargins().left() );
}
if ( hoverArea.width() )
{
hoverArea.setY( 0 );
hoverArea.setHeight( height() - 1 );
}
if ( hoverArea != m_hoverArea )
{
m_hoverArea = hoverArea;
repaint();
}
}
void
QueryLabel::leaveEvent( QEvent* event )
{
m_hoverArea = QRect();
}
QString
QueryLabel::smartAppend( QString& text, const QString& appendage ) const
{
QString s;
if ( !text.isEmpty() )
s = " - ";
text += s + appendage;
return text;
}

90
src/utils/querylabel.h Normal file
View File

@ -0,0 +1,90 @@
#ifndef QUERYLABEL_H
#define QUERYLABEL_H
#include <QFrame>
#include <QTime>
#include "result.h"
class QueryLabel : public QFrame
{
Q_OBJECT
public:
enum DisplayType
{
Artist = 1,
Album = 2,
Track = 4,
ArtistAndAlbum = 3,
ArtistAndTrack = 5,
AlbumAndTrack = 6,
Complete = 7
};
explicit QueryLabel( QWidget* parent = 0, Qt::WindowFlags flags = 0 );
explicit QueryLabel( DisplayType type = Complete, QWidget* parent = 0, Qt::WindowFlags flags = 0 );
explicit QueryLabel( const Tomahawk::result_ptr& result, DisplayType type = Complete, QWidget* parent = 0, Qt::WindowFlags flags = 0 );
explicit QueryLabel( const Tomahawk::query_ptr& query, DisplayType type = Complete, QWidget* parent = 0, Qt::WindowFlags flags = 0 );
virtual ~QueryLabel();
QString text() const;
QString artist() const;
QString album() const;
QString track() const;
Tomahawk::result_ptr result() const { return m_result; }
Tomahawk::query_ptr query() const { return m_query; }
DisplayType type() const { return m_type; }
void setType( DisplayType type ) { m_type = type; }
Qt::Alignment alignment() const;
void setAlignment( Qt::Alignment alignment );
Qt::TextElideMode elideMode() const;
void setElideMode( Qt::TextElideMode mode );
virtual QSize sizeHint() const;
virtual QSize minimumSizeHint() const;
void init();
void updateLabel();
public slots:
void setText( const QString& text );
void setResult( const Tomahawk::result_ptr& result );
void setQuery( const Tomahawk::query_ptr& query );
signals:
void clicked();
void textChanged( const QString& text );
void resultChanged( const Tomahawk::result_ptr& result );
void queryChanged( const Tomahawk::query_ptr& query );
protected:
virtual void mousePressEvent( QMouseEvent* event );
virtual void mouseReleaseEvent( QMouseEvent* event );
virtual void mouseMoveEvent( QMouseEvent* event );
virtual void leaveEvent( QEvent* event );
virtual void changeEvent( QEvent* event );
virtual void paintEvent( QPaintEvent* event );
private:
QString smartAppend( QString& text, const QString& appendage ) const;
QTime time;
DisplayType m_type;
QString m_text;
Tomahawk::result_ptr m_result;
Tomahawk::query_ptr m_query;
Qt::Alignment align;
Qt::TextElideMode mode;
QRect m_hoverArea;
};
#endif // QUERYLABEL_H