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