diff -r b01126ce0bec -r ba63c83f4716 menufw/menufwui/mmwidgets/src/mmlistbox.cpp --- a/menufw/menufwui/mmwidgets/src/mmlistbox.cpp Wed Sep 15 12:00:00 2010 +0300 +++ b/menufw/menufwui/mmwidgets/src/mmlistbox.cpp Wed Oct 13 14:18:30 2010 +0300 @@ -58,6 +58,7 @@ // CMmListBox::~CMmListBox() { + delete iRedrawTimer; } // ----------------------------------------------------------------------------- @@ -119,6 +120,7 @@ iItemDrawer->SetDrawMark(EFalse); CEikListBox::ConstructL(aParent,aFlags); iMmDrawer->SetView( this ); + iRedrawTimer = CPeriodic::NewL( EPriorityRealTime ); } // ----------------------------------------------------------------------------- @@ -232,68 +234,53 @@ // // ----------------------------------------------------------------------------- // -void CMmListBox::ScrollWithoutRedraw( TInt distanceInPixels ) - { - // desired view position relative to the first item in list (always positive) - TInt desiredViewPosition = ItemHeight() * TopItemIndex() - VerticalItemOffset(); - desiredViewPosition += distanceInPixels; - - const TInt viewPositionMax = Max( 0, ( iModel->NumberOfItems() - * ItemHeight() ) - iView->ViewRect().Height() ); - - desiredViewPosition = Min( desiredViewPosition, viewPositionMax ); - desiredViewPosition = Max( desiredViewPosition, 0 ); - - ASSERT( desiredViewPosition >= 0 ); - - SetTopItemIndex( desiredViewPosition / ItemHeight() ); - SetVerticalItemOffset( -( desiredViewPosition % ItemHeight() ) ); - } - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -// TInt CMmListBox::ScrollIfNeeded( const TPointerEvent& aPointerEvent ) { TInt nextScrollDelay = 0; - TBool readyForScrolling = iMmDrawer->GetAnimator()->IsReadyForNewAnimation() - && iMmDrawer->GetFloatingItemCount() != 0; + TBool readyForScrolling = + iMmDrawer->GetAnimator()->IsReadyForNewAnimation() + && iMmDrawer->GetFloatingItemCount() != 0; - if( IsPointerInTopScrollingThreshold( aPointerEvent ) ) + if ( IsPointerInTopScrollingThreshold( aPointerEvent ) ) + { + // scroll up by one row + TInt newCurrentItemIndex = CurrentItemIndex() - 1; + + if ( newCurrentItemIndex >= 0 ) + { + nextScrollDelay = MmEffects::KEditModeScrollingDelayFactor * + Max( 1, aPointerEvent.iPosition.iY - Rect().iTl.iY ); + if (readyForScrolling) { - // scroll up - TInt startPos = MmListBox::KFocusScrollingThreshold * TReal( - View()->ItemSize().iHeight ); - TInt diff = Max( 1, Min( aPointerEvent.iPosition.iY - - Rect().iTl.iY, startPos ) ); - nextScrollDelay = ( (TReal) diff / (TReal) startPos ) - * ( MmListBox::KEditModeScrollingListBoxMaxDelay - - MmListBox::KEditModeScrollingListBoxMinDelay ) - + MmListBox::KEditModeScrollingListBoxMinDelay; - if( readyForScrolling ) - { - ScrollWithoutRedraw( -MmListBox::KScrollingStep ); - } + View()->VScrollTo( View()->CalcNewTopItemIndexSoItemIsVisible( + newCurrentItemIndex ) ); + View()->SetCurrentItemIndex( newCurrentItemIndex ); + UpdateScrollBarThumbs(); } - else if( IsPointerInBottomScrollingThreshold( aPointerEvent ) ) + } + } + else if ( IsPointerInBottomScrollingThreshold( aPointerEvent) ) + { + // scroll down by one row + TInt lastItemIndex = iModel->NumberOfItems() - 1; + TInt newCurrentItemIndex = CurrentItemIndex() + 1; + + + if ( newCurrentItemIndex <= lastItemIndex ) + { + nextScrollDelay = MmEffects::KEditModeScrollingDelayFactor * + Max( 1, Rect().iBr.iY - aPointerEvent.iPosition.iY ); + + if (readyForScrolling) { - // scroll down - TInt startPos = MmListBox::KFocusScrollingThreshold * TReal( - View()->ItemSize().iHeight ); - TInt diff = Max( 1, Min( Rect().iBr.iY - - aPointerEvent.iPosition.iY, startPos ) ); - nextScrollDelay = ( (TReal) diff / (TReal) startPos ) - * ( MmListBox::KEditModeScrollingListBoxMaxDelay - - MmListBox::KEditModeScrollingListBoxMinDelay ) - + MmListBox::KEditModeScrollingListBoxMinDelay; - - if( readyForScrolling ) - { - ScrollWithoutRedraw( MmListBox::KScrollingStep ); - } + View()->VScrollTo( View()->CalcNewTopItemIndexSoItemIsVisible( + newCurrentItemIndex ) ); + View()->SetCurrentItemIndex( newCurrentItemIndex ); + UpdateScrollBarThumbs(); } + } + } return nextScrollDelay; } @@ -402,6 +389,33 @@ // // ----------------------------------------------------------------------------- // +void CMmListBox::HandleRedrawTimerEventL() + { + if ( iSkippedScrollbarEventsCount ) + { + ProcessScrollEventL( ScrollBarFrame()->VerticalScrollBar(), + EEikScrollThumbDragVert ); + } + iSkippedScrollbarEventsCount = 0; + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +TInt CMmListBox::RedrawTimerCallback( TAny* aPtr ) + { + CMmListBox* self = static_cast( aPtr ); + TRAP_IGNORE( self->HandleRedrawTimerEventL() ); + // Do not bother returning a meaningful error code, CPeriodic will ignore it + // anyway. + return 0; + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// TKeyResponse CMmListBox::OfferKeyEventL( const TKeyEvent& aKeyEvent,TEventCode aType ) { @@ -942,17 +956,34 @@ void CMmListBox::HandleScrollEventL( CEikScrollBar* aScrollBar, TEikScrollEvent aEventType ) { - if ( aEventType == EEikScrollThumbDragVert ) + if ( aEventType == EEikScrollThumbDragVert && !iScrollbarThumbIsBeingDragged ) { + iScrollbarThumbIsBeingDragged = ETrue; static_cast( View()->ItemDrawer() )->EnableCachedDataUse( ETrue ); + iRedrawTimer->Start( KScrollingRedrawInterval, KScrollingRedrawInterval, + TCallBack( &CMmListBox::RedrawTimerCallback, static_cast( this ) ) ); } else if ( aEventType == EEikScrollThumbReleaseVert ) { + iScrollbarThumbIsBeingDragged = EFalse; static_cast( View()->ItemDrawer() )->EnableCachedDataUse( EFalse ); + // The view will be redrawn with cache disabled when ProcessScrollEventL + // calls the base class's HandleScrollEventL method -- no need to + // explicitly redraw the view. + iRedrawTimer->Cancel(); } - ProcessScrollEventL( aScrollBar, aEventType ); + + if ( !iScrollbarThumbIsBeingDragged ) + { + ProcessScrollEventL( aScrollBar, aEventType ); + } + else + { + __ASSERT_DEBUG( aEventType == EEikScrollThumbDragVert, User::Invariant() ); + ++iSkippedScrollbarEventsCount; + } } // End of file