15 * |
15 * |
16 */ |
16 */ |
17 |
17 |
18 // System includes |
18 // System includes |
19 #include <QGraphicsLinearLayout> |
19 #include <QGraphicsLinearLayout> |
20 #include <HbAnchorLayout> |
20 #include <QGraphicsSceneResizeEvent> |
21 #include <QPixmap> |
|
22 #include <QGraphicsSceneMouseEvent> |
|
23 #include <HbEffect> |
|
24 #include <QTimer> |
21 #include <QTimer> |
25 #include <QTimeLine> |
|
26 #include <HbPanGesture> |
22 #include <HbPanGesture> |
|
23 #include <HbSwipeGesture> |
|
24 #include <HbFontSpec> |
27 |
25 |
28 // User includes |
26 // User includes |
29 #include "radiostationcarousel.h" |
27 #include "radiostationcarousel.h" |
|
28 #include "radiocarouselanimator.h" |
30 #include "radiouiloader.h" |
29 #include "radiouiloader.h" |
31 #include "radiostationitem.h" |
30 #include "radiocarouselitem.h" |
32 #include "radiostation.h" |
31 #include "radiostation.h" |
33 #include "radiouiengine.h" |
32 #include "radiouiengine.h" |
34 #include "radiostationmodel.h" |
33 #include "radiostationmodel.h" |
35 #include "radiofadinglabel.h" |
34 #include "radiofadinglabel.h" |
36 #include "radiologger.h" |
35 #include "radiologger.h" |
37 #include "radiocarouselmodel.h" |
36 #include "radioutil.h" |
38 #include "radiouiutilities.h" |
|
39 #include "radio_global.h" |
37 #include "radio_global.h" |
40 |
38 |
41 #ifdef USE_LAYOUT_FROM_E_DRIVE |
39 // Constants |
42 const QString KFavoriteIconPath = "e:/radiotest/images/favoriteiconactive.png"; |
40 const int RTPLUS_CHECK_TIMEOUT = 700; |
43 const QString KNonFavoriteIconPath = "e:/radiotest/images/favoriteiconinactive.png"; |
41 const int INFOTEXT_NOFAVORITES_TIMEOUT = 5000; |
|
42 const int SET_FREQUENCY_TIMEOUT = 500; |
|
43 const int FAVORITE_HINT_SHOW_DELAY = 1000; |
|
44 const int FAVORITE_HINT_HIDE_DELAY = 2000; |
|
45 |
|
46 #ifdef BUILD_WIN32 |
|
47 # define SCROLLBAR_POLICY ScrollBarAlwaysOn |
44 #else |
48 #else |
45 const QString KFavoriteIconPath = ":/images/favoriteiconactive.png"; |
49 # define SCROLLBAR_POLICY ScrollBarAlwaysOff |
46 const QString KNonFavoriteIconPath = ":/images/favoriteiconinactive.png"; |
50 #endif // BUILD_WIN32 |
47 #endif |
51 |
48 |
52 #define CALL_TO_ALL_ITEMS( expr ) \ |
49 const int KRadioTextPlusCheckTimeout = 700; // 700 ms |
53 mItems[LeftItem]->expr; \ |
50 const int KFreqScrollDivider = 100000; |
54 mItems[CenterItem]->expr; \ |
51 const int INFOTEXT_NOFAVORITES_TIMEOUT = 15000; |
55 mItems[RightItem]->expr; |
52 |
56 |
53 // =============================================================== |
57 /*! |
54 // Scanning helper |
58 * |
55 // =============================================================== |
59 */ |
56 |
60 RadioStationCarousel::RadioStationCarousel( QGraphicsItem* parent ) : |
57 /*! |
61 HbScrollArea( parent ), |
58 * |
62 mUiEngine( NULL ), |
59 */ |
|
60 ScanningHelper::ScanningHelper( RadioStationCarousel& carousel ) : |
|
61 mCarousel( carousel ), |
|
62 mCurrentFrequency( 0 ), |
|
63 mPreviousFrequency( 0 ), |
|
64 mStationItem( 0 ), |
|
65 mNumberScrollingTimeLine( new QTimeLine( 1000, this ) ) |
|
66 { |
|
67 mNumberScrollingTimeLine->setCurveShape( QTimeLine::EaseInCurve ); |
|
68 connectAndTest( mNumberScrollingTimeLine, SIGNAL(finished()), |
|
69 &mCarousel, SIGNAL(scanAnimationFinished()) ); |
|
70 connectAndTest( mNumberScrollingTimeLine, SIGNAL(frameChanged(int)), |
|
71 this, SLOT(numberScrollUpdate(int)) ); |
|
72 } |
|
73 |
|
74 /*! |
|
75 * |
|
76 */ |
|
77 void ScanningHelper::start() |
|
78 { |
|
79 QTimer::singleShot( 0, this, SLOT(startSlide()) ); |
|
80 } |
|
81 |
|
82 /*! |
|
83 * Private slot |
|
84 */ |
|
85 void ScanningHelper::startSlide() |
|
86 { |
|
87 mCarousel.scrollToIndex( mModelIndex, RadioStationCarousel::NoSignal ); |
|
88 startNumberScroll(); |
|
89 } |
|
90 |
|
91 /*! |
|
92 * Private slot |
|
93 */ |
|
94 void ScanningHelper::startNumberScroll() |
|
95 { |
|
96 //TODO: Take italy case into account |
|
97 if ( mPreviousFrequency ) { |
|
98 mNumberScrollingTimeLine->setFrameRange( mPreviousFrequency / KFreqScrollDivider, mCurrentFrequency / KFreqScrollDivider ); |
|
99 mNumberScrollingTimeLine->start(); |
|
100 } else { |
|
101 emit mCarousel.scanAnimationFinished(); |
|
102 } |
|
103 } |
|
104 |
|
105 /*! |
|
106 * Private slot |
|
107 */ |
|
108 void ScanningHelper::numberScrollUpdate( int value ) |
|
109 { |
|
110 if ( mStationItem ) { |
|
111 mStationItem->setFrequency( value * KFreqScrollDivider ); |
|
112 } |
|
113 } |
|
114 |
|
115 // =============================================================== |
|
116 // Carousel |
|
117 // =============================================================== |
|
118 |
|
119 /*! |
|
120 * |
|
121 */ |
|
122 RadioStationCarousel::RadioStationCarousel( RadioUiEngine* uiEngine ) : |
|
123 HbGridView( 0 ), |
|
124 mUiEngine( uiEngine ), |
|
125 mAntennaAttached( false ), |
|
126 mAutoScrollTime( 300 ), |
63 mAutoScrollTime( 300 ), |
127 mGenericTimer( new QTimer( this ) ), |
64 mGenericTimer( new QTimer( this ) ), |
128 mTimerMode( NoTimer ), |
65 mTimerMode( NoTimer ), |
129 mScanningHelper( 0 ), |
66 mAnimator( NULL ), |
130 mInfoText( 0 ), |
67 mInfoText( NULL ), |
131 mCurrentItem( 0 ), |
68 mContainer( new HbWidget( this ) ), |
132 mPanStartPos( 0 ) |
69 mMidScrollPos( 0 ), |
|
70 mMaxScrollPos( 0 ), |
|
71 mCurrentIndex( 0 ), |
|
72 mTargetIndex( -1 ), |
|
73 mIsCustomFreq( false ), |
|
74 mInfoTextType( CarouselInfoText::None ), |
|
75 mModel( NULL ), |
|
76 mPosAdjustmentDisabled( false ), |
|
77 mScrollDirection( Scroll::Shortest ), |
|
78 mManualSeekMode( false ), |
|
79 mAlternateSkipping( false ) |
133 #ifdef USE_DEBUGGING_CONTROLS |
80 #ifdef USE_DEBUGGING_CONTROLS |
134 ,mRdsLabel( new RadioFadingLabel( this ) ) |
81 ,mRdsLabel( new RadioFadingLabel( this ) ) |
135 #endif // USE_DEBUGGING_CONTROLS |
82 #endif // USE_DEBUGGING_CONTROLS |
136 { |
83 { |
137 RadioUiUtilities::setCarousel( this ); |
|
138 setClampingStyle( HbScrollArea::StrictClamping ); |
|
139 setScrollingStyle( HbScrollArea::Pan ); |
|
140 } |
84 } |
141 |
85 |
142 /*! |
86 /*! |
143 * Property |
87 * Property |
144 * |
88 * |
195 * |
139 * |
196 */ |
140 */ |
197 void RadioStationCarousel::init( RadioUiLoader& uiLoader, RadioUiEngine* uiEngine ) |
141 void RadioStationCarousel::init( RadioUiLoader& uiLoader, RadioUiEngine* uiEngine ) |
198 { |
142 { |
199 mUiEngine = uiEngine; |
143 mUiEngine = uiEngine; |
200 mAntennaAttached = mUiEngine->isAntennaAttached(); |
144 RadioUtil::setCarousel( this ); |
|
145 |
|
146 mItems[LeftItem] = new RadioCarouselItem( *this ); |
|
147 mItems[CenterItem] = new RadioCarouselItem( *this ); |
|
148 mItems[RightItem] = new RadioCarouselItem( *this ); |
|
149 |
|
150 QGraphicsLinearLayout* layout = new QGraphicsLinearLayout( Qt::Horizontal ); |
|
151 layout->setContentsMargins( 0, 0, 0, 0 ); |
|
152 layout->setSpacing( 0 ); |
|
153 layout->addItem( mItems[LeftItem] ); |
|
154 layout->addItem( mItems[CenterItem] ); |
|
155 layout->addItem( mItems[RightItem] ); |
|
156 mContainer->setLayout( layout ); |
|
157 setContentWidget( mContainer ); |
|
158 |
|
159 setClampingStyle( HbScrollArea::NoClamping ); |
|
160 setScrollDirections( Qt::Horizontal ); |
|
161 |
|
162 setFrictionEnabled( true ); |
|
163 setHorizontalScrollBarPolicy( HbScrollArea::SCROLLBAR_POLICY ); |
|
164 setVerticalScrollBarPolicy( HbScrollArea::ScrollBarAlwaysOff ); |
201 |
165 |
202 mInfoText = uiLoader.findWidget<HbLabel>( DOCML::MV_NAME_INFO_TEXT ); |
166 mInfoText = uiLoader.findWidget<HbLabel>( DOCML::MV_NAME_INFO_TEXT ); |
203 mInfoText->setTextWrapping( Hb::TextWordWrap ); |
167 mInfoText->setTextWrapping( Hb::TextWordWrap ); |
204 |
168 |
205 setRowCount( 1 ); |
169 #ifdef BUILD_WIN32 |
206 setColumnCount( 1 ); |
170 HbFontSpec spec = mInfoText->fontSpec(); |
|
171 spec.setRole( HbFontSpec::Secondary ); |
|
172 mInfoText->setFontSpec( spec ); |
|
173 #endif |
|
174 |
207 setScrollDirections( Qt::Horizontal ); |
175 setScrollDirections( Qt::Horizontal ); |
208 setFrictionEnabled( true ); |
176 // grabGesture( Qt::SwipeGesture ); |
209 setLongPressEnabled( false ); |
177 |
210 setItemRecycling( false ); |
178 // Radio::connect( this, SIGNAL(scrollPositionChanged(QPointF)), |
211 setUniformItemSizes( true ); |
179 // this, SLOT(scrollPosChanged(QPointF)) ); |
212 setItemPrototype( new RadioStationItem( *this ) ); |
180 Radio::connect( this, SIGNAL(scrollingEnded()), |
213 setSelectionMode( NoSelection ); |
181 this, SLOT(adjustAfterScroll()) ); |
214 |
182 |
215 // grabGesture( Qt::PanGesture ); |
183 mModel = &mUiEngine->stationModel(); |
216 |
184 Radio::connect( mModel, SIGNAL(favoriteChanged(RadioStation)), |
217 RadioCarouselModel* carouselModel = mUiEngine->carouselModel(); |
|
218 setCarouselModel( carouselModel ); |
|
219 |
|
220 mCurrentItem = static_cast<RadioStationItem*>( itemByIndex( carouselModel->index( 0, 0 ) ) ); |
|
221 |
|
222 RadioStationModel* stationModel = &mUiEngine->stationModel(); |
|
223 connectAndTest( stationModel, SIGNAL(favoriteChanged(RadioStation)), |
|
224 this, SLOT(update(RadioStation)) ); |
185 this, SLOT(update(RadioStation)) ); |
225 connectAndTest( stationModel, SIGNAL(stationDataChanged(RadioStation)), |
186 Radio::connect( mModel, SIGNAL(stationDataChanged(RadioStation)), |
226 this, SLOT(update(RadioStation))); |
187 this, SLOT(update(RadioStation))); |
227 connectAndTest( stationModel, SIGNAL(radioTextReceived(RadioStation)), |
188 Radio::connect( mModel, SIGNAL(radioTextReceived(RadioStation)), |
228 this, SLOT(updateRadioText(RadioStation))); |
189 this, SLOT(updateRadioText(RadioStation))); |
229 connectAndTest( stationModel, SIGNAL(dynamicPsChanged(RadioStation)), |
190 Radio::connect( mModel, SIGNAL(dynamicPsChanged(RadioStation)), |
230 this, SLOT(update(RadioStation))); |
191 this, SLOT(update(RadioStation))); |
231 |
192 |
232 updateClampingStyle(); |
|
233 |
|
234 connectAndTest( this, SIGNAL(longPressed(HbAbstractViewItem*,QPointF)), |
|
235 this, SLOT(openContextMenu(HbAbstractViewItem*,QPointF)) ); |
|
236 setLongPressEnabled( true ); |
|
237 |
|
238 mGenericTimer->setSingleShot( true ); |
193 mGenericTimer->setSingleShot( true ); |
239 connectAndTest( mGenericTimer, SIGNAL(timeout()), |
194 Radio::connect( mGenericTimer, SIGNAL(timeout()), |
240 this, SLOT(timerFired())); |
195 this, SLOT(timerFired())); |
241 |
196 |
242 initToLastTunedFrequency(); |
197 Radio::connect( mModel, SIGNAL(rowsInserted(QModelIndex,int,int)), |
|
198 this, SLOT(updateStations()) ); |
|
199 Radio::connect( mModel, SIGNAL(modelReset()), |
|
200 this, SLOT(updateStations()) ); |
|
201 Radio::connect( mModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), |
|
202 this, SLOT(updateStations()) ); |
|
203 |
|
204 setFrequency( mUiEngine->currentFrequency(), TuneReason::Unspecified ); |
243 |
205 |
244 #ifdef USE_DEBUGGING_CONTROLS |
206 #ifdef USE_DEBUGGING_CONTROLS |
245 mRdsLabel->setPos( QPoint( 300, 10 ) ); |
207 mRdsLabel->setPos( QPoint( 300, 10 ) ); |
246 mRdsLabel->setText( "RDS" ); |
208 mRdsLabel->setText( "RDS" ); |
247 mRdsLabel->setElideMode( Qt::ElideNone ); |
209 mRdsLabel->setElideMode( Qt::ElideNone ); |
249 spec.setTextPaneHeight( 10 ); |
211 spec.setTextPaneHeight( 10 ); |
250 spec.setRole( HbFontSpec::Secondary ); |
212 spec.setRole( HbFontSpec::Secondary ); |
251 mRdsLabel->setFontSpec( spec ); |
213 mRdsLabel->setFontSpec( spec ); |
252 mRdsLabel->setTextColor( Qt::gray ); |
214 mRdsLabel->setTextColor( Qt::gray ); |
253 if ( mUiEngine ) { |
215 if ( mUiEngine ) { |
254 connectAndTest( mUiEngine, SIGNAL(rdsAvailabilityChanged(bool)), |
216 Radio::connect( mUiEngine, SIGNAL(rdsAvailabilityChanged(bool)), |
255 this, SLOT(setRdsAvailable(bool)) ); |
217 this, SLOT(setRdsAvailable(bool)) ); |
256 } |
218 } |
257 #endif // USE_DEBUGGING_CONTROLS |
219 #endif // USE_DEBUGGING_CONTROLS |
258 } |
220 } |
259 |
221 |
260 /*! |
222 /*! |
261 * |
223 * |
262 */ |
224 */ |
263 void RadioStationCarousel::setCarouselModel( RadioCarouselModel* carouselModel ) |
225 void RadioStationCarousel::setFrequency( uint frequency, int reason, Scroll::Direction direction ) |
264 { |
226 { |
265 if ( carouselModel ) { |
227 if ( mModel ) { |
266 connectAndTest( carouselModel, SIGNAL(rowsInserted(QModelIndex,int,int)), |
228 if ( !mManualSeekMode ) { |
267 this, SLOT(insertFrequency(QModelIndex,int,int)) ); |
229 |
268 connectAndTest( carouselModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), |
230 if ( mModel->rowCount() <= 1 ) { |
269 this, SLOT(prepareToRemoveFrequency(QModelIndex,int,int)) ); |
231 mItems[LeftItem]->setStation( RadioStation() ); |
270 connectAndTest( carouselModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), |
232 mItems[RightItem]->setStation( RadioStation() ); |
271 this, SLOT(removeFrequency(QModelIndex,int,int)) ); |
233 } |
|
234 |
|
235 mIsCustomFreq = false; |
|
236 if ( reason == TuneReason::Skip || reason == TuneReason::StationScanFinalize ) { |
|
237 const int newIndex = mModel->indexFromFrequency( frequency ); |
|
238 scrollToIndex( newIndex, direction, NoSignal ); |
|
239 mCurrentIndex = newIndex; |
|
240 } else { |
|
241 if ( mModel->contains( frequency ) ) { |
|
242 mCurrentIndex = mModel->indexFromFrequency( frequency ); |
|
243 } else { |
|
244 const RadioStation prevStation = mModel->findClosest( frequency, StationSkip::Previous ); |
|
245 if ( prevStation.isValid() ) { |
|
246 mCurrentIndex = mModel->indexFromFrequency( prevStation.frequency() ); |
|
247 } else { |
|
248 mCurrentIndex = -1; |
|
249 } |
|
250 |
|
251 mIsCustomFreq = true; |
|
252 } |
|
253 |
|
254 mItems[CenterItem]->setFrequency( frequency ); |
|
255 mTimerMode = SetFrequency; |
|
256 mGenericTimer->stop(); |
|
257 mGenericTimer->start( SET_FREQUENCY_TIMEOUT ); |
|
258 } |
|
259 } else { |
|
260 mItems[CenterItem]->setFrequency( frequency ); |
|
261 } |
|
262 } |
|
263 } |
|
264 |
|
265 /*! |
|
266 * |
|
267 */ |
|
268 RadioUiEngine* RadioStationCarousel::uiEngine() |
|
269 { |
|
270 return mUiEngine; |
|
271 } |
|
272 |
|
273 /*! |
|
274 * |
|
275 */ |
|
276 bool RadioStationCarousel::isAntennaAttached() const |
|
277 { |
|
278 return mUiEngine->isAntennaAttached(); |
|
279 } |
|
280 |
|
281 /*! |
|
282 * |
|
283 */ |
|
284 void RadioStationCarousel::setScanningMode( bool scanning ) |
|
285 { |
|
286 CALL_TO_ALL_ITEMS( setSeekLayout( scanning ) ); |
|
287 |
|
288 if ( scanning ) { |
|
289 setInfoText( CarouselInfoText::Scanning ); |
|
290 if ( !mAnimator ) { |
|
291 mAnimator = new RadioCarouselAnimator( *this ); |
|
292 } |
|
293 mAnimator->startFlashingText(); |
272 } else { |
294 } else { |
273 QAbstractItemModel* currentModel = model(); |
295 if ( mAnimator ) { |
274 disconnect( currentModel, SIGNAL(rowsInserted(QModelIndex,int,int)), |
296 mAnimator->stopFlashingText(); |
275 this, SLOT(insertFrequency(QModelIndex,int,int)) ); |
297 } |
276 disconnect( currentModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), |
|
277 this, SLOT(prepareToRemoveFrequency(QModelIndex,int,int)) ); |
|
278 disconnect( currentModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), |
|
279 this, SLOT(removeFrequency(QModelIndex,int,int)) ); |
|
280 } |
|
281 setModel( carouselModel ); |
|
282 updateFrequencies(); |
|
283 initCurrentStationItem(); |
|
284 } |
|
285 |
|
286 /*! |
|
287 * |
|
288 */ |
|
289 void RadioStationCarousel::setFrequency( uint frequency, int reason ) |
|
290 { |
|
291 RadioStationItem* item = currentStationItem(); |
|
292 // if ( item && item->mFrequency == frequency ) { |
|
293 // return; |
|
294 // } |
|
295 |
|
296 if ( mModelIndexes.contains( frequency ) ) { |
|
297 QModelIndex index = mModelIndexes.value( frequency ); |
|
298 |
|
299 if ( reason == TuneReason::FrequencyStrip || reason == TuneReason::StationsList ) { |
|
300 scrollToIndex( index, RadioStationCarousel::NoAnim | RadioStationCarousel::NoSignal ); |
|
301 } else if ( reason == TuneReason::Skip || reason == TuneReason::StationScan ) { |
|
302 scrollToIndex( index, RadioStationCarousel::NoSignal ); |
|
303 } else { |
|
304 scrollToIndex( index ); |
|
305 } |
|
306 } else { |
|
307 if ( item ) { |
|
308 item->setFrequency( frequency ); |
|
309 } |
|
310 } |
|
311 } |
|
312 |
|
313 /*! |
|
314 * |
|
315 */ |
|
316 RadioUiEngine* RadioStationCarousel::uiEngine() |
|
317 { |
|
318 return mUiEngine; |
|
319 } |
|
320 |
|
321 /*! |
|
322 * |
|
323 */ |
|
324 bool RadioStationCarousel::isAntennaAttached() const |
|
325 { |
|
326 return mAntennaAttached; |
|
327 } |
|
328 |
|
329 /*! |
|
330 * |
|
331 */ |
|
332 void RadioStationCarousel::setScanningMode( bool scanning ) |
|
333 { |
|
334 initCurrentStationItem(); |
|
335 |
|
336 if ( scanning ) { |
|
337 |
|
338 setInfoText( CarouselInfoText::Scanning ); |
|
339 if ( !mScanningHelper ) { |
|
340 mScanningHelper = new ScanningHelper( *this ); |
|
341 } |
|
342 } else { |
|
343 delete mScanningHelper; |
|
344 mScanningHelper = 0; |
|
345 clearInfoText(); |
298 clearInfoText(); |
346 } |
299 setCenterIndex( 0 ); |
|
300 mTimerMode = FavoriteHintShow; |
|
301 mGenericTimer->start( FAVORITE_HINT_SHOW_DELAY ); |
|
302 } |
|
303 |
347 setEnabled( !scanning ); |
304 setEnabled( !scanning ); |
348 } |
305 } |
349 |
306 |
350 /*! |
307 /*! |
351 * |
308 * |
352 */ |
309 */ |
353 bool RadioStationCarousel::isInScanningMode() const |
310 bool RadioStationCarousel::isInScanningMode() const |
354 { |
311 { |
355 return RadioUiUtilities::isScannerAlive(); |
312 return RadioUtil::scanStatus() == Scan::ScanningInMainView; |
356 } |
313 } |
357 |
314 |
358 /*! |
315 /*! |
359 * |
316 * |
360 */ |
317 */ |
361 void RadioStationCarousel::cleanRdsData() |
318 void RadioStationCarousel::cleanRdsData() |
362 { |
319 { |
363 RadioStationItem* item = currentStationItem(); |
320 mItems[CenterItem]->cleanRdsData(); |
364 if ( item ) { |
|
365 item->cleanRdsData(); |
|
366 } |
|
367 } |
|
368 |
|
369 /*! |
|
370 * |
|
371 */ |
|
372 void RadioStationCarousel::updateCurrentItem() |
|
373 { |
|
374 RadioStationItem* item = currentStationItem(); |
|
375 if ( item ) { |
|
376 item->update(); |
|
377 } |
|
378 } |
321 } |
379 |
322 |
380 /*! |
323 /*! |
381 * |
324 * |
382 */ |
325 */ |
383 void RadioStationCarousel::animateNewStation( const RadioStation& station ) |
326 void RadioStationCarousel::animateNewStation( const RadioStation& station ) |
384 { |
327 { |
385 if ( mScanningHelper ) { |
328 if ( mAnimator && mUiEngine ) { |
386 RadioCarouselModel* model = carouselModel(); |
329 const uint previousFrequency = mItems[CenterItem]->frequency(); |
387 const QModelIndex index = model->modelIndexFromFrequency( station.frequency() ); |
330 |
388 mScanningHelper->mModelIndex = index; |
331 mItems[RightItem]->setFrequency( previousFrequency ); |
389 mScanningHelper->mCurrentFrequency = station.frequency(); |
332 mCurrentIndex = mModel->indexFromFrequency( station.frequency() ); |
390 mScanningHelper->mStationItem = static_cast<RadioStationItem*>( itemByIndex( index ) ); |
333 |
391 |
334 mAnimator->startNumberScroll( previousFrequency, station.frequency() ); |
392 uint prevFrequency = 0; |
335 } |
393 if ( model->rowCount() > 1 ) { |
336 } |
394 const int prevIndex = index.row() - 1; |
337 |
395 RadioStation prevStation = model->data( model->index( prevIndex, 0 ), RadioStationModel::RadioStationRole ).value<RadioStation>(); |
338 /*! |
396 prevFrequency = prevStation.frequency(); |
339 * |
397 } else if ( mUiEngine ) { |
340 */ |
398 prevFrequency = mUiEngine->minFrequency(); |
341 void RadioStationCarousel::cancelAnimation() |
399 } |
342 { |
400 |
343 if ( mAnimator ) { |
401 mScanningHelper->mPreviousFrequency = prevFrequency; |
344 mAnimator->stopAll(); |
402 if ( mScanningHelper->mStationItem ) { |
|
403 mScanningHelper->mStationItem->setFrequency( prevFrequency ); |
|
404 mScanningHelper->mStationItem->cleanRdsData(); |
|
405 } |
|
406 |
|
407 mScanningHelper->start(); |
|
408 } |
|
409 } |
|
410 |
|
411 /*! |
|
412 * |
|
413 */ |
|
414 void RadioStationCarousel::setItemVisible( bool visible ) |
|
415 { |
|
416 RadioStationItem* item = currentStationItem(); |
|
417 if ( item ) { |
|
418 item->setVisible( visible ); |
|
419 } |
345 } |
420 } |
346 } |
421 |
347 |
422 /*! |
348 /*! |
423 * |
349 * |
424 */ |
350 */ |
425 void RadioStationCarousel::setInfoText( CarouselInfoText::Type type ) |
351 void RadioStationCarousel::setInfoText( CarouselInfoText::Type type ) |
426 { |
352 { |
427 mInfoTextType = type; |
353 mInfoTextType = type; |
428 if ( type == CarouselInfoText::NoFavorites ) { |
354 if ( type == CarouselInfoText::NoFavorites || type == CarouselInfoText::FavoriteIconHint ) { |
429 mInfoText->setPlainText( hbTrId( "txt_rad_dialog_long_press_arrow_keys_to_search_str" ) ); |
355 // mInfoText->setPlainText( hbTrId( "txt_rad_dialog_long_press_arrow_keys_to_search_str" ) ); |
|
356 //TODO: Remove hardcoding. Temporarily hardcoded for usability testing |
|
357 mInfoText->setPlainText( "Tap star to mark favourites" ); |
430 mInfoText->setAlignment( Qt::AlignCenter ); |
358 mInfoText->setAlignment( Qt::AlignCenter ); |
431 setItemVisible( false ); |
359 mItems[CenterItem]->setItemVisibility( RadioCarouselItem::IconVisible ); |
432 mTimerMode = InfoText; |
360 mTimerMode = InfoText; |
433 mGenericTimer->setInterval( INFOTEXT_NOFAVORITES_TIMEOUT ); |
361 mGenericTimer->setInterval( INFOTEXT_NOFAVORITES_TIMEOUT ); |
434 mGenericTimer->start(); |
362 mGenericTimer->start(); |
|
363 |
|
364 if ( !mAnimator ) { |
|
365 mAnimator = new RadioCarouselAnimator( *this ); |
|
366 } |
|
367 mAnimator->startFlashingIcon(); |
|
368 |
435 } else if ( type == CarouselInfoText::ConnectAntenna ) { |
369 } else if ( type == CarouselInfoText::ConnectAntenna ) { |
436 cleanRdsData(); |
370 cleanRdsData(); |
437 mInfoText->setPlainText( hbTrId( "txt_rad_info_connect_wired_headset1" ) ); |
371 mInfoText->setPlainText( hbTrId( "txt_rad_info_connect_wired_headset1" ) ); |
438 mInfoText->setAlignment( Qt::AlignBottom | Qt::AlignHCenter ); |
372 mInfoText->setAlignment( Qt::AlignBottom | Qt::AlignHCenter ); |
439 } else if ( type == CarouselInfoText::Seeking ) { |
373 } else if ( type == CarouselInfoText::Seeking ) { |
453 * |
390 * |
454 */ |
391 */ |
455 void RadioStationCarousel::clearInfoText() |
392 void RadioStationCarousel::clearInfoText() |
456 { |
393 { |
457 if ( mInfoTextType != CarouselInfoText::None ) { |
394 if ( mInfoTextType != CarouselInfoText::None ) { |
|
395 if ( mAnimator ) { |
|
396 mAnimator->stopFlashingIcon(); |
|
397 } |
|
398 |
458 mGenericTimer->stop(); |
399 mGenericTimer->stop(); |
459 mInfoTextType = CarouselInfoText::None; |
400 mInfoTextType = CarouselInfoText::None; |
460 mInfoText->setVisible( false ); |
401 mInfoText->setVisible( false ); |
461 mInfoText->clear(); |
402 mInfoText->clear(); |
462 setItemVisible( true ); |
403 mItems[CenterItem]->setItemVisibility( RadioCarouselItem::AllVisible ); |
463 updateCurrentItem(); |
404 } |
464 } |
405 } |
|
406 |
|
407 /*! |
|
408 * |
|
409 */ |
|
410 void RadioStationCarousel::setManualSeekMode( bool manualSeekActive ) |
|
411 { |
|
412 mManualSeekMode = manualSeekActive; |
|
413 setEnabled( !manualSeekActive ); |
|
414 |
|
415 mItems[CenterItem]->setSeekLayout( manualSeekActive ); |
|
416 if ( manualSeekActive ) { |
|
417 setInfoText( CarouselInfoText::ManualSeek ); |
|
418 } else { |
|
419 clearInfoText(); |
|
420 setFrequency( mUiEngine->currentFrequency(), TuneReason::Unspecified ); |
|
421 } |
|
422 } |
|
423 |
|
424 /*! |
|
425 * TODO: Remove this! This is test code |
|
426 */ |
|
427 void RadioStationCarousel::setAlternateSkippingMode( bool alternateSkipping ) |
|
428 { |
|
429 mAlternateSkipping = alternateSkipping; |
465 } |
430 } |
466 |
431 |
467 /*! |
432 /*! |
468 * Private slot |
433 * Private slot |
|
434 * |
|
435 */ |
|
436 void RadioStationCarousel::scrollPosChanged( const QPointF& newPosition ) |
|
437 { |
|
438 Q_UNUSED( newPosition ); |
|
439 // const int xPos = static_cast<int>( newPosition.x() ); |
|
440 // mItems[CenterItem]->setPos( xPos - mMidScrollPos, 0 ); |
|
441 } |
|
442 |
|
443 /*! |
|
444 * Private slot |
|
445 '' |
|
446 */ |
|
447 void RadioStationCarousel::adjustAfterScroll() |
|
448 { |
|
449 if ( isInScanningMode() ) { |
|
450 return; |
|
451 } |
|
452 |
|
453 if ( mTargetIndex != -1 ) { |
|
454 setCenterIndex( mTargetIndex ); |
|
455 } |
|
456 } |
|
457 |
|
458 /*! |
|
459 * Private slot |
|
460 * |
469 */ |
461 */ |
470 void RadioStationCarousel::update( const RadioStation& station ) |
462 void RadioStationCarousel::update( const RadioStation& station ) |
471 { |
463 { |
472 RadioStationItem* item = currentStationItem(); |
464 if ( !mManualSeekMode && !isInScanningMode() ) { |
473 if ( item && item->frequency() == station.frequency() && !isInScanningMode() ) { |
465 for ( int i = LeftItem; i <= RightItem; ++i ) { |
474 item->update( &station ); |
466 if ( mItems[i]->frequency() == station.frequency() ) { |
|
467 mItems[i]->update( &station ); |
|
468 } |
|
469 } |
475 } |
470 } |
476 } |
471 } |
477 |
472 |
478 /*! |
473 /*! |
479 * Private slot |
474 * Private slot |
480 */ |
475 */ |
481 void RadioStationCarousel::updateRadioText( const RadioStation& station ) |
476 void RadioStationCarousel::updateRadioText( const RadioStation& station ) |
482 { |
477 { |
483 if ( isAntennaAttached() && !isInScanningMode() ) { |
478 if ( isAntennaAttached() && !isInScanningMode() ) { |
484 if ( station.radioText().isEmpty() ) { |
479 if ( station.radioText().isEmpty() ) { |
485 RadioStationItem* item = currentStationItem(); |
480 mItems[CenterItem]->setRadioText( "" ); |
486 if ( item ) { |
|
487 item->mRadiotextLabel->setText( "" ); |
|
488 } |
|
489 } else { |
481 } else { |
490 mRadioTextHolder = station.radioText(); |
482 mRadioTextHolder = station.radioText(); |
491 mTimerMode = RtPlusCheck; |
483 mTimerMode = RtPlusCheck; |
492 mGenericTimer->stop(); |
484 mGenericTimer->stop(); |
493 mGenericTimer->setInterval( KRadioTextPlusCheckTimeout ); |
485 mGenericTimer->setInterval( RTPLUS_CHECK_TIMEOUT ); |
494 mGenericTimer->start(); |
486 mGenericTimer->start(); |
495 } |
487 } |
496 } |
488 } |
497 } |
489 } |
498 |
490 |
499 /*! |
491 /*! |
500 * Private slot |
492 * Private slot |
501 */ |
493 */ |
502 void RadioStationCarousel::insertFrequency( const QModelIndex& parent, int first, int last ) |
494 void RadioStationCarousel::updateStations() |
503 { |
495 { |
504 Q_UNUSED( parent ); |
496 if ( isInScanningMode() ) { |
505 QAbstractItemModel* freqModel = model(); |
497 return; |
506 |
498 } |
507 for ( int i = first; freqModel && i <= last; ++i ) { |
499 |
508 QModelIndex index = freqModel->index( i, 0 ); |
500 setFrequency( mUiEngine->currentFrequency(), TuneReason::Unspecified ); |
509 RadioStation station = freqModel->data( index, RadioStationModel::RadioStationRole ).value<RadioStation>(); |
|
510 mModelIndexes.insert( station.frequency(), index ); |
|
511 LOG_FORMAT( "Added frequency %u", station.frequency() ); |
|
512 if ( !isInScanningMode() ) { |
|
513 scrollToIndex( index, RadioStationCarousel::NoAnim | RadioStationCarousel::NoSignal ); |
|
514 } |
|
515 } |
|
516 |
|
517 initCurrentStationItem(); |
|
518 |
|
519 updateClampingStyle(); |
|
520 } |
501 } |
521 |
502 |
522 /*! |
503 /*! |
523 * Private slot |
504 * Private slot |
524 */ |
505 */ |
525 void RadioStationCarousel::prepareToRemoveFrequency( const QModelIndex& parent, int first, int last ) |
|
526 { |
|
527 Q_UNUSED( parent ); |
|
528 QAbstractItemModel* freqModel = model(); |
|
529 for ( int i = first; freqModel && i <= last; ++i ) { |
|
530 QModelIndex index = freqModel->index( i, 0 ); |
|
531 RadioStation station = freqModel->data( index, RadioStationModel::RadioStationRole ).value<RadioStation>(); |
|
532 mModelIndexes.remove( station.frequency() ); |
|
533 } |
|
534 } |
|
535 |
|
536 /*! |
|
537 * Private slot |
|
538 */ |
|
539 void RadioStationCarousel::removeFrequency( const QModelIndex& parent, int first, int last ) |
|
540 { |
|
541 Q_UNUSED( parent ); |
|
542 Q_UNUSED( first ); |
|
543 Q_UNUSED( last ); |
|
544 |
|
545 initCurrentStationItem(); |
|
546 updateClampingStyle(); |
|
547 } |
|
548 |
|
549 /*! |
|
550 * Private slot |
|
551 */ |
|
552 void RadioStationCarousel::updateFrequencies() |
|
553 { |
|
554 mModelIndexes.clear(); |
|
555 QAbstractItemModel* itemModel = model(); |
|
556 if ( itemModel ) { |
|
557 const int count = itemModel->rowCount(); |
|
558 for ( int i = 0; i < count; ++i ) { |
|
559 QModelIndex index = itemModel->index( i, 0 ); |
|
560 uint frequency = itemModel->data( index, RadioStationModel::RadioStationRole ).value<RadioStation>().frequency(); |
|
561 mModelIndexes.insert( frequency, index ); |
|
562 } |
|
563 } |
|
564 } |
|
565 |
|
566 /*! |
|
567 * Private slot |
|
568 */ |
|
569 void RadioStationCarousel::timerFired() |
506 void RadioStationCarousel::timerFired() |
570 { |
507 { |
571 if ( mTimerMode == RtPlusCheck ) { |
508 if ( mTimerMode == SetFrequency ) { |
572 RadioStationItem* item = currentStationItem(); |
509 setCenterIndex( mCurrentIndex, NoSignal | IgnoreCenter ); |
573 if ( item ) { |
510 mTimerMode = NoTimer; |
574 item->mRadiotextLabel->setText( mRadioTextHolder ); |
511 } else if ( mTimerMode == RtPlusCheck ) { |
575 } |
512 //mItems[CenterItem]->mRadiotextLabel->setText( mRadioTextHolder ); |
576 mRadioTextHolder = ""; |
513 mRadioTextHolder = ""; |
|
514 mTimerMode = NoTimer; |
577 } else if ( mTimerMode == InfoText ) { |
515 } else if ( mTimerMode == InfoText ) { |
578 clearInfoText(); |
516 clearInfoText(); |
579 } |
517 mTimerMode = NoTimer; |
580 |
518 } else if ( mTimerMode == FavoriteHintShow ) { |
581 mTimerMode = NoTimer; |
519 setInfoText( CarouselInfoText::FavoriteIconHint ); |
|
520 mTimerMode = FavoriteHintHide; |
|
521 mGenericTimer->start( FAVORITE_HINT_HIDE_DELAY ); |
|
522 } else if ( mTimerMode == FavoriteHintHide ) { |
|
523 clearInfoText(); |
|
524 mTimerMode = NoTimer; |
|
525 } |
582 } |
526 } |
583 |
527 |
584 /*! |
528 /*! |
585 * Private slot |
529 * Private slot |
586 */ |
530 */ |
587 void RadioStationCarousel::openContextMenu( HbAbstractViewItem* item, const QPointF& coords ) |
531 void RadioStationCarousel::toggleFavorite() |
588 { |
532 { |
589 if ( item ) { |
533 if ( mModel ) { |
590 static_cast<RadioStationItem*>( item )->handleLongPress( coords ); |
534 mModel->setData( QModelIndex(), mItems[CenterItem]->frequency(), RadioRole::ToggleFavoriteRole ); |
591 } |
535 } |
592 } |
536 } |
|
537 |
|
538 /*! |
|
539 * Private slot |
|
540 */ |
|
541 //void RadioStationCarousel::openContextMenu( HbAbstractViewItem* item, const QPointF& coords ) |
|
542 //{ |
|
543 // if ( item ) { |
|
544 // static_cast<RadioStationItem*>( item )->handleLongPress( coords ); |
|
545 // } |
|
546 //} |
593 |
547 |
594 #ifdef USE_DEBUGGING_CONTROLS |
548 #ifdef USE_DEBUGGING_CONTROLS |
595 /*! |
549 /*! |
596 * Public slot |
550 * Public slot |
597 */ |
551 */ |
627 /*! |
580 /*! |
628 * \reimp |
581 * \reimp |
629 */ |
582 */ |
630 void RadioStationCarousel::mousePressEvent( QGraphicsSceneMouseEvent* event ) |
583 void RadioStationCarousel::mousePressEvent( QGraphicsSceneMouseEvent* event ) |
631 { |
584 { |
632 if ( mInfoTextType == CarouselInfoText::NoFavorites ) { |
585 if ( mInfoTextType == CarouselInfoText::NoFavorites || mInfoTextType == CarouselInfoText::FavoriteIconHint ) { |
633 clearInfoText(); |
586 clearInfoText(); |
634 } |
587 } |
635 |
588 |
636 HbGridView::mousePressEvent( event ); |
589 HbScrollArea::mousePressEvent( event ); |
637 } |
590 } |
638 |
591 |
639 /*! |
592 /*! |
640 * \reimp |
593 * \reimp |
641 */ |
594 */ |
|
595 void RadioStationCarousel::resizeEvent( QGraphicsSceneResizeEvent* event ) |
|
596 { |
|
597 HbScrollArea::resizeEvent( event ); |
|
598 |
|
599 const int width = (int)event->newSize().width(); |
|
600 |
|
601 mMidScrollPos = -width; |
|
602 mMaxScrollPos = mMidScrollPos * 2; |
|
603 |
|
604 if ( isInitialized() ) { |
|
605 mItems[LeftItem]->setMinimumWidth( width ); |
|
606 mItems[CenterItem]->setMinimumWidth( width ); |
|
607 mItems[RightItem]->setMinimumWidth( width ); |
|
608 } |
|
609 } |
|
610 |
|
611 /*! |
|
612 * \reimp |
|
613 */ |
|
614 void RadioStationCarousel::showEvent( QShowEvent* event ) |
|
615 { |
|
616 HbScrollArea::showEvent( event ); |
|
617 // mContainer->setPos( mMidScrollPos, 0 ); |
|
618 } |
|
619 |
|
620 /*! |
|
621 * \reimp |
|
622 */ |
642 void RadioStationCarousel::gestureEvent( QGestureEvent* event ) |
623 void RadioStationCarousel::gestureEvent( QGestureEvent* event ) |
643 { |
624 { |
644 HbGridView::gestureEvent( event ); |
625 // if ( HbSwipeGesture* swipeGesture = static_cast<HbSwipeGesture*>( event->gesture( Qt::SwipeGesture ) ) ) { |
|
626 // if ( swipeGesture->state() == Qt::GestureFinished ) { |
|
627 // if ( swipeGesture->horizontalDirection() == QSwipeGesture::Left ) { |
|
628 // emit skipRequested( StationSkip::Next ); |
|
629 // } else if ( swipeGesture->horizontalDirection() == QSwipeGesture::Right ) { |
|
630 // emit skipRequested( StationSkip::Previous ); |
|
631 // } |
|
632 // mIsCustomFreq = false; |
|
633 // } |
|
634 // return; |
|
635 // } |
|
636 |
|
637 HbScrollArea::gestureEvent( event ); |
645 |
638 |
646 if ( HbPanGesture* gesture = qobject_cast<HbPanGesture*>( event->gesture( Qt::PanGesture ) ) ) { |
639 if ( HbPanGesture* gesture = qobject_cast<HbPanGesture*>( event->gesture( Qt::PanGesture ) ) ) { |
647 if ( gesture->state() == Qt::GestureFinished ) { |
640 if ( gesture->state() == Qt::GestureFinished ) { |
648 updatePos( (int)gesture->offset().x() ); |
641 adjustPos( (int)gesture->offset().x() ); |
649 } |
642 } |
650 } |
643 } |
651 } |
644 } |
652 |
645 |
653 /*! |
646 /*! |
654 * |
647 * |
655 */ |
648 */ |
656 void RadioStationCarousel::initToLastTunedFrequency() |
649 bool RadioStationCarousel::isInitialized() const |
657 { |
650 { |
658 const uint currentFrequency = mUiEngine->currentFrequency(); |
651 return mUiEngine != NULL; |
659 const QModelIndex currentIndex = carouselModel()->modelIndexFromFrequency( currentFrequency ); |
652 } |
660 |
653 |
661 if ( currentIndex.isValid() ) {//&& itemByIndex( currentIndex ) ) { |
654 /*! |
662 scrollToIndex( currentIndex, RadioStationCarousel::NoSignal | RadioStationCarousel::NoAnim ); |
655 * |
663 } else { |
656 */ |
664 RadioStationItem* item = static_cast<RadioStationItem*>( itemAt( 0, 0 ) ); |
657 void RadioStationCarousel::setCenterIndex( int index, ScrollMode mode ) |
665 if ( item ) { |
658 { |
666 item->setFrequency( currentFrequency ); |
659 Q_UNUSED( mode ); |
667 } |
660 if ( mModel ) { |
668 } |
661 const int newIndex = trimIndex( index ); |
669 } |
662 mCurrentIndex = newIndex; |
670 |
663 mTargetIndex = -1; |
671 /*! |
664 |
672 * |
665 if ( !mIsCustomFreq ) { |
673 */ |
666 mItems[CenterItem]->setStation( mModel->stationAt( mCurrentIndex ) ); |
674 void RadioStationCarousel::updateClampingStyle() |
667 } |
675 { |
668 |
676 if ( model()->rowCount() > 1 ) { |
669 if ( mModel->rowCount() > 1 ) { |
677 setClampingStyle( HbScrollArea::StrictClamping ); |
670 const int leftIndex = prevIndex( mCurrentIndex ); |
678 } else { |
671 const int rightIndex = nextIndex( mCurrentIndex ); |
679 setClampingStyle( HbScrollArea::BounceBackClamping ); |
672 mItems[LeftItem]->setStation( mModel->stationAt( leftIndex ) ); |
680 update( mUiEngine->stationModel().currentStation() ); |
673 mItems[RightItem]->setStation( mModel->stationAt( rightIndex ) ); |
681 } |
674 } else { |
682 } |
675 |
683 |
676 if ( mIsCustomFreq ) { |
684 /*! |
677 const uint frequency = mItems[CenterItem]->frequency(); |
685 * |
678 mItems[LeftItem]->setStation( mModel->findClosest( frequency, StationSkip::Previous ) ); |
686 */ |
679 mItems[RightItem]->setStation( mModel->findClosest( frequency, StationSkip::Next ) ); |
687 void RadioStationCarousel::initCurrentStationItem() |
680 } else { |
688 { |
681 mItems[LeftItem]->setStation( RadioStation() ); |
689 mCurrentItem = static_cast<RadioStationItem*>( visibleItems().first() ); |
682 mItems[RightItem]->setStation( RadioStation() ); |
690 } |
683 } |
691 |
684 } |
692 /*! |
685 |
693 * |
686 scrollContentsTo( QPointF( -mMidScrollPos /* + delta */, 0 ), 0 ); |
694 */ |
687 |
695 RadioStationItem* RadioStationCarousel::currentStationItem() |
688 // if ( !mode.testFlag( NoSignal ) ) { |
696 { |
689 // uint frequency = mModel->stationAt( mCurrentIndex ).frequency(); |
697 return mCurrentItem; |
690 // emit frequencyChanged( frequency, TuneReason::StationCarousel, mScrollDirection ); |
698 } |
691 // mScrollDirection = Scroll::Shortest; |
699 |
692 // } |
700 /*! |
693 } |
701 * |
694 } |
702 */ |
695 |
703 RadioCarouselModel* RadioStationCarousel::carouselModel() const |
696 /*! |
704 { |
697 * |
705 return static_cast<RadioCarouselModel*>( model() ); |
698 */ |
706 } |
699 void RadioStationCarousel::scrollToIndex( int index, Scroll::Direction direction, ScrollMode mode ) |
707 |
700 { |
708 /*! |
701 if ( mModel && index >= 0 ) { |
709 * |
702 mTargetIndex = index; |
710 */ |
703 const int difference = calculateDifference( index, direction ); |
711 void RadioStationCarousel::scrollToIndex( const QModelIndex& index, RadioStationCarousel::ScrollMode mode ) |
704 int scrollTime = mAutoScrollTime; |
712 { |
705 |
713 RadioStationItem* item = static_cast<RadioStationItem*>( itemByIndex( index ) ); |
706 int posX = direction == Scroll::Left ? -mMaxScrollPos : 0; |
714 if ( index.isValid() && item ) { |
707 if ( difference == 1 ) { |
715 const int posX = index.row() * (int)size().width(); |
708 if ( direction == Scroll::Right ) { |
716 setCurrentIndex( index, QItemSelectionModel::ClearAndSelect ); |
709 posX = 0; |
|
710 } else if ( direction == Scroll::Left ) { |
|
711 posX = -mMaxScrollPos; |
|
712 } |
|
713 } else { |
|
714 if ( direction == Scroll::Right ) { |
|
715 // Item where the scrolling starts |
|
716 mItems[RightItem]->setStation( mModel->stationAt( mCurrentIndex ) ); |
|
717 |
|
718 // Item that is skipped over |
|
719 const uint centerFreq = mModel->stationAt( nextIndex( index ) ).frequency(); |
|
720 mItems[CenterItem]->setFrequency( centerFreq ); |
|
721 |
|
722 // Item where the scrolling ends |
|
723 const RadioStation station = mModel->stationAt( index ); |
|
724 mItems[LeftItem]->setStation( station ); |
|
725 |
|
726 mContainer->setPos( mMaxScrollPos, 0 ); |
|
727 posX = 0; |
|
728 } else if ( direction == Scroll::Left ) { |
|
729 // Item where the scrolling starts |
|
730 mItems[LeftItem]->setStation( mModel->stationAt( mCurrentIndex ) ); |
|
731 |
|
732 // Item that is skipped over |
|
733 const uint centerFreq = mModel->stationAt( prevIndex( index ) ).frequency(); |
|
734 mItems[CenterItem]->setFrequency( centerFreq ); |
|
735 |
|
736 // Item where the scrolling ends |
|
737 const RadioStation station = mModel->stationAt( index ); |
|
738 mItems[RightItem]->setStation( station ); |
|
739 |
|
740 mContainer->setPos( 0, 0 ); |
|
741 posX = -mMaxScrollPos; |
|
742 } |
|
743 } |
717 |
744 |
718 if ( mode.testFlag( UpdateItem ) ) { |
745 if ( mode.testFlag( UpdateItem ) ) { |
719 item->update(); |
746 //item->update(); |
720 } |
747 } |
721 |
748 |
722 int scrollTime = mAutoScrollTime; |
|
723 if ( mode.testFlag( NoAnim ) ) { |
749 if ( mode.testFlag( NoAnim ) ) { |
724 scrollTime = 0; |
750 scrollTime = 0; |
725 } |
751 } else if ( mode.testFlag( FromPanGesture ) ) { |
|
752 if ( mAlternateSkipping ) { //TODO: Remove this! This is test code |
|
753 scrollTime = 500; |
|
754 } else { |
|
755 scrollTime = 300; |
|
756 } |
|
757 } else if ( mode.testFlag( FromSwipeGesture ) ) { |
|
758 scrollTime = 100; |
|
759 } |
|
760 |
726 scrollContentsTo( QPointF( posX, 0 ), scrollTime ); |
761 scrollContentsTo( QPointF( posX, 0 ), scrollTime ); |
727 mCurrentItem = static_cast<RadioStationItem*>( item ); |
762 } |
728 if ( !mode.testFlag( NoSignal ) ) { |
763 } |
729 uint frequency = model()->data( index, RadioStationModel::RadioStationRole ).value<RadioStation>().frequency(); |
764 |
730 emit frequencyChanged( frequency, TuneReason::StationCarousel ); |
765 /*! |
731 } |
766 * |
732 } |
767 */ |
733 } |
768 int RadioStationCarousel::calculateDifference( int targetIndex, Scroll::Direction& direction ) |
734 |
769 { |
735 /*! |
770 int difference = 0; |
736 * |
771 const int rowCount = mModel->rowCount(); |
737 */ |
772 |
738 void RadioStationCarousel::updatePos( int offset ) |
773 int diffToLeft = 0; |
739 { |
774 int diffToRight = 0; |
740 // QModelIndex index = currentIndex(); |
775 if ( targetIndex > mCurrentIndex ) { |
741 // |
776 const int loopedDiff = mCurrentIndex + rowCount - targetIndex; |
742 // ScrollMode mode = 0; |
777 const int directDiff = targetIndex - mCurrentIndex; |
743 // const qreal threshold = size().width() / 3; |
778 diffToLeft = loopedDiff; |
744 // if ( abs( offset ) >= threshold ) { |
779 diffToRight = directDiff; |
745 // if ( offset > 0 ) { |
780 } else { |
746 // index = previousIndex( index ); |
781 const int loopedDiff = targetIndex + rowCount - mCurrentIndex; |
747 // } else { |
782 const int directDiff = mIsCustomFreq ? 1 : mCurrentIndex - targetIndex; |
748 // index = nextIndex( index ); |
783 diffToLeft = directDiff; |
749 // } |
784 diffToRight = loopedDiff; |
750 // } else { |
785 } |
751 // mode |= RadioStationCarousel::NoSignal; |
786 |
752 // } |
787 if ( direction == Scroll::Right ) { |
753 // |
788 difference = diffToLeft; |
754 // scrollToIndex( index, mode ); |
789 } else if ( direction == Scroll::Left ) { |
|
790 difference = diffToRight; |
|
791 } else { |
|
792 if ( diffToLeft < diffToRight ) { |
|
793 difference = diffToLeft; |
|
794 direction = Scroll::Right; |
|
795 } else { |
|
796 difference = diffToRight; |
|
797 direction = Scroll::Left; |
|
798 } |
|
799 } |
|
800 |
|
801 return difference; |
|
802 } |
|
803 |
|
804 /*! |
|
805 * |
|
806 */ |
|
807 bool RadioStationCarousel::isScrollingAllowed() const |
|
808 { |
|
809 const int rowCount = mModel->rowCount(); |
|
810 return rowCount > 1 || ( rowCount == 1 && mIsCustomFreq ); |
|
811 } |
|
812 |
|
813 /*! |
|
814 * |
|
815 */ |
|
816 void RadioStationCarousel::adjustPos( int offset ) |
|
817 { |
|
818 int newPos = mMidScrollPos; |
|
819 const int threshold = (int)size().width() / 5; |
|
820 int newIndex = mCurrentIndex; |
|
821 bool needsToScroll = false; |
|
822 |
|
823 if ( isScrollingAllowed() && abs( offset ) >= threshold ) { |
|
824 needsToScroll = true; |
|
825 if ( offset > 0 ) { |
|
826 newPos = 0; |
|
827 mScrollDirection = Scroll::Right; |
|
828 if ( !mIsCustomFreq ) { |
|
829 |
|
830 if ( mAlternateSkipping ) { //TODO: Remove this! This is test code |
|
831 const uint newFreq = mModel->findClosest( mItems[CenterItem]->frequency(), StationSkip::PreviousFavorite ).frequency(); |
|
832 if ( newFreq > 0 ) { |
|
833 newIndex = mModel->indexFromFrequency( newFreq ); |
|
834 } else { |
|
835 needsToScroll = false; |
|
836 newPos = mMidScrollPos; |
|
837 } // End test code |
|
838 |
|
839 } else { |
|
840 --newIndex; |
|
841 } |
|
842 } |
|
843 } else { |
|
844 mScrollDirection = Scroll::Left; |
|
845 newPos = mMaxScrollPos; |
|
846 |
|
847 if ( mAlternateSkipping ) { //TODO: Remove this! This is test code |
|
848 const uint newFreq = mModel->findClosest( mItems[CenterItem]->frequency(), StationSkip::NextFavorite ).frequency(); |
|
849 if ( newFreq > 0 ) { |
|
850 newIndex = mModel->indexFromFrequency( newFreq ); |
|
851 } else { |
|
852 needsToScroll = false; |
|
853 newPos = mMidScrollPos; |
|
854 } // End test code |
|
855 |
|
856 } else { |
|
857 ++newIndex; |
|
858 } |
|
859 } |
|
860 } |
|
861 |
|
862 newIndex = trimIndex( newIndex ); |
|
863 if ( needsToScroll ) { |
|
864 const uint frequency = mModel->stationAt( newIndex ).frequency(); |
|
865 emit frequencyChanged( frequency, TuneReason::StationCarousel, mScrollDirection ); |
|
866 scrollToIndex( newIndex, mScrollDirection, RadioStationCarousel::FromPanGesture ); |
|
867 mIsCustomFreq = false; |
|
868 } else { |
|
869 scrollContentsTo( QPointF( -newPos, 0 ), 300 ); |
|
870 } |
|
871 } |
|
872 |
|
873 /*! |
|
874 * |
|
875 */ |
|
876 int RadioStationCarousel::trimIndex( int index ) |
|
877 { |
|
878 const int count = mModel ? mModel->rowCount() : 0; |
|
879 |
|
880 if ( count == 0 ) { |
|
881 return -1; |
|
882 } |
|
883 |
|
884 if ( index < 0 ) { |
|
885 index = count - 1; |
|
886 } |
|
887 index %= count; |
|
888 return index; |
|
889 } |
|
890 |
|
891 /*! |
|
892 * |
|
893 */ |
|
894 int RadioStationCarousel::prevIndex( int index ) |
|
895 { |
|
896 if ( !mIsCustomFreq ) { |
|
897 --index; |
|
898 } |
|
899 return trimIndex( index ); |
|
900 } |
|
901 |
|
902 /*! |
|
903 * |
|
904 */ |
|
905 int RadioStationCarousel::nextIndex( int index ) |
|
906 { |
|
907 return trimIndex( index + 1 ); |
755 } |
908 } |
756 |
909 |
757 /*! |
910 /*! |
758 * |
911 * |
759 */ |
912 */ |
760 void RadioStationCarousel::skip( StationSkip::Mode mode ) |
913 void RadioStationCarousel::skip( StationSkip::Mode mode ) |
761 { |
914 { |
762 RadioStationItem* item = currentStationItem(); |
915 if ( mModel ) { |
763 if ( item ) { |
916 const uint frequency = mModel->findClosest( mItems[CenterItem]->frequency(), mode ).frequency(); |
764 RadioCarouselModel* model = carouselModel(); |
917 const int index = mModel->indexFromFrequency( frequency ); |
765 const uint frequency = model->findClosest( item->frequency(), mode ).frequency(); |
918 const Scroll::Direction direction = RadioUtil::scrollDirectionFromSkipMode( mode ); |
766 const QModelIndex& index = model->modelIndexFromFrequency( frequency ); |
919 scrollToIndex( index, direction, RadioStationCarousel::NoSignal ); |
767 scrollToIndex( index, RadioStationCarousel::NoSignal ); |
920 } |
768 } |
921 } |
769 } |
|