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