menufw/menufwui/mmwidgets/src/mmlistbox.cpp
changeset 0 f72a12da539e
child 2 08c6ee43b396
equal deleted inserted replaced
-1:000000000000 0:f72a12da539e
       
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <aknlists.h>
       
    20 #include <eikspmod.h>
       
    21 #include <eikclb.h>
       
    22 #include <eikfrlb.h>
       
    23 #include <eikslb.h>
       
    24 #include <AknUtils.h>
       
    25 #include <aknlayoutscalable_avkon.cdl.h>
       
    26 #include <aknlayoutscalable_apps.cdl.h>
       
    27 #include <layoutmetadata.cdl.h>
       
    28 
       
    29 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
    30 #include <aknlistboxtfxinternal.h>
       
    31 #include <akntransitionutils.h>
       
    32 #include <aknlistloadertfx.h>
       
    33 #endif
       
    34 
       
    35 #include "mmlistboxmodel.h"
       
    36 #include "mmlistbox.h"
       
    37 #include "mmlistboxview.h"
       
    38 #include "mmlistboxitemdrawer.h"
       
    39 #include "mmmarqueeadapter.h"
       
    40 #include "mmwidgetcontainer.h"
       
    41 #include "mmwidgetsconstants.h"
       
    42 #include "mmdraweranimator.h"
       
    43 #include "mmtemplatelibrary.h"
       
    44 
       
    45 
       
    46 // -----------------------------------------------------------------------------
       
    47 //
       
    48 // -----------------------------------------------------------------------------
       
    49 //
       
    50 CMmListBox::CMmListBox() : AKNDOUBLELISTBOXNAME(R_LIST_PANE_LINES_AB_COLUMN)
       
    51 	{
       
    52 	// No implementation required
       
    53 	}
       
    54 
       
    55 // -----------------------------------------------------------------------------
       
    56 //
       
    57 // -----------------------------------------------------------------------------
       
    58 //
       
    59 CMmListBox::~CMmListBox()
       
    60 	{
       
    61 	}
       
    62 
       
    63 // -----------------------------------------------------------------------------
       
    64 //
       
    65 // -----------------------------------------------------------------------------
       
    66 //
       
    67 CMmListBox* CMmListBox::NewLC( const CCoeControl* aParent, TInt aFlags,
       
    68     CMmTemplateLibrary* aTemplateLibrary )
       
    69 	{
       
    70 	CMmListBox* self = new (ELeave)CMmListBox();
       
    71 	CleanupStack::PushL(self);
       
    72 	self->ConstructL( aParent, aFlags, aTemplateLibrary );
       
    73 	return self;
       
    74 	}
       
    75 
       
    76 // -----------------------------------------------------------------------------
       
    77 //
       
    78 // -----------------------------------------------------------------------------
       
    79 //
       
    80 void CMmListBox::SetListFlag( TInt aFlag )
       
    81 	{
       
    82 	iListBoxFlags = iListBoxFlags | aFlag;
       
    83 	}
       
    84 
       
    85 // -----------------------------------------------------------------------------
       
    86 //
       
    87 // -----------------------------------------------------------------------------
       
    88 //
       
    89 void CMmListBox::ClearListFlag( TInt aFlag )
       
    90 	{
       
    91 	iListBoxFlags = iListBoxFlags & !aFlag;
       
    92 	}
       
    93 
       
    94 // -----------------------------------------------------------------------------
       
    95 //
       
    96 // -----------------------------------------------------------------------------
       
    97 //
       
    98 CMmListBox* CMmListBox::NewL( const CCoeControl* aParent, TInt aFlags,
       
    99     CMmTemplateLibrary* aTemplateLibrary )
       
   100 	{
       
   101 	CMmListBox* self = CMmListBox::NewLC( aParent, aFlags, aTemplateLibrary );
       
   102 	CleanupStack::Pop( self );
       
   103 	return self;
       
   104 	}
       
   105 
       
   106 // -----------------------------------------------------------------------------
       
   107 //
       
   108 // -----------------------------------------------------------------------------
       
   109 //
       
   110 void CMmListBox::ConstructL( const CCoeControl* aParent, TInt aFlags,
       
   111     CMmTemplateLibrary* aTemplateLibrary )
       
   112 	{
       
   113 	iDisableChildComponentDrawing = EFalse;
       
   114 	iModel = iMmModel = CMmListBoxModel::NewL();
       
   115     CreateItemDrawerL( aTemplateLibrary );
       
   116 
       
   117     EnableExtendedDrawingL();
       
   118 
       
   119 
       
   120     iItemDrawer->SetDrawMark(EFalse);
       
   121     CEikListBox::ConstructL(aParent,aFlags);
       
   122     iMmDrawer->SetView( this );
       
   123 	}
       
   124 
       
   125 // -----------------------------------------------------------------------------
       
   126 //
       
   127 // -----------------------------------------------------------------------------
       
   128 //
       
   129 void CMmListBox::HandlePointerEventInEditModeL(
       
   130         const TPointerEvent& aPointerEvent )
       
   131     {
       
   132     TInt itemUnderPointerIndex = KErrNotFound;
       
   133     if ( aPointerEvent.iType == TPointerEvent::EButton1Up ||
       
   134             aPointerEvent.iType == TPointerEvent::EButton1Down )
       
   135         {
       
   136         CEikFormattedCellListBoxTypedef::HandlePointerEventL( aPointerEvent );
       
   137         }
       
   138     else if ( View()->XYPosToItemIndex(
       
   139             aPointerEvent.iPosition, itemUnderPointerIndex ) )
       
   140         {
       
   141         TInt currentItemIndex = CurrentItemIndex();
       
   142         if ( currentItemIndex != itemUnderPointerIndex )
       
   143             {
       
   144             View()->SetCurrentItemIndex( itemUnderPointerIndex );
       
   145             // remove hightlight from the previously highlighted item
       
   146             }
       
   147         }
       
   148     HandleScrollingInEditMode( aPointerEvent );
       
   149     }
       
   150 
       
   151 // -----------------------------------------------------------------------------
       
   152 //
       
   153 // -----------------------------------------------------------------------------
       
   154 //
       
   155 void CMmListBox::HandleScrollingInEditMode( const TPointerEvent& aPointerEvent )
       
   156     {
       
   157     if ( aPointerEvent.iType == TPointerEvent::EDrag
       
   158             || aPointerEvent.iType == TPointerEvent::EButtonRepeat )
       
   159         {
       
   160         TInt nextScrollDelay = ScrollIfNeeded( aPointerEvent );
       
   161         if ( nextScrollDelay )
       
   162             {
       
   163             TRect ignoreDragRect(
       
   164                 TPoint(aPointerEvent.iParentPosition.iX - MmEffects::KDragIgnoreRectValue,
       
   165                     aPointerEvent.iParentPosition.iY - MmEffects::KDragIgnoreRectValue),
       
   166                 TPoint(aPointerEvent.iParentPosition.iX + MmEffects::KDragIgnoreRectValue,
       
   167                     aPointerEvent.iParentPosition.iY + MmEffects::KDragIgnoreRectValue));
       
   168 
       
   169             Window().CancelPointerRepeatEventRequest();
       
   170             Window().RequestPointerRepeatEvent( nextScrollDelay, ignoreDragRect );
       
   171             }
       
   172         }
       
   173     }
       
   174 
       
   175 // -----------------------------------------------------------------------------
       
   176 //
       
   177 // -----------------------------------------------------------------------------
       
   178 //
       
   179 TBool CMmListBox::IsPointerInTopScrollingThreshold(
       
   180             const TPointerEvent& aPointerEvent ) const
       
   181     {
       
   182     TInt topScrollingTreshold = Rect().iTl.iY
       
   183         + ( MmEffects::KFocusScrollingThreshold
       
   184             * TReal( View()->ItemSize().iHeight ) );
       
   185 
       
   186     return ( aPointerEvent.iPosition.iY < topScrollingTreshold );
       
   187     }
       
   188 
       
   189 // -----------------------------------------------------------------------------
       
   190 //
       
   191 // -----------------------------------------------------------------------------
       
   192 //
       
   193 TBool CMmListBox::IsPointerInBottomScrollingThreshold(
       
   194             const TPointerEvent& aPointerEvent ) const
       
   195     {
       
   196     TInt bottomScrollingTreshold = Rect().iBr.iY
       
   197         - ( MmEffects::KFocusScrollingThreshold
       
   198             * TReal( View()->ItemSize().iHeight ) );
       
   199 
       
   200     return ( aPointerEvent.iPosition.iY > bottomScrollingTreshold );
       
   201     }
       
   202 
       
   203 // -----------------------------------------------------------------------------
       
   204 //
       
   205 // -----------------------------------------------------------------------------
       
   206 //
       
   207 TInt CMmListBox::ScrollIfNeeded( const TPointerEvent& aPointerEvent )
       
   208     {
       
   209     TInt nextScrollDelay = 0;
       
   210     
       
   211 	TBool readyForScrolling =
       
   212 			iMmDrawer->GetAnimator()->IsReadyForNewAnimation()
       
   213 					&& iMmDrawer->GetFloatingItemCount() != 0;
       
   214 	
       
   215 	if ( IsPointerInTopScrollingThreshold( aPointerEvent ) )
       
   216 		{
       
   217 		// scroll up by one row
       
   218 		TInt newCurrentItemIndex = CurrentItemIndex() - 1;
       
   219 
       
   220 		if ( newCurrentItemIndex >= 0 )
       
   221 			{
       
   222 			nextScrollDelay = MmEffects::KEditModeScrollingDelayFactor *
       
   223 				Max( 1, aPointerEvent.iPosition.iY - Rect().iTl.iY );
       
   224 			if (readyForScrolling)
       
   225 				{
       
   226 				View()->VScrollTo( View()->CalcNewTopItemIndexSoItemIsVisible(
       
   227                         newCurrentItemIndex ) );
       
   228                 View()->SetCurrentItemIndex( newCurrentItemIndex );
       
   229                 UpdateScrollBarThumbs();
       
   230 				}
       
   231 			}
       
   232 		}
       
   233 	else if ( IsPointerInBottomScrollingThreshold( aPointerEvent) )
       
   234 		{
       
   235 		// scroll down by one row
       
   236 		TInt lastItemIndex = iModel->NumberOfItems() - 1;
       
   237 		TInt newCurrentItemIndex = CurrentItemIndex() + 1;
       
   238 		
       
   239 		
       
   240 		if ( newCurrentItemIndex <= lastItemIndex )
       
   241 			{
       
   242 			nextScrollDelay = MmEffects::KEditModeScrollingDelayFactor *
       
   243 				Max( 1, Rect().iBr.iY - aPointerEvent.iPosition.iY );
       
   244 
       
   245 			if (readyForScrolling)
       
   246 				{
       
   247 				View()->VScrollTo( View()->CalcNewTopItemIndexSoItemIsVisible(
       
   248 						newCurrentItemIndex ) );
       
   249 				View()->SetCurrentItemIndex( newCurrentItemIndex );
       
   250                 UpdateScrollBarThumbs();
       
   251 				}
       
   252 			}
       
   253 		}
       
   254 
       
   255     return nextScrollDelay;
       
   256     }
       
   257 
       
   258 // -----------------------------------------------------------------------------
       
   259 //
       
   260 // -----------------------------------------------------------------------------
       
   261 //
       
   262 void CMmListBox::HandlePointerEventL(const TPointerEvent& aPointerEvent)
       
   263     {
       
   264 //    if ( aPointerEvent.iType == TPointerEvent::EButton1Down &&
       
   265 //            iMmDrawer->CachedDataUseIsEnabled() )
       
   266 //        {
       
   267 //        // Touching the screen stops flick but avkon does not send us
       
   268 //        // MEikListBoxObserver::EEventFlickStopped event in such case.
       
   269 //        // Thus this little hack:
       
   270 //        iMmDrawer->EnableCachedDataUse( EFalse );
       
   271 //        DrawView();
       
   272 //        }
       
   273 
       
   274     CMmWidgetContainer* parent = static_cast<CMmWidgetContainer*>( Parent() );
       
   275 
       
   276     if ( parent->IsEditMode() )
       
   277         {
       
   278         HandlePointerEventInEditModeL( aPointerEvent );
       
   279         }
       
   280     else
       
   281     	{
       
   282         CEikFormattedCellListBoxTypedef::HandlePointerEventL( aPointerEvent );
       
   283     	}
       
   284 
       
   285     if ( iMmDrawer->GetAnimator()->IsActive() )
       
   286     	{
       
   287     	iMmDrawer->GetAnimator()->CancelNextRedrawL();
       
   288     	}
       
   289 
       
   290     }
       
   291 
       
   292 // -----------------------------------------------------------------------------
       
   293 //
       
   294 // -----------------------------------------------------------------------------
       
   295 //
       
   296 void CMmListBox::FixViewForMirroredLayout()
       
   297     {
       
   298     TInt scrollbarWidth =
       
   299             ScrollBarFrame()->VerticalScrollBar()->Rect().Width();
       
   300     TRect r( View()->ViewRect() );
       
   301     TInt currentShift = r.iTl.iX;
       
   302     TBool scrollbarVisible = ScrollBarFrame()->VerticalScrollBar()->IsVisible();
       
   303     TBool layoutMirrored = AknLayoutUtils::LayoutMirrored();
       
   304 
       
   305     if ( layoutMirrored && scrollbarVisible && currentShift != scrollbarWidth )
       
   306         {
       
   307         // shift view rect to the right
       
   308         r.Move( scrollbarWidth - currentShift, 0 );
       
   309         View()->SetViewRect( r );
       
   310         }
       
   311     else if ( ( !layoutMirrored || !scrollbarVisible ) && currentShift != 0 )
       
   312         {
       
   313         // restore view rect to its normal position
       
   314         r.Move( -currentShift, 0 );
       
   315         View()->SetViewRect( r );
       
   316         }
       
   317     }
       
   318 
       
   319 // -----------------------------------------------------------------------------
       
   320 //
       
   321 // -----------------------------------------------------------------------------
       
   322 //
       
   323 void CMmListBox::RedrawScrollbarBackground() const
       
   324     {
       
   325     TRect viewRect( View()->ViewRect() );
       
   326     if ( viewRect.iTl.iX > 0 )
       
   327         {
       
   328         TRect scrollbarRect( TPoint( 0, 0 ),
       
   329                 TSize( viewRect.iTl.iX, viewRect.Height() ) );
       
   330 
       
   331         CWindowGc* gc = iItemDrawer->Gc();
       
   332         CMmListBoxItemDrawer* itemDrawer =
       
   333                 static_cast<CMmListBoxItemDrawer*>( iItemDrawer );
       
   334         MAknsSkinInstance *skin = AknsUtils::SkinInstance();
       
   335         CCoeControl* control = itemDrawer->FormattedCellData()->Control();
       
   336         MAknsControlContext *cc = AknsDrawUtils::ControlContext( control );
       
   337         if( gc )
       
   338             {
       
   339             if ( control )
       
   340                 {
       
   341                 AknsDrawUtils::Background( skin, cc, control, *gc, scrollbarRect );
       
   342                 }
       
   343             else
       
   344                 {
       
   345                 gc->SetBrushColor( BackColor() );
       
   346                 gc->Clear( scrollbarRect );
       
   347                 }
       
   348             }
       
   349         }
       
   350     }
       
   351 
       
   352 // -----------------------------------------------------------------------------
       
   353 //
       
   354 // -----------------------------------------------------------------------------
       
   355 //
       
   356 TKeyResponse CMmListBox::OfferKeyEventL(
       
   357         const TKeyEvent& aKeyEvent,TEventCode aType )
       
   358     {
       
   359     TInt itemIndex = CurrentItemIndex();
       
   360     TInt previousItemIndex = CurrentItemIndex();
       
   361     TKeyResponse ret = CEikFormattedCellListBoxTypedef::OfferKeyEventL(
       
   362         aKeyEvent, aType );
       
   363     TInt currentItemIndex = CurrentItemIndex();
       
   364 
       
   365     TInt itemY = View()->ItemPos( currentItemIndex ).iY
       
   366                + View()->ItemSize( currentItemIndex ).iHeight;
       
   367 
       
   368     if ( currentItemIndex == BottomItemIndex()
       
   369     		&& currentItemIndex != previousItemIndex
       
   370     		&& itemY > View()->ViewRect().iBr.iY )
       
   371     	{
       
   372     	if( aType == EEventKey )
       
   373     		{
       
   374 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   375     		MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal(
       
   376     		    View()->ItemDrawer()->Gc() );
       
   377     		TBool effects = transApi && !transApi->EffectsDisabled();
       
   378     		if ( effects )
       
   379     			{
       
   380     			transApi->SetMoveType( MAknListBoxTfxInternal::EListScrollDown );
       
   381     			}
       
   382 #endif
       
   383 			iView->VScrollTo(
       
   384 				iView->CalcNewTopItemIndexSoItemIsVisible( currentItemIndex ) );
       
   385 
       
   386 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   387 			if ( effects )
       
   388 				{
       
   389 				transApi->Draw( Rect() );
       
   390 				}
       
   391 #endif
       
   392 			}
       
   393     	SetCurrentItemIndex( currentItemIndex );
       
   394     	}
       
   395 
       
   396     RedrawIfNecessary( itemIndex, CurrentItemIndex());
       
   397     return ret;
       
   398     }
       
   399 
       
   400 // -----------------------------------------------------------------------------
       
   401 //
       
   402 // -----------------------------------------------------------------------------
       
   403 //
       
   404 TBool CMmListBox::RedrawIfNecessary( TInt aPreviousCurrent, TInt aCurrent )
       
   405     {
       
   406     TBool redrawConsumed( EFalse );
       
   407     if( aCurrent == KErrNotFound )
       
   408         {
       
   409         return redrawConsumed;
       
   410         }
       
   411 
       
   412     CMmListBoxView * view = static_cast<CMmListBoxView *>(iView);
       
   413     TInt differenceIndex = Abs( aPreviousCurrent - aCurrent );
       
   414     if ( aPreviousCurrent == KErrNotFound  || differenceIndex == 0 )
       
   415         {
       
   416         //TODO: It should be checked if this is really necessary
       
   417         view->RedrawBackground();
       
   418         return redrawConsumed;
       
   419         }
       
   420 
       
   421     TInt sizePrevBefore = iMmDrawer->GetItemHeight(aPreviousCurrent, ETrue);
       
   422     TInt sizeCurBefore = iMmDrawer->GetItemHeight(aCurrent, EFalse);
       
   423     TInt sizePrevAfter = iMmDrawer->GetItemHeight(aPreviousCurrent, EFalse);
       
   424     TInt sizeCurAfter = iMmDrawer->GetItemHeight(aCurrent, ETrue);
       
   425 
       
   426     if ( ( sizePrevBefore == sizePrevAfter ) && (sizeCurBefore == sizeCurAfter) )
       
   427         {
       
   428         return redrawConsumed;
       
   429         }
       
   430      else
       
   431         {
       
   432         TInt sizeAllBefore = sizePrevBefore + sizePrevAfter;
       
   433         TInt sizeAllAfter = sizeCurBefore + sizeCurAfter;
       
   434 
       
   435         TInt lastPotentialItemIndex = Min( iModel->NumberOfItems(),
       
   436                 iView->TopItemIndex() + iView->NumberOfItemsThatFitInRect(
       
   437                         iView->ViewRect() ) );
       
   438         TInt redrawIndex = lastPotentialItemIndex;
       
   439 
       
   440         if ( differenceIndex == 1 )
       
   441             {
       
   442             if( sizeAllBefore != sizeAllAfter )
       
   443             	{
       
   444                 redrawIndex = Min( aPreviousCurrent, aCurrent );
       
   445             	}
       
   446             else
       
   447             	{
       
   448             	return redrawConsumed;
       
   449             	}
       
   450             }
       
   451         else if ( differenceIndex > 1 && sizeAllBefore == sizeAllAfter  )
       
   452             {
       
   453             redrawIndex = Min( aPreviousCurrent, aCurrent );
       
   454             lastPotentialItemIndex = Max( aPreviousCurrent, aCurrent );
       
   455             }
       
   456         else if ( differenceIndex > 1 )
       
   457             {
       
   458             redrawIndex = Min( aPreviousCurrent, aCurrent );
       
   459             }
       
   460 
       
   461         if (redrawIndex < iView->TopItemIndex())
       
   462             redrawIndex = iView->TopItemIndex();
       
   463 
       
   464         if (lastPotentialItemIndex > iView->BottomItemIndex())
       
   465             lastPotentialItemIndex = iView->BottomItemIndex();
       
   466 
       
   467         if ( aPreviousCurrent < TopItemIndex() )
       
   468         	{
       
   469         	lastPotentialItemIndex = BottomItemIndex() ;
       
   470         	}
       
   471         else if ( BottomItemIndex() < aPreviousCurrent )
       
   472         	{
       
   473         	lastPotentialItemIndex = BottomItemIndex() + 1;
       
   474         	}
       
   475         
       
   476         while ( redrawIndex < lastPotentialItemIndex +1 )
       
   477             {
       
   478             view->DrawSingleItem( redrawIndex++ );
       
   479             redrawConsumed = ETrue;
       
   480             }
       
   481 
       
   482         view->RedrawBackground();
       
   483         }
       
   484     return redrawConsumed;
       
   485     }
       
   486 
       
   487 // -----------------------------------------------------------------------------
       
   488 //
       
   489 // -----------------------------------------------------------------------------
       
   490 //
       
   491 void CMmListBox::CreateItemDrawerL( CMmTemplateLibrary* aTemplateLibrary )
       
   492     {
       
   493     CFormattedCellListBoxData* cellData=CFormattedCellListBoxData::NewL();
       
   494     CleanupStack::PushL( cellData );
       
   495     iItemDrawer = iMmDrawer = CMmListBoxItemDrawer::NewL( MmModel(),
       
   496             iEikonEnv->NormalFont(), cellData, EListbox, aTemplateLibrary );
       
   497     CleanupStack::Pop( cellData );
       
   498     }
       
   499 
       
   500 // -----------------------------------------------------------------------------
       
   501 //
       
   502 // -----------------------------------------------------------------------------
       
   503 //
       
   504 CMmListBoxModel* CMmListBox::MmModel()
       
   505 	{
       
   506 	return iMmModel;
       
   507 	}
       
   508 
       
   509 // -----------------------------------------------------------------------------
       
   510 //
       
   511 // -----------------------------------------------------------------------------
       
   512 //
       
   513 void CMmListBox::SetMmModel( CMmListBoxModel* aMmModel )
       
   514 	{
       
   515 	if ( iMmModel != aMmModel )
       
   516 		{
       
   517 		delete iMmModel;
       
   518 		iMmModel = aMmModel;
       
   519 		}
       
   520 	}
       
   521 
       
   522 // -----------------------------------------------------------------------------
       
   523 //
       
   524 // -----------------------------------------------------------------------------
       
   525 //
       
   526 CListBoxView* CMmListBox::MakeViewClassInstanceL()
       
   527     {
       
   528     return CMmListBoxView::NewL();
       
   529     }
       
   530 
       
   531 // -----------------------------------------------------------------------------
       
   532 //
       
   533 // -----------------------------------------------------------------------------
       
   534 //
       
   535 TInt CMmListBox::AdjustRectHeightToWholeNumberOfItems(TRect& /*aRect*/) const
       
   536     {
       
   537     return KErrNone;
       
   538     }
       
   539 
       
   540 // -----------------------------------------------------------------------------
       
   541 //
       
   542 // -----------------------------------------------------------------------------
       
   543 //
       
   544 void CMmListBox::SetItemDrawerAndViewBgContext (CAknsBasicBackgroundControlContext * aBgContext)
       
   545 	{
       
   546 	iMmDrawer->SetBgContext (aBgContext);
       
   547 	}
       
   548 
       
   549 // -----------------------------------------------------------------------------
       
   550 //
       
   551 // -----------------------------------------------------------------------------
       
   552 //
       
   553 TBool CMmListBox::HandleScrollbarVisibilityChangeL()
       
   554 	{
       
   555 	TBool ret = EFalse;
       
   556 	if ( AllItemsFitInViewRect() )
       
   557 		{
       
   558 		if ( ScrollBarFrame()->VerticalScrollBar()->IsVisible()
       
   559             || iMmDrawer->TemplateLibrary()->GetScrollbarVisibility() )
       
   560 			{
       
   561 			ScrollBarFrame()->VerticalScrollBar()->MakeVisible( EFalse );
       
   562 			iMmDrawer->SetScrollbarVisibilityL( EFalse );
       
   563 
       
   564 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   565 			MAknListBoxTfxInternal *trans = CAknListLoader::TfxApiInternal( ItemDrawer()->Gc() );
       
   566 				if ( trans )
       
   567 					{
       
   568 					trans->Remove( MAknListBoxTfxInternal::EListEverything );
       
   569 					}
       
   570 #endif
       
   571 
       
   572 			ret = ETrue; //redraw is needed
       
   573 			}
       
   574 		}
       
   575 	else if ( !ScrollBarFrame()->VerticalScrollBar()->IsVisible()
       
   576 	          || !iMmDrawer->TemplateLibrary()->GetScrollbarVisibility() )
       
   577 		{
       
   578 		ScrollBarFrame()->VerticalScrollBar()->MakeVisible( ETrue );
       
   579 		iMmDrawer->SetScrollbarVisibilityL( ETrue );
       
   580 		ret = ETrue; //redraw is needed
       
   581 		}
       
   582 	return ret;
       
   583 	}
       
   584 
       
   585 
       
   586 // -----------------------------------------------------------------------------
       
   587 //
       
   588 // -----------------------------------------------------------------------------
       
   589 //
       
   590 TBool CMmListBox::AllItemsFitInViewRect()
       
   591 	{
       
   592 	CMmListBoxView* view = static_cast< CMmListBoxView* >(iView);
       
   593 	TInt totalHeight = view->GetTotalHeight( view->TopItemIndex(), view->BottomItemIndex());
       
   594 	if ( view->TopItemIndex() == 0 && iMmModel->NumberOfItems() <= view->BottomItemIndex() + 1
       
   595 	        && totalHeight <= iView->ViewRect().Height() )
       
   596 		{
       
   597 		return ETrue;
       
   598 		}
       
   599 	else
       
   600 		{
       
   601 		return EFalse;
       
   602 		}
       
   603 	}
       
   604 
       
   605 /**
       
   606  * Helper class whose only purpose is to ensure that
       
   607  * ScrollToItem method will be always re-enabled. 
       
   608  */
       
   609 struct TScrollToItemEnabler
       
   610     {
       
   611     CMmListBoxView* iV;
       
   612     void Close() { iV->DisableScrollToItem( EFalse ); }
       
   613     };
       
   614 
       
   615 // -----------------------------------------------------------------------------
       
   616 //
       
   617 // -----------------------------------------------------------------------------
       
   618 //
       
   619 void CMmListBox::UpdateScrollBarsL()
       
   620 	{
       
   621 	TBool redrawNeeded = HandleScrollbarVisibilityChangeL();
       
   622 	if (ScrollBarFrame()->VerticalScrollBar()->IsVisible())
       
   623 		{
       
   624 		CMmListBoxView* view = static_cast<CMmListBoxView*>( View() );
       
   625 		view->DisableScrollToItem( ETrue );
       
   626 		TScrollToItemEnabler reverter = { view };
       
   627 		CleanupClosePushL( reverter );
       
   628 		CEikFormattedCellListBoxTypedef::UpdateScrollBarsL();
       
   629 		CleanupStack::PopAndDestroy( &reverter );
       
   630 		}
       
   631 	iMmDrawer->TemplateLibrary()->SetScrollbarWidthL(
       
   632         ScrollBarFrame()->VerticalScrollBar()->Rect().Width() );
       
   633 	FixViewForMirroredLayout();
       
   634 	if ( redrawNeeded )
       
   635 		{
       
   636 		DrawNow();
       
   637 		}
       
   638 	}
       
   639 
       
   640 // -----------------------------------------------------------------------------
       
   641 //
       
   642 // -----------------------------------------------------------------------------
       
   643 //
       
   644 void CMmListBox::UpdateScrollBarsNoRedrawL()
       
   645 	{
       
   646 	HandleScrollbarVisibilityChangeL();
       
   647 	if ( ScrollBarFrame()->VerticalScrollBar()->IsVisible() )
       
   648 		{
       
   649 		CMmListBoxView* view = static_cast<CMmListBoxView*>( View() );
       
   650 		view->DisableScrollToItem( ETrue );
       
   651 		TScrollToItemEnabler reverter = { view };
       
   652 		CleanupClosePushL( reverter );
       
   653 		CEikFormattedCellListBoxTypedef::UpdateScrollBarsL();
       
   654 		CleanupStack::PopAndDestroy( &reverter );
       
   655 		iMmDrawer->TemplateLibrary()->SetScrollbarWidthL(
       
   656 		        ScrollBarFrame()->VerticalScrollBar()->Rect().Width() );
       
   657 		}
       
   658 	}
       
   659 
       
   660 // -----------------------------------------------------------------------------
       
   661 //
       
   662 // -----------------------------------------------------------------------------
       
   663 //
       
   664 void CMmListBox::SetMarqueeAdapter( CMmMarqueeAdapter* aAdapter )
       
   665 	{
       
   666 	iMarqueeAdapter = aAdapter;
       
   667 	iMarqueeAdapter->SetControl( const_cast< CMmListBox *>(this) );
       
   668 	}
       
   669 
       
   670 // -----------------------------------------------------------------------------
       
   671 //
       
   672 // -----------------------------------------------------------------------------
       
   673 //
       
   674 void CMmListBox::SetMarqueeDrawing( TBool aIsMarqueeBeingDrawn )
       
   675 	{
       
   676 	iMmDrawer->SetMarqueeDrawing( aIsMarqueeBeingDrawn );
       
   677 	}
       
   678 
       
   679 // -----------------------------------------------------------------------------
       
   680 //
       
   681 // -----------------------------------------------------------------------------
       
   682 //
       
   683 void CMmListBox::HandleItemRemovalL()
       
   684 	{
       
   685 	CEikFormattedCellListBoxTypedef::HandleItemRemovalL();
       
   686     DrawNow();
       
   687     //avkon does not redraw the items for listbox when item is
       
   688     //removed. This needs to be forced here.
       
   689     UpdateScrollBarsL();
       
   690 	}
       
   691 
       
   692 // -----------------------------------------------------------------------------
       
   693 // If a parent to the supplied control has its Gc set, this function will find
       
   694 // it and return it. (Copied from EIKLBX.CPP, needed by CMmListBox::Draw)
       
   695 // -----------------------------------------------------------------------------
       
   696 //
       
   697 LOCAL_C CWindowGc* ReplaceGcWithCustomGc( const CEikListBox* aListBox )
       
   698     {
       
   699     const CCoeControl* parent = aListBox;
       
   700     CWindowGc* customGc;
       
   701     while(parent)
       
   702         {
       
   703         customGc = parent->GetGc();
       
   704         if ( customGc )
       
   705             {
       
   706             CListItemDrawer* itemDrawer = aListBox->View()->ItemDrawer();
       
   707             CWindowGc* originalGc = itemDrawer->Gc();
       
   708             if ( customGc == originalGc )
       
   709             {
       
   710                 return NULL;
       
   711                 }
       
   712             else
       
   713                 {
       
   714                 itemDrawer->SetGc( customGc );
       
   715                 return originalGc;
       
   716                 }
       
   717             }
       
   718         parent = parent->Parent();
       
   719         }
       
   720     return NULL;
       
   721     }
       
   722 
       
   723 // -----------------------------------------------------------------------------
       
   724 //
       
   725 // -----------------------------------------------------------------------------
       
   726 //
       
   727 void CMmListBox::Draw(const TRect& aRect) const
       
   728     {
       
   729 //    if (!iResized)
       
   730 //        {
       
   731 //        return;
       
   732 //        }
       
   733 
       
   734     CWindowGc* gc = this->iItemDrawer->Gc();
       
   735 
       
   736     // If a parent has a custom gc, draw listbox using that gc
       
   737     CWindowGc* replacedGc = ReplaceGcWithCustomGc(
       
   738                                     static_cast<const CEikListBox*>( this ) );
       
   739 
       
   740     if (this->iModel->NumberOfItems() == 0)
       
   741         {
       
   742         this->iView->DrawEmptyList(this->Rect());
       
   743 
       
   744         if ( replacedGc )
       
   745             {
       
   746             // Stop using the custom gc
       
   747             this->iItemDrawer->SetGc( replacedGc );
       
   748             }
       
   749         return;
       
   750         }
       
   751 
       
   752 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   753     MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( gc );
       
   754     
       
   755     if ( transApi )
       
   756         {
       
   757         transApi->SetListType( MAknListBoxTfxInternal::EListBoxTypeMainPane );
       
   758         // ViewRect might have been moved to the right to prevent grid items
       
   759         // from overlapping the scrollbar in mirrored layout.
       
   760         // However, we still have to draw scrollbar background, thus the
       
   761         // rectangle object passed to MAknListBoxTfxInternal::BeginRedraw must
       
   762         // be placed at (0, 0) so that it covers the area where scrollbar is
       
   763         // drawn.
       
   764         TRect r( View()->ViewRect().Size() );
       
   765         transApi->BeginRedraw( MAknListBoxTfxInternal::EListView, r );
       
   766         }
       
   767 #endif //RD_UI_TRANSITION_EFFECTS_LIST
       
   768     if (!this->iView->RedrawDisabled())
       
   769         {
       
   770         MAknsControlContext *cc = AknsDrawUtils::ControlContext( this );
       
   771         if (!cc) cc = ItemDrawer()->FormattedCellData()->SkinBackgroundContext();
       
   772 
       
   773         if (gc)
       
   774             {
       
   775             TRect clientRect;
       
   776             this->RestoreClientRectFromViewRect(clientRect);
       
   777 #ifdef RD_UI_TRANSITION_EFFECTS_LIST           
       
   778             if ( transApi )
       
   779                 {
       
   780                 transApi->StartDrawing( MAknListBoxTfxInternal::EListView );
       
   781                 }
       
   782 #endif //RD_UI_TRANSITION_EFFECTS_LIST
       
   783             gc->SetBrushColor(this->BackColor());
       
   784             AknsDrawUtils::BackgroundBetweenRects( AknsUtils::SkinInstance(), cc, this, *gc, clientRect, this->iView->ViewRect() );
       
   785             RedrawScrollbarBackground();
       
   786 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   787             if ( transApi )
       
   788                 {
       
   789                 transApi->StopDrawing();
       
   790         }
       
   791 #endif //RD_UI_TRANSITION_EFFECTS_LIST
       
   792             }
       
   793         }
       
   794     if ( this->iModel->NumberOfItems() )
       
   795         {
       
   796         // finally, draw the actual list
       
   797         this->iView->Draw(&aRect);
       
   798         }
       
   799 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   800     if ( transApi )
       
   801         {
       
   802         CMmListBoxView* view = static_cast<CMmListBoxView*>( View() );
       
   803         view->DisableScrollToItem( ETrue );
       
   804         transApi->EndViewRedraw( aRect );
       
   805         view->DisableScrollToItem( EFalse );
       
   806         }
       
   807 #endif //RD_UI_TRANSITION_EFFECTS_LIST
       
   808     if ( replacedGc )
       
   809         {
       
   810         // Stop using the custom gc
       
   811         this->iItemDrawer->SetGc( replacedGc );
       
   812         }
       
   813     }
       
   814 
       
   815 // -----------------------------------------------------------------------------
       
   816 //
       
   817 // -----------------------------------------------------------------------------
       
   818 // 
       
   819 void CMmListBox::DrawView()
       
   820     {
       
   821     iDisableChildComponentDrawing = ETrue;
       
   822     DrawNow(Rect());
       
   823     iDisableChildComponentDrawing = EFalse;
       
   824     }
       
   825 
       
   826 // -----------------------------------------------------------------------------
       
   827 //
       
   828 // -----------------------------------------------------------------------------
       
   829 //
       
   830 void CMmListBox::SetVerticalItemOffset( TInt aOffset )
       
   831 	{
       
   832 	static_cast<CMmListBoxView*>( View() )->SetItemOffsetInPixels( aOffset );
       
   833 	UpdateScrollBarThumbs();
       
   834 	}
       
   835 
       
   836 // -----------------------------------------------------------------------------
       
   837 //
       
   838 // -----------------------------------------------------------------------------
       
   839 //
       
   840 TInt CMmListBox::VerticalItemOffset() const
       
   841 	{
       
   842 	return static_cast<CMmListBoxView*>( View() )->VerticalItemOffset();
       
   843 	}
       
   844 
       
   845 // -----------------------------------------------------------------------------
       
   846 //
       
   847 // -----------------------------------------------------------------------------
       
   848 //
       
   849 void CMmListBox::SetItemHeight( TInt aItemHeight )
       
   850 	{
       
   851 	if ( aItemHeight != iItemHeight )
       
   852 	    {
       
   853 	    iItemHeight = aItemHeight;
       
   854 	    TRAP_IGNORE( UpdateScrollBarsNoRedrawL() );
       
   855 	    }
       
   856 	}
       
   857 
       
   858 // -----------------------------------------------------------------------------
       
   859 //
       
   860 // -----------------------------------------------------------------------------
       
   861 //
       
   862 void CMmListBox::UpdateScrollBarThumbs()
       
   863 	{
       
   864 	CEikFormattedCellListBox::UpdateScrollBarThumbs();
       
   865 	}
       
   866 
       
   867 // -----------------------------------------------------------------------------
       
   868 //
       
   869 // -----------------------------------------------------------------------------
       
   870 //
       
   871 TInt CMmListBox::CountComponentControls() const
       
   872     {
       
   873     TInt componentControls(0);
       
   874     if ( !iDisableChildComponentDrawing )
       
   875 		{
       
   876         componentControls = CEikFormattedCellListBoxTypedef::CountComponentControls();
       
   877     	}
       
   878     return componentControls;
       
   879     }
       
   880 // -----------------------------------------------------------------------------
       
   881 //
       
   882 // -----------------------------------------------------------------------------
       
   883 //
       
   884 void CMmListBox::SetDisableChildComponentDrawing( TBool aDisable )
       
   885     {
       
   886     iDisableChildComponentDrawing = aDisable;
       
   887     }
       
   888 
       
   889 // End of file