1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-07 14:46:33 +02:00

Merge branch 'master' into tweetsip

This commit is contained in:
Jeff Mitchell
2011-02-12 00:18:48 -05:00
5 changed files with 100 additions and 34 deletions

View File

@@ -110,6 +110,8 @@ DynamicModel::trackResolved()
emit collapseFromTo( m_lastResolvedRow, m_currentAttempts ); emit collapseFromTo( m_lastResolvedRow, m_currentAttempts );
} }
m_currentAttempts = 0; m_currentAttempts = 0;
emit checkForOverflow();
} }
void void

View File

@@ -43,8 +43,11 @@ public:
void loadPlaylist( const dynplaylist_ptr& playlist ); void loadPlaylist( const dynplaylist_ptr& playlist );
virtual void removeIndex( const QModelIndex& index, bool moreToCome = false ); virtual void removeIndex( const QModelIndex& index, bool moreToCome = false );
bool searchingForNext() const { return m_searchingForNext; }
signals: signals:
void collapseFromTo( int startRow, int num ); void collapseFromTo( int startRow, int num );
void checkForOverflow();
void trackGenerationFailure( const QString& msg ); void trackGenerationFailure( const QString& msg );
@@ -60,6 +63,7 @@ private:
bool m_startOnResolved; bool m_startOnResolved;
bool m_onDemandRunning; bool m_onDemandRunning;
bool m_changeOnNext; bool m_changeOnNext;
bool m_searchingForNext;
int m_currentAttempts; int m_currentAttempts;
int m_lastResolvedRow; int m_lastResolvedRow;
}; };

View File

