117 EnableExtendedDrawingL(); |
118 EnableExtendedDrawingL(); |
118 |
119 |
119 iItemDrawer->SetDrawMark(EFalse); |
120 iItemDrawer->SetDrawMark(EFalse); |
120 CEikListBox::ConstructL(aParent,aFlags); |
121 CEikListBox::ConstructL(aParent,aFlags); |
121 iMmDrawer->SetView( this ); |
122 iMmDrawer->SetView( this ); |
|
123 iRedrawTimer = CPeriodic::NewL( EPriorityRealTime ); |
122 } |
124 } |
123 |
125 |
124 // ----------------------------------------------------------------------------- |
126 // ----------------------------------------------------------------------------- |
125 // Clearing ELeftDownInViewRect flag before invoking the base class |
127 // Clearing ELeftDownInViewRect flag before invoking the base class |
126 // HandlePointerEventL method effectively prevents that method from doing most |
128 // HandlePointerEventL method effectively prevents that method from doing most |
230 |
232 |
231 // ----------------------------------------------------------------------------- |
233 // ----------------------------------------------------------------------------- |
232 // |
234 // |
233 // ----------------------------------------------------------------------------- |
235 // ----------------------------------------------------------------------------- |
234 // |
236 // |
235 void CMmListBox::ScrollWithoutRedraw( TInt distanceInPixels ) |
|
236 { |
|
237 // desired view position relative to the first item in list (always positive) |
|
238 TInt desiredViewPosition = ItemHeight() * TopItemIndex() - VerticalItemOffset(); |
|
239 desiredViewPosition += distanceInPixels; |
|
240 |
|
241 const TInt viewPositionMax = Max( 0, ( iModel->NumberOfItems() |
|
242 * ItemHeight() ) - iView->ViewRect().Height() ); |
|
243 |
|
244 desiredViewPosition = Min( desiredViewPosition, viewPositionMax ); |
|
245 desiredViewPosition = Max( desiredViewPosition, 0 ); |
|
246 |
|
247 ASSERT( desiredViewPosition >= 0 ); |
|
248 |
|
249 SetTopItemIndex( desiredViewPosition / ItemHeight() ); |
|
250 SetVerticalItemOffset( -( desiredViewPosition % ItemHeight() ) ); |
|
251 } |
|
252 |
|
253 // ----------------------------------------------------------------------------- |
|
254 // |
|
255 // ----------------------------------------------------------------------------- |
|
256 // |
|
257 TInt CMmListBox::ScrollIfNeeded( const TPointerEvent& aPointerEvent ) |
237 TInt CMmListBox::ScrollIfNeeded( const TPointerEvent& aPointerEvent ) |
258 { |
238 { |
259 TInt nextScrollDelay = 0; |
239 TInt nextScrollDelay = 0; |
260 |
240 |
261 TBool readyForScrolling = iMmDrawer->GetAnimator()->IsReadyForNewAnimation() |
241 TBool readyForScrolling = |
262 && iMmDrawer->GetFloatingItemCount() != 0; |
242 iMmDrawer->GetAnimator()->IsReadyForNewAnimation() |
263 |
243 && iMmDrawer->GetFloatingItemCount() != 0; |
264 if( IsPointerInTopScrollingThreshold( aPointerEvent ) ) |
244 |
265 { |
245 if ( IsPointerInTopScrollingThreshold( aPointerEvent ) ) |
266 // scroll up |
246 { |
267 TInt startPos = MmListBox::KFocusScrollingThreshold * TReal( |
247 // scroll up by one row |
268 View()->ItemSize().iHeight ); |
248 TInt newCurrentItemIndex = CurrentItemIndex() - 1; |
269 TInt diff = Max( 1, Min( aPointerEvent.iPosition.iY |
249 |
270 - Rect().iTl.iY, startPos ) ); |
250 if ( newCurrentItemIndex >= 0 ) |
271 nextScrollDelay = ( (TReal) diff / (TReal) startPos ) |
251 { |
272 * ( MmListBox::KEditModeScrollingListBoxMaxDelay |
252 nextScrollDelay = MmEffects::KEditModeScrollingDelayFactor * |
273 - MmListBox::KEditModeScrollingListBoxMinDelay ) |
253 Max( 1, aPointerEvent.iPosition.iY - Rect().iTl.iY ); |
274 + MmListBox::KEditModeScrollingListBoxMinDelay; |
254 if (readyForScrolling) |
275 if( readyForScrolling ) |
255 { |
276 { |
256 View()->VScrollTo( View()->CalcNewTopItemIndexSoItemIsVisible( |
277 ScrollWithoutRedraw( -MmListBox::KScrollingStep ); |
257 newCurrentItemIndex ) ); |
278 } |
258 View()->SetCurrentItemIndex( newCurrentItemIndex ); |
279 } |
259 UpdateScrollBarThumbs(); |
280 else if( IsPointerInBottomScrollingThreshold( aPointerEvent ) ) |
260 } |
281 { |
261 } |
282 // scroll down |
262 } |
283 TInt startPos = MmListBox::KFocusScrollingThreshold * TReal( |
263 else if ( IsPointerInBottomScrollingThreshold( aPointerEvent) ) |
284 View()->ItemSize().iHeight ); |
264 { |
285 TInt diff = Max( 1, Min( Rect().iBr.iY |
265 // scroll down by one row |
286 - aPointerEvent.iPosition.iY, startPos ) ); |
266 TInt lastItemIndex = iModel->NumberOfItems() - 1; |
287 nextScrollDelay = ( (TReal) diff / (TReal) startPos ) |
267 TInt newCurrentItemIndex = CurrentItemIndex() + 1; |
288 * ( MmListBox::KEditModeScrollingListBoxMaxDelay |
268 |
289 - MmListBox::KEditModeScrollingListBoxMinDelay ) |
269 |
290 + MmListBox::KEditModeScrollingListBoxMinDelay; |
270 if ( newCurrentItemIndex <= lastItemIndex ) |
291 |
271 { |
292 if( readyForScrolling ) |
272 nextScrollDelay = MmEffects::KEditModeScrollingDelayFactor * |
293 { |
273 Max( 1, Rect().iBr.iY - aPointerEvent.iPosition.iY ); |
294 ScrollWithoutRedraw( MmListBox::KScrollingStep ); |
274 |
295 } |
275 if (readyForScrolling) |
296 } |
276 { |
|
277 View()->VScrollTo( View()->CalcNewTopItemIndexSoItemIsVisible( |
|
278 newCurrentItemIndex ) ); |
|
279 View()->SetCurrentItemIndex( newCurrentItemIndex ); |
|
280 UpdateScrollBarThumbs(); |
|
281 } |
|
282 } |
|
283 } |
297 |
284 |
298 return nextScrollDelay; |
285 return nextScrollDelay; |
299 } |
286 } |
300 |
287 |
301 // ----------------------------------------------------------------------------- |
288 // ----------------------------------------------------------------------------- |
394 void CMmListBox::ProcessScrollEventL( CEikScrollBar* aScrollBar, |
381 void CMmListBox::ProcessScrollEventL( CEikScrollBar* aScrollBar, |
395 TEikScrollEvent aEventType ) |
382 TEikScrollEvent aEventType ) |
396 { |
383 { |
397 CEikFormattedCellListBoxTypedef::HandleScrollEventL( |
384 CEikFormattedCellListBoxTypedef::HandleScrollEventL( |
398 aScrollBar, aEventType ); |
385 aScrollBar, aEventType ); |
|
386 } |
|
387 |
|
388 // ----------------------------------------------------------------------------- |
|
389 // |
|
390 // ----------------------------------------------------------------------------- |
|
391 // |
|
392 void CMmListBox::HandleRedrawTimerEventL() |
|
393 { |
|
394 if ( iSkippedScrollbarEventsCount ) |
|
395 { |
|
396 ProcessScrollEventL( ScrollBarFrame()->VerticalScrollBar(), |
|
397 EEikScrollThumbDragVert ); |
|
398 } |
|
399 iSkippedScrollbarEventsCount = 0; |
|
400 } |
|
401 |
|
402 // ----------------------------------------------------------------------------- |
|
403 // |
|
404 // ----------------------------------------------------------------------------- |
|
405 // |
|
406 TInt CMmListBox::RedrawTimerCallback( TAny* aPtr ) |
|
407 { |
|
408 CMmListBox* self = static_cast<CMmListBox*>( aPtr ); |
|
409 TRAP_IGNORE( self->HandleRedrawTimerEventL() ); |
|
410 // Do not bother returning a meaningful error code, CPeriodic will ignore it |
|
411 // anyway. |
|
412 return 0; |
399 } |
413 } |
400 |
414 |
401 // ----------------------------------------------------------------------------- |
415 // ----------------------------------------------------------------------------- |
402 // |
416 // |
403 // ----------------------------------------------------------------------------- |
417 // ----------------------------------------------------------------------------- |
940 // ----------------------------------------------------------------------------- |
954 // ----------------------------------------------------------------------------- |
941 // |
955 // |
942 void CMmListBox::HandleScrollEventL( CEikScrollBar* aScrollBar, |
956 void CMmListBox::HandleScrollEventL( CEikScrollBar* aScrollBar, |
943 TEikScrollEvent aEventType ) |
957 TEikScrollEvent aEventType ) |
944 { |
958 { |
945 if ( aEventType == EEikScrollThumbDragVert ) |
959 if ( aEventType == EEikScrollThumbDragVert && !iScrollbarThumbIsBeingDragged ) |
946 { |
960 { |
|
961 iScrollbarThumbIsBeingDragged = ETrue; |
947 static_cast<CMmListBoxItemDrawer*>( |
962 static_cast<CMmListBoxItemDrawer*>( |
948 View()->ItemDrawer() )->EnableCachedDataUse( ETrue ); |
963 View()->ItemDrawer() )->EnableCachedDataUse( ETrue ); |
|
964 iRedrawTimer->Start( KScrollingRedrawInterval, KScrollingRedrawInterval, |
|
965 TCallBack( &CMmListBox::RedrawTimerCallback, static_cast<TAny*>( this ) ) ); |
949 } |
966 } |
950 else if ( aEventType == EEikScrollThumbReleaseVert ) |
967 else if ( aEventType == EEikScrollThumbReleaseVert ) |
951 { |
968 { |
|
969 iScrollbarThumbIsBeingDragged = EFalse; |
952 static_cast<CMmListBoxItemDrawer*>( |
970 static_cast<CMmListBoxItemDrawer*>( |
953 View()->ItemDrawer() )->EnableCachedDataUse( EFalse ); |
971 View()->ItemDrawer() )->EnableCachedDataUse( EFalse ); |
954 } |
972 // The view will be redrawn with cache disabled when ProcessScrollEventL |
955 ProcessScrollEventL( aScrollBar, aEventType ); |
973 // calls the base class's HandleScrollEventL method -- no need to |
|
974 // explicitly redraw the view. |
|
975 iRedrawTimer->Cancel(); |
|
976 } |
|
977 |
|
978 if ( !iScrollbarThumbIsBeingDragged ) |
|
979 { |
|
980 ProcessScrollEventL( aScrollBar, aEventType ); |
|
981 } |
|
982 else |
|
983 { |
|
984 __ASSERT_DEBUG( aEventType == EEikScrollThumbDragVert, User::Invariant() ); |
|
985 ++iSkippedScrollbarEventsCount; |
|
986 } |
956 } |
987 } |
957 |
988 |
958 // End of file |
989 // End of file |