mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-07-31 03:10:12 +02:00
* Now we have a proper AnimatedSplitter class.
This commit is contained in:
@@ -105,6 +105,7 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui}
|
||||
utils/progresstreeview.cpp
|
||||
utils/proxystyle.cpp
|
||||
utils/widgetdragfilter.cpp
|
||||
utils/animatedsplitter.cpp
|
||||
|
||||
playlist/collectionmodel.cpp
|
||||
playlist/collectionproxymodel.cpp
|
||||
@@ -233,6 +234,7 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui}
|
||||
utils/imagebutton.h
|
||||
utils/progresstreeview.h
|
||||
utils/widgetdragfilter.h
|
||||
utils/animatedsplitter.h
|
||||
|
||||
playlist/collectionmodel.h
|
||||
playlist/collectionproxymodel.h
|
||||
|
@@ -2,7 +2,9 @@
|
||||
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "audioengine.h"
|
||||
#include "audio/audioengine.h"
|
||||
#include "utils/animatedsplitter.h"
|
||||
|
||||
#include "collectionmodel.h"
|
||||
#include "collectionflatmodel.h"
|
||||
#include "collectionview.h"
|
||||
@@ -35,9 +37,10 @@ PlaylistManager::PlaylistManager( QObject* parent )
|
||||
|
||||
m_widget->setLayout( new QVBoxLayout() );
|
||||
|
||||
m_splitter = new QSplitter();
|
||||
m_splitter = new AnimatedSplitter();
|
||||
m_splitter->setOrientation( Qt::Vertical );
|
||||
m_splitter->setChildrenCollapsible( false );
|
||||
m_splitter->setGreedyWidget( 0 );
|
||||
|
||||
m_splitter->addWidget( m_stack );
|
||||
m_splitter->addWidget( m_queueView );
|
||||
@@ -281,7 +284,7 @@ PlaylistManager::showQueue()
|
||||
return;
|
||||
}
|
||||
|
||||
m_queueView->showQueue();
|
||||
m_splitter->show( 1 );
|
||||
}
|
||||
|
||||
|
||||
@@ -296,7 +299,7 @@ PlaylistManager::hideQueue()
|
||||
return;
|
||||
}
|
||||
|
||||
m_queueView->hideQueue();
|
||||
m_splitter->hide( 1 );
|
||||
}
|
||||
|
||||
|
||||
|
@@ -4,11 +4,11 @@
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
#include <QStackedWidget>
|
||||
#include <QSplitter>
|
||||
|
||||
#include "tomahawk/collection.h"
|
||||
#include "tomahawk/playlistinterface.h"
|
||||
|
||||
class AnimatedSplitter;
|
||||
class CollectionModel;
|
||||
class CollectionFlatModel;
|
||||
class CollectionView;
|
||||
@@ -72,7 +72,7 @@ private:
|
||||
|
||||
QWidget* m_widget;
|
||||
QStackedWidget* m_stack;
|
||||
QSplitter* m_splitter;
|
||||
AnimatedSplitter* m_splitter;
|
||||
|
||||
PlaylistModel* m_queueModel;
|
||||
QueueView* m_queueView;
|
||||
|
@@ -1,7 +1,6 @@
|
||||
#include "queueview.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QTimeLine>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "playlist/queueproxymodel.h"
|
||||
@@ -11,26 +10,22 @@ using namespace Tomahawk;
|
||||
|
||||
QueueView::QueueView( QWidget* parent )
|
||||
: QWidget( parent )
|
||||
, m_prevHeight( 175 )
|
||||
{
|
||||
setMinimumHeight( 25 );
|
||||
setMaximumHeight( 25 );
|
||||
setLayout( new QVBoxLayout() );
|
||||
|
||||
m_queue = new PlaylistView( this );
|
||||
m_queue->setProxyModel( new QueueProxyModel( this ) );
|
||||
m_queue->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Ignored );
|
||||
|
||||
m_button = new QPushButton();
|
||||
m_button->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed );
|
||||
m_button->setText( tr( "Click to show queue" ) );
|
||||
connect( m_button, SIGNAL( clicked() ), SLOT( showQueue() ) );
|
||||
connect( m_button, SIGNAL( clicked() ), SIGNAL( showWidget() ) );
|
||||
|
||||
layout()->setMargin( 0 );
|
||||
layout()->addWidget( m_button );
|
||||
layout()->addWidget( m_queue );
|
||||
layout()->setAlignment( Qt::AlignTop );
|
||||
|
||||
m_queue->hide();
|
||||
}
|
||||
|
||||
|
||||
@@ -41,82 +36,26 @@ QueueView::~QueueView()
|
||||
|
||||
|
||||
void
|
||||
QueueView::showQueue()
|
||||
QueueView::onShown( QWidget* widget )
|
||||
{
|
||||
if ( !m_queue->isHidden() )
|
||||
qDebug() << Q_FUNC_INFO << widget;
|
||||
if ( widget != this )
|
||||
return;
|
||||
|
||||
m_button->setText( tr( "Click to hide queue" ) );
|
||||
disconnect( m_button, SIGNAL( clicked() ), this, SLOT( showQueue() ) );
|
||||
connect( m_button, SIGNAL( clicked() ), SLOT( hideQueue() ) );
|
||||
|
||||
m_queue->setMaximumHeight( m_prevHeight );
|
||||
m_queue->resize( m_queue->width(), m_prevHeight );
|
||||
m_queue->show();
|
||||
|
||||
QTimeLine *timeLine = new QTimeLine( 300, this );
|
||||
timeLine->setFrameRange( 0, m_prevHeight );
|
||||
timeLine->setUpdateInterval( 20 );
|
||||
timeLine->setCurveShape( QTimeLine::EaseOutCurve );
|
||||
|
||||
connect( timeLine, SIGNAL( frameChanged( int ) ), SLOT( onAnimationStep( int ) ) );
|
||||
connect( timeLine, SIGNAL( finished() ), SLOT( onAnimationFinished() ) );
|
||||
timeLine->start();
|
||||
disconnect( m_button, SIGNAL( clicked() ), this, SIGNAL( showWidget() ) );
|
||||
connect( m_button, SIGNAL( clicked() ), SIGNAL( hideWidget() ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
QueueView::hideQueue()
|
||||
QueueView::onHidden( QWidget* widget )
|
||||
{
|
||||
if ( m_queue->isHidden() )
|
||||
qDebug() << Q_FUNC_INFO << widget;
|
||||
if ( widget != this )
|
||||
return;
|
||||
|
||||
m_button->setText( tr( "Click to show queue" ) );
|
||||
disconnect( m_button, SIGNAL( clicked() ), this, SLOT( hideQueue() ) );
|
||||
connect( m_button, SIGNAL( clicked() ), SLOT( showQueue() ) );
|
||||
|
||||
m_prevHeight = height() - 25;
|
||||
QTimeLine *timeLine = new QTimeLine( 300, this );
|
||||
timeLine->setFrameRange( 0, m_prevHeight );
|
||||
timeLine->setUpdateInterval( 20 );
|
||||
timeLine->setDirection( QTimeLine::Backward );
|
||||
timeLine->setCurveShape( QTimeLine::EaseOutCurve );
|
||||
|
||||
connect( timeLine, SIGNAL( frameChanged( int ) ), SLOT( onAnimationStep( int ) ) );
|
||||
connect( timeLine, SIGNAL( finished() ), SLOT( onAnimationFinished() ) );
|
||||
timeLine->start();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
QueueView::onAnimationStep( int frame )
|
||||
{
|
||||
setUpdatesEnabled( false );
|
||||
|
||||
setMinimumHeight( frame + 25 );
|
||||
setMaximumHeight( frame + 25 );
|
||||
|
||||
setUpdatesEnabled( true );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
QueueView::onAnimationFinished()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << maximumHeight();
|
||||
|
||||
if ( maximumHeight() < 32 )
|
||||
{
|
||||
setMinimumHeight( 25 );
|
||||
setMaximumHeight( 25 );
|
||||
m_queue->hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
setMinimumHeight( 200 );
|
||||
setMaximumHeight( QWIDGETSIZE_MAX );
|
||||
m_queue->setMaximumHeight( QWIDGETSIZE_MAX );
|
||||
}
|
||||
|
||||
sender()->deleteLater();
|
||||
disconnect( m_button, SIGNAL( clicked() ), this, SIGNAL( hideWidget() ) );
|
||||
connect( m_button, SIGNAL( clicked() ), SIGNAL( showWidget() ) );
|
||||
}
|
||||
|
@@ -15,18 +15,19 @@ public:
|
||||
|
||||
PlaylistView* queue() const { return m_queue; }
|
||||
|
||||
public slots:
|
||||
void showQueue();
|
||||
void hideQueue();
|
||||
QSize sizeHint() const { return QSize( 0, 200 ); }
|
||||
|
||||
private slots:
|
||||
void onAnimationStep( int frame );
|
||||
void onAnimationFinished();
|
||||
public slots:
|
||||
void onShown( QWidget* );
|
||||
void onHidden( QWidget* );
|
||||
|
||||
signals:
|
||||
void showWidget();
|
||||
void hideWidget();
|
||||
|
||||
private:
|
||||
PlaylistView* m_queue;
|
||||
QPushButton* m_button;
|
||||
unsigned int m_prevHeight;
|
||||
};
|
||||
|
||||
#endif // QUEUEVIEW_H
|
||||
|
160
src/utils/animatedsplitter.cpp
Normal file
160
src/utils/animatedsplitter.cpp
Normal file
@@ -0,0 +1,160 @@
|
||||
#include "animatedsplitter.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QTimeLine>
|
||||
|
||||
|
||||
AnimatedSplitter::AnimatedSplitter( QWidget* parent )
|
||||
: QSplitter( parent )
|
||||
, m_animateIndex( -1 )
|
||||
, m_greedyIndex( -1 )
|
||||
, m_greedyHeight( -1 )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AnimatedSplitter::show( int index )
|
||||
{
|
||||
if ( m_greedyIndex < 0 )
|
||||
return;
|
||||
|
||||
m_animateIndex = index;
|
||||
|
||||
QWidget* w = widget( index );
|
||||
QSize size = w->sizeHint();
|
||||
qDebug() << "SizeHint:" << index << w->height() << size;
|
||||
|
||||
m_greedyHeight = widget( m_greedyIndex )->height();
|
||||
|
||||
QTimeLine *timeLine = new QTimeLine( 300, this );
|
||||
timeLine->setFrameRange( w->height(), size.height() );
|
||||
timeLine->setUpdateInterval( 20 );
|
||||
timeLine->setCurveShape( QTimeLine::EaseOutCurve );
|
||||
|
||||
connect( timeLine, SIGNAL( frameChanged( int ) ), SLOT( onAnimationStep( int ) ) );
|
||||
connect( timeLine, SIGNAL( finished() ), SLOT( onAnimationFinished() ) );
|
||||
timeLine->start();
|
||||
|
||||
emit shown( w );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AnimatedSplitter::hide( int index )
|
||||
{
|
||||
if ( m_greedyIndex < 0 )
|
||||
return;
|
||||
|
||||
m_animateIndex = index;
|
||||
|
||||
QWidget* w = widget( index );
|
||||
qDebug() << "SizeHint:" << index << w->height();
|
||||
|
||||
m_greedyHeight = widget( m_greedyIndex )->height();
|
||||
|
||||
QTimeLine *timeLine = new QTimeLine( 300, this );
|
||||
timeLine->setFrameRange( 25, w->height() );
|
||||
timeLine->setUpdateInterval( 20 );
|
||||
timeLine->setDirection( QTimeLine::Backward );
|
||||
timeLine->setCurveShape( QTimeLine::EaseOutCurve );
|
||||
|
||||
connect( timeLine, SIGNAL( frameChanged( int ) ), SLOT( onAnimationStep( int ) ) );
|
||||
connect( timeLine, SIGNAL( finished() ), SLOT( onAnimationFinished() ) );
|
||||
timeLine->start();
|
||||
|
||||
emit hidden( w );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AnimatedSplitter::addWidget( QWidget* widget )
|
||||
{
|
||||
QSplitter::addWidget( widget );
|
||||
|
||||
connect( widget, SIGNAL( showWidget() ), SLOT( onShowRequest() ) );
|
||||
connect( widget, SIGNAL( hideWidget() ), SLOT( onHideRequest() ) );
|
||||
connect( this, SIGNAL( shown( QWidget* ) ), widget, SLOT( onShown( QWidget* ) ) );
|
||||
connect( this, SIGNAL( hidden( QWidget* ) ), widget, SLOT( onHidden( QWidget* ) ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AnimatedSplitter::onShowRequest()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
int j = -1;
|
||||
for ( int i = 0; i < count(); i ++ )
|
||||
{
|
||||
if ( widget( i ) == sender() )
|
||||
{
|
||||
j = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( j > 0 )
|
||||
show( j );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AnimatedSplitter::onHideRequest()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
int j = -1;
|
||||
for ( int i = 0; i < count(); i ++ )
|
||||
{
|
||||
if ( widget( i ) == sender() )
|
||||
{
|
||||
j = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( j > 0 )
|
||||
hide( j );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AnimatedSplitter::onAnimationStep( int frame )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << frame;
|
||||
|
||||
QList< int > sizes;
|
||||
|
||||
for ( int i = 0; i < count(); i ++ )
|
||||
{
|
||||
int j = 0;
|
||||
|
||||
if ( i == m_greedyIndex )
|
||||
{
|
||||
j = height() - frame; // FIXME
|
||||
}
|
||||
else if ( i == m_animateIndex )
|
||||
{
|
||||
j = frame;
|
||||
}
|
||||
else
|
||||
{
|
||||
j = widget( i )->height();
|
||||
}
|
||||
|
||||
sizes << j;
|
||||
}
|
||||
|
||||
qDebug() << sizes;
|
||||
setSizes( sizes );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AnimatedSplitter::onAnimationFinished()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
sender()->deleteLater();
|
||||
}
|
38
src/utils/animatedsplitter.h
Normal file
38
src/utils/animatedsplitter.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#ifndef ANIMATEDSPLITTER_H
|
||||
#define ANIMATEDSPLITTER_H
|
||||
|
||||
#include <QSplitter>
|
||||
|
||||
class AnimatedSplitter : public QSplitter
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AnimatedSplitter( QWidget* parent = 0 );
|
||||
|
||||
void show( int index );
|
||||
void hide( int index );
|
||||
|
||||
void setGreedyWidget( int index ) { m_greedyIndex = index; }
|
||||
|
||||
void addWidget( QWidget* widget );
|
||||
|
||||
signals:
|
||||
void shown( QWidget* );
|
||||
void hidden( QWidget* );
|
||||
|
||||
private slots:
|
||||
void onShowRequest();
|
||||
void onHideRequest();
|
||||
|
||||
void onAnimationStep( int frame );
|
||||
void onAnimationFinished();
|
||||
|
||||
private:
|
||||
int m_animateIndex;
|
||||
|
||||
int m_greedyIndex;
|
||||
int m_greedyHeight;
|
||||
};
|
||||
|
||||
#endif //ANIMATEDSPLITTER_H
|
Reference in New Issue
Block a user