diff -r aecbbf00d063 -r d48ab3b357f1 uifw/EikStd/coctlsrc/EIKLBX.CPP --- a/uifw/EikStd/coctlsrc/EIKLBX.CPP Tue Aug 31 15:28:30 2010 +0300 +++ b/uifw/EikStd/coctlsrc/EIKLBX.CPP Wed Sep 01 12:16:19 2010 +0100 @@ -1,5 +1,5 @@ /* -* Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +* Copyright (c) 1997-2010 Nokia Corporation and/or its subsidiary(-ies). * All rights reserved. * This component and the accompanying materials are made available * under the terms of "Eclipse Public License v1.0" @@ -74,6 +74,7 @@ #include #include #include +#include #include "akntrace.h" // timeout for long keypress used in markable lists @@ -85,7 +86,8 @@ const TInt KDefaultStepSpeed = 5; const TInt KEikListBoxInvalidIndex=-1; //interval time for disable second point event -const TInt KTwoPointerUpEventInterval = 120; // 120 millisecond ( = 0.12 second ) +const TInt KTwoPointerUpEventInterval = 120; // 120 millisecond ( = 0.12 second ) +const TInt KPointerDownAndUpThreshold = 5; // ----------------------------------------------------------------------------- // If a parent to the supplied control has its Gc set, this function will find // it and return it. @@ -377,6 +379,7 @@ public MCenRepNotifyHandlerCallback, public MAknPhysicsObserver, public MAknCollection, + public MAknMarkingCollection, public MAknLongTapDetectorCallBack { public: @@ -448,6 +451,51 @@ */ TInt CollectionExtension( TUint aExtensionId, TAny*& a0, TAny* a1 ); +// From MAknMarkingCollection + /** + * Sets multiple marking state. + * + * @param aActive ETrue if multiple marking should be active. + */ + void SetMultipleMarkingState( TBool aActive ); + + /** + * Returns whether the observer accepts ending of marking mode + * + * @return ETrue if observer accepts exiting marking mode + */ + TBool ExitMarkingMode(); + + /** + * Returns the collection marking state. The state is combination of + * flags defined in @c TStateFlag. + * + * @return Collection state. + */ + TUint MarkingState() const; + + /** + * Marks the currently selected item. + */ + void MarkCurrentItemL(); + + /** + * Marks all items in the collection. + */ + void MarkAllL(); + + /** + * Unmarks all items in the collection. + */ + void UnmarkAll(); + + /* + * Can current item be marked + * + * @return ETrue if item can be marked + */ + TBool CurrentItemMarkable(); + // From MAknLongTapDetectorCallBack /** * Long tap detector callback @@ -478,6 +526,11 @@ void DisableSingleClick(); /** + * Enables single click + */ + void EnableSingleClickL(); + + /** * Disables item specific menu. */ void DisableItemSpecificMenu(); @@ -512,6 +565,13 @@ * @return ETrue if list has marked items. */ TBool MarkedItems() const; + + /** + * Ignores pointer events until next up event. + * + * @return ETrue if the pointer event ignore was enabled. + */ + TBool IgnorePointerEventsUntilUp(); public: void InitPhysicsL(); @@ -618,7 +678,6 @@ CAknPhysics *iPhysics; TPoint iDragStartPosition; TPoint iLastPointerPos; - TBool iBackgroundDrawingSuppressed; TBool iClickEventsAllowed; TBool iScrolling; TSize iViewSize; @@ -682,12 +741,34 @@ * Item that opened the item action menu */ TInt iLongTappedItem; + + /** + * Marking mode on / off. + */ + TBool iMarkingModeInUse; + + /** + * Marking mode observer. + */ + MAknMarkingModeObserver* iMarkingModeObserver; + /** * Pointer event to be forwarded to the long tap detector upon * highlight timer completion. */ TPointerEvent iDelayedPointerDownEvent; + /** + * Ordinal position of listbox window, before stylus menu is opened. + */ + TInt iOldWinPos; + + /** + * If double click modifier is set on PointerEvent, the event may be ignored + * in some situation(To prevent extra dialog launched by AO). + */ + TBool iDoubleClickEventIgnored; + private: CMatchBuffer* iBuffer; CEikListBox& iListBox; @@ -720,7 +801,7 @@ /** * Height of the list in pixels. */ - TInt iListBottomLimit; + TInt iListBottomLimit; }; // CEikListBoxExt @@ -751,7 +832,8 @@ iLongTapDetector( NULL ), iSingleClickEnabled( iAvkonAppUi->IsSingleClickCompatible() ), iLongTappedItem( KErrNotFound ), - iListBox(aListBox) + iOldWinPos( KErrNotFound ), + iListBox(aListBox) { } @@ -852,7 +934,7 @@ iItemsInSingleLine = 1; iFeedback = MTouchFeedback::Instance(); - iItemActionMenu = CAknItemActionMenu::RegisterCollectionL( *this ); + iItemActionMenu = CAknItemActionMenu::RegisterCollectionL( *this, &iListBox ); if ( !( iListBox.iListBoxFlags & CEikListBox::EDisableItemSpecificMenu ) && iItemActionMenu ) @@ -929,6 +1011,10 @@ { state |= MAknCollection::EStateMultipleSelection; } + if ( MarkedItems() ) + { + state |= MAknCollection::EStateMarkedItems; + } _AKNTRACE_FUNC_EXIT; return state; } @@ -945,6 +1031,7 @@ EnableHighlight( EFalse ); iListBox.iView->DrawItem( iLongTappedItem ); iLongTappedItem = KErrNotFound; + iOldWinPos = KErrNotFound; } } @@ -954,9 +1041,137 @@ // ----------------------------------------------------------------------------- // TInt CListBoxExt::CollectionExtension( - TUint /*aExtensionId*/, TAny*& /*a0*/, TAny* /*a1*/ ) - { - return KErrNone; + TUint aExtensionId, TAny*& a0, TAny* /*a1*/ ) + { + if ( aExtensionId == MAknMarkingCollection::TYPE ) + { + a0 = static_cast( this ); + return KErrNone; + } + + return KErrNotFound; + } + + +// ----------------------------------------------------------------------------- +// CListBoxExt::SetMultipleMarkingState +// ----------------------------------------------------------------------------- +// +void CListBoxExt::SetMultipleMarkingState( TBool aActive ) + { + _AKNTRACE_FUNC_ENTER; + iListBox.SetMarkingMode( aActive ); + _AKNTRACE_FUNC_EXIT; + } + +// ----------------------------------------------------------------------------- +// CListBoxExt::ExitMarkingMode +// ----------------------------------------------------------------------------- +// +TBool CListBoxExt::ExitMarkingMode() + { + if ( iListBox.MarkingModeObserver() ) + { + return iListBox.MarkingModeObserver()->ExitMarkingMode(); + } + return ETrue; + } + +// ----------------------------------------------------------------------------- +// CListBoxExt::MarkingState +// ----------------------------------------------------------------------------- +// +TUint CListBoxExt::MarkingState() const + { + _AKNTRACE_FUNC_ENTER; + TUint state( 0 ); + if ( iListBox.MarkingMode() ) + { + state |= MAknMarkingCollection::EStateMarkingMode; + if ( MarkedItems() ) + { + state |= MAknMarkingCollection::EStateMarkedItems; + } + if ( iListBox.Model()->NumberOfItems() == 0 ) + { + state |= MAknMarkingCollection::EStateCollectionEmpty; + } + } + _AKNTRACE_FUNC_EXIT; + return state; + } + + +// ----------------------------------------------------------------------------- +// CListBoxExt::MarkCurrentItemL +// ----------------------------------------------------------------------------- +// +void CListBoxExt::MarkCurrentItemL() + { + _AKNTRACE_FUNC_ENTER; + + if ( iListBox.MarkingMode() ) + { + TInt index = iListBox.CurrentItemIndex(); + if ( index >= 0 && + !iListBox.iItemDrawer->Properties( index ).IsSelectionHidden() ) + { + iListBox.View()->SelectItemL( index ); + } + } + _AKNTRACE_FUNC_EXIT; + } + + +// ----------------------------------------------------------------------------- +// CListBoxExt::MarkAllL +// ----------------------------------------------------------------------------- +// +void CListBoxExt::MarkAllL() + { + _AKNTRACE_FUNC_ENTER; + + if ( iListBox.MarkingMode() && + iListBox.Model()->NumberOfItems() > 0 ) + { + iListBox.View()->SelectAllL( ETrue ); + } + _AKNTRACE_FUNC_EXIT; + } + + +// ----------------------------------------------------------------------------- +// CListBoxExt::UnmarkAll +// ----------------------------------------------------------------------------- +// +void CListBoxExt::UnmarkAll() + { + _AKNTRACE_FUNC_ENTER; + + if ( iListBox.MarkingMode() ) + { + iListBox.View()->ClearSelection(); + } + + _AKNTRACE_FUNC_EXIT; + } + +// ----------------------------------------------------------------------------- +// CListBoxExt::CurrentItemMarkable +// ----------------------------------------------------------------------------- +// +TBool CListBoxExt::CurrentItemMarkable() + { + _AKNTRACE_FUNC_ENTER; + TBool itemCanBeMarked = ETrue; + TInt index = iListBox.CurrentItemIndex(); + if ( index >= 0 && + iListBox.iItemDrawer->Properties( index ).IsSelectionHidden() ) + { + itemCanBeMarked = EFalse; + } + _AKNTRACE_FUNC_EXIT; + return itemCanBeMarked; } @@ -971,6 +1186,7 @@ iLongTappedItem = iLastDownTappedItem; iLastDownTappedItem = KErrNotFound; iItemActionMenu->ShowMenuL( aPenEventScreenLocation, 0 ); + iOldWinPos = iListBox.DrawableWindow()->OrdinalPosition(); _AKNTRACE_FUNC_EXIT; } @@ -1035,12 +1251,18 @@ if ( iListBox.iView->ViewRect() != TRect() ) { - TInt topItemIndex = iListBox.iView->TopItemIndex(); - if ( iListBox.iView->ItemIsPartiallyVisible( topItemIndex) ) - { - topItemIndex++; - } - TRAP_IGNORE( iListBox.UpdateHighlightL( topItemIndex ) ); + // Set current item index highlighted if it is visible, otherwise + // the first visible index + TInt index = iListBox.iView->CurrentItemIndex(); + if ( !iListBox.iView->ItemIsVisible( index ) ) + { + index = iListBox.iView->TopItemIndex(); + if ( iListBox.iView->ItemIsPartiallyVisible( index ) ) + { + index++; + } + } + TRAP_IGNORE( iListBox.UpdateHighlightL( index ) ); } DisableItemSpecificMenu(); @@ -1054,6 +1276,28 @@ _AKNTRACE_FUNC_EXIT; } +// ----------------------------------------------------------------------------- +// CListBoxExt::EnableSingleClickL +// ----------------------------------------------------------------------------- +// +void CListBoxExt::EnableSingleClickL() + { + _AKNTRACE_FUNC_ENTER; + if ( !iLongTapDetector ) + { + iLongTapDetector = CAknLongTapDetector::NewL( this ); + } + if ( !iItemActionMenu ) + { + iItemActionMenu = CAknItemActionMenu::RegisterCollectionL( + *this, &iListBox ); + iListBox.iListBoxFlags &= ( ~CEikListBox::EDisableItemSpecificMenu ); + } + iSingleClickEnabled = ETrue; + EnableHighlight( EFalse ); + // iListBox.UpdateHighlightL( iListBox.iView->CurrentItemIndex() ); + _AKNTRACE_FUNC_EXIT; + } // ----------------------------------------------------------------------------- // CListBoxExt::DisableItemSpecificMenu @@ -1071,6 +1315,7 @@ _AKNTRACE_FUNC_EXIT; } + // ----------------------------------------------------------------------------- // CListBoxExt::LongTapPointerEventL // ----------------------------------------------------------------------------- @@ -1079,10 +1324,14 @@ { if ( iSingleClickEnabled && iLongTapDetector && iItemActionMenu ) { - // Send event on down only if no marked items and item specific items - // were found - if ( aPointerEvent.iType != TPointerEvent::EButton1Down - || ( !MarkedItems() && iItemActionMenu->InitMenuL() ) ) + // Send event on down only if item specific items were found. + // Long tap is also disabled if current item is not marked while + // there are some marked items or marking mode is active. + if ( ( !( ( iListBox.MarkingMode() || MarkedItems() ) + && !iListBox.View()->ItemIsSelected( iListBox.CurrentItemIndex() ) ) + || ( iListBox.iListBoxFlags & CEikListBox::EItemSpecificMenuAlwaysShown ) ) + && ( aPointerEvent.iType != TPointerEvent::EButton1Down + || iItemActionMenu->InitMenuL() ) ) { iLongTapDetector->PointerEventL ( aPointerEvent ); } @@ -1183,7 +1432,33 @@ { return ( iListBox.iListBoxFlags & CEikListBox::ES60StyleMarkable || iListBox.iListBoxFlags & CEikListBox::EMultipleSelection ) - && iListBox.SelectionIndexes()->Count() > 0; + && iListBox.iView && iListBox.SelectionIndexes()->Count() > 0; + } + + +// ----------------------------------------------------------------------------- +// CListBoxExt::IgnorePointerEventsUntilUp +// ----------------------------------------------------------------------------- +// +TBool CListBoxExt::IgnorePointerEventsUntilUp() + { + _AKNTRACE_FUNC_ENTER; + + // Pointer event ignore must be done for the window-owning + // control or it doesn't have any effect! + CCoeControl* windowOwningControl = &iListBox; + + while ( windowOwningControl && !windowOwningControl->OwnsWindow() ) + { + windowOwningControl = windowOwningControl->Parent(); + } + + if ( windowOwningControl ) + { + windowOwningControl->IgnoreEventsUntilNextPointerUp(); + } + _AKNTRACE_FUNC_EXIT; + return ( windowOwningControl != NULL ); } @@ -1559,6 +1834,13 @@ _AKNTRACE_FUNC_ENTER; if ( iScrolling ) { + // currently, this is the only way to fix ou1cimx1#375869 + // iViewPosision is changed but we can't provent that + if ( iListBox.iView->TopItemIndex() == 0 + && iListBox.iView->ItemOffsetInPixels() > 0 ) + { + iListBox.ScrollView( -iListBox.iView->ItemOffsetInPixels(), ETrue ); + } #ifdef RD_UI_TRANSITION_EFFECTS_LIST iListBox.SuspendEffects( EFalse ); #endif // RD_UI_TRANSITION_EFFECTS_LIST @@ -1585,7 +1867,8 @@ TInt topItemIndex = iListBox.iView->TopItemIndex(); TInt itemHeight = iListBox.iView->ItemHeight(); TInt numberOfItems = iListBox.iModel->NumberOfItems(); - + TInt emptySpaceOffset ( 0 ); + TSize viewSize( iListBox.iView->ViewRect().Size() ); TSize worldSize( viewSize.iWidth, itemHeight * numberOfItems ); @@ -1600,6 +1883,15 @@ { worldSize.iHeight += itemHeight; } + + // Check empty space below the grid + if ( topItemIndex != 0 ) + { + TInt lastItemBottomY = + iListBox.iView->ItemPos( + numberOfItems - 1 ).iY + itemHeight +1; + emptySpaceOffset = Min( 0, lastItemBottomY - viewSize.iHeight ); + } } // Reset offset if view's size has changed - this is needed if e.g. @@ -1610,6 +1902,7 @@ } TPoint viewCenter( viewSize.iWidth / 2, ( topItemIndex / iItemsInSingleLine ) * itemHeight - iListBox.iView->ItemOffsetInPixels() + ( viewSize.iHeight / 2 ) ); + viewCenter.iY += emptySpaceOffset; // Make sure that world's size is always at least view size. worldSize.iHeight = Max( worldSize.iHeight, viewSize.iHeight ); @@ -1715,18 +2008,29 @@ } // --------------------------------------------------------------------------- -// CListBoxExt::FeedbackEnabledOnUpEvent +// Checks whether or not tactile feedback should be given on a pointer +// up event. // --------------------------------------------------------------------------- // TBool CListBoxExt::FeedbackEnabledOnUpEvent() { _AKNTRACE_FUNC_ENTER; TBool enabled( EFalse ); - if ( ( iListBox.iItemDrawer->Flags() & CListItemDrawer::EPressedDownState ) && - !iFlickStopped ) + + // As there's no pressed down highlight in single click enabled lists, + // the iLastDownTappedItem is used to track whether or not the pointer + // up event happened inside the same list item as the pointer down event. + // Feedback should not be given if the pointer up is received outside of + // the item that received the pointer down event, or in cases when the + // list has been dragged or flicked between the pointer down and pointer + // up events. + if ( ( iListBox.iItemDrawer->Flags() & CListItemDrawer::EPressedDownState + || ( iSingleClickEnabled && iLastDownTappedItem != KErrNotFound ) ) && + !iFlickStopped ) { enabled = ETrue; } + _AKNTRACE_FUNC_EXIT; return enabled; } @@ -1810,6 +2114,22 @@ } } + +// ----------------------------------------------------------------------------- +// CEikListBox::ItemsInSingleLine +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CEikListBox::ItemsInSingleLine() const + { + if ( iListBoxExt ) + { + return iListBoxExt->iItemsInSingleLine; + } + + return 1; + } + + EXPORT_C void CEikListBox::UpdateViewColors() { _AKNTRACE_FUNC_ENTER; @@ -2071,7 +2391,8 @@ iView->CalcBottomItemIndex(); iView->CalcDataWidth(); TInt currentItemIndex = iView->CurrentItemIndex(); - + TInt totalItems = iModel->NumberOfItems(); + if ( ItemExists(currentItemIndex) ) { TInt topItemIndex( iView->TopItemIndex() ); @@ -2083,25 +2404,48 @@ || iListBoxExt && iListBoxExt->iPhysics && currentItemIndex == ( topItemIndex + numberOfItems - 1 ) ) { - newTopItemIndex = iView->CalcNewTopItemIndexSoItemIsVisible( currentItemIndex ); + if ( iListBoxExt && iListBoxExt->iSingleClickEnabled ) + { + TInt offset = (iListBoxExt->iWorldSize.iHeight / 2) + - iListBoxExt->iViewPosition.iY; + TInt itemsInRect = + iView->NumberOfItemsThatFitInRect( iView->ViewRect() ); + + if ( ( iListBoxExt->CollectionState() + & MAknCollection::EStateHighlightVisible ) + || ( ItemsInSingleLine() + && ( totalItems <= itemsInRect ) + && ( offset != 0 ) ) ) + { + newTopItemIndex = iView->CalcNewTopItemIndexSoItemIsVisible( currentItemIndex ); + } + else + { + newTopItemIndex = iView->CalcNewTopItemIndexSoItemIsVisible( topItemIndex ); + } + } + else + { + newTopItemIndex = iView->CalcNewTopItemIndexSoItemIsVisible( currentItemIndex ); + } } else { - // recalculates top index of list when mode be changed - TInt totalItems = iModel->NumberOfItems(); + // recalculates top index of list when mode be changed if ( (totalItems - topItemIndex) < numberOfItems ) { newTopItemIndex = Max( 0, totalItems - numberOfItems ); } } - if ( newTopItemIndex != KEikListBoxInvalidIndex ) + if ( newTopItemIndex > KEikListBoxInvalidIndex + && newTopItemIndex < totalItems ) { iView->SetTopItemIndex( newTopItemIndex ); - if ( iListBoxExt && iListBoxExt->iPhysics ) - { - iListBoxExt->InitPhysicsL(); - } + } + if ( iListBoxExt && iListBoxExt->iPhysics ) + { + iListBoxExt->InitPhysicsL(); } } UpdateScrollBarsL(); @@ -2373,8 +2717,9 @@ UpdateCurrentItem(aItemIndex); iView->SetDisableRedraw(redrawDisabled); - if ( iListBoxExt && iListBoxExt->iPhysics && aItemIndex == 0 ) - { + if ( iListBoxExt && iListBoxExt->iPhysics && aItemIndex == 0 + && !iListBoxExt->iScrolling ) + { iView->SetItemOffsetInPixels( 0 ); } _AKNTRACE_FUNC_EXIT; @@ -2427,6 +2772,8 @@ if(iItemDrawer && (iItemDrawer->MinimumCellSize().iHeight != 0)) iItemHeight = iItemDrawer->MinimumCellSize().iHeight; + CheckCreateExtensionL(); + if ( iListBoxExt->iLongTapDetector && iListBoxFlags & EDisableItemSpecificMenu ) { @@ -2854,7 +3201,7 @@ TEikScrollBarFrameLayout layout; CreateScrollBarFrameLayout(layout); TBool sizeChanged=iSBFrame->TileL(&hSbarModel, &vSbarModel, clientRect, inclusiveRect, layout); - if (iListBoxExt->UpdateScrollBarsColors()) + if ( iListBoxExt && iListBoxExt->UpdateScrollBarsColors() ) UpdateScrollBarsColors(); if (!sizeChanged) return; @@ -2981,11 +3328,7 @@ _AKNTRACE_FUNC_EXIT; return; } - if( !iListBoxExt ) - { - _AKNTRACE_FUNC_EXIT; - return; - } + CEikButtonGroupContainer *bgc; CCoeControl* MSK( NULL ); CEikCba* cba( NULL ); @@ -3023,16 +3366,22 @@ // marking still works even MSK isn't changed if ( err ) { - iListBoxExt->iSelectionModeEnabled = EFalse; + if ( iListBoxExt ) + { + iListBoxExt->iSelectionModeEnabled = EFalse; + } _AKNTRACE_FUNC_EXIT; return; } cba->DrawNow(); - iListBoxExt->iSelectionModeEnabled = ETrue; + if ( iListBoxExt ) + { + iListBoxExt->iSelectionModeEnabled = ETrue; + } } // remove stacked MSK - if( !aEnable && iListBoxExt->iSelectionModeEnabled ) + if( !aEnable && iListBoxExt && iListBoxExt->iSelectionModeEnabled ) { if( ( MSK && cba->ControlId( MSK ) == EAknSoftkeyMark ) || ( MSK && cba->ControlId( MSK ) == EAknSoftkeyUnmark ) ) @@ -3041,11 +3390,13 @@ } iListBoxExt->iSelectionModeEnabled = EFalse; // just in case } - - TInt count = iListBoxExt->iSelectionObservers.Count(); - for ( int i=0; i < count; i++ ) - { - iListBoxExt->iSelectionObservers[i]->SelectionModeChanged( this, aEnable ); + if ( iListBoxExt ) + { + TInt count = iListBoxExt->iSelectionObservers.Count(); + for ( int i=0; i < count; i++ ) + { + iListBoxExt->iSelectionObservers[i]->SelectionModeChanged( this, aEnable ); + } } _AKNTRACE_FUNC_EXIT; } @@ -3064,6 +3415,16 @@ UpdateScrollBarThumbs(); iView->ClearFlags(CListBoxView::EItemCountModified); + + if ( iListBoxExt->iItemActionMenu && + iListBoxExt->iLongTappedItem != KErrNotFound ) + { + // Item action menu is being shown and it needs to be closed when + // items are added or removed to the list array, otherwise the + // item specific commands may be targeted to the wrong item. + iListBoxExt->iItemActionMenu->HideMenu(); + } + FireItemChange(); if ( iListBoxExt && iListBoxExt->iPhysics ) @@ -3145,7 +3506,8 @@ EXPORT_C void CEikListBox::HandleItemAdditionL() { _AKNTRACE_FUNC_ENTER; - //fix the bug EGGO-7SQA4S and EVSG-7TD9WZ + __ASSERT_DEBUG( iView, Panic( EEikPanicListBoxNoView ) ); + TInt curItemIndex = iView->CurrentItemIndex(); if(curItemIndex >= 0 && curItemIndex < iModel->NumberOfItems() ) { @@ -3153,8 +3515,7 @@ iView->SetTopItemIndex( newTopItemIndex ); } iView->SetFlags(CListBoxView::EItemCountModified); - // following breaks lists in square layout, not needed in SERIES60? - //iView->CalcDataWidth(); + iView->CalcBottomItemIndex(); UpdateScrollBarsL(); UpdateScrollBarThumbs(); @@ -3164,7 +3525,7 @@ FireItemChange(); if ( iListBoxExt ) - { + { iListBoxExt->CheckScrollBarVisibility(); // Physics engine world size needs to be updated here, otherwise aknphysics // cone observer may block pointer events on new items. this can happen @@ -3173,7 +3534,17 @@ { iListBoxExt->InitPhysicsL(); } - } + + if ( iListBoxExt->iItemActionMenu && + iListBoxExt->iLongTappedItem != KErrNotFound ) + { + // Item action menu is being shown and it needs to be closed when + // items are added or removed to the list array, otherwise the + // item specific commands may be targeted to the wrong item. + iListBoxExt->iItemActionMenu->HideMenu(); + } + } + _AKNTRACE_FUNC_EXIT; } @@ -3354,7 +3725,8 @@ { selectionMode = CListBoxView::ENoSelection; UpdateMarkUnmarkMSKL(); - if (IsSelectionMarkKeys(code, aKeyEvent.iScanCode, iListBoxExt->iWesternVariant)) + if ( iListBoxExt + && IsSelectionMarkKeys( code, aKeyEvent.iScanCode, iListBoxExt->iWesternVariant ) ) { __KeyDebug(ETrue, "SelectionMarkKey") View()->ClearSelectionAnchorAndActiveIndex(); @@ -3365,7 +3737,7 @@ // CAknGrid marking is implemeted in avkon.dll. But we still need to disable short // hash mark in here. - if ( iListBoxFlags & EMultipleSelection && + if ( iListBoxExt && iListBoxFlags & EMultipleSelection && iListBoxFlags & EShiftEnterMarks && aType == EEventKeyUp ) { if ( aKeyEvent.iScanCode == EStdKeyLeftArrow || @@ -3577,7 +3949,8 @@ } } - if ( ScrollingDisabled() || ( !iListBoxExt->MovePhysicsCursorL( moveto, selectionMode ) ) ) + if ( ScrollingDisabled() + || ( iListBoxExt && !iListBoxExt->MovePhysicsCursorL( moveto, selectionMode ) ) ) { iView->MoveCursorL(moveto, selectionMode); } @@ -3626,7 +3999,8 @@ } } - if ( ScrollingDisabled() || ( !iListBoxExt->MovePhysicsCursorL( moveto, selectionMode ) ) ) + if ( ScrollingDisabled() + || ( iListBoxExt && !iListBoxExt->MovePhysicsCursorL( moveto, selectionMode ) ) ) { iView->MoveCursorL(moveto, selectionMode); } @@ -3668,7 +4042,7 @@ if (!shiftKeyPressed && iListBoxFlags & EShiftEnterMarks) { // enter key pressed on markable list without shift - if (SelectionIndexes()->Count() > 0) + if ( SelectionIndexes()->Count() > 0 && !MarkingMode() ) { // when there's marked items, should open options menu. __KeyDebug(ETrue, "ok without shift => ok options menu"); @@ -3711,7 +4085,7 @@ // if(switchMSK) { - if( selectionMode == CListBoxView::EDisjointMarkSelection ) + if( iListBoxExt && selectionMode == CListBoxView::EDisjointMarkSelection ) { // if hash and either up or down pressed -> no short marking iListBoxExt->iShortHashMark = EFalse; @@ -3770,7 +4144,7 @@ // only if a markable list is active, otherwise the simulated event might open // the selected item, which we don't want. if((iListBoxFlags & EMultipleSelection) && (iListBoxFlags & EShiftEnterMarks) && - iListBoxExt->iWesternVariant && + iListBoxExt && iListBoxExt->iWesternVariant && iListBoxExt->iAknFepHashKeySelection && iListBoxExt->iQwertyMode == EFalse && aType == EEventKeyUp && aKeyEvent.iScanCode == EStdKeyHash && @@ -3871,27 +4245,46 @@ case MEikListBoxObserver::EEventFlickStarted: case MEikListBoxObserver::EEventPanningStarted: { + if ( iListBoxExt && ( iListBoxExt->iWorldSize.iHeight + <= iListBoxExt->iViewSize.iHeight ) ) + { + return; + } iItemDrawer->SetFlags( CListItemDrawer::EDisableMarquee ); - if ( aEvent == MEikListBoxObserver::EEventFlickStarted ) - iListBoxExt->SetFlickOngoing( ETrue ); - else - iListBoxExt->SetPanningOngoing( ETrue ); + if ( iListBoxExt ) + { + if ( aEvent == MEikListBoxObserver::EEventFlickStarted ) + { + iListBoxExt->SetFlickOngoing( ETrue ); + } + else + { + iListBoxExt->SetPanningOngoing( ETrue ); + } + } break; } case MEikListBoxObserver::EEventFlickStopped: case MEikListBoxObserver::EEventPanningStopped: { - iItemDrawer->ClearFlags( CListItemDrawer::EDisableMarquee ); - if ( aEvent == MEikListBoxObserver::EEventFlickStopped ) + if ( iListBoxExt && ( iListBoxExt->iWorldSize.iHeight + <= iListBoxExt->iViewSize.iHeight ) ) { - iListBoxExt->SetFlickOngoing( EFalse ); + return; } - else - { - iListBoxExt->SetPanningOngoing( EFalse ); - } - + iItemDrawer->ClearFlags( CListItemDrawer::EDisableMarquee ); + if ( iListBoxExt ) + { + if ( aEvent == MEikListBoxObserver::EEventFlickStopped ) + { + iListBoxExt->SetFlickOngoing( EFalse ); + } + else + { + iListBoxExt->SetPanningOngoing( EFalse ); + } + } break; } } @@ -3901,10 +4294,34 @@ TBool allowed = ETrue; if ( iListBoxExt && iListBoxExt->iPhysics - && aEvent != MEikListBoxObserver::EEventFlickStopped ) + && aEvent != MEikListBoxObserver::EEventFlickStopped + && aEvent != MEikListBoxObserver::EEventFlickStarted ) { allowed = iListBoxExt->iClickEventsAllowed; } + + if ( MarkingMode() && allowed ) + { + switch ( aEvent ) + { + case MEikListBoxObserver::EEventItemSingleClicked: + case MEikListBoxObserver::EEventEnterKeyPressed: + { + TInt index = CurrentItemIndex(); + if ( index >= 0 && + !iItemDrawer->Properties(index).IsSelectionHidden() ) + { + iView->ToggleItemL( iView->CurrentItemIndex() ); + } + + allowed = EFalse; + } + break; + + default: + break; + } + } if ( allowed ) { @@ -3940,7 +4357,7 @@ EXPORT_C void CEikListBox::HandlePhysicsScrollEventL( TInt aDeltaPixels ) { _AKNTRACE_FUNC_ENTER; - if ( iListBoxExt->iPhysics ) + if ( iListBoxExt && iListBoxExt->iPhysics ) { iListBoxExt->InitPhysicsL(); @@ -3955,7 +4372,7 @@ EXPORT_C void CEikListBox::HandleScrollEventL(CEikScrollBar* aScrollBar,TEikScrollEvent aEventType) { _AKNTRACE_FUNC_ENTER; - if ( iListBoxExt->iSingleClickEnabled ) + if ( iListBoxExt && iListBoxExt->iSingleClickEnabled ) { iListBoxExt->EnableHighlight( EFalse ); iView->DrawItem( iView->CurrentItemIndex() ); @@ -4098,17 +4515,17 @@ } #endif - if ( iListBoxExt->iPhysics ) + if ( iListBoxExt && iListBoxExt->iPhysics ) { iListBoxExt->InitPhysicsL(); TInt deltaPixels = newThumbPos; #ifdef _DEBUG - RDebug::Print( _L( "CListBox::HandleScrollEventL, deltaPixels = %d" ), deltaPixels ); + RDebug::Print( _L( "CListBox::HandleScrollEventL, deltaPixels = %d" ), deltaPixels ); #endif // _DEBUG TPoint newPosition( iListBoxExt->iViewPosition.iX, deltaPixels + iView->ViewRect().Height() / 2 ); - iListBoxExt->ViewPositionChanged( newPosition ); + iListBoxExt->ViewPositionChanged( newPosition ); } else { @@ -4130,7 +4547,9 @@ // If the event has changed thumb position, then update scroll bar // unless physics is used. In that case thumb is updated via // CEikListBox::ScrollView. - if ( AknLayoutUtils::PenEnabled() && newThumbPos != newThumbPosBeforeCorrecting && !iListBoxExt->iPhysics ) + if ( AknLayoutUtils::PenEnabled() + && newThumbPos != newThumbPosBeforeCorrecting + && iListBoxExt && !iListBoxExt->iPhysics ) { UpdateScrollBarThumbs(); } @@ -4149,7 +4568,6 @@ return; } - CheckCreateExtensionL(); if (!(iListBoxFlags & ELeftDownInViewRect)) { _AKNTRACE_FUNC_EXIT; @@ -4611,7 +5029,7 @@ // Handle empty list area events if ( aPointerEvent.iType == TPointerEvent::EButton1Up && - !iListBoxExt->iScrolling ) + !iListBoxExt->iScrolling && !iListBoxExt->iIsDownOnItem ) { if ( listEmpty ) { @@ -4635,11 +5053,6 @@ return; } - - // When in marking mode, pointer events should not be forwarded to - // long tap detector, this boolean indicates if marking mode is active - TBool markingMode( iListBoxExt->MarkedItems() ); - if ( aPointerEvent.iType == TPointerEvent::EButton1Down ) { if ( iListBoxExt->iSingleClickEnabled && @@ -4649,25 +5062,19 @@ iView->DrawItem( iView->CurrentItemIndex() ); } - iListBoxExt->iFeedbackType = ETouchFeedbackBasicItem; - - if ( itemIndex != iView->CurrentItemIndex() || - iListBoxFlags & ES60StyleMultiselection ) - { - iListBoxExt->iFeedbackType = ETouchFeedbackSensitiveItem; + iListBoxExt->iFeedbackType = ETouchFeedbackList; + iListBoxExt->iDoubleClickEventIgnored = EFalse; + + if ( !iListBoxExt->iSingleClickEnabled && + itemIndex != iView->CurrentItemIndex() ) + { + iListBoxExt->iFeedbackType = ETouchFeedbackSensitiveList; } if ( iListBoxExt->iPhysics && iListBoxExt->iPhysics->OngoingPhysicsAction() == CAknPhysics::EAknPhysicsActionFlicking ) { - iListBoxExt->iFeedbackType = ETouchFeedbackBasicItem; - } - - if ( !iListBoxExt->iPhysics || itemIndex == iView->CurrentItemIndex() ) - { - iListBoxExt->ImmediateFeedback( iListBoxExt->iFeedbackType, - TTouchFeedbackType(ETouchFeedbackVibra | ETouchFeedbackAudio), - aPointerEvent ); + iListBoxExt->iFeedbackType = ETouchFeedbackList; } } iListBoxExt->iEventModifiers = aPointerEvent.iModifiers; @@ -4726,6 +5133,7 @@ if(Buffer()->iPressedIndex == itemIndex) { Buffer()->iPressedIndex = KEikListBoxInvalidIndex; + iListBoxExt->iDoubleClickEventIgnored = ETrue; _AKNTRACE_FUNC_EXIT; return; } @@ -4757,10 +5165,12 @@ _AKNTRACE("TPointerEvent::EButton1Down"); // For drag outside listbox iListBoxExt->iIsDownOnItem = pointerIsOverAnItem; - iListBoxExt->iLastPoint = pointerPos; + iListBoxExt->iLastPoint = pointerPos; + iListBoxExt->iLongTappedItem = KErrNotFound; // update index of the last down tapped item iListBoxExt->iLastDownTappedItem = itemIndex; + iListBoxExt->iMarkableListShiftKeyPressed = EFalse; if ((! (Rect().Contains(aPointerEvent.iPosition))) && (iListBoxFlags & EPopout)) { @@ -4803,14 +5213,17 @@ UpdateHighlightL( itemIndex ); CCoeEnv::Static()->WsSession().Finish(); } - if ( itemIndex != oldCurrentItemIndex ) + + if ( !( ( iListBoxFlags & EViewerFlag ) && + ( iListBoxFlags & EDisableItemSpecificMenu ) ) ) { - iListBoxExt->ImmediateFeedback( + iListBoxExt->ImmediateFeedback( iListBoxExt->iFeedbackType, TTouchFeedbackType( ETouchFeedbackVibra | ETouchFeedbackAudio ), aPointerEvent ); - } + } + if ( !wasFlicking ) { ReportListBoxEventL( @@ -4820,6 +5233,18 @@ } else { + if( itemIndex == oldCurrentItemIndex ) + { + if( !( ( iListBoxFlags & EViewerFlag ) && + ( iListBoxFlags & EDisableItemSpecificMenu ) ) ) + { + iListBoxExt->ImmediateFeedback( + iListBoxExt->iFeedbackType, + TTouchFeedbackType( ETouchFeedbackVibra | + ETouchFeedbackAudio ), + aPointerEvent ); + } + } ReportListBoxEventL( MEikListBoxObserver::EEventPenDownOnItem ); } @@ -4841,7 +5266,8 @@ } } #endif - if (!(iListBoxFlags & EMultipleSelection)) // i.e. this is a single selection listbox + if ( !( iListBoxFlags & EMultipleSelection ) + || MarkingMode() ) { if (itemIndex == oldCurrentItemIndex) { @@ -4908,7 +5334,7 @@ } } - if ( itemIndex == oldCurrentItemIndex ) + if ( itemIndex == oldCurrentItemIndex && !iListBoxExt->iSingleClickEnabled ) { if ( shiftKeyPressed ) { @@ -4987,10 +5413,17 @@ case TPointerEvent::EButton1Up: _AKNTRACE("TPointerEvent::EButton1Up"); - if ( iListBoxExt->FeedbackEnabledOnUpEvent() && iListBoxExt->iClickEventsAllowed ) + if ( iListBoxExt->FeedbackEnabledOnUpEvent() && + iListBoxExt->iClickEventsAllowed && + ( !( ( iListBoxFlags & EViewerFlag ) && + ( iListBoxFlags & EDisableItemSpecificMenu ) ) )&& + ( iListBoxExt->iLastDownTappedItem == itemIndex ) && + ( !iListBoxExt->iDoubleClickEventIgnored ) && + itemIndex == iView->CurrentItemIndex() ) { - TTouchLogicalFeedback fbType = ETouchFeedbackBasicItem; - if ( iListBoxFlags & ES60StyleMultiselection ) + TTouchLogicalFeedback fbType = ETouchFeedbackList; + if ( iListBoxFlags & ES60StyleMultiselection + || iListBoxFlags & EMultipleSelection ) { fbType = ETouchFeedbackCheckbox; } @@ -5046,7 +5479,8 @@ } if ( !s60StyleMultiselection ) { - if ( !iListBoxExt->iSingleClickEnabled ) + if ( !iListBoxExt->iSingleClickEnabled && + itemIndex == iListBoxExt->iLastDownTappedItem ) { ReportListBoxEventL(MEikListBoxObserver::EEventItemClicked); } @@ -5061,9 +5495,15 @@ return; } } - else if ( s60StyleMultiselection && - iListBoxExt->iLastDownTappedItem == itemIndex && - !Buffer()->iDragToAnotherItem ) + // Due to the feature of capactior panel, the pointer position + // may change between pointer down and up during user click + // action. When the click position is between two items + // and flick or drag event is not performed, the item index may + // change unwanted, so we make a threshold for this situation. + else if ( s60StyleMultiselection && !Buffer()->iDragToAnotherItem + && ( iListBoxExt->iLastDownTappedItem == itemIndex + || ( iListBoxExt->iLastDownTappedItem != KErrNotFound + && Abs( iListBoxExt->iLastPointerPos.iY - aPointerEvent.iPosition.iY ) < KPointerDownAndUpThreshold ) ) ) { iListBoxFlags |= EStateChanged; Buffer()->iPressedIndex = itemIndex; @@ -5331,7 +5771,7 @@ // switch off selection (marking) mode when we lose focus // this also corrects situation, where FEP-menu is launched // and thus listbox doesn't receive shift up event - if (NULL != iListBoxExt) + if ( iListBoxExt ) { if ((iListBoxFlags & EMultipleSelection) && (iListBoxFlags & EShiftEnterMarks)) { @@ -5351,9 +5791,9 @@ iView->SetEmphasized(EFalse); iView->HideMatcherCursor(); - if (iItemEditor && - (iListBoxFlags & EPaintedSelection) && - (NULL != iListBoxExt && iListBoxExt->ReasonForFocusLost() == EFocusLostToExternalControl)) + if ( iItemEditor && + ( iListBoxFlags & EPaintedSelection ) && + ( iListBoxExt && iListBoxExt->ReasonForFocusLost() == EFocusLostToExternalControl ) ) { iView->DeselectItem(CurrentItemIndex()); } @@ -5421,9 +5861,12 @@ EXPORT_C TBool CEikListBox::BackgroundDrawingSuppressed() const { - if ( iListBoxExt ) - { - return iListBoxExt->iBackgroundDrawingSuppressed; + if ( iItemDrawer ) + { + TInt flags = iItemDrawer->Flags(); + + return ( flags & CListItemDrawer::EDrawWholeBackground ) + && ( flags & CListItemDrawer::EBackgroundDrawn ); } return EFalse; @@ -5705,7 +6148,7 @@ if ( iView ) { - iView->SetItemOffsetInPixels( 0 ); + iView->SetItemOffsetInPixels( 0 ); } // make sure that highlight is removed and long tap is canceled @@ -5743,8 +6186,22 @@ EColorControlDimmedBackground : EColorControlBackground,*this); UpdateViewColors(); UpdateItemDrawerColors(); - + + // store the value of virtical offset as it will be 0 in SizeChange, + // that will affect view position in skin changed, which is a bug. + TInt oldOffset = 0; + if ( iView ) + { + oldOffset = iView->ItemOffsetInPixels(); + } + // TODO: check if this call is real need here. SizeChanged(); + if ( oldOffset !=0 && iView ) + { + iView->SetItemOffsetInPixels( oldOffset ); + UpdateScrollBarThumbs(); + } + // this methord is empty. UpdateScrollBarsColors(); #ifdef RD_UI_TRANSITION_EFFECTS_LIST @@ -5774,10 +6231,12 @@ // Some client does not let list get button1up, so we do it there... iItemDrawer->ClearFlags( CListItemDrawer::EPressedDownState ); TInt index = View()->CurrentItemIndex(); - if ( index != KErrNotFound ) + TBool enabled( !( iItemDrawer->Flags() + & CListItemDrawer::ESingleClickDisabledHighlight ) ); + if ( index != KErrNotFound && enabled ) { Window().Invalidate( TRect( View()->ItemPos(index), - View()->ItemSize() ) ); + iItemDrawer->ItemCellSize() ) ); } break; } @@ -5789,7 +6248,12 @@ case KAknMessageFocusLost: { - if ( iListBoxExt && iListBoxExt->iSingleClickEnabled ) + // Do not remove highlight if window ordinal position has changed + // during the time when stylus menu is open + if ( iListBoxExt && iListBoxExt->iSingleClickEnabled && + ( iListBoxExt->iOldWinPos == KErrNotFound || + iListBoxExt->iOldWinPos == + DrawableWindow()->OrdinalPosition() ) ) { TBool enabled( iItemDrawer && !( iItemDrawer->Flags() & CListItemDrawer::ESingleClickDisabledHighlight ) ); @@ -5952,9 +6416,15 @@ { rect.iTl.iX += iItemDrawer->MarkColumn() + iItemDrawer->MarkGutter(); } - iListBoxExt->SetReasonForFocusLost(EFocusLostToInternalEditor); + if ( iListBoxExt ) + { + iListBoxExt->SetReasonForFocusLost(EFocusLostToInternalEditor); + } itemEditor->StartEditingL(*this,rect,index,aMaxLength); - iListBoxExt->SetReasonForFocusLost(EFocusLostToExternalControl); + if ( iListBoxExt ) + { + iListBoxExt->SetReasonForFocusLost(EFocusLostToExternalControl); + } ReportListBoxEventL( MEikListBoxObserver::EEventEditingStarted ); } _AKNTRACE_FUNC_EXIT; @@ -6082,18 +6552,21 @@ EXPORT_C void CEikListBox::DisableScrolling( TBool aDisabled ) { _AKNTRACE_FUNC_ENTER; - iListBoxExt->iScrollingDisabled = aDisabled; - iView->iExtension->iScrollingDisabled = aDisabled; - - if ( aDisabled && iListBoxExt->iPhysics ) - { - delete iListBoxExt->iPhysics; - iListBoxExt->iPhysics = NULL; - iView->SetItemOffsetInPixels( 0 ); - } - else if ( !aDisabled && !iListBoxExt->iPhysics && CAknPhysics::FeatureEnabled() ) - { - iListBoxExt->iPhysics = CAknPhysics::NewL( *iListBoxExt, this); + if ( iListBoxExt ) + { + iListBoxExt->iScrollingDisabled = aDisabled; + iView->iExtension->iScrollingDisabled = aDisabled; + + if ( aDisabled && iListBoxExt->iPhysics ) + { + delete iListBoxExt->iPhysics; + iListBoxExt->iPhysics = NULL; + iView->SetItemOffsetInPixels( 0 ); + } + else if ( !aDisabled && !iListBoxExt->iPhysics && CAknPhysics::FeatureEnabled() ) + { + iListBoxExt->iPhysics = CAknPhysics::NewL( *iListBoxExt, this); + } } _AKNTRACE_FUNC_EXIT; } @@ -6105,19 +6578,29 @@ // EXPORT_C TBool CEikListBox::ScrollingDisabled() { - return !iListBoxExt->iPhysics || iListBoxExt->iScrollingDisabled; + if ( iListBoxExt ) + { + return !iListBoxExt->iPhysics || iListBoxExt->iScrollingDisabled; + } + else + { + return ETrue; + } } EXPORT_C void CEikListBox::SetPointerEventFilterDisabledL( const CArrayFix& aItemIndexes ) { _AKNTRACE_FUNC_ENTER; - iListBoxExt->iMutiTappingItems.Reset(); - - for(TInt i=0; iiMutiTappingItems.InsertInOrderL( aItemIndexes.At(i) ); - } + if ( iListBoxExt ) + { + iListBoxExt->iMutiTappingItems.Reset(); + + for(TInt i=0; iiMutiTappingItems.InsertInOrderL( aItemIndexes.At(i) ); + } + } _AKNTRACE_FUNC_EXIT; } @@ -6173,10 +6656,22 @@ // EXPORT_C void CEikListBox::DisableSingleClick( TBool aDisabled ) { - _AKNTRACE_FUNC_ENTER; - if ( aDisabled && iListBoxExt->iSingleClickEnabled ) + _AKNTRACE_FUNC_ENTER; + if ( aDisabled && + iListBoxExt && + iListBoxExt->iSingleClickEnabled && + iItemDrawer ) { iListBoxExt->DisableSingleClick(); + iItemDrawer->ClearFlags( CListItemDrawer::ESingleClickEnabled); + } + else if ( !aDisabled && + iListBoxExt && + !iListBoxExt->iSingleClickEnabled && + iItemDrawer ) + { + TRAP_IGNORE( iListBoxExt->EnableSingleClickL() ); + iItemDrawer->SetFlags( CListItemDrawer::ESingleClickEnabled ); } _AKNTRACE_FUNC_EXIT; } @@ -6188,10 +6683,89 @@ // EXPORT_C void CEikListBox::DisableItemSpecificMenu() { + _AKNTRACE_FUNC_ENTER; if ( iListBoxExt ) { iListBoxExt->DisableItemSpecificMenu(); } + _AKNTRACE_FUNC_EXIT; + } + +// --------------------------------------------------------------------------- +// CEikListBox::IsHighlightEnabled +// --------------------------------------------------------------------------- +// +EXPORT_C TBool CEikListBox::IsHighlightEnabled() + { + _AKNTRACE_FUNC_ENTER; + TBool enabled( EFalse ); + if ( !( iItemDrawer->Flags() & CListItemDrawer::EDisableHighlight ) ) + { + if ( iListBoxExt && iListBoxExt->iSingleClickEnabled ) + { + enabled = !( iItemDrawer->Flags() + & CListItemDrawer::ESingleClickDisabledHighlight ); + } + else + { + enabled = ETrue; + } + } + _AKNTRACE_FUNC_EXIT; + return enabled; + } + + +// --------------------------------------------------------------------------- +// CEikListBox::SetMarkingMode +// --------------------------------------------------------------------------- +// +EXPORT_C void CEikListBox::SetMarkingMode( TBool aEnable ) + { + if ( iListBoxExt && iListBoxExt->iSingleClickEnabled && + ( iListBoxFlags & CEikListBox::ES60StyleMarkable ) ) + { + if ( iListBoxExt->iMarkingModeInUse != aEnable ) + { + if ( aEnable ) + { + iView->ItemDrawer()->SetFlags( + CListItemDrawer::EMarkingModeEnabled ); + } + else + { + iView->ItemDrawer()->ClearFlags( + CListItemDrawer::EMarkingModeEnabled ); + + if ( iView->SelectionIndexes()->Count() > 0 ) + { + iView->ClearSelection( EFalse ); + } + } + + iListBoxExt->iMarkingModeInUse = aEnable; + DrawDeferred(); + } + + if ( MarkingModeObserver() ) + { + MarkingModeObserver()->MarkingModeStatusChanged( aEnable ); + } + } + } + + +// --------------------------------------------------------------------------- +// CEikListBox::SetMarkingModeObserver +// --------------------------------------------------------------------------- +// +EXPORT_C void CEikListBox::SetMarkingModeObserver( + MAknMarkingModeObserver* aObserver ) + { + if ( iListBoxExt ) + { + iListBoxExt->iMarkingModeObserver = aObserver; + } } @@ -6200,9 +6774,9 @@ _AKNTRACE_FUNC_ENTER; #ifdef _DEBUG RDebug::Print( _L( "CEikListBox::ScrollView, aOffset = %d, aDrawNow = %d" ), aOffset, aDrawNow ); -#endif // _DEBUG - - if ( aOffset != 0 ) +#endif // _DEBUG + + if ( iListBoxExt && aOffset != 0 ) { TInt itemHeight = iView->ItemHeight(); TInt viewHeight = iView->ViewRect().Size().iHeight; @@ -6233,18 +6807,18 @@ ( newListBottomPos >= iListBoxExt->ListBottomLimit() ) || ( newListTopPos <= 0 && newListTopPos + viewHeight >= 0 && newListLastItemPos > viewHeight ) ) { - if ( CAknPhysics::EAknPhysicsActionFlicking == iListBoxExt->iPhysics->OngoingPhysicsAction() || - CAknPhysics::EAknPhysicsActionBouncing == iListBoxExt->iPhysics->OngoingPhysicsAction() ) + switch(iListBoxExt->iPhysics->OngoingPhysicsAction()) { - iListBoxExt->ImmediateFeedback( ETouchFeedbackSensitiveItem, - TTouchFeedbackType( ETouchFeedbackVibra ), - TPointerEvent() ); - } - else if ( CAknPhysics::EAknPhysicsActionDragging == iListBoxExt->iPhysics->OngoingPhysicsAction() ) - { - iListBoxExt->ImmediateFeedback( iListBoxExt->iFeedbackType, - TTouchFeedbackType( ETouchFeedbackVibra | ETouchFeedbackAudio ), - TPointerEvent() ); + case CAknPhysics::EAknPhysicsActionBouncing: + case CAknPhysics::EAknPhysicsActionDragging: + case CAknPhysics::EAknPhysicsActionFlicking: + iListBoxExt->ImmediateFeedback( + ETouchFeedbackSensitiveList, + TTouchFeedbackType( ETouchFeedbackVibra ), + TPointerEvent() ); + break; + default: + break; } } } @@ -6271,14 +6845,20 @@ #endif // _DEBUG iView->SetTopItemIndex( newTopItemIndex ); } + if ( aDrawNow ) { TRect rect(Rect()); // list position changed - iListBoxExt->iBackgroundDrawingSuppressed = ETrue; + if ( iListBoxExt && iListBoxExt->FlickOrPanningOngoing() ) + { + iItemDrawer->SetFlags( CListItemDrawer::EDrawWholeBackground ); + } + UpdateScrollBarThumbs(); DrawNow(); + if (iSBFrame && iSBFrame->VerticalScrollBar() && !iSBFrame->VerticalScrollBar()->OwnsWindow()) { TRect srect( iSBFrame->VerticalScrollBar()->Rect() ); @@ -6287,7 +6867,12 @@ iSBFrame->DrawScrollBarsNow(); } } - iListBoxExt->iBackgroundDrawingSuppressed = EFalse; + + if ( iListBoxExt ) + { + iItemDrawer->ClearFlags( CListItemDrawer::EDrawWholeBackground + | CListItemDrawer::EBackgroundDrawn ); + } } _AKNTRACE_FUNC_EXIT; } @@ -6302,20 +6887,10 @@ _AKNTRACE_FUNC_ENTER; _AKNTRACE( "aPointerEvent.iType = %d", aPointerEvent.iType ); if ( iListBoxExt->iPhysics->OngoingPhysicsAction() == CAknPhysics::EAknPhysicsActionBouncing ) - { - // Block scrolling events outside listbox area. Note that pointer - // event ignore must be done for the window-owning control or it - // doesn't have any effect! - CCoeControl* windowOwningControl = this; - - while ( windowOwningControl && !windowOwningControl->OwnsWindow() ) - { - windowOwningControl = windowOwningControl->Parent(); - } - - if ( windowOwningControl ) - { - windowOwningControl->IgnoreEventsUntilNextPointerUp(); + { + // Block scrolling events outside listbox area. + if ( iListBoxExt->IgnorePointerEventsUntilUp() ) + { _AKNTRACE_FUNC_EXIT; return ETrue; } @@ -6323,8 +6898,12 @@ TBool blockEvent = EFalse; - TBool allowDragEvent( ( iListBoxFlags & ELeftDownInViewRect ) && iSBFrame && !iListBoxExt->iScrollingDisabled ); - + // If tap down in listbox area, kinetic scrolling is enabled and style popup menu is not shown, + // drag event is sent to listbox. + TBool allowDragEvent( ( iListBoxFlags & ELeftDownInViewRect ) + && !iListBoxExt->iScrollingDisabled + && ( iListBoxExt->iSingleClickEnabled + && iListBoxExt->iLongTappedItem == KErrNotFound ) ); switch ( aPointerEvent.iType ) { @@ -6354,7 +6933,13 @@ { iListBoxExt->iLastDownTappedItem = tappedItemIndex; iListBoxExt->iMarkingDisabled = ETrue; + iListBoxFlags|=ELeftDownInViewRect; blockEvent = ETrue; + iListBoxExt->ImmediateFeedback( + ETouchFeedbackList, + TTouchFeedbackType( ETouchFeedbackVibra | + ETouchFeedbackAudio ), + aPointerEvent ); } } } @@ -6558,7 +7143,8 @@ _AKNTRACE_FUNC_ENTER; TInt oldCurrentItemIndex = iView->CurrentItemIndex(); - if ( iListBoxExt->iReportDelayedPenDown && !iListBoxExt->iScrolling ) + if ( iListBoxExt && iListBoxExt->iReportDelayedPenDown + && !iListBoxExt->iScrolling ) { #ifdef RD_UI_TRANSITION_EFFECTS_LIST if ( aItemIndex != oldCurrentItemIndex ) @@ -6581,16 +7167,24 @@ iListBoxExt->iDelayedPointerDownEvent ); } - if ( iListBoxExt->iDelayedMultiselection ) + if ( iListBoxExt && iListBoxExt->iDelayedMultiselection ) { iItemDrawer->SetFlags( CListItemDrawer::EPressedDownState ); } iView->SetItemIndex( aItemIndex ); - if ( iListBoxExt->iMarkableListMarking ) - { - if ( iListBoxExt->iMarkableListShiftKeyPressed ) + if ( iListBoxExt && iListBoxExt->iMarkableListMarking ) + { + if ( iListBoxExt->iSingleClickEnabled ) + { + if ( iListBoxExt->iMarkableListShiftKeyPressed ) + { + iView->ToggleItemL( iView->CurrentItemIndex() ); + iListBoxExt->iClickEventsAllowed = EFalse; + } + } + else if ( iListBoxExt->iMarkableListShiftKeyPressed ) { #ifdef RD_UI_TRANSITION_EFFECTS_LIST iListBoxExt->iAnchor = oldCurrentItemIndex; @@ -6618,7 +7212,7 @@ iView->DrawItem( oldCurrentItemIndex ); iView->DrawItem( aItemIndex ); - if ( iListBoxExt->iDelayedMultiselection ) + if ( iListBoxExt && iListBoxExt->iDelayedMultiselection ) { iListBoxFlags |= EStateChanged; Buffer()->iPressedIndex = aItemIndex; @@ -6630,6 +7224,40 @@ // --------------------------------------------------------------------------- +// CEikListBox::MarkingMode +// --------------------------------------------------------------------------- +// +TBool CEikListBox::MarkingMode() const + { + TBool markingModeInUse = EFalse; + + if ( iListBoxExt ) + { + markingModeInUse = iListBoxExt->iMarkingModeInUse; + } + + return markingModeInUse; + } + + +// --------------------------------------------------------------------------- +// CEikListBox::MarkingModeObserver +// --------------------------------------------------------------------------- +// +MAknMarkingModeObserver* CEikListBox::MarkingModeObserver() + { + MAknMarkingModeObserver* observer = NULL; + + if ( iListBoxExt ) + { + observer = iListBoxExt->iMarkingModeObserver; + } + + return observer; + } + + +// --------------------------------------------------------------------------- // Sets this control as visible or invisible. // --------------------------------------------------------------------------- //