@@ -37,6 +37,7 @@ using namespace Tomahawk;
DynamicView::DynamicView( QWidget* parent ) DynamicView::DynamicView( QWidget* parent )
: PlaylistView( parent ) : PlaylistView( parent )
, m_onDemand( false ) , m_onDemand( false )
, m_checkOnCollapse( false )
{ {
m_fadeOutAnim.setDuration( FADE_LENGTH ); m_fadeOutAnim.setDuration( FADE_LENGTH );
m_fadeOutAnim.setCurveShape( QTimeLine::LinearCurve ); m_fadeOutAnim.setCurveShape( QTimeLine::LinearCurve );
@@ -51,6 +52,7 @@ DynamicView::DynamicView( QWidget* parent )
connect( &m_fadeOutAnim, SIGNAL( frameChanged( int ) ), viewport(), SLOT( update() ) ); connect( &m_fadeOutAnim, SIGNAL( frameChanged( int ) ), viewport(), SLOT( update() ) );
connect( &m_fadeOutAnim, SIGNAL( finished() ), this, SLOT( animFinished() ) );
} }
DynamicView::~DynamicView() DynamicView::~DynamicView()
@@ -61,15 +63,22 @@ DynamicView::~DynamicView()
void void
DynamicView::setModel( DynamicModel* model) DynamicView::setModel( DynamicModel* model)
{ {
m_model = model;
PlaylistView::setModel( model ); PlaylistView::setModel( model );
connect( model, SIGNAL( trackCountChanged( unsigned int ) ), SLOT( onTrackCountChanged( unsigned int ) ) ); connect( model, SIGNAL( trackCountChanged( unsigned int ) ), SLOT( onTrackCountChanged( unsigned int ) ) );
connect( model, SIGNAL( checkForOverflow() ), this, SLOT( checkForOverflow() ) );
} }
void void
DynamicView::setOnDemand( bool onDemand ) DynamicView::setOnDemand( bool onDemand )
{ {
m_onDemand = onDemand; m_onDemand = onDemand;
if( m_onDemand )
setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
else
setVerticalScrollBarPolicy( Qt::ScrollBarAsNeeded );
} }
void void
@@ -116,24 +125,54 @@ DynamicView::onTrackCountChanged( unsigned int tracks )
} }
else else
overlay()->hide(); overlay()->hide();
// make sure we can see all our tracks
scrollTo( proxyModel()->index( proxyModel()->rowCount() - 1, 0, QModelIndex() ), EnsureVisible );
} }
void void
DynamicView::collapseEntries( int startRow, int num ) DynamicView::checkForOverflow()
{ {
if( !m_onDemand || proxyModel()->rowCount( QModelIndex() ) == 0 )
return;
if( m_fadeOutAnim.state() == QTimeLine::Running )
m_checkOnCollapse = true;
/// We don't want stations to grow forever, because we don't want the view to have to scroll
/// So if there are too many tracks, we remove some that have already been played
/// Our threshold is 4 rows to the end. That's when we collapse.
QModelIndex last = proxyModel()->index( proxyModel()->rowCount( QModelIndex() ) - 1, 0, QModelIndex() );
QRect lastRect = visualRect( last );
qDebug() << "Checking viewport height of" << viewport()->height() << "and last track bottom:" << lastRect.bottomLeft().y() << "under threshold" << 4 * lastRect.height();
if( viewport()->height() - lastRect.bottomLeft().y() <= ( 4 * lastRect.height() ) ) {
qDebug() << "Deciding to remove some tracks from this station";
// figure out how many to remove. lets get rid of 1/3rd of the backlog, visually.
int toRemove = ( viewport()->height() / 3 ) / lastRect.height();
qDebug() << "Decided to remove" << toRemove << "rows!";
collapseEntries( 0, toRemove, proxyModel()->rowCount( QModelIndex() ) - toRemove );
}
}
void
DynamicView::collapseEntries( int startRow, int num, int numToKeep )
{
qDebug() << "BEGINNING TO COLLAPSE FROM" << startRow << num << numToKeep;
if( m_fadeOutAnim.state() == QTimeLine::Running ) if( m_fadeOutAnim.state() == QTimeLine::Running )
qDebug() << "COLLAPSING TWICE!"; qDebug() << "COLLAPSING TWICE!";
// TODO if we are scrolled, we can't animate this way.
// we have to animate the top coming down, which i haven't implemented yet.. /// Two options: Either we are overflowing our view, or we're not. If we are, it's because the search for a playable track
if( verticalScrollBar()->sliderPosition() == 0 ) { /// went past the limit of the view. Just fade out from the beginning to the end in that case. otherwise, animate a slide
bool justFade = false;
int realNum = num;
QModelIndex last = indexAt( QPoint( 3, viewport()->height() - 3 ) );
if( last.isValid() && last.row() < startRow + num ) {
justFade = true;
realNum = last.row();
}
// we capture the image of the rows we're going to collapse // we capture the image of the rows we're going to collapse
// then we capture the image of the target row we're going to animate downwards // then we capture the image of the target row we're going to animate downwards
// then we fade the first image out while sliding the second image up. // then we fade the first image out while sliding the second image up.
QModelIndex topLeft = proxyModel()->index( startRow, 0, QModelIndex() ); QModelIndex topLeft = proxyModel()->index( startRow, 0, QModelIndex() );
QModelIndex bottomRight = proxyModel()->index( startRow + num - 1, proxyModel()->columnCount( QModelIndex() ) - 1, QModelIndex() ); QModelIndex bottomRight = proxyModel()->index( startRow + realNum - 1, proxyModel()->columnCount( QModelIndex() ) - 1, QModelIndex() );
QItemSelection sel( topLeft, bottomRight ); QItemSelection sel( topLeft, bottomRight );
QRect fadingRect = visualRegionForSelection( sel ).boundingRect(); QRect fadingRect = visualRegionForSelection( sel ).boundingRect();
QRect fadingRectViewport = fadingRect; // all values that we use in paintEvent() have to be in viewport coords QRect fadingRectViewport = fadingRect; // all values that we use in paintEvent() have to be in viewport coords
@@ -142,13 +181,20 @@ DynamicView::collapseEntries( int startRow, int num )
m_fadingIndexes = QPixmap::grabWidget( this, fadingRect ); // but all values we use to grab the widgetr have to be in scrollarea coords :( m_fadingIndexes = QPixmap::grabWidget( this, fadingRect ); // but all values we use to grab the widgetr have to be in scrollarea coords :(
m_fadingPointAnchor = QPoint( 0, fadingRectViewport.topLeft().y() ); m_fadingPointAnchor = QPoint( 0, fadingRectViewport.topLeft().y() );
m_fadeOutAnim.start();
qDebug() << "Grabbed fading indexes from rect:" << fadingRect << m_fadingIndexes.size(); qDebug() << "Grabbed fading indexes from rect:" << fadingRect << m_fadingIndexes.size();
topLeft = proxyModel()->index( startRow + num, 0, QModelIndex() ); if( !justFade ) {
bottomRight = proxyModel()->index( startRow + num, proxyModel()->columnCount( QModelIndex() ) - 1, QModelIndex() ); /// sanity checks. make sure we have all the rows we need
int firstSlider = startRow + realNum;
Q_ASSERT( firstSlider + numToKeep - 1 <= proxyModel()->rowCount() );
topLeft = proxyModel()->index( startRow + realNum, 0, QModelIndex() );
bottomRight = proxyModel()->index( startRow + realNum + numToKeep - 1, proxyModel()->columnCount( QModelIndex() ) - 1, QModelIndex() );
QRect slidingRect = visualRegionForSelection( QItemSelection( topLeft, bottomRight ) ).boundingRect(); QRect slidingRect = visualRegionForSelection( QItemSelection( topLeft, bottomRight ) ).boundingRect();
QRect slidingRectViewport = slidingRect; QRect slidingRectViewport = slidingRect;
// map internal view cord to external qscrollarea // map internal view coord to external qscrollarea
slidingRect.moveTo( viewport()->mapTo( this, slidingRect.topLeft() ) ); slidingRect.moveTo( viewport()->mapTo( this, slidingRect.topLeft() ) );
m_slidingIndex = QPixmap::grabWidget( this, slidingRect ); m_slidingIndex = QPixmap::grabWidget( this, slidingRect );
@@ -161,9 +207,9 @@ DynamicView::collapseEntries( int startRow, int num )
m_slideAnim.setDuration( SLIDE_LENGTH + frameRange * LONG_MULT ); m_slideAnim.setDuration( SLIDE_LENGTH + frameRange * LONG_MULT );
m_slideAnim.setFrameRange( slidingRectViewport.topLeft().y(), fadingRectViewport.topLeft().y() ); m_slideAnim.setFrameRange( slidingRectViewport.topLeft().y(), fadingRectViewport.topLeft().y() );
m_fadeOutAnim.start();
QTimer::singleShot( SLIDE_OFFSET, &m_slideAnim, SLOT( start() ) ); QTimer::singleShot( SLIDE_OFFSET, &m_slideAnim, SLOT( start() ) );
} }
// delete the actual indices // delete the actual indices
QModelIndexList todel; QModelIndexList todel;
for( int i = 0; i < num; i++ ) { for( int i = 0; i < num; i++ ) {
@@ -174,6 +220,14 @@ DynamicView::collapseEntries( int startRow, int num )
proxyModel()->removeIndexes( todel ); proxyModel()->removeIndexes( todel );
} }
void
DynamicView::animFinished()
{
if( m_checkOnCollapse )
checkForOverflow();
m_checkOnCollapse = false;
}
void void
DynamicView::paintEvent( QPaintEvent* event ) DynamicView::paintEvent( QPaintEvent* event )
{ {

View File

@@ -21,6 +21,7 @@
#include <QTimer> #include <QTimer>
#include <QPropertyAnimation> #include <QPropertyAnimation>
#include <QTimeLine> #include <QTimeLine>
#include <QMutex>
class PlaylistModel; class PlaylistModel;
class TrackModel; class TrackModel;
@@ -51,17 +52,22 @@ public slots:
// collapse and animate the transition // collapse and animate the transition
// there MUST be a row *after* startRow + num. that is, you can't collapse // there MUST be a row *after* startRow + num. that is, you can't collapse
// entries unless there is at least one entry after the last collapsed row // entries unless there is at least one entry after the last collapsed row
void collapseEntries( int startRow, int num ); // optionally you can specify how many rows are past the block of collapsed rows
void collapseEntries( int startRow, int num, int numToKeep = 1 );
private slots: private slots:
void onTrackCountChanged( unsigned int ); void onTrackCountChanged( unsigned int );
void checkForOverflow();
void animFinished();
private: private:
DynamicModel* m_model;
QString m_title; QString m_title;
QString m_body; QString m_body;
bool m_onDemand; bool m_onDemand;
bool m_readOnly; bool m_readOnly;
bool m_checkOnCollapse;
// for collapsing animation // for collapsing animation
QPoint m_fadingPointAnchor; QPoint m_fadingPointAnchor;

View File

@@ -64,7 +64,7 @@ DynamicWidget::DynamicWidget( const Tomahawk::dynplaylist_ptr& playlist, QWidget
m_view->setContentsMargins( 0, 0, 0, 0 ); m_view->setContentsMargins( 0, 0, 0, 0 );
m_layout->addWidget( m_view, 1 ); m_layout->addWidget( m_view, 1 );
connect( m_model, SIGNAL( collapseFromTo( int, int ) ), m_view, SLOT( collapseEntries( int, int ) ), Qt::QueuedConnection ); connect( m_model, SIGNAL( collapseFromTo( int, int ) ), m_view, SLOT( collapseEntries( int, int ) ) );
connect( m_model, SIGNAL( trackGenerationFailure( QString ) ), m_view, SLOT( showMessage( QString ) ) ); connect( m_model, SIGNAL( trackGenerationFailure( QString ) ), m_view, SLOT( showMessage( QString ) ) );