radioapp/radiowidgets/src/radiostationcarousel.cpp
changeset 13 46974bebc798
child 14 63aabac4416d
equal deleted inserted replaced
0:f3d95d9c00ab 13:46974bebc798
       
     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:
       
    15 *
       
    16 */
       
    17 
       
    18 // System includes
       
    19 #include <qgraphicslinearlayout>
       
    20 #include <hbanchorlayout.h>
       
    21 #include <hbpushbutton.h>
       
    22 #include <qpixmap>
       
    23 #include <QGraphicsSceneMouseEvent>
       
    24 #include <hbeffect>
       
    25 
       
    26 // User includes
       
    27 #include "radiostationcarousel.h"
       
    28 #include "radiouiengine.h"
       
    29 #include "radiostationmodel.h"
       
    30 #include "radiofadinglabel.h"
       
    31 #include "radiologger.h"
       
    32 #include "radiolocalization.h"
       
    33 #include "radiostationfiltermodel.h"
       
    34 #include "radio_global.h"
       
    35 
       
    36 #ifdef USE_LAYOUT_FROM_E_DRIVE
       
    37     const QString KFavoriteIconPath = "e:/radiotest/images/favoriteiconactive.png";
       
    38     const QString KNonFavoriteIconPath = "e:/radiotest/images/favoriteiconinactive.png";
       
    39 #else
       
    40     const QString KFavoriteIconPath = ":/images/favoriteiconactive.png";
       
    41     const QString KNonFavoriteIconPath = ":/images/favoriteiconinactive.png";
       
    42 #endif
       
    43 
       
    44 // =============================================
       
    45 // Station Item
       
    46 // =============================================
       
    47 
       
    48 /*!
       
    49  *
       
    50  */
       
    51 RadioStationItem::RadioStationItem( QGraphicsItem* parent ) :
       
    52     HbAbstractViewItem( parent ),
       
    53     mLayout( 0 ),
       
    54     mNameLabel( 0 ),
       
    55     mIconButton( 0 ),
       
    56     mGenreLabel( 0 ),
       
    57     mRadiotextLabel( 0 )
       
    58 {
       
    59     setFlag( QGraphicsItem::ItemIsFocusable, true );
       
    60 }
       
    61 
       
    62 /*!
       
    63  * From HbAbstractViewItem
       
    64  *
       
    65  */
       
    66 HbAbstractViewItem* RadioStationItem::createItem()
       
    67 {
       
    68     return new RadioStationItem( *this ); // Calls copy constructor
       
    69 }
       
    70 
       
    71 /*!
       
    72  * From HbAbstractViewItem
       
    73  */
       
    74 void RadioStationItem::updateChildItems()
       
    75 {
       
    76     if ( !mLayout )
       
    77     {
       
    78         mNameLabel = new RadioFadingLabel( this );
       
    79         HbFontSpec spec = mNameLabel->fontSpec();
       
    80         spec.setTextPaneHeight( 40 );
       
    81         spec.setRole( HbFontSpec::Primary );
       
    82         mNameLabel->setFontSpec( spec );
       
    83         mNameLabel->setAlignment( Qt::AlignLeft );
       
    84 
       
    85         spec.setRole( HbFontSpec::Secondary );
       
    86         spec.setPointSize( 6 );
       
    87 
       
    88         mIconButton = new HbPushButton( this );
       
    89         QPixmap background( QSize( 50, 50 ) );
       
    90         background.fill( Qt::transparent );        
       
    91         mIconButton->setBackground( HbIcon( background ) );
       
    92         HbIcon favoriteIcon( KFavoriteIconPath );
       
    93         mIconButton->setOrientation( Qt::Horizontal );
       
    94         mIconButton->setIcon( favoriteIcon );
       
    95         mIconButton->setPreferredSize( 50, 50 );
       
    96         connectAndTest( mIconButton, SIGNAL(clicked()), this, SLOT(toggleFavorite()));
       
    97 
       
    98         mGenreLabel = new RadioFadingLabel( this );
       
    99         mGenreLabel->setAlignment( Qt::AlignCenter );
       
   100 //        mGenreLabel->setFadingEnabled( true );    TODO
       
   101         mGenreLabel->setFontSpec( spec );
       
   102         mGenreLabel->setTextColor( Qt::white );
       
   103 
       
   104         mRadiotextLabel = new RadioFadingLabel( this );
       
   105         mRadiotextLabel->setAlignment( Qt::AlignCenter );
       
   106         mRadiotextLabel->setTextWrapping( Hb::TextWordWrap );
       
   107 //        mRadiotextLabel->setFadingEnabled( true );    TODO
       
   108         mRadiotextLabel->setFontSpec( spec );
       
   109         mRadiotextLabel->setTextColor( Qt::white );
       
   110 
       
   111         mLayout = new HbAnchorLayout();
       
   112 
       
   113         mLayout->setAnchor( mLayout, Hb::TopEdge, mIconButton, Hb::TopEdge, 40.0 );
       
   114         mLayout->setAnchor( mLayout, Hb::LeftEdge, mIconButton, Hb::LeftEdge, 20.0 );
       
   115 
       
   116         mLayout->setAnchor( mLayout, Hb::TopEdge, mNameLabel, Hb::TopEdge, 40.0 );
       
   117         mLayout->setAnchor( mIconButton, Hb::RightEdge, mNameLabel, Hb::LeftEdge, 10.0 );
       
   118         mLayout->setAnchor( mLayout, Hb::RightEdge, mNameLabel, Hb::RightEdge, 10.0 );
       
   119 
       
   120         mLayout->setAnchor( mNameLabel, Hb::BottomEdge, mGenreLabel, Hb::TopEdge, 0.0 );
       
   121 
       
   122         mLayout->setAnchor( mLayout, Hb::LeftEdge, mGenreLabel, Hb::LeftEdge, 10.0 );
       
   123         mLayout->setAnchor( mLayout, Hb::CenterHEdge, mGenreLabel, Hb::CenterHEdge, 0.0 );
       
   124 
       
   125         mLayout->setAnchor( mGenreLabel, Hb::BottomEdge, mRadiotextLabel, Hb::TopEdge, 0.0 );
       
   126         mLayout->setAnchor( mLayout, Hb::LeftEdge, mRadiotextLabel, Hb::LeftEdge, 10.0 );
       
   127         mLayout->setAnchor( mLayout, Hb::CenterHEdge, mRadiotextLabel, Hb::CenterHEdge, 0.0 );
       
   128         mLayout->setAnchor( mLayout, Hb::BottomEdge, mRadiotextLabel, Hb::BottomEdge, -20.0 );
       
   129 
       
   130         setLayout( mLayout );
       
   131     }
       
   132 
       
   133     update();
       
   134 }
       
   135 
       
   136 /*!
       
   137  * Private slot
       
   138  *
       
   139  */
       
   140 void RadioStationItem::toggleFavorite()
       
   141 {
       
   142     carousel()->uiEngine().model().setData( modelIndex(), mFrequency, RadioStationModel::ToggleFavoriteRole );
       
   143 }
       
   144 
       
   145 /*!
       
   146  *
       
   147  */
       
   148 uint RadioStationItem::frequency() const
       
   149 {
       
   150     return mFrequency;
       
   151 }
       
   152 
       
   153 /*!
       
   154  *
       
   155  */
       
   156 void RadioStationItem::update( const RadioStation* station )
       
   157 {
       
   158     QModelIndex index = modelIndex();
       
   159     if ( !( station && station->isValid() ) && !index.isValid() )
       
   160         {
       
   161         return;
       
   162         }
       
   163 
       
   164     RadioStation tempStation = ( station && station->isValid() ) ? *station
       
   165                     : index.data( RadioStationModel::RadioStationRole ).value<RadioStation>();
       
   166 
       
   167     mNameLabel->setTextWithoutFading( RadioUiEngine::nameOrFrequency( tempStation ) );
       
   168     QString dynamicPs = tempStation.dynamicPsText();
       
   169     mGenreLabel->setText( dynamicPs.isEmpty() ? carousel()->uiEngine().genreToString( tempStation.genre() ) : dynamicPs );
       
   170     mRadiotextLabel->setText( carousel()->isAntennaAttached() ? tempStation.radioText() : TRANSLATE(KConnectHeadsetAntenna) );
       
   171     mFrequency = tempStation.frequency();
       
   172 
       
   173     updateFavoriteIcon( tempStation.isFavorite() );
       
   174 }
       
   175 
       
   176 /*!
       
   177  *
       
   178  */
       
   179 void RadioStationItem::setFrequency( uint frequency )
       
   180 {
       
   181     LOG_FORMAT( "RadioStationItem::setFrequency: %u", frequency );
       
   182     mNameLabel->setTextWithoutFading( RadioUiEngine::parseFrequency( frequency ) );
       
   183     mGenreLabel->setTextWithoutFading( "" );
       
   184     mRadiotextLabel->setTextWithoutFading( carousel()->isAntennaAttached() ? "" : TRANSLATE(KConnectHeadsetAntenna) );
       
   185     mFrequency = frequency;
       
   186     updateFavoriteIcon( false );
       
   187 }
       
   188 
       
   189 /*!
       
   190  *
       
   191  */
       
   192 void RadioStationItem::setSeekingText()
       
   193 {
       
   194     mNameLabel->setTextWithoutFading( TRANSLATE( KHeadingSeeking ) );
       
   195     mGenreLabel->setTextWithoutFading( "" );
       
   196     mRadiotextLabel->setTextWithoutFading( "" );
       
   197 }
       
   198 
       
   199 /*!
       
   200  *
       
   201  */
       
   202 void RadioStationItem::updateFavoriteIcon( bool isFavorite )
       
   203 {
       
   204 //    mIconButton->setOpacity( isFavorite ? 1.0 : 0.5 );
       
   205     mIconButton->setIcon( isFavorite ? KFavoriteIconPath : KNonFavoriteIconPath );
       
   206 }
       
   207 
       
   208 /*!
       
   209  *
       
   210  */
       
   211 RadioStationCarousel* RadioStationItem::carousel()
       
   212 {
       
   213     return static_cast<RadioStationCarousel*>( itemView() );
       
   214 }
       
   215 
       
   216 // =============================================
       
   217 // Station Carousel
       
   218 // =============================================
       
   219 
       
   220 /*!
       
   221  *
       
   222  */
       
   223 RadioStationCarousel::RadioStationCarousel( RadioUiEngine& uiEngine, QGraphicsItem* parent ) :
       
   224     HbGridView( parent ),
       
   225     mUiEngine( uiEngine ),
       
   226     mAntennaAttached( false ),
       
   227     mAutoScrollTime( 1000 ),
       
   228     mPreviousButtonPos( 0.0 ),
       
   229     mMovingLeft( false ),
       
   230     mCurrentItem( 0 )
       
   231 {
       
   232     mAntennaAttached = mUiEngine.isAntennaAttached();
       
   233 
       
   234     setScrollDirections( Qt::Horizontal );
       
   235     setFrictionEnabled( true );
       
   236     setRowCount( 1 );
       
   237     setColumnCount( 1 );
       
   238     setClampingStyle( HbScrollArea::BounceBackClamping );
       
   239     setScrollingStyle( HbScrollArea::PanOrFlick );
       
   240     setLongPressEnabled( false );
       
   241     setItemRecycling( false ); // TODO: Enable recycling
       
   242     setUniformItemSizes( true );
       
   243     setItemPrototype( new RadioStationItem( this ) );
       
   244     setSelectionMode( SingleSelection );
       
   245 
       
   246     RadioStationFilterModel* filterModel = mUiEngine.createNewFilterModel( this );
       
   247     filterModel->setCyclic( false );
       
   248 
       
   249     setModel( filterModel );
       
   250     mCurrentItem = static_cast<RadioStationItem*>( itemByIndex( model()->index( 0, 0 ) ) );
       
   251 
       
   252     updateFrequencies();
       
   253 
       
   254     connectAndTest( model(),        SIGNAL(rowsInserted(QModelIndex,int,int)),
       
   255                     this,           SLOT(insertFrequency(QModelIndex,int,int)) );
       
   256     connectAndTest( model(),        SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
       
   257                     this,           SLOT(removeFrequency(QModelIndex,int,int)) );
       
   258 //    connectAndTest( model(),        SIGNAL(layoutChanged()),
       
   259 //                    this,           SLOT(updateFrequencies()) );
       
   260     connectAndTest( this,           SIGNAL(scrollingEnded()),
       
   261                     this,           SLOT(updateLoopedPos()) );
       
   262 
       
   263     RadioStationModel* stationModel = &mUiEngine.model();
       
   264     connectAndTest( stationModel,   SIGNAL(favoriteChanged(RadioStation)),
       
   265                     this,           SLOT(update(RadioStation)) );
       
   266     connectAndTest( stationModel,   SIGNAL(stationDataChanged(RadioStation)),
       
   267                     this,           SLOT(update(RadioStation)));
       
   268     connectAndTest( stationModel,   SIGNAL(radioTextReceived(RadioStation)),
       
   269                     this,           SLOT(update(RadioStation)));
       
   270     connectAndTest( stationModel,   SIGNAL(dynamicPsChanged(RadioStation)),
       
   271                     this,           SLOT(update(RadioStation)));
       
   272 }
       
   273 
       
   274 /*!
       
   275  * Property
       
   276  *
       
   277  */
       
   278 void RadioStationCarousel::setBackground( const HbIcon& background )
       
   279 {
       
   280     mBackground = background;
       
   281 }
       
   282 
       
   283 /*!
       
   284  * Property
       
   285  *
       
   286  */
       
   287 HbIcon RadioStationCarousel::background() const
       
   288 {
       
   289     return mBackground;
       
   290 }
       
   291 
       
   292 /*!
       
   293  *
       
   294  */
       
   295 RadioUiEngine& RadioStationCarousel::uiEngine()
       
   296 {
       
   297     return mUiEngine;
       
   298 }
       
   299 
       
   300 /*!
       
   301  *
       
   302  */
       
   303 bool RadioStationCarousel::isAntennaAttached() const
       
   304 {
       
   305     return mAntennaAttached;
       
   306 }
       
   307 
       
   308 /*!
       
   309  * Private slot
       
   310  */
       
   311 void RadioStationCarousel::update( const RadioStation& station )
       
   312 {
       
   313     RadioStationItem* item = currentStationItem();
       
   314     if ( item && item->frequency() == station.frequency() ) {
       
   315         item->update( &station );
       
   316     }
       
   317 }
       
   318 
       
   319 /*!
       
   320  * Private slot
       
   321  */
       
   322 void RadioStationCarousel::leftGesture( int speedPixelsPerSecond )
       
   323 {
       
   324     Q_UNUSED( speedPixelsPerSecond );
       
   325     QModelIndex index = currentIndex();
       
   326 
       
   327     if ( index == model()->index( model()->rowCount() - 1, 0 ) ) {
       
   328         index = model()->index( 0, 0 );
       
   329     } else {
       
   330         index = nextIndex( index );
       
   331     }
       
   332 
       
   333     scrollToIndex( index, mAutoScrollTime );
       
   334 }
       
   335 
       
   336 /*!
       
   337  * Private slot
       
   338  */
       
   339 void RadioStationCarousel::rightGesture( int speedPixelsPerSecond )
       
   340 {
       
   341     Q_UNUSED( speedPixelsPerSecond );
       
   342     QModelIndex index = currentIndex();
       
   343 
       
   344     if ( index == model()->index( 0, 0 ) ) {
       
   345         index = model()->index( model()->rowCount() - 1, 0 );
       
   346     } else {
       
   347         index = previousIndex( index );
       
   348     }
       
   349 
       
   350     scrollToIndex( index, mAutoScrollTime );
       
   351 }
       
   352 
       
   353 /*!
       
   354  * Private slot
       
   355  */
       
   356 void RadioStationCarousel::insertFrequency( const QModelIndex& parent, int first, int last )
       
   357 {
       
   358     Q_UNUSED( parent );
       
   359     QAbstractItemModel* freqModel = model();
       
   360     for ( int i = first; i <= last; ++i ) {
       
   361         QModelIndex index = freqModel->index( i, 0 );
       
   362         RadioStation station = freqModel->data( index, RadioStationModel::RadioStationRole ).value<RadioStation>();
       
   363         mModelIndexes.insert( station.frequency(), index );
       
   364         LOG_FORMAT( "Added frequency %u", station.frequency() );
       
   365         scrollToIndex( index, 0 );
       
   366     }
       
   367 }
       
   368 
       
   369 /*!
       
   370  * Private slot
       
   371  */
       
   372 void RadioStationCarousel::removeFrequency( const QModelIndex& parent, int first, int last )
       
   373 {
       
   374     Q_UNUSED( parent );
       
   375     QAbstractItemModel* freqModel = model();
       
   376     for ( int i = first; i <= last; ++i ) {
       
   377         QModelIndex index = freqModel->index( i, 0 );
       
   378         RadioStation station = freqModel->data( index, RadioStationModel::RadioStationRole ).value<RadioStation>();
       
   379         mModelIndexes.remove( station.frequency() );
       
   380     }
       
   381 }
       
   382 
       
   383 /*!
       
   384  * Private slot
       
   385  */
       
   386 void RadioStationCarousel::updateFrequencies()
       
   387 {
       
   388     mModelIndexes.clear();
       
   389     QAbstractItemModel* itemModel = model();
       
   390     const int count = itemModel->rowCount();
       
   391     for ( int i = 0; i < count; ++i ) {
       
   392         QModelIndex index = itemModel->index( i, 0 );
       
   393         uint frequency = itemModel->data( index, RadioStationModel::RadioStationRole ).value<RadioStation>().frequency();
       
   394         mModelIndexes.insert( frequency, index );
       
   395     }
       
   396 }
       
   397 
       
   398 /*!
       
   399  * Private slot
       
   400  */
       
   401 void RadioStationCarousel::updateLoopedPos()
       
   402 {
       
   403     const int row = currentIndex().row();
       
   404     if ( filterModel()->hasLooped( currentIndex() ) ) {
       
   405         QModelIndex realIndex = filterModel()->realIndex( currentIndex() );
       
   406         scrollTo( realIndex );
       
   407         setCurrentIndex( realIndex, QItemSelectionModel::SelectCurrent );
       
   408 //        scrollToIndex( realIndex , 0 );
       
   409         LOG_FORMAT( "Index %d has looped. real index is %d", row, realIndex.row() );
       
   410     }
       
   411 }
       
   412 
       
   413 /*!
       
   414  * Public slot
       
   415  *
       
   416  */
       
   417 void RadioStationCarousel::setFrequency( uint frequency )
       
   418 {
       
   419     RadioStationItem* item = currentStationItem();
       
   420     if ( item && item->mFrequency == frequency ) {
       
   421         return;
       
   422     }
       
   423 /*
       
   424     QModelIndex index = static_cast<RadioStationFilterModel*>( model() )->modelIndexFromFrequency( frequency );
       
   425     if ( index.isValid() ) {
       
   426         scrollToIndex( index, 0 );
       
   427     } else {
       
   428         if ( item ) {
       
   429             item->setFrequency( frequency );
       
   430         }
       
   431     }
       
   432     */
       
   433 /*
       
   434 
       
   435 
       
   436     QAbstractItemModel* itemModel = model();
       
   437     const int count = itemModel->rowCount();
       
   438     for ( int i = 0; i < count; ++i ) {
       
   439         QModelIndex index = itemModel->index( i, 0 );
       
   440         uint stationFrequency = itemModel->data( index, RadioStationModel::RadioStationRole ).value<RadioStation>().frequency();
       
   441         if ( frequency == stationFrequency ) {
       
   442             scrollToIndex( index, mAutoScrollTime );
       
   443             return;
       
   444         }
       
   445     }
       
   446  */
       
   447 
       
   448     if ( mModelIndexes.contains( frequency ) ) {
       
   449         QModelIndex index = mModelIndexes.value( frequency );
       
   450         scrollToIndex( index, 0 );
       
   451     } else {
       
   452         if ( item ) {
       
   453             item->setFrequency( frequency );
       
   454         }
       
   455     }
       
   456 }
       
   457 
       
   458 /*!
       
   459  * Public slot
       
   460  *
       
   461  */
       
   462 void RadioStationCarousel::setSeekingText()
       
   463 {
       
   464     RadioStationItem* item = currentStationItem();
       
   465     if ( item ) {
       
   466         item->setSeekingText();
       
   467     }
       
   468 }
       
   469 
       
   470 /*!
       
   471  * Public slot
       
   472  */
       
   473 void RadioStationCarousel::updateHeadsetStatus( bool connected )
       
   474 {
       
   475     mAntennaAttached = connected;
       
   476     RadioStationItem* item = currentStationItem();
       
   477     if ( item  ) {
       
   478         item->update();
       
   479     }
       
   480 }
       
   481 
       
   482 /*!
       
   483  * \reimp
       
   484  *
       
   485  */
       
   486 void RadioStationCarousel::paint( QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget )
       
   487 {
       
   488     mBackground.paint( painter, QRectF( QPoint( 0, 0 ), size() ), Qt::IgnoreAspectRatio );
       
   489     HbGridView::paint( painter, option, widget );
       
   490 }
       
   491 
       
   492 /*!
       
   493  * \reimp
       
   494  */
       
   495 void RadioStationCarousel::mouseMoveEvent( QGraphicsSceneMouseEvent* event )
       
   496 {
       
   497     HbGridView::mouseMoveEvent( event );
       
   498 }
       
   499 
       
   500 /*!
       
   501  * \reimp
       
   502  */
       
   503 void RadioStationCarousel::mouseReleaseEvent( QGraphicsSceneMouseEvent* event )
       
   504 {
       
   505     QPointF pos = QPointF( size().width() / 2, size().height() / 2 );
       
   506     HbAbstractViewItem* item = itemAtPosition( pos );
       
   507     if ( item ) {
       
   508         scrollToIndex( item->modelIndex(), mAutoScrollTime );
       
   509     }
       
   510 
       
   511     HbGridView::mouseReleaseEvent( event );
       
   512 }
       
   513 
       
   514 /*!
       
   515  * \reimp
       
   516  */
       
   517 void RadioStationCarousel::resizeEvent( QGraphicsSceneResizeEvent* event )
       
   518 {
       
   519     HbGridView::resizeEvent( event );
       
   520     QModelIndex index = filterModel()->modelIndexFromFrequency( mUiEngine.currentFrequency() );
       
   521     setCurrentIndex( index, QItemSelectionModel::SelectCurrent );
       
   522     scrollTo( index );
       
   523 }
       
   524 
       
   525 /*!
       
   526  *
       
   527  */
       
   528 RadioStationItem* RadioStationCarousel::currentStationItem()
       
   529 {
       
   530     return static_cast<RadioStationItem*>( currentViewItem() );
       
   531 //    return mCurrentItem;
       
   532 }
       
   533 
       
   534 /*!
       
   535  *
       
   536  */
       
   537 RadioStationFilterModel* RadioStationCarousel::filterModel() const
       
   538 {
       
   539     return static_cast<RadioStationFilterModel*>( model() );
       
   540 }
       
   541 
       
   542 /*!
       
   543  *
       
   544  */
       
   545 void RadioStationCarousel::scrollToIndex( const QModelIndex& index, int time )
       
   546 {
       
   547     RadioStationItem* item = static_cast<RadioStationItem*>( itemByIndex( index ) );
       
   548     if ( index.isValid() && item ) {
       
   549         int posX = item->pos().x();
       
   550         const int currentRow = currentIndex().row();
       
   551         const int nextRow = index.row();
       
   552         if ( currentRow != nextRow ) {
       
   553             LOG_FORMAT( "Current row is %d, scrolling to row %d", currentRow, nextRow);
       
   554         }
       
   555         if ( !filterModel()->isEqual( currentIndex(), index ) ) {
       
   556             setCurrentIndex( index, QItemSelectionModel::SelectCurrent );
       
   557             mCurrentItem = static_cast<RadioStationItem*>( item );
       
   558             emit frequencyChanged( static_cast<RadioStationItem*>( item )->frequency(), CommandSender::StationCarousel );
       
   559         }
       
   560         scrollContentsTo( QPointF( posX, 0 ) , time );
       
   561     }
       
   562 }