213 // ----------------------------------------------------------------------------- |
214 // ----------------------------------------------------------------------------- |
214 // |
215 // |
215 void CMmGrid::HandleScrollEventL( CEikScrollBar* aScrollBar, |
216 void CMmGrid::HandleScrollEventL( CEikScrollBar* aScrollBar, |
216 TEikScrollEvent aEventType ) |
217 TEikScrollEvent aEventType ) |
217 { |
218 { |
218 if ( aEventType == EEikScrollThumbDragVert ) |
219 if ( aEventType == EEikScrollThumbDragVert && !iScrollbarThumbIsBeingDragged ) |
219 { |
220 { |
|
221 iScrollbarThumbIsBeingDragged = ETrue; |
220 static_cast<CMmListBoxItemDrawer*>( |
222 static_cast<CMmListBoxItemDrawer*>( |
221 View()->ItemDrawer() )->EnableCachedDataUse( ETrue ); |
223 View()->ItemDrawer() )->EnableCachedDataUse( ETrue ); |
|
224 iRedrawTimer->Start( KScrollingRedrawInterval, KScrollingRedrawInterval, |
|
225 TCallBack( &CMmGrid::RedrawTimerCallback, static_cast<TAny*>( this ) ) ); |
222 } |
226 } |
223 else if ( aEventType == EEikScrollThumbReleaseVert ) |
227 else if ( aEventType == EEikScrollThumbReleaseVert ) |
224 { |
228 { |
|
229 iScrollbarThumbIsBeingDragged = EFalse; |
225 static_cast<CMmListBoxItemDrawer*>( |
230 static_cast<CMmListBoxItemDrawer*>( |
226 View()->ItemDrawer() )->EnableCachedDataUse( EFalse ); |
231 View()->ItemDrawer() )->EnableCachedDataUse( EFalse ); |
227 } |
232 // The view will be redrawn with cache disabled when ProcessScrollEventL |
|
233 // calls the base class's HandleScrollEventL method -- no need to |
|
234 // explicitly redraw the view. |
|
235 iRedrawTimer->Cancel(); |
|
236 } |
|
237 |
|
238 if ( !iScrollbarThumbIsBeingDragged ) |
|
239 { |
228 ProcessScrollEventL( aScrollBar, aEventType ); |
240 ProcessScrollEventL( aScrollBar, aEventType ); |
229 } |
241 } |
|
242 else |
|
243 { |
|
244 __ASSERT_DEBUG( aEventType == EEikScrollThumbDragVert, User::Invariant() ); |
|
245 ++iSkippedScrollbarEventsCount; |
|
246 } |
|
247 } |
230 |
248 |
231 // ----------------------------------------------------------------------------- |
249 // ----------------------------------------------------------------------------- |
232 // Clearing ELeftDownInViewRect flag before invoking the base class |
250 // Clearing ELeftDownInViewRect flag before invoking the base class |
233 // HandlePointerEventL method effectively prevents that method from doing most |
251 // HandlePointerEventL method effectively prevents that method from doing most |
234 // of the things it would normally do in response to EButton1Down event. |
252 // of the things it would normally do in response to EButton1Down event. |
359 // |
377 // |
360 // ----------------------------------------------------------------------------- |
378 // ----------------------------------------------------------------------------- |
361 // |
379 // |
362 void CMmGrid::ScrollWithoutRedraw( TInt distanceInPixels ) |
380 void CMmGrid::ScrollWithoutRedraw( TInt distanceInPixels ) |
363 { |
381 { |
364 CAknGridView* view = static_cast<CAknGridView*> ( iView ); |
382 CAknGridView* view = static_cast<CAknGridView*>( iView ); |
365 const TInt rowHeight = ItemHeight(); |
383 const TInt rowHeight = ItemHeight(); |
366 const TInt numOfCols = view->NumberOfColsInView(); |
384 const TInt numOfCols = view->NumberOfColsInView(); |
367 const TInt itemCount = iModel->NumberOfItems(); |
385 const TInt itemCount = iModel->NumberOfItems(); |
368 TInt totalNumberOfRows = itemCount / numOfCols; |
386 TInt totalNumberOfRows = itemCount / numOfCols; |
369 if( itemCount % numOfCols ) |
387 if ( itemCount % numOfCols ) |
370 { |
388 { |
371 ++totalNumberOfRows; |
389 ++totalNumberOfRows; |
372 } |
390 } |
373 const TInt topItemRowIndex = TopItemIndex() / numOfCols; |
391 const TInt topItemRowIndex = TopItemIndex() / numOfCols; |
374 |
392 |
376 TInt desiredViewPosition = rowHeight * topItemRowIndex - VerticalItemOffset(); |
394 TInt desiredViewPosition = rowHeight * topItemRowIndex - VerticalItemOffset(); |
377 |
395 |
378 desiredViewPosition += distanceInPixels; |
396 desiredViewPosition += distanceInPixels; |
379 |
397 |
380 const TInt viewPositionMin = 0; |
398 const TInt viewPositionMin = 0; |
381 const TInt viewPositionMax = Max( 0, ( totalNumberOfRows * rowHeight ) |
399 const TInt viewPositionMax = |
382 - view->ViewRect().Height() ); |
400 Max( 0, ( totalNumberOfRows * rowHeight ) - view->ViewRect().Height() ); |
383 |
401 |
384 desiredViewPosition = Min( desiredViewPosition, viewPositionMax ); |
402 desiredViewPosition = Min( desiredViewPosition, viewPositionMax ); |
385 desiredViewPosition = Max( desiredViewPosition, viewPositionMin ); |
403 desiredViewPosition = Max( desiredViewPosition, viewPositionMin ); |
386 |
404 |
387 ASSERT( desiredViewPosition >= 0 ); |
405 ASSERT( desiredViewPosition >= 0 ); |
396 // |
414 // |
397 // ----------------------------------------------------------------------------- |
415 // ----------------------------------------------------------------------------- |
398 // |
416 // |
399 TInt CMmGrid::ScrollIfNeeded( const TPointerEvent& aPointerEvent ) |
417 TInt CMmGrid::ScrollIfNeeded( const TPointerEvent& aPointerEvent ) |
400 { |
418 { |
|
419 CAknGridView* view = static_cast<CAknGridView*>( View() ); |
401 TInt nextScrollDelay = 0; |
420 TInt nextScrollDelay = 0; |
402 |
421 |
403 TBool readyForScrolling = iMmDrawer->GetAnimator()->IsReadyForNewAnimation() |
422 TBool readyForScrolling = iMmDrawer->GetAnimator()->IsReadyForNewAnimation() |
404 && iMmDrawer->GetFloatingItemCount() != 0; |
423 && iMmDrawer->GetFloatingItemCount() != 0; |
405 |
424 |
406 if( IsPointerInTopScrollingThreshold( aPointerEvent ) ) |
425 if ( IsPointerInTopScrollingThreshold( aPointerEvent ) ) |
407 { |
426 { |
408 // scroll up |
427 // scroll up by one row |
409 TInt startPos = MmGrid::KFocusScrollingThreshold * TReal( |
428 TInt newCurrentItemIndex = CurrentItemIndex() - view->NumberOfColsInView(); |
410 View()->ItemSize().iHeight ); |
429 if ( newCurrentItemIndex < 0 ) |
411 TInt diff = Max( 1, Min( aPointerEvent.iPosition.iY |
430 { |
412 - Rect().iTl.iY, startPos ) ); |
431 newCurrentItemIndex = CurrentItemIndex(); |
413 nextScrollDelay = ( (TReal) diff / (TReal) startPos ) |
432 } |
414 * ( MmGrid::KEditModeScrollingGridMaxDelay |
433 |
415 - MmGrid::KEditModeScrollingGridMinDelay ) |
434 nextScrollDelay = MmEffects::KEditModeScrollingDelayFactor * |
416 + MmGrid::KEditModeScrollingGridMinDelay; |
435 Max( 1, aPointerEvent.iPosition.iY - Rect().iTl.iY ); |
417 |
436 |
418 if( readyForScrolling ) |
437 if ( readyForScrolling ) |
419 { |
438 { |
420 ScrollWithoutRedraw( -MmGrid::KScrollingStep ); |
439 ScrollWithoutRedraw( -iItemHeight ); |
421 } |
440 View()->SetCurrentItemIndex( newCurrentItemIndex ); |
422 } |
441 } |
423 else if( IsPointerInBottomScrollingThreshold( aPointerEvent ) ) |
442 } |
424 { |
443 else if ( IsPointerInBottomScrollingThreshold( aPointerEvent) ) |
425 // scroll down |
444 { |
426 TInt startPos = MmGrid::KFocusScrollingThreshold * TReal( |
445 TInt newCurrentItemIndex = CurrentItemIndex() + view->NumberOfColsInView(); |
427 View()->ItemSize().iHeight ); |
446 if ( newCurrentItemIndex > iModel->NumberOfItems() - 1 ) |
428 TInt diff = Max( 1, Min( Rect().iBr.iY |
447 { |
429 - aPointerEvent.iPosition.iY, startPos ) ); |
448 newCurrentItemIndex = CurrentItemIndex(); |
430 nextScrollDelay = ( (TReal) diff / (TReal) startPos ) |
449 } |
431 * ( MmGrid::KEditModeScrollingGridMaxDelay |
450 |
432 - MmGrid::KEditModeScrollingGridMinDelay ) |
451 nextScrollDelay = MmEffects::KEditModeScrollingDelayFactor * |
433 + MmGrid::KEditModeScrollingGridMinDelay; |
452 Max( 1, Rect().iBr.iY - aPointerEvent.iPosition.iY ); |
434 |
453 |
435 if( readyForScrolling ) |
454 if ( readyForScrolling ) |
436 { |
455 { |
437 ScrollWithoutRedraw( MmGrid::KScrollingStep ); |
456 ScrollWithoutRedraw( iItemHeight ); |
438 } |
457 View()->SetCurrentItemIndex( newCurrentItemIndex ); |
439 } |
458 } |
|
459 } |
440 |
460 |
441 return nextScrollDelay; |
461 return nextScrollDelay; |
442 } |
462 } |
443 |
463 |
444 // ----------------------------------------------------------------------------- |
464 // ----------------------------------------------------------------------------- |
938 |
959 |
939 // ----------------------------------------------------------------------------- |
960 // ----------------------------------------------------------------------------- |
940 // |
961 // |
941 // ----------------------------------------------------------------------------- |
962 // ----------------------------------------------------------------------------- |
942 // |
963 // |
|
964 void CMmGrid::HandleRedrawTimerEventL() |
|
965 { |
|
966 if ( iSkippedScrollbarEventsCount ) |
|
967 { |
|
968 ProcessScrollEventL( ScrollBarFrame()->VerticalScrollBar(), |
|
969 EEikScrollThumbDragVert ); |
|
970 } |
|
971 iSkippedScrollbarEventsCount = 0; |
|
972 } |
|
973 |
|
974 // ----------------------------------------------------------------------------- |
|
975 // |
|
976 // ----------------------------------------------------------------------------- |
|
977 // |
|
978 TInt CMmGrid::RedrawTimerCallback( TAny* aPtr ) |
|
979 { |
|
980 CMmGrid* self = static_cast<CMmGrid*>( aPtr ); |
|
981 TRAP_IGNORE( self->HandleRedrawTimerEventL() ); |
|
982 // Do not bother returning a meaningful error code, CPeriodic will ignore it |
|
983 // anyway. |
|
984 return 0; |
|
985 } |
|
986 |
|
987 // ----------------------------------------------------------------------------- |
|
988 // |
|
989 // ----------------------------------------------------------------------------- |
|
990 // |
943 void CMmGrid::SetVerticalItemOffset(TInt aOffset) |
991 void CMmGrid::SetVerticalItemOffset(TInt aOffset) |
944 { |
992 { |
945 static_cast<CMmGridView*> (View())->SetItemOffsetInPixels(aOffset); |
993 static_cast<CMmGridView*> (View())->SetItemOffsetInPixels(aOffset); |
946 UpdateScrollBarThumbs(); |
994 UpdateScrollBarThumbs(); |
947 } |
995 } |