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