PageRenderTime 125ms CodeModel.GetById 40ms app.highlight 55ms RepoModel.GetById 25ms app.codeStats 0ms

/src/libtomahawk/context/ContextWidget.cpp

http://github.com/tomahawk-player/tomahawk
C++ | 363 lines | 272 code | 72 blank | 19 comment | 26 complexity | a96d33ffc0cde82fcdde46a7f56bb391 MD5 | raw file
  1/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
  2 *
  3 *   Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
  4 *
  5 *   Tomahawk is free software: you can redistribute it and/or modify
  6 *   it under the terms of the GNU General Public License as published by
  7 *   the Free Software Foundation, either version 3 of the License, or
  8 *   (at your option) any later version.
  9 *
 10 *   Tomahawk is distributed in the hope that it will be useful,
 11 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 12 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 13 *   GNU General Public License for more details.
 14 *
 15 *   You should have received a copy of the GNU General Public License
 16 *   along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
 17 */
 18
 19#include "ContextWidget.h"
 20#include "ui_ContextWidget.h"
 21
 22#include <QGraphicsProxyWidget>
 23#include <QGraphicsScene>
 24#include <QPropertyAnimation>
 25#include <QTimeLine>
 26
 27#include "context/ContextPage.h"
 28#include "context/pages/RelatedArtistsContext.h"
 29#include "context/pages/TopTracksContext.h"
 30#include "context/pages/WikipediaContext.h"
 31
 32#include "Source.h"
 33
 34#include "utils/StyleHelper.h"
 35#include "utils/TomahawkUtilsGui.h"
 36
 37#define ANIMATION_TIME 450
 38#define SLIDE_TIME 350
 39
 40using namespace Tomahawk;
 41
 42
 43ContextWidget::ContextWidget( QWidget* parent )
 44    : QWidget( parent )
 45    , ui( new Ui::ContextWidget )
 46    , m_currentView( 0 )
 47    , m_visible( false )
 48{
 49    ui->setupUi( this );
 50    TomahawkUtils::unmarginLayout( layout() );
 51    setContentsMargins( 0, 0, 0, 0 );
 52
 53    m_scene = new QGraphicsScene( this );
 54
 55    TopTracksContext* ttc = new TopTracksContext();
 56    RelatedArtistsContext* rac = new RelatedArtistsContext();
 57    WebContext* wiki = new WikipediaContext();
 58    /*WebContext* lastfm = new LastfmContext();*/
 59
 60    m_views << ttc;
 61    m_views << rac;
 62    m_views << wiki;
 63/*    m_views << lastfm;*/
 64
 65    foreach ( ContextPage* view, m_views )
 66    {
 67        ContextProxyPage* page = new ContextProxyPage();
 68        page->setPage( view );
 69        m_scene->addItem( page );
 70
 71        connect( page, SIGNAL( focused() ), SLOT( onPageFocused() ) );
 72        m_pages << page;
 73    }
 74
 75    ui->contextView->setScene( m_scene );
 76    ui->contextView->setFrameShape( QFrame::NoFrame );
 77    ui->contextView->setStyleSheet( "QGraphicsView { background: transparent; }" );
 78    ui->contextView->setAttribute( Qt::WA_MacShowFocusRect, 0 );
 79    ui->contextView->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
 80
 81    ui->contextView->hide();
 82
 83    QPalette whitePal = ui->toggleButton->palette();
 84    whitePal.setColor( QPalette::Foreground, Qt::white );
 85    ui->toggleButton->setPalette( whitePal );
 86    ui->toggleButton->setCursor( Qt::PointingHandCursor );
 87
 88    m_minHeight = TomahawkUtils::defaultFontHeight() * 1.4;
 89    ui->toggleButton->setMinimumHeight( m_minHeight );
 90
 91    setAutoFillBackground( true );
 92    setFixedHeight( m_minHeight );
 93
 94    ensurePolished();
 95    QPalette pal = palette();
 96    pal.setBrush( QPalette::Window, QColor( "#454e59" ) );
 97    setPalette( pal );
 98
 99    connect( ui->toggleButton, SIGNAL( clicked() ), SLOT( toggleSize() ) );
100
101    m_timeLine = new QTimeLine( ANIMATION_TIME, this );
102    m_timeLine->setUpdateInterval( 20 );
103    m_timeLine->setEasingCurve( QEasingCurve::OutCubic );
104
105    connect( m_timeLine, SIGNAL( frameChanged( int ) ), SLOT( onAnimationStep( int ) ) );
106    connect( m_timeLine, SIGNAL( finished() ), SLOT( onAnimationFinished() ) );
107}
108
109
110ContextWidget::~ContextWidget()
111{
112}
113
114
115void
116ContextWidget::changeEvent( QEvent* e )
117{
118    QWidget::changeEvent( e );
119    switch ( e->type() )
120    {
121        case QEvent::LanguageChange:
122            ui->retranslateUi( this );
123            break;
124
125        default:
126            break;
127    }
128}
129
130
131void
132ContextWidget::layoutViews( bool animate )
133{
134    int smallViewWidth = 120;
135    float smallViewOpacity = 0.6;
136
137    int margin = 6;
138    int maxVisible = 2;
139    int itemSize = ( m_scene->sceneRect().width() - smallViewWidth * 2 ) / maxVisible;
140    int firstPos = margin;
141    float opacity;
142
143    if ( m_currentView > 0 )
144        firstPos = smallViewWidth;
145
146    if ( m_currentView + maxVisible >= m_pages.count() )
147    {
148        int delta = m_pages.count() - m_currentView;
149        firstPos = m_scene->sceneRect().width() - ( delta * itemSize ) + 1;
150    }
151
152    for ( int i = 0; i < m_pages.count(); i++ )
153    {
154        QGraphicsWidget* view = m_pages.at( i );
155
156        int x = firstPos - ( ( m_currentView - i ) * itemSize );
157
158        if ( ( x < smallViewWidth && x < firstPos ) || i > m_currentView + maxVisible - 1 )
159        {
160            opacity = smallViewOpacity;
161        }
162        else
163        {
164            opacity = 1.0;
165        }
166
167        {
168            QPropertyAnimation* animation = new QPropertyAnimation( view, "opacity" );
169            animation->setDuration( SLIDE_TIME );
170            animation->setEndValue( opacity );
171            animation->start();
172        }
173
174        QRect rect( x, margin, itemSize - margin * 2, m_scene->sceneRect().height() - margin * 2 );
175        if ( animate )
176        {
177            {
178                QPropertyAnimation* animation = new QPropertyAnimation( view, "geometry" );
179                animation->setDuration( SLIDE_TIME );
180                animation->setEndValue( rect );
181                animation->start();
182            }
183        }
184        else
185        {
186            view->setGeometry( rect );
187        }
188    }
189}
190
191
192void
193ContextWidget::onPageFocused()
194{
195    ContextProxyPage* widget = qobject_cast< ContextProxyPage* >( sender() );
196
197    int i = 0;
198    foreach ( ContextProxyPage* view, m_pages )
199    {
200        if ( view == widget )
201        {
202            m_currentView = i;
203            layoutViews( true );
204            return;
205        }
206
207        i++;
208    }
209}
210
211
212void
213ContextWidget::fadeOut( bool animate )
214{
215    foreach ( QGraphicsWidget* view, m_pages )
216    {
217        if ( animate )
218        {
219            QPropertyAnimation* animation = new QPropertyAnimation( view, "opacity" );
220            animation->setDuration( SLIDE_TIME );
221            animation->setEndValue( 0.0 );
222            animation->start();
223        }
224        else
225            view->setOpacity( 0.0 );
226    }
227}
228
229
230void
231ContextWidget::setArtist( const Tomahawk::artist_ptr& artist )
232{
233    if ( artist.isNull() )
234        return;
235
236    m_artist = artist;
237    if ( height() > m_minHeight )
238    {
239        foreach ( ContextProxyPage* proxy, m_pages )
240        {
241            proxy->page()->setArtist( artist );
242        }
243
244        layoutViews( true );
245    }
246}
247
248
249void
250ContextWidget::setAlbum( const Tomahawk::album_ptr& album )
251{
252    if ( album.isNull() )
253        return;
254
255    m_album = album;
256    if ( height() > m_minHeight )
257    {
258        foreach ( ContextProxyPage* proxy, m_pages )
259        {
260            proxy->page()->setAlbum( album );
261        }
262
263        layoutViews( true );
264    }
265}
266
267
268void
269ContextWidget::setQuery( const Tomahawk::query_ptr& query, bool force )
270{
271    if ( query.isNull() )
272        return;
273    if ( !force && !m_query.isNull() && query->artist() == m_query->artist() )
274        return;
275
276    m_query = query;
277    if ( height() > m_minHeight )
278    {
279        foreach ( ContextProxyPage* proxy, m_pages )
280        {
281            proxy->page()->setQuery( query );
282        }
283
284        layoutViews( true );
285    }
286}
287
288
289void
290ContextWidget::toggleSize()
291{
292    m_maxHeight = TomahawkUtils::tomahawkWindow()->height() * 0.3;
293
294    if ( height() == m_minHeight )
295    {
296        m_timeLine->setFrameRange( height(), m_maxHeight );
297        m_timeLine->setDirection( QTimeLine::Forward );
298        m_timeLine->start();
299    }
300    else
301    {
302        m_visible = false;
303        ui->contextView->hide();
304
305        m_timeLine->setFrameRange( m_minHeight, height() );
306        m_timeLine->setDirection( QTimeLine::Backward );
307        m_timeLine->start();
308    }
309}
310
311
312void
313ContextWidget::onAnimationStep( int frame )
314{
315    setFixedHeight( frame );
316}
317
318
319void
320ContextWidget::onAnimationFinished()
321{
322    if ( m_timeLine->direction() == QTimeLine::Forward )
323    {
324        setFixedHeight( m_maxHeight );
325        m_visible = true;
326        ui->contextView->show();
327
328        fadeOut( false );
329        m_scene->setSceneRect( ui->contextView->viewport()->rect() );
330        layoutViews( false );
331        setArtist( m_artist );
332        setAlbum( m_album );
333        setQuery( m_query, true );
334
335        ui->toggleButton->setText( tr( "Hide Footnotes" ) );
336    }
337    else
338    {
339        setFixedHeight( m_minHeight );
340
341        ui->toggleButton->setText( tr( "Show Footnotes" ) );
342    }
343}
344
345
346void
347ContextWidget::paintEvent( QPaintEvent* e )
348{
349    QWidget::paintEvent( e );
350}
351
352
353void
354ContextWidget::resizeEvent( QResizeEvent* e )
355{
356    QWidget::resizeEvent( e );
357
358    if ( m_visible )
359    {
360        m_scene->setSceneRect( ui->contextView->viewport()->rect() );
361        layoutViews( false );
362    }
363}