mpviewplugins/mpmediawallviewplugin/src/mpmediawallview.cpp
changeset 35 fdb31ab341af
child 32 c163ef0b758d
equal deleted inserted replaced
34:2c5162224003 35:fdb31ab341af
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: Music Player Settings view.
       
    15 *
       
    16 */
       
    17 
       
    18 #include <QParallelAnimationGroup>
       
    19 #include <QPropertyAnimation>
       
    20 
       
    21 #include <hbicon.h>
       
    22 #include <hbaction.h>
       
    23 #include <hbapplication.h>
       
    24 #include <hbscrollbar.h>
       
    25 #include <hblabel.h>
       
    26 #include <hbpushbutton.h>
       
    27 #include <hbtoolbutton.h>
       
    28 
       
    29 #include <hgmediawall.h>
       
    30 
       
    31 #include "mpmediawallview.h"
       
    32 #include "mpmediawalldocumentloader.h"
       
    33 #include "mpcommondefs.h"
       
    34 #include "mpmpxcollectiondata.h"
       
    35 #include "mpcollectiondatamodel.h"
       
    36 #include "mpenginefactory.h"
       
    37 #include "mpplaybackdata.h"
       
    38 #include "mpalbumcoverwidget.h"
       
    39 #include "mptracklistwidget.h"
       
    40 #include "mpcollectiontbonelistdatamodel.h"
       
    41 #include "mptrace.h"
       
    42 
       
    43 const char*MUSIC_MEDIAWALL_DOCML = ":/mediawallviewdocml/mediawall.docml";
       
    44 
       
    45 /*!
       
    46     \class MpMediaWallView
       
    47     \brief Music Player Settings view.
       
    48 
       
    49     Music player media wall view displays music players albums on an full screen view
       
    50 */
       
    51 
       
    52 /*!
       
    53     \fn void command( int command )
       
    54 
       
    55     This signal is emitted when the view issues a \a command to the
       
    56     application such as request to switch to a different view.
       
    57  */
       
    58 
       
    59 
       
    60 /*!
       
    61  Constructs the media wall view.
       
    62  */
       
    63 MpMediaWallView::MpMediaWallView()
       
    64     : mEngine( 0 ),
       
    65       mCollectionData( 0 ),
       
    66       mModel( 0 ),
       
    67       mMediaWallWidget( 0 ),
       
    68       mNoMusic( 0 ),
       
    69       mDocumentLoader( 0 ),
       
    70       mPlayPauseContainer( 0 ),
       
    71       mPlayIcon( 0 ),
       
    72       mPauseIcon( 0 ),
       
    73       mPlayPauseAction( 0 ),
       
    74       mLibraryUpdating( false ),
       
    75       mPlaybackData( 0 ),
       
    76       mActivated( false ),
       
    77       mIconUpdateNedded( false ),
       
    78       mListShowAnimationGroup( 0 ),
       
    79       mListShowListAnimation( 0 ),
       
    80       mCoverShowListAnimation( 0 ),
       
    81       mShowingSongsList( false ),
       
    82       mAlbumCover( 0 ),
       
    83       mTrackList( 0 )
       
    84 {
       
    85     connect( MpEngineFactory::sharedEngine(), SIGNAL( libraryAboutToUpdate() ),
       
    86                     this, SLOT( libraryAboutToUpdate() ) );
       
    87     connect( MpEngineFactory::sharedEngine(), SIGNAL( libraryUpdated() ),
       
    88                     this, SLOT( libraryUpdated() ) );
       
    89     TX_LOG
       
    90 }
       
    91     
       
    92 /*!
       
    93  Destructs the media wall view.
       
    94  */
       
    95 MpMediaWallView::~MpMediaWallView()
       
    96 {
       
    97     TX_ENTRY
       
    98     //delete not parented objects
       
    99     delete mDocumentLoader;
       
   100     delete mPlayIcon;
       
   101     delete mPauseIcon;
       
   102     TX_EXIT
       
   103 }
       
   104 
       
   105 /*!
       
   106  Initializes the media wall view.
       
   107  */
       
   108 void MpMediaWallView::initializeView()
       
   109 {
       
   110     TX_ENTRY
       
   111     setTitleBarVisible( false );
       
   112     setStatusBarVisible( false );
       
   113        
       
   114     mDocumentLoader = new MpMediaWallDocumentLoader();  
       
   115     bool ok = false;
       
   116     mDocumentLoader->load( MUSIC_MEDIAWALL_DOCML, &ok );
       
   117     if ( ok ) {
       
   118         QGraphicsWidget *widget;
       
   119         
       
   120         //Setup fake softkey to hide the app
       
   121         widget = mDocumentLoader->findWidget( QString( "navigationButton" ) );
       
   122         HbAction  *action;
       
   123         action = new HbAction( Hb::BackNaviAction, this );
       
   124         connect( action, SIGNAL( triggered( bool ) ), this, SLOT( sendToBackground() ) );
       
   125         qobject_cast<HbToolButton*>( widget )->setAction( action );
       
   126         
       
   127         //Setup the play/pause command button
       
   128         widget = mDocumentLoader->findWidget( QString( "playPauseButton" ) );
       
   129         mPauseIcon = new HbIcon( "qtg_mono_pause" );
       
   130         mPlayIcon = new HbIcon( "qtg_mono_play" );
       
   131         mPlayPauseAction = new HbAction( HbIcon() , QString(), this );  
       
   132         mPlaybackData = MpEngineFactory::sharedEngine()->playbackData();
       
   133         qobject_cast<HbToolButton*>( widget )->setAction( mPlayPauseAction );
       
   134         //we need this widget to hide the play pause button, for soem reaosn it does not want to hide.
       
   135         mPlayPauseContainer = mDocumentLoader->findWidget( QString( "playPauseButtonContainer" ) );
       
   136         updatePlayPauseAction();
       
   137         connect( mPlaybackData, SIGNAL( playbackStateChanged() ),
       
   138                  this, SLOT( updatePlayPauseAction() ) );
       
   139         connect( mPlayPauseAction, SIGNAL( triggered( bool ) ),
       
   140                  MpEngineFactory::sharedEngine(), SLOT( playPause() ) );
       
   141 
       
   142         
       
   143         //Get the main container and set as widget.
       
   144         widget = mDocumentLoader->findWidget( QString( "container" ) );
       
   145         setWidget( widget );
       
   146         
       
   147         mEngine = MpEngineFactory::createIsolatedEngine( MpEngine::MediaBrowsing );
       
   148         mCollectionData = mEngine->collectionData();
       
   149         mModel = new MpCollectionDataModel( mCollectionData, this );
       
   150         
       
   151         connect( mCollectionData, SIGNAL( contextChanged( TCollectionContext ) ), 
       
   152                  this, SLOT( contextOpened( TCollectionContext ) ) );
       
   153         connect( mEngine, SIGNAL( containerContentsChanged() ),
       
   154                 this, SLOT( containerContentsChanged() ) );
       
   155         if ( !mLibraryUpdating ) {
       
   156         mEngine->openCollection( ECollectionContextAlbumsMediaWall );
       
   157         }
       
   158     }
       
   159     else {
       
   160         TX_LOG_ARGS( "Error: invalid xml file." );
       
   161         Q_ASSERT_X( ok, "MpCollectionView::initializeView", "invalid xml file" );
       
   162     }
       
   163     
       
   164     mAlbumCover = new MpAlbumCoverWidget( this );
       
   165     mAlbumCover->setDefaultIcon( HbIcon( "qtg_large_music_album" ) );
       
   166     mAlbumCover->hide();
       
   167     
       
   168     mTrackList = new MpTrackListWidget( this );
       
   169     mTrackList->list()->setModel( new MpCollectionTBoneListDataModel(mCollectionData, mTrackList ) );
       
   170     mTrackList->hide();
       
   171     
       
   172     connect(mAlbumCover,SIGNAL(clicked()),this, SLOT(hideTracksList()));
       
   173     connect(mTrackList->list(), SIGNAL(activated(QModelIndex)), this, SLOT(listItemActivated(QModelIndex)));
       
   174     connect(mTrackList,SIGNAL(close()),this, SLOT(hideTracksList()));
       
   175 
       
   176 
       
   177     
       
   178     TX_EXIT
       
   179 }
       
   180 
       
   181 /*!
       
   182  Activates the media wall view.
       
   183  */
       
   184 void MpMediaWallView::activateView()
       
   185 {
       
   186     TX_ENTRY
       
   187     mActivated = true;
       
   188     if ( mIconUpdateNedded ) {
       
   189         updatePlayPauseAction();
       
   190         mIconUpdateNedded = false;
       
   191     }
       
   192     scrollToNowPlaying();   
       
   193     TX_EXIT
       
   194 }
       
   195 
       
   196 /*!
       
   197  Deactivates the media wall view.
       
   198  */
       
   199 void MpMediaWallView::deactivateView()
       
   200 {
       
   201     TX_ENTRY
       
   202     mActivated = false;
       
   203     dismissListClosingAnimation();
       
   204     TX_EXIT
       
   205 }
       
   206 
       
   207 /*!
       
   208  Slot to be called when the context is opened.
       
   209  */
       
   210 void MpMediaWallView::contextOpened( TCollectionContext context )
       
   211 {
       
   212     if ( context != ECollectionContextAlbumsMediaWall ) {
       
   213         //Force the context to Albums Media Wall, this to get the model and 
       
   214         //data to provide the right funtionality to media wall.
       
   215         mCollectionData->setContext( ECollectionContextAlbumsMediaWall );
       
   216         return;
       
   217     }
       
   218     if ( mCollectionData->count() ) {
       
   219         if (mNoMusic) {
       
   220             delete mNoMusic;
       
   221             mNoMusic = 0;
       
   222         }
       
   223         if ( mMediaWallWidget ) {
       
   224             mModel->refreshModel();
       
   225         } else {
       
   226             bool ok = false;
       
   227             mDocumentLoader->load( MUSIC_MEDIAWALL_DOCML, "mediaWall", &ok);
       
   228             if ( ok ) {
       
   229                 QGraphicsWidget *widget;
       
   230                 widget = mDocumentLoader->findWidget(QString("mediaWallWidget"));
       
   231                 mMediaWallWidget = qobject_cast<HgMediawall*>(widget);
       
   232                 mModel->refreshModel();
       
   233                 setUpMediaWallWidget();
       
   234             }
       
   235             else {
       
   236                 TX_LOG_ARGS("Error: invalid xml file.");
       
   237                 Q_ASSERT_X(ok, "MpMediaWallView::contextOpened", "invalid xml file");
       
   238 
       
   239             }          
       
   240         }
       
   241     }
       
   242     else {
       
   243         if ( mMediaWallWidget ) {
       
   244             delete mMediaWallWidget;
       
   245             mMediaWallWidget = 0;
       
   246             
       
   247         }
       
   248         if ( !mNoMusic ) {
       
   249             bool ok = false;
       
   250             mDocumentLoader->load( MUSIC_MEDIAWALL_DOCML, "empty", &ok);
       
   251             if ( ok ) {
       
   252                 QGraphicsWidget *widget;
       
   253                 widget = mDocumentLoader->findWidget(QString("noMusic"));
       
   254                 mNoMusic = qobject_cast<HbLabel*>(widget);
       
   255             }
       
   256             else {
       
   257                 TX_LOG_ARGS("Error: invalid xml file.");
       
   258                 Q_ASSERT_X(ok, "MpMediaWallView::contextOpened", "invalid xml file");
       
   259 
       
   260             }
       
   261         }
       
   262     }
       
   263 }
       
   264 
       
   265 /*!
       
   266  Slot to be called when the container contents changed.
       
   267  */
       
   268 void MpMediaWallView::containerContentsChanged() 
       
   269 {
       
   270     if ( !mLibraryUpdating && mEngine ) {
       
   271         mEngine->openCollection( ECollectionContextAlbumsMediaWall );
       
   272     }
       
   273 }
       
   274 
       
   275 /*!
       
   276  Slot to be called when the container contents changed.
       
   277  */
       
   278 void MpMediaWallView::libraryAboutToUpdate()
       
   279 {
       
   280     mLibraryUpdating = true;
       
   281 }
       
   282 
       
   283 /*!
       
   284  Slot to be called when the container contents changed.
       
   285  */
       
   286 void MpMediaWallView::libraryUpdated()
       
   287 {
       
   288     mLibraryUpdating = false;
       
   289     if ( mEngine ) {
       
   290         mEngine->openCollection( ECollectionContextAlbumsMediaWall );
       
   291     }
       
   292 }
       
   293 
       
   294 /*!
       
   295  Slot to be called to send to background.
       
   296  */
       
   297 void MpMediaWallView::sendToBackground()
       
   298 {
       
   299     TX_ENTRY
       
   300     emit command( MpCommon::SendToBackground );
       
   301     TX_EXIT
       
   302 }
       
   303 
       
   304 /*!
       
   305  Slot to update teh play pause action icon.
       
   306  */
       
   307 void MpMediaWallView::updatePlayPauseAction()
       
   308 {
       
   309     if ( !mActivated ) {
       
   310         mIconUpdateNedded = true;
       
   311         return;
       
   312     }
       
   313     TX_ENTRY
       
   314     switch ( mPlaybackData->playbackState() ) {
       
   315         case MpPlaybackData::Playing:
       
   316             TX_LOG_ARGS( "MpPlaybackData::Playing" )
       
   317             mPlayPauseAction->setIcon( *mPauseIcon );
       
   318             mPlayPauseContainer->show();
       
   319             break;
       
   320         case MpPlaybackData::Paused:
       
   321         case MpPlaybackData::Stopped:
       
   322             TX_LOG_ARGS( "MpPlaybackData::Paused" )
       
   323             mPlayPauseAction->setIcon( *mPlayIcon );
       
   324             mPlayPauseContainer->show();
       
   325             break;
       
   326         case MpPlaybackData::NotPlaying:
       
   327             mPlayPauseContainer->hide();       
       
   328             break;
       
   329         default:
       
   330             break;
       
   331     }
       
   332     TX_EXIT
       
   333 }
       
   334 
       
   335 /*!
       
   336  Slot called to start the album and list opening animation.
       
   337  */
       
   338 void MpMediaWallView::showTrackList()
       
   339 {
       
   340     if( mShowingSongsList ) {
       
   341         return;
       
   342     }
       
   343     mShowingSongsList = true;
       
   344     setUpListAnimation();
       
   345     mListShowAnimationGroup->setDirection(QAbstractAnimation::Forward);
       
   346     mListShowAnimationGroup->start();
       
   347 }
       
   348 
       
   349 /*!
       
   350  Slot to be called to starts the album and list closing animation.
       
   351  */
       
   352 void MpMediaWallView::hideTracksList()
       
   353 {
       
   354     mListShowAnimationGroup->setDirection(QAbstractAnimation::Backward);
       
   355     connect(mListShowAnimationGroup, SIGNAL(finished()), this, SLOT(dismissListClosingAnimation()));
       
   356     mListShowAnimationGroup->start();
       
   357 }
       
   358 
       
   359 /*!
       
   360  Slot to be called when list closing animation is done or when we want to cancel the animation.
       
   361  */
       
   362 void MpMediaWallView::dismissListClosingAnimation()
       
   363 {
       
   364     if ( !mShowingSongsList ) {
       
   365         return;
       
   366     }
       
   367     mShowingSongsList = false;
       
   368     mAlbumCover->hide();
       
   369     mTrackList->hide();
       
   370     mListShowAnimationGroup->stop();
       
   371     disconnect(mListShowAnimationGroup, SIGNAL(finished()), this, SLOT(dismissListClosingAnimation()));
       
   372 }
       
   373 
       
   374 /*!
       
   375  Slot to be called when a list item is selected by the user.
       
   376  */
       
   377 void MpMediaWallView::listItemActivated( const QModelIndex &index )
       
   378 {
       
   379     int albumIndex = mMediaWallWidget->currentIndex().row();
       
   380     //We are playing on the shared engine, but we pass the collection data that
       
   381     //points to albums on media wall, this is used to construct the playlist.
       
   382     MpEngineFactory::sharedEngine()->playAlbumSongs( albumIndex, index.row(), mCollectionData );
       
   383 }
       
   384 
       
   385 /*!
       
   386  Loads the media wall widget.
       
   387  */
       
   388 void MpMediaWallView::setUpMediaWallWidget()
       
   389 {
       
   390     HbIcon defaultIcon( "qtg_large_music_album" );
       
   391     defaultIcon.setSize(mMediaWallWidget->itemSize());
       
   392     mMediaWallWidget->setDefaultImage( defaultIcon.pixmap().toImage() );
       
   393     mMediaWallWidget->enableReflections( false );
       
   394     mMediaWallWidget->setModel( mModel );
       
   395     if ( mPlaybackData->playbackState() != MpPlaybackData::NotPlaying ) {
       
   396         scrollToNowPlaying();
       
   397     }
       
   398     //The rest of the cases are attepting to balance the items on screen.
       
   399     else if ( mModel->rowCount() >= 5 ) {
       
   400         /* 5 and more
       
   401         [0] [1] [X] [3] [4]...
       
   402         */
       
   403         QModelIndex index;
       
   404         index = mModel->index( 2 );
       
   405         mMediaWallWidget->scrollTo( index );
       
   406     }
       
   407     else if ( mModel->rowCount() >=3  ) {
       
   408         /* 4 and 3
       
   409         __ [0] [X] [2] [3]
       
   410         __ [0] [X] [2] __
       
   411         */
       
   412         QModelIndex index;
       
   413         index = mModel->index( 1 );
       
   414         mMediaWallWidget->scrollTo( index );
       
   415     }
       
   416     else {
       
   417         /* 2 and 1
       
   418         __ __ [X] [1] __
       
   419         __ __ [X] __ __
       
   420         */
       
   421         QModelIndex index;
       
   422         index = mModel->index( 0 );
       
   423         mMediaWallWidget->scrollTo( index );
       
   424     }
       
   425     mMediaWallWidget->setTitleFontSpec( HbFontSpec( HbFontSpec::Primary ) );
       
   426     mMediaWallWidget->setDescriptionFontSpec( HbFontSpec( HbFontSpec::Secondary ) );
       
   427     mMediaWallWidget->setScrollBarPolicy( HgWidget::ScrollBarAlwaysOn ); //HgWidget::ScrollBarAutoHide
       
   428     mMediaWallWidget->scrollBar()->setInteractive( true );
       
   429     mMediaWallWidget->setIndexFeedbackPolicy( HgWidget::IndexFeedbackSingleCharacter );
       
   430     connect(mMediaWallWidget, SIGNAL(activated(QModelIndex)), SLOT(showTrackList()));
       
   431     connect(mMediaWallWidget, SIGNAL(scrollingStarted()), SLOT(dismissListClosingAnimation()));
       
   432 }
       
   433 
       
   434 /*!
       
   435  Scrolls the media wall to now playing position.
       
   436  */
       
   437 void MpMediaWallView::scrollToNowPlaying()
       
   438 {
       
   439     if ( mMediaWallWidget  && mPlaybackData->playbackState() != MpPlaybackData::NotPlaying ) {
       
   440         int albumId = mPlaybackData->albumId();
       
   441         QModelIndex index;
       
   442         index = mModel->index( mCollectionData->itemIndex( albumId ) );
       
   443         mMediaWallWidget->scrollTo( index );
       
   444     }
       
   445 }
       
   446 
       
   447 /*!
       
   448  Sets up the album and list animation.
       
   449  */
       
   450 void MpMediaWallView::setUpListAnimation()
       
   451 {
       
   452     if ( !mListShowAnimationGroup ) {
       
   453         mListShowAnimationGroup = new QParallelAnimationGroup( this );
       
   454         mCoverShowListAnimation = new QPropertyAnimation(mAlbumCover, "geometry", this );
       
   455         mCoverShowListAnimation->setDuration( 400 );        
       
   456         mCoverShowListAnimation->setEasingCurve(QEasingCurve::InOutCubic);
       
   457         mListShowAnimationGroup->addAnimation(mCoverShowListAnimation);
       
   458         mListShowListAnimation = new QPropertyAnimation( mTrackList, "geometry", this );
       
   459         mListShowListAnimation->setDuration( 400 );
       
   460         mListShowListAnimation->setEasingCurve(QEasingCurve::InOutCubic);
       
   461         mListShowAnimationGroup->addAnimation(mListShowListAnimation);
       
   462         //track list goes on top of media wall.
       
   463         mTrackList->setZValue(mMediaWallWidget->zValue()+1);
       
   464         //album cover goes on top of track list.
       
   465         mAlbumCover->setZValue(mMediaWallWidget->zValue()+2);
       
   466     }
       
   467     
       
   468     //Get the current album cover geometry.
       
   469     QPolygonF poly;
       
   470     QModelIndex index = mMediaWallWidget->currentIndex();
       
   471     if ( !mMediaWallWidget->getItemOutline( index, poly ) ) {
       
   472         return;
       
   473     }
       
   474     QRectF itemRect = poly.boundingRect();
       
   475 
       
   476     //Request the albums tracks, they are set to the track list model.
       
   477     if ( !mCollectionData->setCurrentAlbum( index.row() ) ) {
       
   478         mEngine->findAlbumSongs( index.row() );
       
   479     }
       
   480     
       
   481     //Get the album cover icon.
       
   482     QVariant image = mModel->data(index, Qt::DecorationRole);
       
   483     if ( image.canConvert<HbIcon>() ) {
       
   484        mAlbumCover->setIcon(image.value<HbIcon>());
       
   485     }
       
   486     else {
       
   487         mAlbumCover->setIcon(HbIcon());
       
   488     }
       
   489     
       
   490     //Mapping form local media wall coords to window coors.
       
   491     itemRect.moveTo( mMediaWallWidget->geometry().topLeft() + itemRect.topLeft());   
       
   492     //Calculate start and end position of items for the animation.
       
   493     QRectF endRect = itemRect;
       
   494     endRect.moveTo( endRect.topLeft().x() - endRect.size().width() / 2.0, endRect.topLeft().y() );
       
   495     mCoverShowListAnimation->setStartValue(itemRect);
       
   496     mCoverShowListAnimation->setEndValue(endRect);
       
   497     endRect.moveTo(endRect.topRight() - QPointF(1,0)); //adjust by one pixel to prevent a gap.
       
   498     mListShowListAnimation->setStartValue(itemRect);
       
   499     mListShowListAnimation->setEndValue(endRect);
       
   500     
       
   501     //set initial condition and show to prevent flicker.
       
   502     mAlbumCover->setPos(itemRect.topLeft());
       
   503     mTrackList->setPos(itemRect.topLeft());
       
   504     mTrackList->setGeometry(itemRect);
       
   505     mAlbumCover->show();
       
   506     mTrackList->show();
       
   507 }
       
   508