diff -r aecbbf00d063 -r d48ab3b357f1 uifw/AvKon/aknhlist/src/akntreelistview.cpp --- a/uifw/AvKon/aknhlist/src/akntreelistview.cpp Tue Aug 31 15:28:30 2010 +0300 +++ b/uifw/AvKon/aknhlist/src/akntreelistview.cpp Wed Sep 01 12:16:19 2010 +0100 @@ -1,5 +1,5 @@ /* -* Copyright (c) 2006, 2007 Nokia Corporation and/or its subsidiary(-ies). +* Copyright (c) 2006-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" @@ -26,13 +26,17 @@ #include #include // for testability hooks #include +#include +#include +#include +#include #include "akntreelistview.h" #include "akntree.h" #include "akntreelist.h" #include "akntreeiterator.h" #include "akntreelistphysicshandler.h" - +#include "akntrace.h" #ifdef RD_UI_TRANSITION_EFFECTS_LIST @@ -49,6 +53,8 @@ // Number of additional items to draw const TInt KAdditionalItems = 2; +// Number of icons in marking mode icon array +const TInt KMarkingModeIconArraySize = 2; // Tree list view flag definitions. enum TAknTreeListViewFlags @@ -58,7 +64,7 @@ EFlagLooping, EFlagUpdateBackground, EFlagMarkingEnabled, // Marking of list items is enabled. - EFlagMarkingMode, // List in marking mode (MSK controlled by list). + EFlagMarkingState, // List in marking state (MSK controlled by list). EFlagMark, // List items are being marked. EFlagUnmark, // List items are being unmarked. EFlagSimultaneousMarking, // Simultaneous marking ongoing. @@ -68,7 +74,11 @@ EFlagSaveFocusAfterSorting, EFlagSingleClickEnabled, EFlagHighlightEnabled, // Is highlight drawing enabled - EFlagIgnoreButtonUpEvent // Up event ignored (when styluspopup menu open) + EFlagIsPressedDownState, + EFlagIsDragged, + EFlagScrollPhysicsTop, // Physics view adjusted according to top item + EFlagMirroredLayoutInUse, // Mirrored layout in use + EFlagMarkingMode // Marking mode activated }; @@ -112,6 +122,13 @@ } delete iLongTapDetector; + if ( iMarkingIconArray ) + { + iMarkingIconArray->ResetAndDestroy(); + } + + delete iMarkingIconArray; + #ifdef RD_UI_TRANSITION_EFFECTS_LIST if ( CAknListLoader::TfxApiInternal( iGc ) ) { @@ -163,7 +180,8 @@ { Window().Invalidate( Rect() ); } - UpdateScrollbars(); + + UpdateScrollbars( ETrue ); } @@ -213,7 +231,7 @@ // Draw always Window().Invalidate( Rect() ); - UpdateScrollbars(); + UpdateScrollbars( ETrue ); } @@ -422,6 +440,7 @@ delete iEmptyListText; iEmptyListText = NULL; iEmptyListText = aText.AllocL(); + UpdateScrollbars( ETrue ); } @@ -468,7 +487,21 @@ // void CAknTreeListView::SelectItem( CAknTreeItem* aSelectedItem ) { - SelectItem( aSelectedItem, EFalse ); + if ( iFlags.IsSet( EFlagMarkingMode ) ) + { + if ( aSelectedItem->IsMarkable() ) + { + MarkItem( aSelectedItem, !aSelectedItem->IsMarked(), ETrue ); + } + else if ( aSelectedItem->IsNode() ) + { + SelectItem( aSelectedItem, EFalse ); + } + } + else + { + SelectItem( aSelectedItem, EFalse ); + } } @@ -490,7 +523,14 @@ // void CAknTreeListView::SetPressedDownState( const TBool& aPressedDown ) { - iIsPressedDownState = aPressedDown; + if ( aPressedDown ) + { + iFlags.Set( EFlagIsPressedDownState ); + } + else + { + iFlags.Clear( EFlagIsPressedDownState ); + } } @@ -503,7 +543,7 @@ { CAknTreeItem* first = iTree.VisibleItem( aFirstItem ); UpdateVisibleItems( 0, first ); - UpdateScrollbars(); + UpdateScrollbars( ETrue ); UpdateAnimation(); if ( aDrawNow ) @@ -741,11 +781,7 @@ void CAknTreeListView::MakeVisible( TBool aVisible ) { CAknControl::MakeVisible( aVisible ); - - if ( aVisible ) - { - UpdateScrollbars(); - } + UpdateScrollbars( aVisible ); } @@ -770,6 +806,11 @@ iScrollbarFrame = new ( ELeave ) CEikScrollBarFrame( this, this ); iScrollbarFrame->CreateDoubleSpanScrollBarsL( EFalse, EFalse ); + if ( CAknEnv::Static()->TransparencyEnabled() && iPhysicsHandler ) + { + // disable background drawing of scrollbar + iScrollbarFrame->DrawBackground( EFalse, EFalse ); + } } @@ -781,62 +822,127 @@ void CAknTreeListView::HandleResourceChange( TInt aType ) { CAknControl::HandleResourceChange( aType ); - if ( aType == KAknsMessageSkinChange ) - { - TRAPD( error, CreateAnimationL() ) - if ( error ) - { - delete iAnimation; - iAnimation = NULL; - } - } - else if ( aType == KEikDynamicLayoutVariantSwitch && FocusedItem() ) + + switch ( aType ) { - if ( !FocusedItemVisible() ) + case KEikMessageWindowsFadeChange: + { + ReportCollectionChangedEvent(); + } + + case KAknsMessageSkinChange: { - TInt firstItemIndex = 0; - if ( iItems.Count() && iItems[0].Item() ) + TRAPD( error, CreateAnimationL() ) + if ( error ) { - firstItemIndex = iTree.VisibleItemIndex( iItems[0].Item() ); + delete iAnimation; + iAnimation = NULL; } - TInt index = 0; - if ( firstItemIndex < iTree.VisibleItemIndex( FocusedItem() ) ) + TRAP_IGNORE( LoadMarkingIconsL() ); + break; + } + + case KEikDynamicLayoutVariantSwitch: + { + if ( AknLayoutUtils::LayoutMirrored() ) { - index = iItems.Count() - 1; + iFlags.Set( EFlagMirroredLayoutInUse ); + } + else + { + iFlags.Clear( EFlagMirroredLayoutInUse ); } - SetFocusedItem( FocusedItem(), index, ETrue ); - } - else - { - SetFocusedItem( FocusedItem(), FocusIndex(), ETrue ); - - - // This block moves visible view after layout switch - // if there are not enough items to fill whole screen - TInt visibleItemIndex = iTree.VisibleItemIndex( FocusedItem() ); - if ( visibleItemIndex != KErrNotFound) + CAknTreeItem* focusedItem( FocusedItem() ); + if ( focusedItem ) { - TInt focusedItemIndex = FocusedItemIndex(); - if (focusedItemIndex != -1) + if ( !FocusedItemVisible() ) { - TInt height = iTree.VisibleItemCount() - visibleItemIndex + focusedItemIndex; - TInt itemCountLimit = iItems.Count(); - - if ( height < itemCountLimit && height < iTree.VisibleItemCount() ) + TInt firstItemIndex = 0; + if ( iItems.Count() && iItems[0].Item() ) + { + firstItemIndex = + iTree.VisibleItemIndex( iItems[0].Item() ); + } + + TInt index = 0; + if ( firstItemIndex < iTree.VisibleItemIndex( focusedItem ) ) + { + index = iItems.Count() - 1; + } + + if( HighlightEnabled() ) + { + SetFocusedItem( focusedItem, index, ETrue ); + } + else { - TInt move = itemCountLimit - height; - UpdateVisibleItems( focusedItemIndex + move, FocusedItem() ); + // This block moves visible view after layout switch + // if there are not enough items to fill whole screen + TInt visibleItemIndex = iTree.VisibleItemIndex( focusedItem ); + if ( visibleItemIndex != KErrNotFound ) + { + TInt visibleItemCount( iTree.VisibleItemCount() ); + TInt itemCountLimit = iItems.Count(); + if ( visibleItemCount <= itemCountLimit - KAdditionalItems ) + { + UpdateVisibleItems( visibleItemIndex, focusedItem ); + } + } } + + } + else + { + SetFocusedItem( focusedItem, FocusIndex(), ETrue ); + + // This block moves visible view after layout switch + // if there are not enough items to fill whole screen + TInt visibleItemIndex = + iTree.VisibleItemIndex( focusedItem ); + if ( visibleItemIndex != KErrNotFound ) + { + TInt focusedItemIndex = FocusedItemIndex(); + if ( focusedItemIndex != -1 ) + { + TInt visibleItemCount( iTree.VisibleItemCount() ); + + TInt height = + visibleItemCount - visibleItemIndex + focusedItemIndex; + TInt itemCountLimit = iItems.Count(); + + if ( height < itemCountLimit && + height < visibleItemCount ) + { + TInt move = itemCountLimit - height; + UpdateVisibleItems( focusedItemIndex + move, focusedItem ); + } + } + } + // end of block } } - // end of block + break; } - } - else if ( aType == KAknMessageFocusLost && HighlightEnabled() ) - { - EnableHighlight( EFalse ); + + case KAknMessageFocusLost: + { + if ( SingleClickEnabled() && HighlightEnabled() && + ( iOldWinPos == KErrNotFound || + iOldWinPos == DrawableWindow()->OrdinalPosition() ) ) + { + EnableHighlight( EFalse ); + // Redraw item + SetFocusedItem( FocusedItem(), FocusIndex(), ETrue ); + } + break; + } + + default: + { + break; + } } } @@ -851,13 +957,7 @@ // void CAknTreeListView::HandlePointerEventL( const TPointerEvent& aPointerEvent ) { - if ( iFlags.IsSet( EFlagIgnoreButtonUpEvent ) - && aPointerEvent.iType == TPointerEvent::EButton1Up ) - { - return; - } - - if ( GrabbingComponent() != NULL ) + if ( GrabbingComponent() ) { iPhysicsHandler->ResetEventBlockingStatus(); } @@ -912,7 +1012,7 @@ } TInt thumbPosition = aScrollBar->ThumbPosition(); - if ( AknLayoutUtils::LayoutMirrored() && + if ( iFlags.IsSet( EFlagMirroredLayoutInUse ) && aScrollBar != iScrollbarFrame->VerticalScrollBar() ) { const TEikScrollBarModel* model = aScrollBar->Model(); @@ -931,7 +1031,7 @@ case EEikScrollPageLeft: case EEikScrollPageRight: iViewLevel = thumbPosition; - UpdateScrollbars(); + UpdateScrollbars( ETrue ); UpdateAnimation(); Window().Invalidate( Rect() ); break; @@ -943,15 +1043,15 @@ break; case EEikScrollThumbReleaseHoriz: - UpdateScrollbars(); + UpdateScrollbars( ETrue ); break; case EEikScrollHome: - // Not in use! + // Not in use break; case EEikScrollEnd: - // Not in use! + // Not in use break; default: @@ -1050,7 +1150,8 @@ if ( aDrawNow ) { - Window().Invalidate( Rect() ); + // DrawNow must be used here. + DrawNow(); } } @@ -1134,7 +1235,9 @@ } else if ( IsFocused() && FocusedItemVisible() ) { - TRect rect = iItems[FocusIndex()].HighlightRect( iViewLevel, Indention(), IndentionWidth() ); + TRect rect = iItems[FocusIndex()].HighlightRect( iViewLevel, + Indention(), + IndentionWidth() ); Window().Invalidate( rect ); } @@ -1154,11 +1257,9 @@ LayoutView(); // Update scrollbars. - UpdateScrollbars(); - -#ifdef RD_UI_TRANSITION_EFFECTS_LIST + UpdateScrollbars( ETrue ); + UpdateIndexes(); -#endif AknsUtils::RegisterControlPosition( this, PositionRelativeToScreen() ); TRAP_IGNORE( InitPhysicsL() ); @@ -1200,13 +1301,13 @@ iStylusDownItemIndex( -1 ), iAnimationIID( KAknsIIDQsnAnimList ), iIndentionWidth( -1 ), - iPhysicsHandler( NULL ), - iScrollPhysicsTop( ETrue ) + iPhysicsHandler( NULL ) #ifdef RD_UI_TRANSITION_EFFECTS_LIST ,iGc(NULL) #endif //RD_UI_TRANSITION_EFFECTS_LIST ,iItemActionMenu( NULL ), - iLongTapDetector( NULL ) + iLongTapDetector( NULL ), + iOldWinPos( KErrNotFound ) { if ( static_cast( iCoeEnv->AppUi() )->IsSingleClickCompatible() ) @@ -1216,6 +1317,7 @@ iFlags.Set( EFlagStructureLines ); iFlags.Set( EFlagIndention ); + iFlags.Set( EFlagScrollPhysicsTop ); } @@ -1253,9 +1355,10 @@ &iItems ); } - iIsPressedDownState = EFalse; - iIsDragged = EFalse; - iItemActionMenu = CAknItemActionMenu::RegisterCollectionL( *this ); + iFlags.Clear( EFlagIsPressedDownState ); + iFlags.Clear( EFlagIsDragged ); + iItemActionMenu = CAknItemActionMenu::RegisterCollectionL( *this, this ); + if ( iItemActionMenu ) { iLongTapDetector = CAknLongTapDetector::NewL( this ); @@ -1269,6 +1372,15 @@ { EnableHighlight( ETrue ); } + if ( AknLayoutUtils::LayoutMirrored() ) + { + iFlags.Set( EFlagMirroredLayoutInUse ); + } + else + { + iFlags.Clear( EFlagMirroredLayoutInUse ); + } + LoadMarkingIconsL(); } @@ -1281,10 +1393,7 @@ void CAknTreeListView::HandleItemAddedEvent( CAknTreeItem* /*aItem*/, TBool aDrawNow ) { UpdateVisibleItems(); - if (aDrawNow) - { - UpdateScrollbars(); - } + UpdateScrollbars( aDrawNow ); } @@ -1299,7 +1408,7 @@ // been changed, unless the it receives information from where the // specified item was moved. UpdateVisibleItems(); - UpdateScrollbars(); + UpdateScrollbars( ETrue ); } @@ -1354,10 +1463,7 @@ void CAknTreeListView::HandleItemRemovedEvent( CAknTreeItem* /*aItem*/, TBool aDrawNow ) { UpdateVisibleItems(); - if (aDrawNow) - { - UpdateScrollbars(); - } + UpdateScrollbars( aDrawNow ); } @@ -1380,7 +1486,8 @@ { UpdateVisibleItems(); } - UpdateScrollbars(); + + UpdateScrollbars( ETrue ); } @@ -1420,7 +1527,7 @@ } UpdateVisibleItems(); - UpdateScrollbars(); + UpdateScrollbars( ETrue ); } @@ -1472,10 +1579,8 @@ } } } - if ( aDrawNow ) - { - UpdateScrollbars(); - } + + UpdateScrollbars( aDrawNow ); } @@ -1490,9 +1595,7 @@ SetFocusIndex( KMinTInt ); if ( !iItems.Count() ) { -#ifdef RD_UI_TRANSITION_EFFECTS_LIST UpdateIndexes(); -#endif return; } @@ -1530,9 +1633,7 @@ SetFocusIndex( ii ); } } -#ifdef RD_UI_TRANSITION_EFFECTS_LIST UpdateIndexes(); -#endif } @@ -1578,9 +1679,7 @@ item = iterator.Next(); } } -#ifdef RD_UI_TRANSITION_EFFECTS_LIST UpdateIndexes(); -#endif } else if ( itemCount && iItems.Count() ) { @@ -1613,13 +1712,16 @@ CAknTreeItem* item = FocusedItem(); if ( item ) { - if ( MarkingOngoing() ) + if ( iFlags.IsSet( EFlagMarkingMode ) ) { - MarkItem( item, !item->IsMarked(), ETrue ); + if ( item->IsMarkable() ) + { + MarkItem( item, !item->IsMarked(), ETrue ); + } } else { - SelectItem( item, true ); + SelectItem( item, EFalse ); } } } @@ -1631,7 +1733,7 @@ // void CAknTreeListView::HandleRightArrowKeyEvent() { - if ( AknLayoutUtils::LayoutMirrored() ) + if ( iFlags.IsSet( EFlagMirroredLayoutInUse ) ) { AscendFocus(); } @@ -1648,7 +1750,7 @@ // void CAknTreeListView::HandleLeftArrowKeyEvent() { - if ( AknLayoutUtils::LayoutMirrored() ) + if ( iFlags.IsSet( EFlagMirroredLayoutInUse ) ) { DescendFocus(); } @@ -1949,7 +2051,10 @@ // This should not fail, if enough space was reserved for the // array, and if it fails, it results only fewer items being // shown in the list. - iItems.Append( TAknTreeListViewItem() ); + if ( KErrNone != iItems.Append( TAknTreeListViewItem() ) ) + { + return; + } } } @@ -1962,6 +2067,21 @@ iterator.SetCurrent( first ); iterator.Previous(); } + if ( iFlags.IsSet( EFlagMarkingMode ) ) + { + if ( iFlags.IsSet( EFlagMirroredLayoutInUse )) + { + itemRect.iBr.iX -= + AknLayoutScalable_Avkon::list_double_graphic_pane_t1( + 0 ).LayoutLine().ir; + } + else + { + itemRect.iBr.iX -= + AknLayoutScalable_Avkon::list_double_graphic_pane_t1( + 0 ).LayoutLine().il; + } + } // Update items and their rectangles. for ( TInt ii = 0; ii < iItems.Count(); ++ii ) @@ -1986,7 +2106,8 @@ // Fill whole control area with list items when physics enabled // and threre is no horizontal scrollbar. if ( iScrollbarFrame && - iScrollbarFrame->ScrollBarVisibility( CEikScrollBar::EHorizontal ) != CEikScrollBarFrame::EOn && + iScrollbarFrame->ScrollBarVisibility( + CEikScrollBar::EHorizontal ) != CEikScrollBarFrame::EOn && viewRect.Height() < Rect().Height() ) { viewRect.iTl.iY = Rect().iTl.iY; @@ -2004,12 +2125,27 @@ // scrollbars changes. // --------------------------------------------------------------------------- // -void CAknTreeListView::UpdateScrollbars() +void CAknTreeListView::UpdateScrollbars( TBool aDrawNow ) { if ( iScrollbarFrame ) { - iPhysicsHandler->UpdateScrollIndex( iScrollPhysicsTop ); - iScrollPhysicsTop = ETrue; + TBool drawHorizontal; + TBool drawVertical; + if ( !aDrawNow ) + { + // Backup the old values. + iScrollbarFrame->DrawBackgroundState( drawHorizontal, + drawVertical ); + + // Disable the scrollbar background drawing for the duration + // of this call. + iScrollbarFrame->DrawBackground( EFalse, EFalse ); + } + + iPhysicsHandler->UpdateScrollIndex( + iFlags.IsSet( EFlagScrollPhysicsTop ) ); + iFlags.Set( EFlagScrollPhysicsTop ); + // Get values for horizontal scrollbar. TInt hThumbPos = iViewLevel; @@ -2025,8 +2161,8 @@ hThumbSpan = a/b; hScrollSpan = Max( hThumbPos + hThumbSpan, c/b ); } - - if ( AknLayoutUtils::LayoutMirrored() ) + if ( iFlags.IsSet( EFlagMirroredLayoutInUse ) ) + { hThumbPos = hScrollSpan - ( hThumbPos + hThumbSpan ); } @@ -2073,7 +2209,7 @@ iScrollbarFrame->Tile( &hModel, &vModel ); LayoutView(); - UpdateScrollbars(); // Recursion + UpdateScrollbars( aDrawNow ); // Recursion // Update animation in case that scrollbar visibility change // has affected the highlight size of focused item. @@ -2083,7 +2219,13 @@ { // Set new model for scrollbars. iScrollbarFrame->Tile( &hModel, &vModel ); - } + } + + if ( !aDrawNow ) + { + // Restore the previous draw background state values. + iScrollbarFrame->DrawBackground( drawHorizontal, drawVertical ); + } } } @@ -2534,9 +2676,9 @@ } // Exits marking mode. - if ( iFlags.IsSet( EFlagMarkingMode ) ) + if ( iFlags.IsSet( EFlagMarkingState ) ) { - ExitMarkingMode(); + ExitMarking(); } // Remove MSK observer. @@ -2597,18 +2739,18 @@ // void CAknTreeListView::DoHandleLongPressL() { - if ( iFlags.IsClear( EFlagMarkingMode ) ) + if ( iFlags.IsClear( EFlagMarkingState ) ) { - EnterMarkingMode(); + EnterMarking(); } } // --------------------------------------------------------------------------- -// Enters marking mode. +// Enters marking state. // --------------------------------------------------------------------------- // -void CAknTreeListView::EnterMarkingMode() +void CAknTreeListView::EnterMarking() { CEikButtonGroupContainer* bgc; CCoeControl* MSK = NULL; @@ -2642,7 +2784,7 @@ { ReportTreeListEvent( MAknTreeListObserver::EMarkingModeEnabled, iTree.Id( FocusedItem() ) ); - iFlags.Set( EFlagMarkingMode ); + iFlags.Set( EFlagMarkingState ); bgc->DrawNow(); } } @@ -2650,12 +2792,12 @@ // --------------------------------------------------------------------------- -// Exits marking mode. +// Exits marking state. // --------------------------------------------------------------------------- // -void CAknTreeListView::ExitMarkingMode() +void CAknTreeListView::ExitMarking() { - if ( iFlags.IsSet( EFlagMarkingMode ) ) + if ( iFlags.IsSet( EFlagMarkingState ) ) { CEikButtonGroupContainer* bgc = NULL; CCoeControl* MSK = NULL; @@ -2675,7 +2817,7 @@ } ReportTreeListEvent( MAknTreeListObserver::EMarkingModeDisabled, iTree.Id( FocusedItem() ) ); - iFlags.Clear( EFlagMarkingMode ); + iFlags.Clear( EFlagMarkingState ); } } @@ -2721,14 +2863,29 @@ void CAknTreeListView::DrawItemsWithPhysics( const TRect& aRect ) const { TBool empty = IsEmpty(); - + TInt offset = Offset(); #ifdef RD_UI_TRANSITION_EFFECTS_LIST CWindowGc& gc = iGc && !empty ? *iGc : SystemGc(); - TInt offset = Offset(); #else CWindowGc& gc = SystemGc(); #endif + TInt checkBoxOffset ( 0 ); + if ( iFlags.IsSet( EFlagMarkingMode ) ) + { + if ( iFlags.IsSet( EFlagMirroredLayoutInUse ) ) + { + checkBoxOffset = + AknLayoutScalable_Avkon::list_double_graphic_pane_t1( + 0 ).LayoutLine().ir; + } + else + { + checkBoxOffset = + AknLayoutScalable_Avkon::list_double_graphic_pane_t1( + 0 ).LayoutLine().il; + } + } #ifdef RD_UI_TRANSITION_EFFECTS_LIST MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( &gc ); if ( !empty && transApi ) @@ -2773,13 +2930,57 @@ } #endif // RD_UI_TRANSITION_EFFECTS_LIST + // text color, used to draw the separator line between list items + TRgb textColor( KRgbBlack ); + AknsUtils::GetCachedColor( skin, + textColor, + KAknsIIDQsnTextColors, + EAknsCIQsnTextColorsCG6 ); + if ( iFlags.IsSet( EFlagMarkingMode ) + && iMarkingIconArray + && iMarkingIconArray->Count() == KMarkingModeIconArraySize ) + + { + // Set sizes for marking icon bitmaps + TRect drawRect; + drawRect = iItems[0].Rect(); + + // Rect for the marking icon + TRect iconRect = RectFromLayout( drawRect, + AknLayoutScalable_Avkon::list_single_graphic_pane_g1( 0 ) ); + + for ( TInt ii = 0; ii < iMarkingIconArray->Count(); ++ii ) + { + CGulIcon* icon = ( *iMarkingIconArray )[ii]; + CFbsBitmap* bitmap = icon->Bitmap(); + + if ( bitmap ) + { + TSize size( bitmap->SizeInPixels() ); // set size if not already + TSize targetSize( iconRect.Size() ); + + if ( size.iWidth != targetSize.iWidth && size.iHeight + != targetSize.iHeight ) + { + AknIconUtils::SetSize( bitmap, targetSize, + EAspectRatioPreservedAndUnusedSpaceRemoved ); + } + } + } + } const TInt itemCount = iItems.Count(); for ( TInt ii = 0; ii < itemCount; ++ii ) { TRect drawRect( iItems[ii].Rect() ); + if ( iFlags.IsSet( EFlagMarkingMode ) ) + { + drawRect.iBr.iX += checkBoxOffset; + } + if ( iItems[ii].Item() ) { + #ifdef RD_UI_TRANSITION_EFFECTS_LIST TRect tfxDrawRect( drawRect ); tfxDrawRect.Move( 0, -offset ); @@ -2789,7 +2990,6 @@ transApi->StartDrawing( MAknListBoxTfxInternal::EListNotSpecified ); } - TRect clippingRect( tfxDrawRect ); // If horizontal scrollbar on, reduce clipping rect @@ -2803,17 +3003,32 @@ clippingRect.iBr.iY = viewRect.iBr.iY; } } + // Set clipping rect. + if ( clippingRect.Intersects( aRect ) ) + { + clippingRect.Intersection( aRect ); + gc.SetClippingRect( clippingRect ); + } + else + { + //Draw nothing if no overlap between item rectangel and given rect. + continue; + } - // Set clipping rect. - gc.SetClippingRect( clippingRect ); - - if ( transApi ) { transApi->StopDrawing(); } #endif - TBool focused = ( IsFocused() && FocusedItem() && + + if ( iItems[ii].Item() != iBottomItem ) + { + TRect offsetRect( drawRect ); + offsetRect.Move( 0, -offset ); + AknListUtils::DrawSeparator( gc, offsetRect, textColor, skin ); + } + + TBool focused = ( FocusedItem() && iItems[ii].Item() == FocusedItem() ); if ( SingleClickEnabled() && !HighlightEnabled() ) @@ -2826,24 +3041,33 @@ // Draw highlight for focused item. TRect highlightRect( iItems[ii].HighlightRect( iViewLevel, Indention(), IndentionWidth() ) ); + + if ( iFlags.IsSet( EFlagMarkingMode ) ) + { + highlightRect.iBr.iX = drawRect.iBr.iX; + highlightRect.iTl.iX = drawRect.iTl.iX; + } #ifdef RD_UI_TRANSITION_EFFECTS_LIST TRect tfxHighlightRect( highlightRect ); tfxHighlightRect.Move( 0, -offset ); #endif //RD_UI_TRANSITION_EFFECTS_LIST - if ( iIsPressedDownState || !DrawAnimation( gc, highlightRect ) ) + if ( iFlags.IsSet( EFlagIsPressedDownState ) + || !DrawAnimation( gc, highlightRect ) ) { #ifdef RD_UI_TRANSITION_EFFECTS_LIST if ( transApi ) { transApi->Invalidate(MAknListBoxTfxInternal::EListHighlight ); - transApi->BeginRedraw( MAknListBoxTfxInternal::EListHighlight, tfxHighlightRect ); + transApi->BeginRedraw( MAknListBoxTfxInternal::EListHighlight, + tfxHighlightRect ); transApi->StartDrawing( MAknListBoxTfxInternal::EListHighlight ); } #endif //RD_UI_TRANSITION_EFFECTS_LIST - - DrawHighlight( gc, highlightRect, iIsPressedDownState ); + DrawHighlight( gc, highlightRect, + iFlags.IsSet( EFlagIsPressedDownState ) ); + #ifdef RD_UI_TRANSITION_EFFECTS_LIST if ( transApi ) @@ -2861,29 +3085,91 @@ #endif //RD_UI_TRANSITION_EFFECTS_LIST } + if ( iFlags.IsSet( EFlagMarkingMode ) && iMarkingIconArray + && iMarkingIconArray->Count() == + KMarkingModeIconArraySize ) + { + // Rect for the marking icon + TRect iconRect = RectFromLayout( drawRect, + AknLayoutScalable_Avkon::list_single_graphic_pane_g1( 0 ) ); + + iconRect.Move( 0, -offset ); + // unchecked icon + CGulIcon* icon = ( *iMarkingIconArray )[1]; + + TBool marked = ( iItems[ii].Item()->IsMarked() ); + if ( marked ) + { + icon = (*iMarkingIconArray)[0]; + } + + CFbsBitmap* bitmap = icon->Bitmap(); + + if ( bitmap ) + { + gc.BitBltMasked( iconRect.iTl, bitmap, + iconRect.Size(), icon->Mask(), EFalse ); + } + } + + if ( iFlags.IsSet( EFlagMarkingMode ) ) + { + drawRect.iBr.iX -= checkBoxOffset; + if ( iFlags.IsClear( EFlagMirroredLayoutInUse ) ) + { + gc.SetOrigin( TPoint( checkBoxOffset, 0 ) ); + } + } + #ifdef RD_UI_TRANSITION_EFFECTS_LIST if (iItems[ii].Item()) { if ( transApi ) { - transApi->BeginRedraw(MAknListBoxTfxInternal::EListItem, tfxDrawRect, iTree.VisibleItemIndex(iItems[ii].Item())); + transApi->BeginRedraw( + MAknListBoxTfxInternal::EListItem, + tfxDrawRect, + iTree.VisibleItemIndex( iItems[ii].Item() ) ); transApi->StartDrawing( MAknListBoxTfxInternal::EListItem ); } #endif //RD_UI_TRANSITION_EFFECTS_LIST - // Draw item. - iItems[ii].Draw( gc, iTree, drawRect, focused, iViewLevel, - StructureLines(), Indention(), IndentionWidth() ); + if ( iFlags.IsSet( EFlagMarkingMode ) ) + { + TBool marked = iItems[ii].Item()->IsMarked(); + if ( marked ) + { + iItems[ii].Item()->SetMarked( EFalse ); + } + iItems[ii].Draw( gc, iTree, drawRect, focused, iViewLevel, + StructureLines(), Indention(), IndentionWidth() ); + + if ( marked ) + { + iItems[ii].Item()->SetMarked( ETrue ); + } + } + else + { + iItems[ii].Draw( gc, iTree, drawRect, focused, iViewLevel, + StructureLines(), Indention(), IndentionWidth() ); + } #ifdef RD_UI_TRANSITION_EFFECTS_LIST if ( transApi ) { transApi->StopDrawing(); - transApi->EndRedraw(MAknListBoxTfxInternal::EListItem, iTree.VisibleItemIndex(iItems[ii].Item())); + transApi->EndRedraw( + MAknListBoxTfxInternal::EListItem, + iTree.VisibleItemIndex( iItems[ii].Item() ) ); } } #endif //RD_UI_TRANSITION_EFFECTS_LIST + if ( iFlags.IsSet( EFlagMarkingMode ) ) + { + gc.SetOrigin( TPoint( 0, 0 ) ); + } } } } @@ -2974,7 +3260,7 @@ item = iterator.Previous(); } } - iScrollPhysicsTop = EFalse; + iFlags.Clear( EFlagScrollPhysicsTop ); } } @@ -2995,8 +3281,11 @@ // Enables or disables the highlight drawing // --------------------------------------------------------------------------- // -void CAknTreeListView::EnableHighlight( TBool aEnabled ) +void CAknTreeListView::EnableHighlight( TBool aEnabled, + TBool aPointerEnabled ) { + TBool wasEnabled = iFlags.IsSet( EFlagHighlightEnabled ); + if ( aEnabled ) { iFlags.Set( EFlagHighlightEnabled ); @@ -3005,6 +3294,13 @@ { iFlags.Clear( EFlagHighlightEnabled ); } + + if ( !aPointerEnabled + && ( ( wasEnabled && !aEnabled ) + || ( !wasEnabled && aEnabled ) ) ) + { + ReportCollectionChangedEvent(); + } } // --------------------------------------------------------------------------- @@ -3036,7 +3332,7 @@ TUint CAknTreeListView::CollectionState() const { TUint state( 0 ); - if ( IsVisible() ) + if ( IsVisible() && ( !DrawableWindow() || !DrawableWindow()->IsFaded() ) ) { state |= MAknCollection::EStateCollectionVisible; } @@ -3044,6 +3340,17 @@ { state |= MAknCollection::EStateHighlightVisible; } + + if ( iList.Flags() & KAknTreeListMarkable ) + { + state |= MAknCollection::EStateMultipleSelection; + } + TBool markedItems( EFalse ); + TRAP_IGNORE( markedItems = HasMarkedItemsL() ); + if ( markedItems ) + { + state |= MAknCollection::EStateMarkedItems; + } return state; } @@ -3053,7 +3360,7 @@ // void CAknTreeListView::ItemActionMenuClosed() { - iFlags.Clear( EFlagIgnoreButtonUpEvent ); + iOldWinPos = KErrNotFound; EnableHighlight( EFalse ); DrawDeferred(); } @@ -3062,12 +3369,187 @@ // CAknTreeListView::CollectionExtension // ----------------------------------------------------------------------------- // -TInt CAknTreeListView::CollectionExtension( TUint /*aExtensionId*/, - TAny*& /*a0*/, TAny* /*a1*/ ) +TInt CAknTreeListView::CollectionExtension( + TUint aExtensionId, TAny*& a0, TAny* /*a1*/ ) { + if ( aExtensionId == MAknMarkingCollection::TYPE ) + { + a0 = static_cast( this ); + } + return KErrNone; } + +// ----------------------------------------------------------------------------- +// CAknTreeListView::SetMultipleMarkingState +// ----------------------------------------------------------------------------- +// +void CAknTreeListView::SetMultipleMarkingState( TBool aActive ) + { + if ( iFlags.IsSet( EFlagMarkingMode ) != aActive ) + { + if ( !aActive ) + { + TBool markedItems( EFalse ); + TRAP_IGNORE( markedItems = HasMarkedItemsL() ); + if ( markedItems ) + { + UnmarkAll(); + } + } + + EnableMarking( aActive ); + if ( aActive ) + { + iFlags.Set( EFlagMarkingMode ); + } + else + { + iFlags.Clear( EFlagMarkingMode ); + } + if ( aActive ) + { + // Expand all items when entering marking mode + iTree.Expand(); + } + LayoutView(); + DrawDeferred(); + + if ( iList.MarkingModeObserver() ) + { + iList.MarkingModeObserver()->MarkingModeStatusChanged( aActive ); + } + } + } + + +// ----------------------------------------------------------------------------- +// CAknTreeListView::MarkingState +// ----------------------------------------------------------------------------- +// +TUint CAknTreeListView::MarkingState() const + { + TUint state( 0 ); + + if ( iFlags.IsSet( EFlagMarkingMode ) ) + { + state |= MAknMarkingCollection::EStateMarkingMode; + + TBool markedItems ( EFalse ); + TRAP_IGNORE( markedItems = HasMarkedItemsL() ); + if ( markedItems ) + { + state |= MAknMarkingCollection::EStateMarkedItems; + } + if ( iItems.Count() == 0 ) + { + state |= MAknMarkingCollection::EStateCollectionEmpty; + } + } + return state; + } + + +// ----------------------------------------------------------------------------- +// CAknTreeListView::MarkCurrentItemL +// ----------------------------------------------------------------------------- +// +void CAknTreeListView::MarkCurrentItemL() + { + if ( iFlags.IsSet( EFlagMarkingMode ) && FocusedItem() && + FocusedItem()->IsMarkable() ) + { + MarkItem( FocusedItem(), ETrue, ETrue ); + } + } + + +// ----------------------------------------------------------------------------- +// CAknTreeListView::MarkAllL +// ----------------------------------------------------------------------------- +// +void CAknTreeListView::MarkAllL() + { + if ( iFlags.IsSet( EFlagMarkingMode ) ) + { + TAknTreeIterator iterator = iTree.Iterator(); + CAknTreeItem* item = NULL; + item = iterator.First(); + while ( item && iterator.HasNext() ) + { + if ( item->IsMarkable() ) + { + MarkItem( item, ETrue, EFalse ); + } + item = iterator.Next(); + } + DrawDeferred(); + } + } + + +// ----------------------------------------------------------------------------- +// CAknTreeListView::UnmarkAll +// ----------------------------------------------------------------------------- +// +void CAknTreeListView::UnmarkAll() + { + if ( iFlags.IsSet( EFlagMarkingMode ) ) + { + TAknTreeIterator iterator = iTree.Iterator(); + CAknTreeItem* item = NULL; + item = iterator.First(); + while ( item && iterator.HasNext() ) + { + MarkItem( item, EFalse, EFalse ); + item = iterator.Next(); + } + DrawDeferred(); + } + } + + + // ----------------------------------------------------------------------------- +// CAknTreeListView::CurrentItemMarkable +// ----------------------------------------------------------------------------- +// +TBool CAknTreeListView::CurrentItemMarkable() + { + if ( FocusedItem() && !FocusedItem()->IsMarkable() ) + { + return EFalse; + } + return ETrue; + } + +// ----------------------------------------------------------------------------- +// CAknTreeListView::ExitMarkingMode +// ----------------------------------------------------------------------------- +// +TBool CAknTreeListView::ExitMarkingMode() + { + if ( iList.MarkingModeObserver() ) + { + return iList.MarkingModeObserver()->ExitMarkingMode(); + } + return ETrue; + } + + +// ----------------------------------------------------------------------------- +// CAknTreeListView::ReportCollectionChangedEvent +// ----------------------------------------------------------------------------- +// +void CAknTreeListView::ReportCollectionChangedEvent() + { + if ( iItemActionMenu ) + { + iItemActionMenu->CollectionChanged( *this ); + } + } + + // --------------------------------------------------------------------------- // CAknTreeListView::HandleLongTapEventL // --------------------------------------------------------------------------- @@ -3076,8 +3558,9 @@ const TPoint& /*aPenEventLocation*/, const TPoint& aPenEventScreenLocation) { - iFlags.Set( EFlagIgnoreButtonUpEvent ); iItemActionMenu->ShowMenuL( aPenEventScreenLocation, 0 ); + iOldWinPos = DrawableWindow()->OrdinalPosition(); + IgnoreEventsUntilNextPointerUp(); } // --------------------------------------------------------------------------- @@ -3087,7 +3570,9 @@ void CAknTreeListView::LongTapPointerEventL( const TPointerEvent& aPointerEvent) { - if ( iLongTapDetector && iItemActionMenu && iItemActionMenu->InitMenuL() ) + if ( iLongTapDetector && iItemActionMenu + && !( HasMarkedItemsL() && FocusedItem() + && !FocusedItem()->IsMarked() ) && iItemActionMenu->InitMenuL() ) { iLongTapDetector->PointerEventL( aPointerEvent ); } @@ -3109,18 +3594,14 @@ // CAknTreeListView::HasMarkedItemsL // --------------------------------------------------------------------------- // -TBool CAknTreeListView::HasMarkedItemsL() +TBool CAknTreeListView::HasMarkedItemsL() const { RArray selection; CleanupClosePushL( selection ); iList.GetMarkedItemsL( selection ); TInt count( selection.Count() ); CleanupStack::PopAndDestroy( &selection ); - if ( count > 0 ) - { - return ETrue; - } - return EFalse; + return ( count > 0 ); } @@ -3155,10 +3636,19 @@ { return iBottomIndex; } - + +#endif //RD_UI_TRANSITION_EFFECTS_LIST +// --------------------------------------------------------------------------- +// CAknTreeListView::UpdateIndexes +// --------------------------------------------------------------------------- +// void CAknTreeListView::UpdateIndexes() { +#ifdef RD_UI_TRANSITION_EFFECTS_LIST iTopIndex = iBottomIndex = iHighlightIndex = 0; +#else + iBottomIndex = 0; +#endif //RD_UI_TRANSITION_EFFECTS_LIST if ( iItems.Count() ) { @@ -3166,14 +3656,57 @@ { if (iItems[i].Item()) { - iBottomIndex = iTree.VisibleItemIndex(iItems[i].Item()); + iBottomItem = iItems[i].Item(); + iBottomIndex = iTree.VisibleItemIndex( iBottomItem ); break; } } +#ifdef RD_UI_TRANSITION_EFFECTS_LIST iTopIndex = iTree.VisibleItemIndex(iItems[0].Item()); iHighlightIndex = iTree.VisibleItemIndex(FocusedItem()); +#endif //RD_UI_TRANSITION_EFFECTS_LIST } } -#endif //RD_UI_TRANSITION_EFFECTS_LIST + +// ----------------------------------------------------------------------------- +// CAknTreeListView::LoadMarkingIconsL +// ----------------------------------------------------------------------------- +// +void CAknTreeListView::LoadMarkingIconsL() + { + if ( !iMarkingIconArray ) + { + iMarkingIconArray = new ( ELeave ) + CAknIconArray( KMarkingModeIconArraySize ); + } + else + { + iMarkingIconArray->ResetAndDestroy(); + } + + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + const TDesC& avkonIconFile = AknIconUtils::AvkonIconFileName(); + + CGulIcon* icon = AknsUtils::CreateGulIconL( skin, + KAknsIIDQgnPropCheckboxOn, + avkonIconFile, + EMbmAvkonQgn_prop_checkbox_on, + EMbmAvkonQgn_prop_checkbox_on_mask ); + + CleanupStack::PushL( icon ); + iMarkingIconArray->AppendL( icon ); + CleanupStack::Pop( icon ); + + icon = AknsUtils::CreateGulIconL( skin, + KAknsIIDQgnPropCheckboxOff, + avkonIconFile, + EMbmAvkonQgn_prop_checkbox_off, + EMbmAvkonQgn_prop_checkbox_off_mask ); + + CleanupStack::PushL( icon ); + iMarkingIconArray->AppendL( icon ); + CleanupStack::Pop( icon ); + } +