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:
@@ -159,6 +159,7 @@ set( libGuiSources
|
|||||||
widgets/RecentPlaylistsModel.cpp
|
widgets/RecentPlaylistsModel.cpp
|
||||||
widgets/RecentlyPlayedPlaylistsModel.cpp
|
widgets/RecentlyPlayedPlaylistsModel.cpp
|
||||||
widgets/ScriptCollectionHeader.cpp
|
widgets/ScriptCollectionHeader.cpp
|
||||||
|
widgets/ScrollingLabel.cpp
|
||||||
widgets/SearchWidget.cpp
|
widgets/SearchWidget.cpp
|
||||||
widgets/SeekSlider.cpp
|
widgets/SeekSlider.cpp
|
||||||
widgets/SourceTreePopupDialog.cpp
|
widgets/SourceTreePopupDialog.cpp
|
||||||
|
@@ -21,6 +21,7 @@
|
|||||||
#include "ColumnView.h"
|
#include "ColumnView.h"
|
||||||
#include "widgets/PlayableCover.h"
|
#include "widgets/PlayableCover.h"
|
||||||
#include "widgets/QueryLabel.h"
|
#include "widgets/QueryLabel.h"
|
||||||
|
#include "widgets/ScrollingLabel.h"
|
||||||
#include "utils/Logger.h"
|
#include "utils/Logger.h"
|
||||||
#include "Source.h"
|
#include "Source.h"
|
||||||
#include "utils/TomahawkUtilsGui.h"
|
#include "utils/TomahawkUtilsGui.h"
|
||||||
@@ -66,12 +67,13 @@ ColumnViewPreviewWidget::ColumnViewPreviewWidget( ColumnView* parent )
|
|||||||
mainLayout->addSpacing( 16 );
|
mainLayout->addSpacing( 16 );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_trackLabel = new QLabel( this );
|
m_trackLabel = new ScrollingLabel( this );
|
||||||
m_trackLabel->setAlignment( Qt::AlignCenter );
|
//m_trackLabel->setAlignment( Qt::AlignCenter );
|
||||||
QFont font;
|
QFont font;
|
||||||
font.setPointSize( TomahawkUtils::defaultFontSize() + 9 );
|
font.setPointSize( TomahawkUtils::defaultFontSize() + 9 );
|
||||||
font.setBold( true );
|
font.setBold( true );
|
||||||
m_trackLabel->setFont( font );
|
m_trackLabel->setFont( font );
|
||||||
|
m_trackLabel->setFixedHeight( QFontMetrics( font ).height() + 6 );
|
||||||
mainLayout->addWidget( m_trackLabel );
|
mainLayout->addWidget( m_trackLabel );
|
||||||
|
|
||||||
m_artistLabel = new QueryLabel( this );
|
m_artistLabel = new QueryLabel( this );
|
||||||
|
@@ -28,6 +28,7 @@ class ColumnView;
|
|||||||
class QueryLabel;
|
class QueryLabel;
|
||||||
class PlayableCover;
|
class PlayableCover;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
|
class ScrollingLabel;
|
||||||
|
|
||||||
class DLLEXPORT ColumnViewPreviewWidget : public QWidget
|
class DLLEXPORT ColumnViewPreviewWidget : public QWidget
|
||||||
{
|
{
|
||||||
@@ -66,7 +67,7 @@ private:
|
|||||||
QLabel* m_yearLabel;
|
QLabel* m_yearLabel;
|
||||||
QLabel* m_yearValue;
|
QLabel* m_yearValue;
|
||||||
|
|
||||||
QLabel* m_trackLabel;
|
ScrollingLabel* m_trackLabel;
|
||||||
|
|
||||||
QueryLabel* m_artistLabel;
|
QueryLabel* m_artistLabel;
|
||||||
};
|
};
|
||||||
|
191
src/libtomahawk/widgets/ScrollingLabel.cpp
Normal file
191
src/libtomahawk/widgets/ScrollingLabel.cpp
Normal 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();
|
||||||
|
}
|
64
src/libtomahawk/widgets/ScrollingLabel.h
Normal file
64
src/libtomahawk/widgets/ScrollingLabel.h
Normal 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
|
Reference in New Issue
Block a user