radioapp/radiowidgets/src/radiofrequencystrip.cpp
branchGCC_SURGE
changeset 37 451b2e1545b2
parent 19 afea38384506
parent 33 11b6825f0862
equal deleted inserted replaced
26:6bcf277166c1 37:451b2e1545b2
    23 #include <HbPushButton>
    23 #include <HbPushButton>
    24 #include <QTimer>
    24 #include <QTimer>
    25 #include <HbColorScheme>
    25 #include <HbColorScheme>
    26 #include <HbEvent>
    26 #include <HbEvent>
    27 #include <HbSwipeGesture>
    27 #include <HbSwipeGesture>
       
    28 #include <HbDeviceProfile>
    28 
    29 
    29 #include "radiofrequencystrip.h"
    30 #include "radiofrequencystrip.h"
    30 #include "radiofrequencyitem.h"
    31 #include "radiofrequencyitem.h"
    31 #include "radiouiengine.h"
    32 #include "radiouiengine.h"
    32 #include "radiostation.h"
    33 #include "radiostation.h"
    33 #include "radiostationmodel.h"
    34 #include "radiostationmodel.h"
    34 #include "radiouiutilities.h"
    35 #include "radioutil.h"
       
    36 #include "radiouiloader.h"
    35 #include "radiologger.h"
    37 #include "radiologger.h"
    36 
    38 
    37 // Frequency lines
    39 // Frequency lines
    38 const int KTabHeightSmall = 10;
    40 const int TAB_HEIGHT_SMALL = 12;
    39 const int KTabHeightBig = 15;
    41 const int TAB_HEIGHT_BIG = 18;
    40 const int KTabWidthFavorite = 4;
    42 const int PEN_WIDTH_FAVORITE = 4;
    41 const qreal KIndicatorWidth = 2.0;
    43 const qreal INDICATOR_WIDTH = 2.0;
    42 
    44 
    43 const qreal KRounder = 0.5;
    45 const qreal ROUNDER = 0.5;
    44 const int KSelectorWidth = 2;
    46 const int SELECTOR_WIDTH = 2;
    45 const int KSelectorZPos = 100;
    47 const int SELECTOR_Z_POS = 100;
    46 
    48 
    47 const int KHalfHertz = KOneHertz / 2;
    49 const int HALF_HERTZ = ONE_HERTZ / 2;
    48 const int KOneTabDistance = 15;
    50 const int ONE_TAB_DISTANCE = 20;
    49 const uint KOneTabInHz = 0.2 * KOneHertz;
    51 const uint ONE_TAB_IN_HZ = uint( 0.2 * ONE_HERTZ );
    50 const qreal KPixelInHz = KOneTabInHz / KOneTabDistance;
    52 const qreal PIXEL_IN_HZ = ONE_TAB_IN_HZ / ONE_TAB_DISTANCE;
    51 const int KWidth = KOneTabDistance * 5;
    53 const qreal PIXMAP_OVERLAP = qreal( ONE_TAB_DISTANCE ) / 2;
    52 //const int KPixmapWidth = KWidth + KOneTabDistance;
    54 const int ITEM_WIDTH = ONE_TAB_DISTANCE * 5;
    53 const int KHeight = 50;                 //TODO: Remove hardcoding
    55 const int PIXMAP_WIDTH = ITEM_WIDTH + (int)PIXMAP_OVERLAP;
    54 
    56 
    55 const int K100Khz = 100000;
    57 const uint ONE_HUNDRED_KHZ = 100000;
    56 
    58 
    57 const char* KSlideToLeft        = "SlideToLeft";
    59 const char* DECIMAL_TEXT = ".0";
    58 const char* KSlideFromLeft      = "SlideFromLeft";
    60 
    59 const char* KSlideToRight       = "SlideToRight";
    61 #ifdef BUILD_WIN32
    60 const char* KSlideFromRight     = "SlideFromRight";
    62     const int FREQUENCY_FONT_SIZE = 12;
       
    63     const int DECIMAL_FONT_SIZE = 8;
       
    64 #else
       
    65     const int FREQUENCY_FONT_SIZE = 6;
       
    66     const int DECIMAL_FONT_SIZE = 4;
       
    67 #endif // BUILD_WIN32
       
    68 
       
    69 const QFont FREQUENCY_FONT( "", FREQUENCY_FONT_SIZE );
       
    70 const QFont DECIMAL_FONT( "", DECIMAL_FONT_SIZE );
       
    71 
       
    72 const char* SLIDE_TO_LEFT       = "SlideToLeft";
       
    73 const char* SLIDE_FROM_LEFT     = "SlideFromLeft";
       
    74 const char* SLIDE_TO_RIGHT      = "SlideToRight";
       
    75 const char* SLIDE_FROM_RIGHT    = "SlideFromRight";
    61 const char* LEFT_BUTTON         = "tv:left_button";
    76 const char* LEFT_BUTTON         = "tv:left_button";
    62 const char* RIGHT_BUTTON        = "tv:right_button";
    77 const char* RIGHT_BUTTON        = "tv:right_button";
    63 
    78 
    64 const char* TEXT_COLOR_ATTRIBUTE = "text";
    79 const char* TEXT_COLOR_ATTRIBUTE = "text";
    65 const int BUTTON_HIDE_TIMEOUT = 500;
    80 const int MANUALSEEK_START_TIMEOUT = 400;
    66 const int BUTTON_SHOW_TIMEOUT = 1000;
    81 const int MANUALSEEK_END_TIMEOUT = 2000;
    67 
    82 const int MANUALSEEK_SIGNAL_DELAY = 300;
    68 /*!
       
    69  *
       
    70  */
       
    71 static QLineF makeTab( qreal pos, int height )
       
    72 {
       
    73     return QLineF( pos, KHeight - height, pos, KHeight );
       
    74 }
       
    75 
    83 
    76 /*!
    84 /*!
    77  *
    85  *
    78  */
    86  */
    79 RadioFrequencyStrip::RadioFrequencyStrip() :
    87 RadioFrequencyStrip::RadioFrequencyStrip() :
    80     RadioStripBase(),
    88     RadioStripBase(),
    81     mUiEngine( NULL ),
    89     mUiEngine( NULL ),
       
    90     mItemHeight( 8 ),
    82     mMinFrequency( 87500000 ),
    91     mMinFrequency( 87500000 ),
    83     mMaxFrequency( 108000000 ),
    92     mMaxFrequency( 108000000 ),
    84     mFrequencyStepSize( 100000 ),
    93     mFrequencyStepSize( 100000 ),
    85     mFrequency( 87500000 ),
    94     mFrequency( 87500000 ),
    86     mSelectorImage( new QGraphicsPixmapItem( this ) ),
    95     mSelectorImage( new QGraphicsPixmapItem( this ) ),
    87     mSeparatorPos( 0.0 ),
    96     mSeparatorPos( 0.0 ),
    88     mMaxWidth( 0 ),
    97     mMaxWidth( 0 ),
    89     mSelectorPos( 0.0 ),
    98     mSelectorPos( 0.0 ),
    90     mLeftButton( new HbPushButton( this ) ),
    99     mLeftButton( 0 ),
    91     mRightButton( new HbPushButton( this ) ),
   100     mRightButton( 0 ),
    92     mButtonTimer( NULL ),
   101     mManualSeekTimer( NULL ),
    93     mButtonsVisible( true ),
   102     mManualSeekMode( false ),
    94     mUserIsScrolling( false ),
   103     mLastReportedFrequency( 0 ),
       
   104     mManualSeekTimerId( 0 ),
    95     mForegroundColor( Qt::white )//HbColorScheme::color( TEXT_COLOR_ATTRIBUTE ) )
   105     mForegroundColor( Qt::white )//HbColorScheme::color( TEXT_COLOR_ATTRIBUTE ) )
    96 {
   106 {
    97     RadioUiUtilities::setFrequencyStrip( this );
   107     RadioUtil::setFrequencyStrip( this );
    98 
   108 
    99     setScrollingStyle( HbScrollArea::Pan );
   109     setScrollingStyle( HbScrollArea::PanWithFollowOn );
   100     setItemSize( QSizeF( KWidth, KHeight ) );
   110     setItemSize( QSizeF( ITEM_WIDTH + PIXMAP_OVERLAP / 2, mItemHeight ) );
   101     setFrictionEnabled( true );
   111     setOverlap( PIXMAP_OVERLAP / 2 );
   102 
   112 }
   103     initModel();
   113 
   104 
   114 /*!
   105     initSelector();
   115  * Property
   106 
   116  */
   107     initButtons();
   117 void RadioFrequencyStrip::setItemHeight( int itemHeight )
   108 
   118 {
   109     initEmptyItems();
   119     mItemHeight = itemHeight;
   110 
   120 }
   111     mFrequency = RadioUiEngine::lastTunedFrequency();
   121 
   112     scrollToFrequency( mFrequency, 0 );
   122 /*!
   113 }
   123  * Property
   114 
   124  */
   115 /*!
   125 int RadioFrequencyStrip::itemHeight() const
   116  *
   126 {
   117  */
   127     return mItemHeight;
   118 void RadioFrequencyStrip::setLeftButtonIcon( const HbIcon& leftButtonIcon )
   128 }
   119 {
   129 
   120     mLeftButtonIcon = leftButtonIcon;
   130 /*!
   121     if ( mLeftButton ) {
   131  *
   122         mLeftButtonIcon.setColor( Qt::white );
   132  */
   123         mLeftButton->setIcon( mLeftButtonIcon );
   133 void RadioFrequencyStrip::init( RadioUiEngine* engine, RadioUiLoader& uiLoader )
   124     }
       
   125 }
       
   126 
       
   127 /*!
       
   128  *
       
   129  */
       
   130 HbIcon RadioFrequencyStrip::leftButtonIcon() const
       
   131 {
       
   132     return mLeftButtonIcon;
       
   133 }
       
   134 
       
   135 /*!
       
   136  *
       
   137  */
       
   138 void RadioFrequencyStrip::setRightButtonIcon( const HbIcon& rightButtonIcon )
       
   139 {
       
   140     mRightButtonIcon = rightButtonIcon;
       
   141     if ( mRightButton ) {
       
   142         mRightButtonIcon.setColor( Qt::white );
       
   143         mRightButton->setIcon( mRightButtonIcon );
       
   144     }
       
   145 }
       
   146 
       
   147 /*!
       
   148  *
       
   149  */
       
   150 HbIcon RadioFrequencyStrip::rightButtonIcon() const
       
   151 {
       
   152     return mRightButtonIcon;
       
   153 }
       
   154 
       
   155 /*!
       
   156  *
       
   157  */
       
   158 void RadioFrequencyStrip::init( RadioUiEngine* engine )
       
   159 {
   134 {
   160     mUiEngine = engine;
   135     mUiEngine = engine;
   161     mMinFrequency       = mUiEngine->minFrequency();
   136     mMinFrequency       = mUiEngine->minFrequency();
   162     mMaxFrequency       = mUiEngine->maxFrequency();
   137     mMaxFrequency       = mUiEngine->maxFrequency();
   163     mFrequencyStepSize  = mUiEngine->frequencyStepSize();
   138     mFrequencyStepSize  = mUiEngine->frequencyStepSize();
   164     mFrequency          = mUiEngine->currentFrequency();
   139     mFrequency          = RadioUiEngine::lastTunedFrequency();
   165     scrollToFrequency( mFrequency, 0 );
   140 
   166 
   141     initModel();
   167     mButtonTimer = new QTimer( this );
   142     initEmptyItems();
   168     mButtonTimer->setInterval( BUTTON_HIDE_TIMEOUT );
   143     initPositions();
   169     mButtonTimer->setSingleShot( true );
   144 
   170     connectAndTest( mButtonTimer, SIGNAL(timeout()),
   145     HbDeviceProfile deviceProfile;
   171                     this,         SLOT(toggleButtons()) );
   146     mItemHeight = static_cast<int>( mItemHeight * deviceProfile.unitValue() );
   172 
   147 
   173     connectAndTest( mLeftButton,    SIGNAL(clicked()),
   148     mLeftButton = uiLoader.findWidget<HbPushButton>( DOCML::MV_NAME_PREV_BUTTON );
       
   149     mRightButton = uiLoader.findWidget<HbPushButton>( DOCML::MV_NAME_NEXT_BUTTON );
       
   150     initButtons();
       
   151 
       
   152     mManualSeekTimer = new QTimer( this );
       
   153     mManualSeekTimer->setInterval( MANUALSEEK_START_TIMEOUT );
       
   154     mManualSeekTimer->setSingleShot( true );
       
   155     Radio::connect( mManualSeekTimer,   SIGNAL(timeout()),
       
   156                     this,               SLOT(toggleManualSeek()) );
       
   157 
       
   158     Radio::connect( mLeftButton,    SIGNAL(clicked()),
   174                     this,           SLOT(handleLeftButton()) );
   159                     this,           SLOT(handleLeftButton()) );
   175     connectAndTest( mRightButton,   SIGNAL(clicked()),
   160     Radio::connect( mRightButton,   SIGNAL(clicked()),
   176                     this,           SLOT(handleRightButton()) );
   161                     this,           SLOT(handleRightButton()) );
   177     connectAndTest( mLeftButton,    SIGNAL(longPress(QPointF)),
   162     Radio::connect( mLeftButton,    SIGNAL(longPress(QPointF)),
   178                     this,           SLOT(handleLongLeftButton()) );
   163                     this,           SLOT(handleLongLeftButton()) );
   179     connectAndTest( mRightButton,   SIGNAL(longPress(QPointF)),
   164     Radio::connect( mRightButton,   SIGNAL(longPress(QPointF)),
   180                     this,           SLOT(handleLongRightButton()) );
   165                     this,           SLOT(handleLongRightButton()) );
   181 
   166 
   182     connectAndTest( this,           SIGNAL(scrollingEnded()),
   167     Radio::connect( this,           SIGNAL(scrollingEnded()),
   183                     this,           SLOT(checkIllegalPos()) );
   168                     this,           SLOT(handleScrollingEnd()) );
   184 
   169 
   185     grabGesture( Qt::SwipeGesture );
   170     grabGesture( Qt::SwipeGesture );
   186 
   171 
   187     //TODO: Remove. Stepsize hardcoded to 100 Khz in europe region during demo
   172     //TODO: Remove. Stepsize hardcoded to 100 Khz in europe region during demo
   188     if ( mFrequencyStepSize < K100Khz ) {
   173     if ( mFrequencyStepSize < ONE_HUNDRED_KHZ ) {
   189         mFrequencyStepSize = K100Khz;
   174         mFrequencyStepSize = ONE_HUNDRED_KHZ;
   190     }
   175     }
   191 
   176 
   192     RadioStationModel* stationModel = &mUiEngine->stationModel();
   177     RadioStationModel* stationModel = &mUiEngine->stationModel();
   193     connectAndTest( stationModel,   SIGNAL(rowsInserted(QModelIndex,int,int)),
   178     Radio::connect( stationModel,   SIGNAL(rowsInserted(QModelIndex,int,int)),
   194                     this,           SLOT(updateStation(QModelIndex,int,int)) );
   179                     this,           SLOT(updateStation(QModelIndex,int,int)) );
   195     connectAndTest( stationModel,   SIGNAL(rowsRemoved(QModelIndex,int,int)),
   180     Radio::connect( stationModel,   SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
   196                     this,           SLOT(updateStation(QModelIndex,int,int)) );
   181                     this,           SLOT(removeStation(QModelIndex,int,int)) );
   197     connectAndTest( stationModel,   SIGNAL(modelReset()),
   182     Radio::connect( stationModel,   SIGNAL(modelReset()),
   198                     this,           SLOT(initEmptyItems()) );
   183                     this,           SLOT(initEmptyItems()) );
   199 
   184 
   200     initPositions();
   185     updateAllItems();
   201 
   186 
   202     void updateItems();
   187     showButtons();
   203 }
   188 }
   204 
   189 
   205 /*!
   190 /*!
   206  *
   191  *
   207  */
   192  */
   208 void RadioFrequencyStrip::setFrequency( const uint frequency, int reason )
   193 void RadioFrequencyStrip::setFrequency( const uint frequency, int reason, Scroll::Direction direction )
   209 {
   194 {
       
   195     Q_UNUSED( reason );
   210     LOG_FORMAT( "RadioFrequencyStrip::setFrequency, frequency: %d, reason: %d", frequency, reason );
   196     LOG_FORMAT( "RadioFrequencyStrip::setFrequency, frequency: %d, reason: %d", frequency, reason );
   211     if ( reason != TuneReason::FrequencyStrip &&            // Not sent by the FrequencyStrip
   197     if ( mFrequencies.contains( frequency ) ) {
   212          frequency != mFrequency &&                         // Different from the current
   198         if ( frequency != mFrequency || reason == TuneReason::Skip ) {
   213          mFrequencies.contains( frequency ) )               // 0 frequency means any illegal value
   199             scrollToFrequency( frequency, direction, mAutoScrollTime, RadioUtil::tuneReason( reason ) );
   214     {
       
   215         scrollToFrequency( frequency, mAutoScrollTime );
       
   216         if ( reason != TuneReason::Skip && reason != TuneReason::StationScan ) {
       
   217             emitFrequencyChanged( frequency );
       
   218         }
   200         }
   219     }
   201     }
   220 }
   202 }
   221 
   203 
   222 /*!
   204 /*!
   226 {
   208 {
   227     return mFrequency;
   209     return mFrequency;
   228 }
   210 }
   229 
   211 
   230 /*!
   212 /*!
   231  * Public slot
   213  *
       
   214  */
       
   215 bool RadioFrequencyStrip::isInManualSeekMode() const
       
   216 {
       
   217     return mManualSeekMode;
       
   218 }
       
   219 
       
   220 /*!
       
   221  *
       
   222  */
       
   223 void RadioFrequencyStrip::cancelManualSeek()
       
   224 {
       
   225     mManualSeekTimer->stop();
       
   226     if ( mManualSeekMode ) {
       
   227         toggleManualSeek();
       
   228     }
       
   229 }
       
   230 
       
   231 /*!
       
   232  *
       
   233  */
       
   234 void RadioFrequencyStrip::addScannedStation( const RadioStation& station )
       
   235 {
       
   236     FrequencyPos pos = mFrequencies.value( station.frequency() );
       
   237     updateItem( pos.mItem, station.frequency() );
       
   238 }
       
   239 
       
   240 /*!
   232  *
   241  *
   233  */
   242  */
   234 void RadioFrequencyStrip::updateFavorite( const RadioStation& station )
   243 void RadioFrequencyStrip::updateFavorite( const RadioStation& station )
   235 {
   244 {
   236     LOG_SLOT_CALLER;
   245     LOG_SLOT_CALLER;
   237     FrequencyPos pos = mFrequencies.value( station.frequency() );
   246     FrequencyPos pos = mFrequencies.value( station.frequency() );
   238     updateFavorites( pos.mItem );
   247     updateItem( pos.mItem );
   239 }
   248 }
   240 
   249 
   241 /*!
   250 /*!
   242  * Public slot
   251  * Public slot
   243  *
   252  *
   244  */
   253  */
   245 void RadioFrequencyStrip::setScanningMode( bool isScanning )
   254 void RadioFrequencyStrip::setScanningMode( bool isScanning )
   246 {
   255 {
   247     mButtonTimer->stop();
   256     mManualSeekTimer->stop();
   248     if ( isScanning ) {
   257     if ( isScanning ) {
   249         scrollToFrequency( mMinFrequency, mAutoScrollTime );
   258         initEmptyItems();
   250         hideButtons();
   259         hideButtons();
       
   260         scrollToFrequency( mMinFrequency, Scroll::Shortest, mAutoScrollTime );
   251     } else {
   261     } else {
   252         showButtons();
   262         showButtons();
   253 
       
   254     }
   263     }
   255     setEnabled( !isScanning );
   264     setEnabled( !isScanning );
   256 }
   265 }
   257 
   266 
   258 /*!
   267 /*!
   259  * Private slot
   268  * Private slot
   260  *
   269  *
   261  */
   270  */
       
   271 void RadioFrequencyStrip::removeStation( const QModelIndex& parent, int first, int last )
       
   272 {
       
   273     Q_UNUSED( parent );
       
   274     updateStationsInRange( first, last, true );
       
   275 }
       
   276 
       
   277 /*!
       
   278  * Private slot
       
   279  *
       
   280  */
   262 void RadioFrequencyStrip::updateStation( const QModelIndex& parent, int first, int last )
   281 void RadioFrequencyStrip::updateStation( const QModelIndex& parent, int first, int last )
   263 {
   282 {
   264     Q_UNUSED( parent );
   283     Q_UNUSED( parent );
   265     RadioStationModel& model = mUiEngine->stationModel();
   284     updateStationsInRange( first, last );
   266     uint frequency = 0;
       
   267     for ( int i = first; i <= last; ++i ) {
       
   268         frequency = model.data( model.index( i, 0, QModelIndex() ),
       
   269                                 RadioStationModel::RadioStationRole ).value<RadioStation>().frequency();
       
   270         if ( mFrequencies.contains( frequency ) ) {
       
   271             FrequencyPos pos = mFrequencies.value( frequency );
       
   272             updateFavorites( pos.mItem );
       
   273         }
       
   274     }
       
   275 }
   285 }
   276 
   286 
   277 /*!
   287 /*!
   278  * Private slot
   288  * Private slot
   279  *
   289  *
   280  */
   290  */
   281 void RadioFrequencyStrip::initEmptyItems()
   291 void RadioFrequencyStrip::initEmptyItems()
   282 {
   292 {
   283     LOG_METHOD;
   293     LOG_METHOD;
   284     QList<RadioStation> emptyList;
   294     //TODO: Remove the weird hack of checking the sender
   285     foreach ( RadioFrequencyItem* item, mFrequencyItems ) {
   295     if ( !sender() || RadioUtil::scanStatus() != Scan::ScanningInMainView ) {
   286         QPixmap pixmap = drawPixmap( item->frequency(), emptyList, item );
   296         QList<RadioStation> emptyList;
   287         item->setPixmap( pixmap );
   297         foreach ( RadioFrequencyItem* item, mFrequencyItems ) {
       
   298             QPixmap pixmap = drawPixmap( item->frequency(), emptyList, item );
       
   299             item->setPixmap( pixmap );
       
   300         }
   288     }
   301     }
   289 }
   302 }
   290 
   303 
   291 /*!
   304 /*!
   292  * Private slot
   305  * Private slot
   299 /*!
   312 /*!
   300  * Private slot
   313  * Private slot
   301  */
   314  */
   302 void RadioFrequencyStrip::handleLongLeftButton()
   315 void RadioFrequencyStrip::handleLongLeftButton()
   303 {
   316 {
   304     emit seekRequested( Seeking::Down );
   317     emit seekRequested( Seek::Down );
   305 }
   318 }
   306 
   319 
   307 /*!
   320 /*!
   308  * Private slot
   321  * Private slot
   309  */
   322  */
   315 /*!
   328 /*!
   316  * Private slot
   329  * Private slot
   317  */
   330  */
   318 void RadioFrequencyStrip::handleLongRightButton()
   331 void RadioFrequencyStrip::handleLongRightButton()
   319 {
   332 {
   320     emit seekRequested( Seeking::Up );
   333     emit seekRequested( Seek::Up );
   321 }
   334 }
   322 
   335 
   323 /*!
   336 /*!
   324  * Private slot
   337  * Private slot
   325  */
   338  *
   326 void RadioFrequencyStrip::toggleButtons()
   339  */
   327 {
   340 void RadioFrequencyStrip::toggleManualSeek()
   328     if ( mButtonsVisible ) {
   341 {
       
   342     mManualSeekMode = !mManualSeekMode;
       
   343     emit manualSeekChanged( mManualSeekMode );
       
   344 
       
   345     if ( mManualSeekMode ) {
       
   346         grabMouse();
   329         hideButtons();
   347         hideButtons();
       
   348         mManualSeekTimerId = startTimer( MANUALSEEK_SIGNAL_DELAY );
   330     } else {
   349     } else {
       
   350         ungrabMouse();
   331         showButtons();
   351         showButtons();
       
   352         killTimer( mManualSeekTimerId );
       
   353         mManualSeekTimerId = 0;
   332     }
   354     }
   333 }
   355 }
   334 
   356 
   335 /*!
   357 /*!
   336  * Private slot
   358  * Private slot
   337  */
   359  */
   338 void RadioFrequencyStrip::checkIllegalPos()
   360 void RadioFrequencyStrip::handleScrollingEnd()
   339 {
   361 {
   340     // Check if the selector is in the invalid area where the strip loops around
   362     // Check if the selector is in the invalid area where the strip loops around
   341     const int selectorPosition = selectorPos();
   363     const int selectorPosition = selectorPos();
   342     if ( !mPositions.contains( selectorPosition ) ) {
   364     if ( mManualSeekMode ) {
   343         if ( selectorPosition < mMaxWidth - KWidth + mSeparatorPos ) {
   365         if ( !mPositions.contains( selectorPosition ) ) {
   344             scrollToFrequency( mMaxFrequency, 500 );
   366             if ( selectorPosition < mMaxWidth - ITEM_WIDTH + mSeparatorPos ) {
   345             emitFrequencyChanged( mMaxFrequency );
   367                 scrollToFrequency( mMaxFrequency, Scroll::Shortest, 500 );
   346         } else {
   368                 emit frequencyChanged( mMaxFrequency, TuneReason::ManualSeekUpdate, Scroll::Shortest );
   347             scrollToFrequency( mMinFrequency, 500 );
   369             } else {
   348             emitFrequencyChanged( mMinFrequency );
   370                 scrollToFrequency( mMinFrequency, Scroll::Shortest, 500 );
   349         }
   371                 emit frequencyChanged( mMinFrequency, TuneReason::ManualSeekUpdate, Scroll::Shortest );
       
   372             }
       
   373         }
       
   374 
       
   375         mManualSeekTimer->start( MANUALSEEK_END_TIMEOUT );
   350     }
   376     }
   351 }
   377 }
   352 
   378 
   353 /*!
   379 /*!
   354  * \reimp
   380  * \reimp
   370 }
   396 }
   371 
   397 
   372 /*!
   398 /*!
   373  * \reimp
   399  * \reimp
   374  */
   400  */
   375 void RadioFrequencyStrip::scrollPosChanged( QPointF newPosition )
   401 void RadioFrequencyStrip::scrollPosChanged()
   376 {
   402 {
   377     Q_UNUSED( newPosition );
   403     if ( mManualSeekMode ) {
   378 
       
   379     if ( mUserIsScrolling ) {
       
   380         const int pos = selectorPos();
   404         const int pos = selectorPos();
   381         emitFrequencyChanged( mPositions.value( pos ) );
   405         const uint frequency = mPositions.value( pos );
       
   406         if ( frequency > 0 ) {
       
   407             mFrequency = mPositions.value( pos );
       
   408             emit frequencyChanged( mFrequency, TuneReason::ManualSeekUpdate, Scroll::Shortest );
       
   409         }
   382     }
   410     }
   383 }
   411 }
   384 
   412 
   385 /*!
   413 /*!
   386  * \reimp
   414  * \reimp
   387  */
   415  */
   388 void RadioFrequencyStrip::resizeEvent ( QGraphicsSceneResizeEvent* event )
   416 void RadioFrequencyStrip::resizeEvent ( QGraphicsSceneResizeEvent* event )
   389 {
   417 {
   390     LOG_METHOD_ENTER;
   418     LOG_METHOD;
   391     RadioStripBase::resizeEvent( event );
   419     RadioStripBase::resizeEvent( event );
   392 
   420 
   393     mSelectorPos = event->newSize().width() / 2;
   421     initSelector();
   394     mSelectorImage->setOffset( mSelectorPos - (KIndicatorWidth / 2), 0.0 );
   422 
   395 
   423     const qreal height = event->newSize().height();
   396     const int stripHeight = event->newSize().height();
   424     const qreal width = event->newSize().width();
   397     if ( !mLeftButtonIcon.isNull() ) {
   425 
   398         mLeftButton->resize( stripHeight, stripHeight );
   426     mSelectorPos = width / 2;
   399         mLeftButton->setBackground( mLeftButtonIcon );
   427     mSelectorImage->setOffset( mSelectorPos - (INDICATOR_WIDTH / 2), 0.0 );
   400     }
   428 
   401 
   429     if ( mLeftButton && mRightButton ) {
   402     if ( !mRightButtonIcon.isNull() ) {
   430         mLeftButton->resize( height, height );
   403         mRightButton->resize( stripHeight, stripHeight );
   431         mRightButton->resize( height, height );
   404         mRightButton->setBackground( mRightButtonIcon );
   432         mRightButton->setPos( QPointF( width - height, 0 ) );
   405     }
   433     }
   406     mRightButton->setPos( QPointF( size().width() - mRightButton->size().width(), 0 ) );
   434 
   407 
   435     scrollToFrequency( mFrequency );
   408     scrollToFrequency( mFrequency, 0 );
   436 }
   409 }
   437 
   410 
   438 /*!
   411 /*!
   439  * \reimp
   412  * \reimp
   440  */
   413  */
   441 //void RadioFrequencyStrip::showEvent( QShowEvent* event )
   414 void RadioFrequencyStrip::showEvent( QShowEvent* event )
   442 //{
   415 {
   443 //    RadioStripBase::showEvent( event );
   416     Q_UNUSED( event );
   444 //    scrollToFrequency( mFrequency );
   417     scrollToFrequency( mFrequency, 0 );
   445 //}
   418 }
       
   419 
   446 
   420 /*!
   447 /*!
   421  * \reimp
   448  * \reimp
   422  */
   449  */
   423 void RadioFrequencyStrip::changeEvent( QEvent* event )
   450 void RadioFrequencyStrip::changeEvent( QEvent* event )
   424 {
   451 {
   425     if ( event->type() == HbEvent::ThemeChanged ) {
   452     if ( event->type() == HbEvent::ThemeChanged ) {
   426         // Update the foreground color and redraw each item
   453         // Update the foreground color and redraw each item
   427         mForegroundColor = Qt::white;// HbColorScheme::color( TEXT_COLOR_ATTRIBUTE );
   454         mForegroundColor = Qt::white;// HbColorScheme::color( TEXT_COLOR_ATTRIBUTE );
   428         updateItems();
   455         updateAllItems();
   429     }
   456     }
   430 
   457 
   431     return HbWidgetBase::changeEvent(event);
   458     return RadioStripBase::changeEvent(event);
   432 }
   459 }
   433 
   460 
   434 /*!
   461 /*!
   435  * \reimp
   462  * \reimp
   436  */
   463  */
   437 void RadioFrequencyStrip::mousePressEvent( QGraphicsSceneMouseEvent* event )
   464 void RadioFrequencyStrip::mousePressEvent( QGraphicsSceneMouseEvent* event )
   438 {
   465 {
   439     RadioStripBase::mousePressEvent( event );
   466     RadioStripBase::mousePressEvent( event );
   440     mUserIsScrolling = true;
   467 
   441     mButtonTimer->stop();
   468     mManualSeekTimer->stop();
   442     mButtonTimer->start( BUTTON_HIDE_TIMEOUT );
   469     if ( mManualSeekMode ) {
       
   470         const bool insideStrip = rect().contains( event->pos() );
       
   471         if ( !insideStrip ) {
       
   472             toggleManualSeek();
       
   473         }
       
   474     } else {
       
   475         mManualSeekTimer->start( MANUALSEEK_START_TIMEOUT );
       
   476     }
   443 }
   477 }
   444 
   478 
   445 /*!
   479 /*!
   446  * \reimp
   480  * \reimp
   447  */
   481  */
   448 void RadioFrequencyStrip::mouseReleaseEvent( QGraphicsSceneMouseEvent* event )
   482 void RadioFrequencyStrip::mouseReleaseEvent( QGraphicsSceneMouseEvent* event )
   449 {
   483 {
   450     mUserIsScrolling = false;
       
   451     RadioStripBase::mouseReleaseEvent( event );
   484     RadioStripBase::mouseReleaseEvent( event );
   452 
   485 
   453 //    if ( !mIsPanGesture ) {
   486     mManualSeekTimer->stop();
   454 //        const qreal touchDelta = event->pos().x() - mSelectorPos;
   487     if ( mManualSeekMode && !isScrolling() ) {
   455 //        const int touchPos = selectorPosition + touchDelta;
   488         mManualSeekTimer->start( MANUALSEEK_END_TIMEOUT );
   456 //        const uint frequencyAtPos = mPositions.value( touchPos );
       
   457 //
       
   458 //        uint foundFrequency = 0;
       
   459 //        for ( int i = 0; i < 10; ++i ) {
       
   460 //            const uint delta = i * mFrequencyStepSize;
       
   461 //            FrequencyPos leftFreq = mFrequencies.value( frequencyAtPos - delta );
       
   462 //            FrequencyPos rightFreq = mFrequencies.value( frequencyAtPos + delta );
       
   463 //
       
   464 //            if ( touchPos - leftFreq.mPosition > KTouchPosThreshold ) {
       
   465 //                break;
       
   466 //            }
       
   467 //
       
   468 //            if ( leftFreq.mFavorite || leftFreq.mLocalStation ) {
       
   469 //                foundFrequency = frequencyAtPos - delta;
       
   470 //                break;
       
   471 //            } else if ( rightFreq.mFavorite || rightFreq.mLocalStation ) {
       
   472 //                foundFrequency = frequencyAtPos + delta;
       
   473 //                break;
       
   474 //            }
       
   475 //        }
       
   476 //
       
   477 //        if ( foundFrequency > 0 ) {
       
   478 //            setFrequency( foundFrequency, 0 );
       
   479 //        }
       
   480 //    }
       
   481 
       
   482     mButtonTimer->stop();
       
   483     if ( !mButtonsVisible ) {
       
   484         mButtonTimer->start( BUTTON_SHOW_TIMEOUT );
       
   485     }
   489     }
   486 }
   490 }
   487 
   491 
   488 /*!
   492 /*!
   489  * \reimp
   493  * \reimp
   490  */
   494  */
   491 void RadioFrequencyStrip::gestureEvent( QGestureEvent* event )
   495 void RadioFrequencyStrip::gestureEvent( QGestureEvent* event )
   492 {
   496 {
   493     if ( HbSwipeGesture* gesture = static_cast<HbSwipeGesture*>( event->gesture( Qt::SwipeGesture ) ) ) {
   497     HbSwipeGesture* swipeGesture = static_cast<HbSwipeGesture*>( event->gesture( Qt::SwipeGesture ) );
   494         if ( gesture->state() == Qt::GestureFinished ) {
   498     if ( swipeGesture && !mManualSeekMode ) {
   495             if ( gesture->horizontalDirection() == QSwipeGesture::Left ) {
   499         if ( swipeGesture->state() == Qt::GestureFinished ) {
       
   500             if ( swipeGesture->horizontalDirection() == QSwipeGesture::Left ) {
   496                 emit skipRequested( StationSkip::Next );
   501                 emit skipRequested( StationSkip::Next );
   497             } else if ( gesture->horizontalDirection() == QSwipeGesture::Right ) {
   502             } else if ( swipeGesture->horizontalDirection() == QSwipeGesture::Right ) {
   498                 emit skipRequested( StationSkip::Previous );
   503                 emit skipRequested( StationSkip::Previous );
   499             }
   504             }
   500         }
   505         }
   501     } else {
   506     } else if ( mManualSeekMode ) {
   502         RadioStripBase::gestureEvent( event );
   507         RadioStripBase::gestureEvent( event );
   503     }
   508     }
   504 }
   509 }
   505 
   510 
   506 /*!
   511 /*!
       
   512  * \reimp
       
   513  */
       
   514 void RadioFrequencyStrip::timerEvent( QTimerEvent* event )
       
   515 {
       
   516     Q_UNUSED( event );
       
   517     if ( mLastReportedFrequency != mFrequency ) {
       
   518         mLastReportedFrequency = mFrequency;
       
   519         emit frequencyChanged( mFrequency, TuneReason::ManualSeekTune, Scroll::Shortest );
       
   520     }
       
   521 }
       
   522 
       
   523 /*!
   507  *
   524  *
   508  */
   525  */
   509 void RadioFrequencyStrip::initModel()
   526 void RadioFrequencyStrip::initModel()
   510 {
   527 {
   511     const uint minFreq = uint( qreal(mMinFrequency) / KOneHertz + KRounder );
   528     const uint minFreq = uint( qreal(mMinFrequency) / ONE_HERTZ + ROUNDER );
   512     const uint maxFreq = uint( qreal(mMaxFrequency) / KOneHertz + 0.9 ); // always round up
   529     const uint maxFreq = uint( qreal(mMaxFrequency) / ONE_HERTZ + 0.9 ); // always round up
   513 
   530 
   514     QStringList list;
   531     QStringList list;
   515     QString freqText;
   532     QString freqText;
   516     for ( uint i = minFreq; i <= maxFreq; ++i ) {
   533     for ( uint i = minFreq; i <= maxFreq; ++i ) {
   517         freqText = QString::number( i );
   534         freqText = QString::number( i );
   519         mFrequencyItems.append( new RadioFrequencyItem( freqText ) );
   536         mFrequencyItems.append( new RadioFrequencyItem( freqText ) );
   520     }
   537     }
   521     mFrequencyItems.append( new RadioFrequencyItem( "" ) );
   538     mFrequencyItems.append( new RadioFrequencyItem( "" ) );
   522     list.append( "" );
   539     list.append( "" );
   523 
   540 
   524     mMaxWidth = list.count() * KWidth;
   541     mMaxWidth = list.count() * ITEM_WIDTH;
   525 
   542 
   526     mSeparatorPos = qreal(KWidth) / 2;
   543     mSeparatorPos = qreal(ITEM_WIDTH) / 2;
   527     const uint minDrawableFreq = minFreq * KOneHertz - KHalfHertz;;
   544     const uint minDrawableFreq = minFreq * ONE_HERTZ - HALF_HERTZ;;
   528     const uint maxDrawableFreq = maxFreq * KOneHertz + KHalfHertz;
   545     const uint maxDrawableFreq = maxFreq * ONE_HERTZ + HALF_HERTZ;
   529     mSeparatorPos += qreal( ( mMinFrequency  - minDrawableFreq ) / 2 ) / KPixelInHz;
   546     mSeparatorPos += qreal( ( mMinFrequency  - minDrawableFreq ) / 2 ) / PIXEL_IN_HZ;
   530     mSeparatorPos -= qreal( ( maxDrawableFreq - mMaxFrequency ) / 2 ) / KPixelInHz;
   547     mSeparatorPos -= qreal( ( maxDrawableFreq - mMaxFrequency ) / 2 ) / PIXEL_IN_HZ;
   531 
   548 
   532     setModel( new QStringListModel( list, this ) );
   549     setModel( new QStringListModel( list, this ) );
   533 }
   550 }
   534 
   551 
   535 /*!
   552 /*!
   536  *
   553  *
   537  */
   554  */
   538 void RadioFrequencyStrip::initSelector()
   555 void RadioFrequencyStrip::initSelector()
   539 {
   556 {
   540     QPixmap selectorPixmap = QPixmap( QSize( KSelectorWidth, KHeight ) );
   557     QPixmap selectorPixmap = QPixmap( QSize( SELECTOR_WIDTH, (int)size().height() ) );
   541     selectorPixmap.fill( Qt::red );
   558     selectorPixmap.fill( Qt::red );
   542     mSelectorImage->setPixmap( selectorPixmap );
   559     mSelectorImage->setPixmap( selectorPixmap );
   543     mSelectorImage->setZValue( KSelectorZPos );
   560     mSelectorImage->setZValue( SELECTOR_Z_POS );
   544 }
   561 }
   545 
   562 
   546 /*!
   563 /*!
   547  *
   564  *
   548  */
   565  */
   570 /*!
   587 /*!
   571  *
   588  *
   572  */
   589  */
   573 void RadioFrequencyStrip::initButtons()
   590 void RadioFrequencyStrip::initButtons()
   574 {
   591 {
   575     mLeftButton->setZValue( KSelectorZPos );
   592     mLeftButton->setZValue( SELECTOR_Z_POS );
   576     mLeftButton->setObjectName( LEFT_BUTTON );
   593     mLeftButton->setObjectName( LEFT_BUTTON );
   577     mRightButton->setZValue( KSelectorZPos );
   594     mRightButton->setZValue( SELECTOR_Z_POS );
   578     mRightButton->setObjectName( RIGHT_BUTTON );
   595     mRightButton->setObjectName( RIGHT_BUTTON );
   579 
   596 
       
   597     const qreal height = size().height();
       
   598     const qreal width = size().width();
       
   599     mLeftButton->resize( height, height );
       
   600     mRightButton->resize( height, height );
       
   601     mRightButton->setPos( QPointF( width - height, 0 ) );
       
   602 
   580     QEffectList effectList;
   603     QEffectList effectList;
   581     effectList.append( EffectInfo( mLeftButton, ":/effects/slide_to_left.fxml", KSlideToLeft ) );
   604     effectList.append( EffectInfo( mLeftButton, ":/effects/slide_to_left.fxml", SLIDE_TO_LEFT ) );
   582     effectList.append( EffectInfo( mLeftButton, ":/effects/slide_from_left.fxml", KSlideFromLeft ) );
   605     effectList.append( EffectInfo( mLeftButton, ":/effects/slide_from_left.fxml", SLIDE_FROM_LEFT ) );
   583     effectList.append( EffectInfo( mRightButton, ":/effects/slide_to_right.fxml", KSlideToRight ) );
   606     effectList.append( EffectInfo( mRightButton, ":/effects/slide_to_right.fxml", SLIDE_TO_RIGHT ) );
   584     effectList.append( EffectInfo( mRightButton, ":/effects/slide_from_right.fxml", KSlideFromRight ) );
   607     effectList.append( EffectInfo( mRightButton, ":/effects/slide_from_right.fxml", SLIDE_FROM_RIGHT ) );
   585     RadioUiUtilities::addEffects( effectList );
   608     RadioUtil::addEffects( effectList );
   586 }
   609 }
   587 
   610 
   588 /*!
   611 /*!
   589  *
   612  *
   590  */
   613  */
   595 }
   618 }
   596 
   619 
   597 /*!
   620 /*!
   598  *
   621  *
   599  */
   622  */
   600 void RadioFrequencyStrip::updateFavorites( RadioFrequencyItem* item )
   623 void RadioFrequencyStrip::updateStationsInRange( int first, int last, bool stationRemoved )
       
   624 {
       
   625     if ( RadioUtil::scanStatus() != Scan::ScanningInMainView ) {
       
   626         RadioStationModel& model = mUiEngine->stationModel();
       
   627         uint frequency = 0;
       
   628         for ( int i = first; i <= last; ++i ) {
       
   629             frequency = model.data( model.index( i, 0, QModelIndex() ),
       
   630                                     RadioRole::RadioStationRole ).value<RadioStation>().frequency();
       
   631             if ( mFrequencies.contains( frequency ) ) {
       
   632                 FrequencyPos pos = mFrequencies.value( frequency );
       
   633                 updateItem( pos.mItem, 0, stationRemoved ? frequency : 0 );
       
   634             }
       
   635         }
       
   636     }
       
   637 }
       
   638 
       
   639 /*!
       
   640  *
       
   641  */
       
   642 void RadioFrequencyStrip::updateItem( RadioFrequencyItem* item, uint upperRange, uint ignoredFrequency )
   601 {
   643 {
   602     if ( item ) {
   644     if ( item ) {
   603         uint frequency = item->frequency();
   645         uint frequency = item->frequency();
   604         QList<RadioStation> stations;
   646         QList<RadioStation> stations;
       
   647 
       
   648         if ( upperRange == 0 ) {
       
   649             upperRange = frequency + HALF_HERTZ;
       
   650         }
       
   651 
   605         if ( mUiEngine ) {
   652         if ( mUiEngine ) {
   606             stations = mUiEngine->stationsInRange( frequency - KHalfHertz, frequency + KHalfHertz );
   653             stations = mUiEngine->stationsInRange( frequency - HALF_HERTZ, upperRange );
       
   654             for ( int i = stations.count() - 1; ignoredFrequency > 0 && i >= 0; --i ) {
       
   655                 if ( stations[i].frequency() == ignoredFrequency ) {
       
   656                     stations.removeAt( i );
       
   657                     break;
       
   658                 }
       
   659             }
   607         }
   660         }
   608 
   661 
   609         QPixmap pixmap = drawPixmap( frequency, stations, item );
   662         QPixmap pixmap = drawPixmap( frequency, stations, item );
   610         item->setPixmap( pixmap );
   663         item->setPixmap( pixmap );
   611 
   664 
   618 }
   671 }
   619 
   672 
   620 /*!
   673 /*!
   621  *
   674  *
   622  */
   675  */
   623 void RadioFrequencyStrip::updateItems()
   676 void RadioFrequencyStrip::updateAllItems()
   624 {
   677 {
   625     foreach ( RadioFrequencyItem* item, mFrequencyItems ) {
   678     foreach ( RadioFrequencyItem* item, mFrequencyItems ) {
   626         updateFavorites( item );
   679         updateItem( item );
   627     }
   680     }
   628 }
   681 }
   629 
   682 
   630 /*!
   683 /*!
   631  *
   684  *
   632  */
   685  */
   633 QPixmap RadioFrequencyStrip::drawPixmap( uint frequency, QList<RadioStation> stations, RadioFrequencyItem* item )
   686 QPixmap RadioFrequencyStrip::drawPixmap( uint frequency, QList<RadioStation> stations, RadioFrequencyItem* item )
   634 {
   687 {
   635     QPixmap pixmap( KWidth, KHeight );
   688     QPixmap pixmap( PIXMAP_WIDTH, mItemHeight );
   636     pixmap.fill( Qt::transparent );
   689     pixmap.fill( Qt::transparent );
   637     QPainter painter( &pixmap );
   690     QPainter painter( &pixmap );
   638     QPen normalPen = painter.pen();
   691     QPen normalPen = painter.pen();
   639     QPen favoritePen = normalPen;
   692     QPen favoritePen = normalPen;
   640     normalPen.setColor( mForegroundColor );
   693     normalPen.setColor( mForegroundColor );
   641     painter.setPen( normalPen );
   694     painter.setPen( normalPen );
   642 
   695 
   643     if ( frequency == 0 ) {
   696     if ( frequency == 0 ) {
   644         painter.drawLine( makeTab( mSeparatorPos - 1 + KRounder, KHeight ) );
   697         painter.drawLine( makeTab( mSeparatorPos - 1 + ROUNDER, mItemHeight ) );
   645         painter.drawLine( makeTab( mSeparatorPos + KRounder, KHeight ) );
   698         painter.drawLine( makeTab( mSeparatorPos + ROUNDER, mItemHeight ) );
   646         return pixmap;
   699         return pixmap;
   647     }
   700     }
   648 
   701 
   649     const QString itemText = QString::number( frequency / KOneHertz );
   702     const QString itemText = QString::number( frequency / ONE_HERTZ );
   650     const uint startFrequency = frequency - KHalfHertz;
   703     const uint startFrequency = frequency - HALF_HERTZ;
   651     const uint endFrequency = startFrequency + KOneHertz;
   704     const uint endFrequency = startFrequency + ONE_HERTZ;
   652     const uint  roundedMin = int( qreal(mMinFrequency) / KOneHertz + KRounder );
   705     const uint  roundedMin = int( qreal(mMinFrequency) / ONE_HERTZ + ROUNDER );
   653     const uint freq = frequency / KOneHertz;
   706     const uint freq = frequency / ONE_HERTZ;
   654     const int diff = freq - roundedMin;
   707     const int diff = freq - roundedMin;
   655     const qreal startPixel = diff * KWidth;
   708     const qreal startPixel = diff * ITEM_WIDTH;
   656     qreal pixels = 0.0;
   709     qreal pixels = 0.0;
   657     QFont painterFont = painter.font();
   710     const qreal leftOverlap = PIXMAP_OVERLAP / 2;
   658     painterFont.setPointSize( 6 );
   711 
   659     painter.setFont( painterFont );
       
   660 
       
   661     const int charWidth = painter.fontMetrics().averageCharWidth();
       
   662     for ( uint frequency = startFrequency; frequency <= endFrequency; frequency += mFrequencyStepSize ) {
   712     for ( uint frequency = startFrequency; frequency <= endFrequency; frequency += mFrequencyStepSize ) {
   663 
   713 
   664         if ( frequency < mMinFrequency || frequency > mMaxFrequency ) {
   714         if ( frequency < mMinFrequency || frequency > mMaxFrequency ) {
   665             continue;
   715             continue;
   666         }
   716         }
   667 
   717 
   668         pixels = qreal( frequency - startFrequency ) / KPixelInHz;
   718         pixels = qreal( frequency - startFrequency ) / PIXEL_IN_HZ;
   669         if ( frequency % KOneHertz == 0 ) {
   719         if ( frequency % ONE_HERTZ == 0 ) {
   670 
   720 
   671             // Draw the high frequency tab and the frequency text for the even number
   721             // Draw the high frequency tab and the frequency text for the even number
   672             painter.drawLine( makeTab( pixels, KTabHeightBig ) );
   722             normalPen.setWidth( 3 );
   673             const int textPosX = pixels - itemText.length() * charWidth / 2;
   723             painter.setPen( normalPen );
       
   724             painter.drawLine( makeTab( pixels + leftOverlap - 1, TAB_HEIGHT_BIG ) );
       
   725             normalPen.setWidth( 1 );
       
   726             painter.setPen( normalPen );
       
   727 
       
   728             // Draw the frequency text and its 00 decimals
       
   729             painter.setFont( DECIMAL_FONT );
       
   730             const int decimalWidth = painter.fontMetrics().width( DECIMAL_TEXT );
       
   731             const int decimalSpace = painter.fontMetrics().leftBearing( '.' );
       
   732             painter.setFont( FREQUENCY_FONT );
       
   733             const int frequencyWidth = painter.fontMetrics().width( itemText );
       
   734             const int textPosX = int( pixels + leftOverlap - ( frequencyWidth + decimalSpace + decimalWidth ) / 2 );
   674             painter.drawText( QPoint( textPosX, 20 ), itemText );
   735             painter.drawText( QPoint( textPosX, 20 ), itemText );
   675 
   736             painter.setFont( DECIMAL_FONT );
   676         } else if ( frequency % KOneTabInHz == 0 ) {
   737             painter.drawText( QPoint( textPosX + frequencyWidth + decimalSpace, 20 ), DECIMAL_TEXT );
       
   738 
       
   739         } else if ( frequency % ONE_TAB_IN_HZ == 0 ) {
   677 
   740 
   678             // Draw the low frequency tab for the uneven number
   741             // Draw the low frequency tab for the uneven number
   679             painter.drawLine( makeTab( pixels, KTabHeightSmall ) );
   742             painter.drawLine( makeTab( pixels + leftOverlap, TAB_HEIGHT_SMALL ) );
   680 
   743 
   681         }
   744         }
   682 
   745 
   683         addFrequencyPos( startPixel + pixels + KRounder, frequency, item );
   746         addFrequencyPos( int( startPixel + pixels + ROUNDER ), frequency, item );
   684     }
   747     }
   685 
   748 
   686     // Draw favorites and local stations
   749     // Draw favorites and local stations
   687     favoritePen.setColor( Qt::yellow );
   750     favoritePen.setColor( Qt::yellow );
   688 
   751 
   689     const int markerYPos = KHeight - 20;
   752     const int markerYPos = mItemHeight - 28;
   690     foreach ( const RadioStation& station, stations ) {
   753     foreach ( const RadioStation& station, stations ) {
   691         const uint frequency = station.frequency();
   754         const uint frequency = station.frequency();
   692         pixels = qreal( frequency - startFrequency ) / KPixelInHz;
   755         pixels = qreal( frequency - startFrequency ) / PIXEL_IN_HZ;
   693 
   756 
   694         if ( station.isFavorite() ) {
   757         if ( station.isFavorite() ) {
   695             favoritePen.setWidth( KTabWidthFavorite );
   758             favoritePen.setWidth( PEN_WIDTH_FAVORITE );
   696             painter.setPen( favoritePen );
   759             painter.setPen( favoritePen );
   697             painter.drawEllipse( pixels - 3, markerYPos - 3, 6, 6 );
   760             painter.drawEllipse( int( pixels + leftOverlap - 3 ), markerYPos - 3, 6, 6 );
   698 //            painter.drawPixmap( pixels - 10, 20, 20, 20, mFavoriteIcon.pixmap() );
       
   699         } else if ( station.isType( RadioStation::LocalStation ) ) {
   761         } else if ( station.isType( RadioStation::LocalStation ) ) {
   700 //            painter.setPen( normalPen );
       
   701 //            painter.drawLine( pixels,                           // Start X
       
   702 //                              KHeight - KTabHeightFavorite,     // Start Y
       
   703 //                              pixels,                           // End X
       
   704 //                              KHeight );                        // End Y
       
   705 
   762 
   706             favoritePen.setWidth( 1 );
   763             favoritePen.setWidth( 1 );
   707             painter.setPen( favoritePen );
   764             painter.setPen( favoritePen );
   708             painter.drawEllipse( pixels - 4, markerYPos - 4, 8, 8 );
   765             painter.drawEllipse( int( pixels + leftOverlap - 4 ), markerYPos - 4, 8, 8 );
   709         }
   766         }
   710     }
   767     }
   711 
   768 
   712     return pixmap;
   769     return pixmap;
       
   770 }
       
   771 
       
   772 /*!
       
   773  *
       
   774  */
       
   775 QLineF RadioFrequencyStrip::makeTab( qreal pos, int height )
       
   776 {
       
   777     return QLineF( pos, mItemHeight - height, pos, mItemHeight );
   713 }
   778 }
   714 
   779 
   715 /*!
   780 /*!
   716  *
   781  *
   717  */
   782  */
   718 void RadioFrequencyStrip::emitFrequencyChanged( uint frequency )
   783 void RadioFrequencyStrip::emitFrequencyChanged( uint frequency )
   719 {
   784 {
   720     if ( frequency > 0 && frequency != mFrequency ) {
   785     if ( frequency > 0 && frequency != mFrequency ) {
   721         mFrequency = frequency;
   786         mFrequency = frequency;
   722         emit frequencyChanged( frequency, TuneReason::FrequencyStrip );
   787         //TOD: Get direction
       
   788         emit frequencyChanged( frequency, TuneReason::FrequencyStrip, Scroll::Shortest );
   723     }
   789     }
   724 }
   790 }
   725 
   791 
   726 /*!
   792 /*!
   727  *
   793  *
   728  */
   794  */
   729 int RadioFrequencyStrip::selectorPos() const
   795 int RadioFrequencyStrip::selectorPos() const
   730 {
   796 {
   731     const int pos = ( -contentWidget()->x() + mSelectorPos ) + KRounder;
   797     const int pos = int( -contentWidget()->x() + mSelectorPos + ROUNDER );
   732     return pos % mMaxWidth;
   798     return pos % mMaxWidth;
   733 }
   799 }
   734 
   800 
   735 /*!
   801 /*!
   736  *
   802  *
   737  */
   803  */
   738 void RadioFrequencyStrip::scrollToFrequency( uint frequency, int time )
   804 void RadioFrequencyStrip::scrollToFrequency( uint frequency, Scroll::Direction direction, int time, TuneReason::Reason reason )
   739 {
   805 {
   740     // Find the shortest route to the requested frequency.
   806     int targetFreqPos = mFrequencies.value( frequency ).mPosition;
   741     const int pos = ( -contentWidget()->x() + mSelectorPos ) + KRounder;
   807     const int currentFreqPos = mFrequencies.value( mFrequency ).mPosition;
   742     if ( pos >= mMaxWidth - KWidth + mSeparatorPos ) {
   808     const int currentPos = int( -contentWidget()->x() + mSelectorPos + ROUNDER );
   743         const qreal newPos = qreal( mFrequencies.value( frequency ).mPosition ) - mSelectorPos + mMaxWidth;
   809     const bool isInSecondHalf = currentPos >= mMaxWidth - ITEM_WIDTH + mSeparatorPos;
   744         scrollContentsTo( QPointF( newPos, 0 ), time );
   810 
   745     } else {
   811     // Special case: When there is only one favorite and the user presses skip
   746         scrollContentsTo( QPointF( qreal( mFrequencies.value( frequency ).mPosition ) - mSelectorPos, 0 ), time );
   812     // the strip must scroll around to the same frequency.
   747     }
   813     if ( mFrequency == frequency && reason == TuneReason::Skip ) {
       
   814         if ( direction == Scroll::Left ) {
       
   815             targetFreqPos += mMaxWidth;
       
   816         } else {
       
   817         targetFreqPos -= mMaxWidth;
       
   818         }
       
   819     }
       
   820 
       
   821     mFrequency = frequency;
       
   822 
       
   823     qreal newPos = targetFreqPos;
       
   824     if ( direction == Scroll::Left ) {
       
   825 
       
   826         if ( currentFreqPos > targetFreqPos ) {
       
   827             newPos += mMaxWidth;
       
   828         }
       
   829 
       
   830     } else if ( direction == Scroll::Right ) {
       
   831 
       
   832         if ( currentFreqPos < targetFreqPos ) {
       
   833             newPos -= mMaxWidth;
       
   834         }
       
   835 
       
   836     }
       
   837 
       
   838     if ( isInSecondHalf ) {
       
   839         newPos += mMaxWidth;
       
   840     }
       
   841 
       
   842     newPos -= mSelectorPos - ROUNDER;
       
   843 
       
   844     scrollContentsTo( QPointF( newPos, 0 ), time );
   748 }
   845 }
   749 
   846 
   750 /*!
   847 /*!
   751  *
   848  *
   752  */
   849  */
   753 void RadioFrequencyStrip::hideButtons()
   850 void RadioFrequencyStrip::hideButtons()
   754 {
   851 {
   755     mButtonsVisible = false;
   852     HbEffect::start( mLeftButton, SLIDE_TO_LEFT );
   756     HbEffect::start( mLeftButton, KSlideToLeft );
   853     HbEffect::start( mRightButton, SLIDE_TO_RIGHT );
   757     HbEffect::start( mRightButton, KSlideToRight );
       
   758 }
   854 }
   759 
   855 
   760 /*!
   856 /*!
   761  *
   857  *
   762  */
   858  */
   763 void RadioFrequencyStrip::showButtons()
   859 void RadioFrequencyStrip::showButtons()
   764 {
   860 {
   765     mButtonsVisible = true;
   861     HbEffect::start( mLeftButton, SLIDE_FROM_LEFT );
   766     HbEffect::start( mLeftButton, KSlideFromLeft );
   862     HbEffect::start( mRightButton, SLIDE_FROM_RIGHT );
   767     HbEffect::start( mRightButton, KSlideFromRight );
   863 }
   768 }