1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-30 01:00:13 +02:00

Added a ScrollingLabel that scrolls on hover when the text doesn't fit.

This commit is contained in:
Teo Mrnjavac
2014-01-08 17:57:05 +01:00
parent 3299dc14d6
commit c86b5ab74e
5 changed files with 262 additions and 3 deletions

View File

@@ -159,6 +159,7 @@ set( libGuiSources
widgets/RecentPlaylistsModel.cpp
widgets/RecentlyPlayedPlaylistsModel.cpp
widgets/ScriptCollectionHeader.cpp
widgets/ScrollingLabel.cpp
widgets/SearchWidget.cpp
widgets/SeekSlider.cpp
widgets/SourceTreePopupDialog.cpp

View File

@@ -21,6 +21,7 @@
#include "ColumnView.h"
#include "widgets/PlayableCover.h"
#include "widgets/QueryLabel.h"
#include "widgets/ScrollingLabel.h"
#include "utils/Logger.h"
#include "Source.h"
#include "utils/TomahawkUtilsGui.h"
@@ -66,12 +67,13 @@ ColumnViewPreviewWidget::ColumnViewPreviewWidget( ColumnView* parent )
mainLayout->addSpacing( 16 );
#endif
m_trackLabel = new QLabel( this );
m_trackLabel->setAlignment( Qt::AlignCenter );
m_trackLabel = new ScrollingLabel( this );
//m_trackLabel->setAlignment( Qt::AlignCenter );
QFont font;
font.setPointSize( TomahawkUtils::defaultFontSize() + 9 );
font.setBold( true );
m_trackLabel->setFont( font );
m_trackLabel->setFixedHeight( QFontMetrics( font ).height() + 6 );
mainLayout->addWidget( m_trackLabel );
m_artistLabel = new QueryLabel( this );

View File

@@ -28,6 +28,7 @@ class ColumnView;
class QueryLabel;
class PlayableCover;
class QLabel;
class ScrollingLabel;
class DLLEXPORT ColumnViewPreviewWidget : public QWidget
{
@@ -66,7 +67,7 @@ private:
QLabel* m_yearLabel;
QLabel* m_yearValue;
QLabel* m_trackLabel;
ScrollingLabel* m_trackLabel;
QueryLabel* m_artistLabel;
};

View File

@@ -0,0 +1,191 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2014, Teo Mrnjavac <teo@kde.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ScrollingLabel.h"
#include "utils/DpiScaler.h"
#include <QPainter>
ScrollingLabel::ScrollingLabel( QWidget* parent)
: QWidget( parent )
, m_scrollPos( 0 )
, m_isMouseOver( false )
{
m_staticText.setTextFormat( Qt::PlainText );
setFixedHeight( fontMetrics().height() );
m_leftMargin = height() / 3;
m_separator = QString::fromUtf8( " \u26AB " );
connect( &m_timer, SIGNAL( timeout() ), this, SLOT( onTimerTimeout() ) );
m_timer.setInterval( 10 );
}
QString
ScrollingLabel::text() const
{
return m_text;
}
void
ScrollingLabel::setText( QString text )
{
m_text = text;
updateText();
update();
}
void
ScrollingLabel::updateText()
{
m_timer.stop();
m_singleTextWidth = fontMetrics().width( m_text );
m_scrollEnabled = ( m_singleTextWidth > width() - m_leftMargin );
m_scrollPos = -64;
if ( m_scrollEnabled && m_isMouseOver )
{
m_staticText.setText( m_text + m_separator );
m_timer.start();
}
else
m_staticText.setText( m_text );
m_staticText.prepare( QTransform(), font() );
m_wholeTextSize = QSize( fontMetrics().width( m_staticText.text() ),
fontMetrics().height() );
}
void
ScrollingLabel::paintEvent( QPaintEvent* )
{
QPainter p( this );
if ( m_scrollEnabled )
{
m_buffer.fill( qRgba(0, 0, 0, 0) );
QPainter pb( &m_buffer );
pb.setPen( p.pen() );
pb.setFont( p.font() );
int x = qMin( -m_scrollPos, 0 ) + m_leftMargin;
while ( x < width() )
{
pb.drawStaticText( QPointF( x, ( height() - m_wholeTextSize.height() ) / 2 ) + QPoint( 2, 2 ), m_staticText );
x += m_wholeTextSize.width();
}
TomahawkUtils::DpiScaler s( this );
//Apply Alpha Channel
pb.setCompositionMode( QPainter::CompositionMode_DestinationIn );
pb.setClipRect( width() - s.scaledX( 15 ),
0,
s.scaledX( 15 ),
height() );
pb.drawImage( 0, 0, m_alphaChannel );
pb.setClipRect( 0, 0, s.scaledX( 15 ), height() );
//initial situation: don't apply alpha channel in the left half of the image at all; apply it more and more until scrollPos gets positive
if ( m_scrollPos < 0 )
pb.setOpacity( (qreal)( qMax( -s.scaledX( 8 ), m_scrollPos ) + s.scaledX( 8 ) ) / s.scaledX( 8 ) );
pb.drawImage( 0, 0, m_alphaChannel );
//pb.end();
p.drawImage( 0, 0, m_buffer );
}
else
{
if ( m_wholeTextSize.width() > width() - 2*m_leftMargin )
{
p.drawStaticText( QPointF( m_leftMargin, ( height() - m_wholeTextSize.height() ) / 2 ),
m_staticText );
}
else
{
p.drawStaticText( QPointF( ( width() - m_wholeTextSize.width() ) / 2.,
( height() - m_wholeTextSize.height() ) / 2. ),
m_staticText );
}
}
}
void
ScrollingLabel::resizeEvent( QResizeEvent* )
{
//From limmes@StackOverflow
//When the widget is resized, we need to update the alpha channel.
m_alphaChannel = QImage( size(), QImage::Format_ARGB32_Premultiplied );
m_buffer = QImage( size(), QImage::Format_ARGB32_Premultiplied );
//Create Alpha Channel:
if ( width() > 64 )
{
//create first scanline
QRgb* scanline1 = (QRgb*)m_alphaChannel.scanLine( 0 );
for ( int x = 1; x < 16; ++x )
scanline1[ x - 1 ] = scanline1[ width() - x ] = qRgba( 0, 0, 0, x << 4 );
for ( int x = 15; x < width() - 15; ++x )
scanline1[ x ] = qRgb( 0, 0, 0 );
//copy scanline to the other ones
for ( int y = 1; y < height(); ++y )
memcpy( m_alphaChannel.scanLine( y ), (uchar*)scanline1, width() * 4 );
}
else
m_alphaChannel.fill( qRgb( 0, 0, 0 ) );
//Update scrolling state
bool newScrollEnabled = ( m_singleTextWidth > width() - m_leftMargin );
if( newScrollEnabled != m_scrollEnabled )
updateText();
}
void
ScrollingLabel::enterEvent( QEvent* )
{
m_isMouseOver = true;
updateText();
update();
}
void
ScrollingLabel::leaveEvent( QEvent* )
{
m_isMouseOver = false;
updateText();
update();
}
void
ScrollingLabel::onTimerTimeout()
{
m_scrollPos = ( m_scrollPos + 1 ) % m_wholeTextSize.width();
update();
}

View File

@@ -0,0 +1,64 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2014, Teo Mrnjavac <teo@kde.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SCROLLINGLABEL_H
#define SCROLLINGLABEL_H
#include <QWidget>
#include <QStaticText>
#include <QTimer>
class ScrollingLabel : public QWidget
{
Q_OBJECT
Q_PROPERTY( QString text READ text WRITE setText )
public:
explicit ScrollingLabel( QWidget* parent = 0 );
public slots:
QString text() const;
void setText( QString text );
protected:
virtual void paintEvent( QPaintEvent* );
virtual void resizeEvent( QResizeEvent* );
virtual void enterEvent( QEvent* );
virtual void leaveEvent( QEvent* );
private:
bool m_isMouseOver;
void updateText();
QString m_text;
QString m_separator;
QStaticText m_staticText;
int m_singleTextWidth;
QSize m_wholeTextSize;
int m_leftMargin;
bool m_scrollEnabled;
int m_scrollPos;
QImage m_alphaChannel;
QImage m_buffer;
QTimer m_timer;
private slots:
virtual void onTimerTimeout();
};
#endif // SCROLLINGLABEL_H