uifw/EikStd/coctlsrc/EIKLBV.CPP
changeset 0 2f259fa3e83a
child 5 aabf2c525e0f
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 /*
       
     2 * Copyright (c) 1997-2009 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 <badesca.h>
       
    20 #include <gdi.h>
       
    21 #include <w32std.h>
       
    22 #include <eiklbx.pan>
       
    23 #include <eiklbx.h>
       
    24 #include <eiklbv.h>
       
    25 #include <eiklbm.h>
       
    26 #include <eiklbi.h>
       
    27 #include <gulutil.h>
       
    28 #include <eikenv.h>
       
    29 #include <avkon.rsg>
       
    30 #include <barsread.h>
       
    31 #include <AknUtils.h>
       
    32 #include <AknsDrawUtils.h>
       
    33 #include <AknsControlContext.h>
       
    34 
       
    35 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
    36 #include <aknlistboxtfxinternal.h>
       
    37 #include <aknlistloadertfx.h>
       
    38 #endif
       
    39 
       
    40 #include "laflbv.h"
       
    41 #include "laflbx.h"
       
    42 #include "akntrace.h"
       
    43 
       
    44 #define ITEM_EXISTS_BEGIN TInt no_of_items__ = iModel->NumberOfItems()
       
    45 #define ITEM_EXISTS(x) (((x) > -1) && ((x) < no_of_items__))
       
    46 
       
    47 #define ITEM_EXISTS_ONCE(x) (((x) > -1) && ((x) < iModel->NumberOfItems()))
       
    48 
       
    49 //
       
    50 // class CListBoxView
       
    51 //
       
    52 CListBoxViewExtension* CListBoxViewExtension::NewL()
       
    53     {
       
    54     CListBoxViewExtension* self = new ( ELeave ) CListBoxViewExtension;
       
    55     CleanupStack::PushL( self );
       
    56     self->ConstructL();
       
    57     CleanupStack::Pop(); // self
       
    58     
       
    59     return self;
       
    60     }
       
    61  
       
    62 CListBoxViewExtension::~CListBoxViewExtension()
       
    63     {
       
    64     }
       
    65  
       
    66 void CListBoxViewExtension::ConstructL()
       
    67     {
       
    68     // Panning and flicking disabled by default
       
    69     iScrollingDisabled = ETrue;
       
    70     }
       
    71  
       
    72  
       
    73 void CListBoxView::SetVisibilityObserver(MListVisibilityObserver* aObserver)
       
    74 	{
       
    75 	iVisibilityObserver=aObserver;
       
    76 	}
       
    77 
       
    78 EXPORT_C TBool CListBoxView::IsVisible() const
       
    79 	{
       
    80 	if(iVisibilityObserver)
       
    81 		return(iVisibilityObserver->IsVisible());
       
    82 	return ETrue;
       
    83 	}
       
    84 
       
    85 EXPORT_C void CListBoxView::SetListEmptyTextL(const TDesC& aText)
       
    86 	{
       
    87 	delete iListEmptyText;
       
    88 	iListEmptyText = NULL;
       
    89 
       
    90 	iListEmptyText= aText.AllocL();
       
    91 	}
       
    92 
       
    93 EXPORT_C CListBoxView::CListBoxView()
       
    94 	{
       
    95 	_AKNTRACE_FUNC_ENTER;
       
    96 	iItemHeight = 20;
       
    97 //	iBackColor = KDefaultLbxBackColor;
       
    98 	iBackColor = CEikonEnv::Static()->Color(EColorControlBackground); //KDefaultLbxBackColor;
       
    99 	iMatcherCursorColor = TRgb(177, 177, 177);		// light gray?
       
   100 	iCurrentItemIndex = 0;
       
   101 	iTopItemIndex = 0;
       
   102 	iListEmptyText = 0;
       
   103 	iVerticalOffset = 0;
       
   104 	_AKNTRACE_FUNC_EXIT;
       
   105 	}
       
   106 
       
   107 EXPORT_C void CListBoxView::ConstructL(MListBoxModel* aList, CListItemDrawer* aItemDrawer, CWsScreenDevice* aScreen, RWindowGroup* aGroupWindow, RWindow* aWsWindow, const TRect& aDisplayArea, TInt aItemHeight)
       
   108 	{
       
   109 	_AKNTRACE_FUNC_ENTER;
       
   110 	iExtension = CListBoxViewExtension::NewL();
       
   111 
       
   112 	iModel = aList;
       
   113 	iItemDrawer = aItemDrawer;
       
   114 	iWin = aWsWindow;
       
   115 	iGroupWin = aGroupWindow;
       
   116 	// create a graphics context
       
   117     User::LeaveIfError(aScreen->CreateContext(iGc));
       
   118 	iGc->Activate(*iWin);
       
   119 	iItemDrawer->SetGc(iGc);
       
   120 	iViewRect = aDisplayArea;
       
   121 	iItemHeight = aItemHeight;
       
   122 	iSelectionIndexes = new(ELeave) CArrayFixFlat<TInt>(5);
       
   123 
       
   124 	//SetListEmptyTextL(_L("No Data"));
       
   125 	TResourceReader rr;
       
   126 	CEikonEnv::Static()->CreateResourceReaderLC(rr,R_AVKON_LISTBOX_DEFAULT_EMPTY_TEXT);
       
   127 	TPtrC emptytext= rr.ReadTPtrC();
       
   128 	SetListEmptyTextL(emptytext);
       
   129 	CleanupStack::PopAndDestroy();
       
   130 	_AKNTRACE_FUNC_EXIT;
       
   131 	}
       
   132 	
       
   133 EXPORT_C CListBoxView::~CListBoxView()
       
   134 	{
       
   135 	_AKNTRACE_FUNC_ENTER;
       
   136 	// Although my "item Drawer" is created by some other object, it is convenient
       
   137 	// for me to destroy it here...
       
   138 	delete iExtension;
       
   139 	delete(iItemDrawer);
       
   140 	delete iSelectionIndexes;
       
   141 	delete(iGc);
       
   142 	delete (iListEmptyText);
       
   143 	_AKNTRACE_FUNC_EXIT;
       
   144 	}
       
   145 
       
   146 EXPORT_C TInt CListBoxView::TopItemIndex() const
       
   147 	{
       
   148 	_AKNTRACE( "iTopItemIndex = %d", iTopItemIndex );
       
   149 	return iTopItemIndex;
       
   150 	}
       
   151 
       
   152 EXPORT_C TInt CListBoxView::BottomItemIndex() const
       
   153 	{
       
   154 	_AKNTRACE( "iBottomItemIndex = %d", iBottomItemIndex );
       
   155 	return iBottomItemIndex;
       
   156 	}
       
   157 
       
   158 EXPORT_C TBool CListBoxView::ItemIsSelected(TInt aItemIndex) const
       
   159 	{
       
   160 	_AKNTRACE( "Item selected is %d", aItemIndex );
       
   161 	TKeyArrayFix key(0, ECmpTInt);	
       
   162 	TInt pos;
       
   163 	if (iSelectionIndexes->Find(aItemIndex, key, pos))
       
   164 		return(EFalse);
       
   165 	return(ETrue);
       
   166 	}
       
   167 
       
   168 EXPORT_C void CListBoxView::ToggleItemL(TInt aItemIndex) 
       
   169 	{
       
   170 	_AKNTRACE_FUNC_ENTER;
       
   171 	__ASSERT_DEBUG(iSelectionIndexes, Panic(EEikPanicListBoxNoSelIndexArray));
       
   172 	if (iItemDrawer->Properties(aItemIndex).IsSelectionHidden()) { DeselectItem(aItemIndex); return; }
       
   173 	TKeyArrayFix key(0, ECmpTInt);	
       
   174 	TInt pos;
       
   175 	if (iSelectionIndexes->Find(aItemIndex, key, pos))
       
   176 		iSelectionIndexes->AppendL(aItemIndex);   
       
   177 	else
       
   178 		iSelectionIndexes->Delete(pos);
       
   179 	DrawItem(aItemIndex);
       
   180 	_AKNTRACE_FUNC_EXIT;
       
   181 	}
       
   182 
       
   183 EXPORT_C void CListBoxView::SelectItemL(TInt aItemIndex)
       
   184     {   
       
   185     // select the specified item; if already selected, do nothing
       
   186     _AKNTRACE_FUNC_ENTER;
       
   187     _AKNTRACE( "SelectItem is %d", aItemIndex );
       
   188     __ASSERT_DEBUG(iSelectionIndexes, Panic(EEikPanicListBoxNoSelIndexArray));
       
   189     if (iItemDrawer->Properties(aItemIndex).IsSelectionHidden()) 
       
   190         { 
       
   191         DeselectItem(aItemIndex); 
       
   192         _AKNTRACE_FUNC_EXIT;
       
   193         return; 
       
   194         }
       
   195     TKeyArrayFix key(0, ECmpTInt);  
       
   196     TInt pos;
       
   197     if (iSelectionIndexes->Find(aItemIndex, key, pos))
       
   198         {
       
   199 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   200         MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iGc );
       
   201         if ( transApi )
       
   202             {
       
   203             transApi->Invalidate( MAknListBoxTfxInternal::EListItem, aItemIndex );
       
   204             }
       
   205 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
   206         iSelectionIndexes->AppendL(aItemIndex);
       
   207         DrawItem(aItemIndex);
       
   208         }
       
   209     _AKNTRACE_FUNC_EXIT;
       
   210     }  
       
   211 
       
   212 EXPORT_C void CListBoxView::DeselectItem(TInt aItemIndex)
       
   213     {
       
   214     // deselect the specified item; if not currently selected, do nothing
       
   215     _AKNTRACE_FUNC_ENTER;
       
   216     _AKNTRACE( "DeselectItem is %d", aItemIndex );
       
   217     __ASSERT_DEBUG(iSelectionIndexes, Panic(EEikPanicListBoxNoSelIndexArray));
       
   218     TKeyArrayFix key(0, ECmpTInt);  
       
   219     TInt pos;
       
   220     if (!(iSelectionIndexes->Find(aItemIndex, key, pos)))
       
   221         {
       
   222 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   223         MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iGc );
       
   224         if ( transApi )
       
   225             {
       
   226             transApi->Invalidate( MAknListBoxTfxInternal::EListItem, aItemIndex );
       
   227             }
       
   228 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
   229         iSelectionIndexes->Delete(pos);
       
   230         DrawItem(aItemIndex);
       
   231         }
       
   232     _AKNTRACE_FUNC_EXIT;
       
   233     }  
       
   234 
       
   235 EXPORT_C void CListBoxView::GetSelectionIndexesL(CSelectionIndexArray *aSelectionArray) const
       
   236 	{
       
   237 	__ASSERT_DEBUG(aSelectionArray, Panic(EEikPanicListBoxInvalidSelIndexArraySpecified));
       
   238 	__ASSERT_DEBUG(iSelectionIndexes, Panic(EEikPanicListBoxNoSelIndexArray));
       
   239 	aSelectionArray->Reset();
       
   240 	TInt selectionIndex;
       
   241 	TInt numOfSelections = iSelectionIndexes->Count();
       
   242 	for (TInt i = 0; i < numOfSelections; i++)
       
   243 		{
       
   244 		selectionIndex = (*(iSelectionIndexes))[i];
       
   245 		aSelectionArray->AppendL(selectionIndex);
       
   246 		}
       
   247 	}
       
   248 
       
   249 EXPORT_C void CListBoxView::SetSelectionIndexesL(const CSelectionIndexArray *aSelectionArray)
       
   250 	{
       
   251 	__ASSERT_DEBUG(aSelectionArray, Panic(EEikPanicListBoxInvalidSelIndexArraySpecified));
       
   252 	ClearSelection();
       
   253 	TInt numOfSelections = aSelectionArray->Count();
       
   254 	TInt selectionIndex;
       
   255 	for (TInt i = 0; i < numOfSelections; i++)
       
   256 		{
       
   257 		selectionIndex = (*aSelectionArray)[i];
       
   258         SelectItemL(selectionIndex);
       
   259 		}
       
   260 	}
       
   261 
       
   262 EXPORT_C const CListBoxView::CSelectionIndexArray* CListBoxView::SelectionIndexes() const
       
   263 	{
       
   264 	return iSelectionIndexes;
       
   265 	}
       
   266 
       
   267 EXPORT_C void CListBoxView::ClearSelection()
       
   268 	{
       
   269 	_AKNTRACE_FUNC_ENTER;
       
   270 	__ASSERT_DEBUG(iSelectionIndexes, Panic(EEikPanicListBoxNoSelIndexArray));
       
   271 	TInt numSelectedItems = iSelectionIndexes->Count();
       
   272 	TInt selectedItemIndex; 
       
   273 	for	(TInt i = 0; i < numSelectedItems; i++)
       
   274 		{
       
   275 		selectedItemIndex = (*(iSelectionIndexes))[0];
       
   276         DeselectItem(selectedItemIndex);
       
   277 		}
       
   278 	ClearSelectionAnchorAndActiveIndex();
       
   279 	_AKNTRACE_FUNC_EXIT;
       
   280 	}
       
   281 
       
   282 EXPORT_C void CListBoxView::ClearSelectionAnchorAndActiveIndex()
       
   283 	{
       
   284 	_AKNTRACE_FUNC_ENTER;
       
   285 	iAnchorIndex = 0;
       
   286 	iActiveEndIndex = 0;
       
   287 	ClearFlags(EAnchorExists);
       
   288 	ClearFlags(EMarkSelection);
       
   289 	ClearFlags(EUnmarkSelection);
       
   290 	_AKNTRACE_FUNC_EXIT;
       
   291 	}
       
   292 
       
   293 EXPORT_C void CListBoxView::SelectRangeL(TInt aItemIndex1, TInt aItemIndex2)
       
   294 	{
       
   295 	TInt startItem, endItem;
       
   296 	startItem = Min(aItemIndex1, aItemIndex2);
       
   297 	endItem = Max(aItemIndex1, aItemIndex2);
       
   298 	for (TInt i = startItem; i <= endItem; i++)
       
   299         SelectItemL(i);
       
   300 	}
       
   301 
       
   302 EXPORT_C void CListBoxView::SetAnchor(TInt aItemIndex)
       
   303 	{
       
   304     SetFlags(EAnchorExists);
       
   305 	iAnchorIndex = aItemIndex;
       
   306 	iActiveEndIndex = aItemIndex;
       
   307 	}
       
   308 
       
   309 EXPORT_C void CListBoxView::UpdateSelectionL(TSelectionMode aSelectionMode)
       
   310 	{
       
   311 	// assumes that iCurrentItemIndex has already been updated...
       
   312 	_AKNTRACE_FUNC_ENTER;
       
   313 	_AKNTRACE( "aSelectionMode is %d", aSelectionMode );
       
   314 	if (iCurrentItemIndex == -1)   // i.e. no selection
       
   315 		{
       
   316 		ClearSelection();
       
   317 		_AKNTRACE_FUNC_EXIT;
       
   318 		return;
       
   319 		}
       
   320 	TInt newActiveEndIndex = iCurrentItemIndex;
       
   321 
       
   322 	if ( Flags() & EPaintedSelection )
       
   323 		{
       
   324 		switch (aSelectionMode)
       
   325 			{
       
   326 		case ENoSelection:
       
   327 			{
       
   328 			ClearFlags(EAnchorExists);
       
   329 			iActiveEndIndex = iCurrentItemIndex;
       
   330 			DrawItem(iCurrentItemIndex);
       
   331 			break;
       
   332 			}
       
   333 		case ESingleSelection:
       
   334 			{
       
   335 			TInt i = 0;
       
   336 			iAnchorIndex = iCurrentItemIndex;
       
   337 			iActiveEndIndex = iCurrentItemIndex;
       
   338 			SetFlags(EAnchorExists);
       
   339 			TInt selectedItemIndex; 
       
   340 			while (i < iSelectionIndexes->Count())
       
   341 				{
       
   342 				selectedItemIndex = (*(iSelectionIndexes))[i];
       
   343                 DeselectItem(selectedItemIndex);
       
   344 				}
       
   345 			//DrawItem(iActiveEndIndex);
       
   346             SelectItemL(newActiveEndIndex);
       
   347 			}
       
   348 			break;
       
   349 		case EContiguousSelection:
       
   350 			{
       
   351 			if (newActiveEndIndex == iActiveEndIndex)
       
   352 				break;
       
   353 
       
   354 			if (!(iFlags & EAnchorExists))
       
   355 				{
       
   356 				iAnchorIndex = newActiveEndIndex;
       
   357 				SetFlags(EAnchorExists);
       
   358 				}
       
   359 
       
   360 			TInt startIndex=0, endIndex=0;
       
   361 			if ( iActiveEndIndex < newActiveEndIndex )
       
   362 				{
       
   363 				startIndex = iActiveEndIndex;
       
   364 				endIndex = newActiveEndIndex; // - 1;  // select current item too
       
   365 				}
       
   366 			else
       
   367 				{
       
   368 				startIndex = newActiveEndIndex; // + 1;  // select current item too
       
   369 				endIndex = iActiveEndIndex;
       
   370 				}
       
   371 			SelectRangeL( startIndex, endIndex );		// select always
       
   372 
       
   373 			iActiveEndIndex = iCurrentItemIndex;
       
   374 			DrawItem(iActiveEndIndex);
       
   375 			}
       
   376 			break;
       
   377 		case EDisjointSelection:
       
   378 			ClearFlags(EAnchorExists);
       
   379 			ToggleItemL(newActiveEndIndex);
       
   380 			iActiveEndIndex = iCurrentItemIndex;
       
   381 			break;
       
   382 		default:
       
   383 			break;
       
   384 			}
       
   385 		}
       
   386 	else	// Here begins the Eikon original code
       
   387 		{
       
   388 		switch (aSelectionMode)
       
   389 			{
       
   390 		case ENoSelection:
       
   391 			DrawItem(iCurrentItemIndex);
       
   392 			break;
       
   393 		case ESingleSelection:
       
   394 			{
       
   395 			TInt i = 0;
       
   396 			iAnchorIndex = newActiveEndIndex;
       
   397 			iActiveEndIndex = newActiveEndIndex;
       
   398 			SetFlags(EAnchorExists);
       
   399 			TInt selectedItemIndex; 
       
   400 			// deselect everything except newActiveEndIndex
       
   401 			while (i < iSelectionIndexes->Count())
       
   402 				{
       
   403 				selectedItemIndex = (*(iSelectionIndexes))[i];
       
   404                 DeselectItem(selectedItemIndex);
       
   405 				}
       
   406             SelectItemL(newActiveEndIndex);
       
   407 			}
       
   408 			break;
       
   409 		case EContiguousSelection:
       
   410 			{
       
   411 			TInt itemIndex=0;
       
   412 			if (newActiveEndIndex == iActiveEndIndex)
       
   413 				break;
       
   414 			if (!(iFlags & EAnchorExists))
       
   415 				{
       
   416 				iAnchorIndex = newActiveEndIndex;
       
   417 				iActiveEndIndex = newActiveEndIndex;
       
   418     			SetFlags(EAnchorExists);
       
   419 				SelectRangeL(iAnchorIndex, newActiveEndIndex);
       
   420 				break;
       
   421 				}
       
   422 			if ((newActiveEndIndex < iActiveEndIndex) && (iActiveEndIndex <= iAnchorIndex))
       
   423 				SelectRangeL(iActiveEndIndex, newActiveEndIndex);
       
   424 			else if ((newActiveEndIndex < iActiveEndIndex) && (iActiveEndIndex > iAnchorIndex))
       
   425 				{
       
   426 				itemIndex = iActiveEndIndex;
       
   427 				while ((itemIndex > newActiveEndIndex) && (itemIndex > iAnchorIndex))
       
   428 					{
       
   429                     DeselectItem(itemIndex);
       
   430 					--itemIndex;
       
   431 					}
       
   432 				SelectRangeL(iAnchorIndex, newActiveEndIndex);
       
   433 				}
       
   434 			else if ((newActiveEndIndex > iActiveEndIndex) && (iActiveEndIndex < iAnchorIndex))
       
   435 				{
       
   436 				itemIndex = iActiveEndIndex;
       
   437 				while ((itemIndex < newActiveEndIndex) && (itemIndex < iAnchorIndex))
       
   438 					{
       
   439                     DeselectItem(itemIndex);
       
   440 					++itemIndex;
       
   441 					}
       
   442 				SelectRangeL(iAnchorIndex, newActiveEndIndex);
       
   443 				}
       
   444 			else if ((newActiveEndIndex > iActiveEndIndex) && (iActiveEndIndex >= iAnchorIndex))
       
   445 				SelectRangeL(iActiveEndIndex, newActiveEndIndex);
       
   446 			iActiveEndIndex = newActiveEndIndex;
       
   447 			DrawItem(iActiveEndIndex);
       
   448 			}
       
   449 			break;
       
   450 		case EDisjointSelection: // toggled behavior
       
   451 		    // Make a choice whether to mark or unmark
       
   452 			// We havent made that choice yet.
       
   453 			if (!ItemIsSelected(newActiveEndIndex)) 
       
   454 			    {
       
   455 			    SetFlags(EMarkSelection);
       
   456 				ClearFlags(EUnmarkSelection);
       
   457 			}
       
   458 			else
       
   459 			    {
       
   460 			    SetFlags(EUnmarkSelection);
       
   461 				ClearFlags(EMarkSelection);
       
   462 			    }
       
   463 
       
   464 			if (newActiveEndIndex == iActiveEndIndex)
       
   465 				{
       
   466     			ClearFlags(EAnchorExists);
       
   467 				ToggleItemL(newActiveEndIndex);
       
   468 				break;
       
   469 				}
       
   470 			iAnchorIndex = newActiveEndIndex;
       
   471 			iActiveEndIndex = newActiveEndIndex;
       
   472     		SetFlags(EAnchorExists);
       
   473 			ToggleItemL(newActiveEndIndex);
       
   474 			break;
       
   475 		case EDisjointMarkSelection: // can only mark items, not unmark them
       
   476 		    // Make a choice whether to mark or unmark
       
   477 		    if (! (Flags()&EMarkSelection ||Flags()&EUnmarkSelection))
       
   478 			{
       
   479 			// We havent made that choice yet.
       
   480 			if (ItemIsSelected(iAnchorIndex)) 
       
   481 			    {
       
   482             	ClearFlags(EMarkSelection);
       
   483 			    SetFlags(EUnmarkSelection);
       
   484 			    }
       
   485 			else
       
   486 			    {
       
   487             	ClearFlags(EUnmarkSelection);
       
   488 			    SetFlags(EMarkSelection);
       
   489 			    }
       
   490 			}
       
   491 
       
   492 		    // order of these is important.
       
   493 		    if (Flags()&EMarkSelection)
       
   494             SelectItemL(iActiveEndIndex);
       
   495 		    else
       
   496             DeselectItem(iActiveEndIndex);
       
   497 		    //iAnchorIndex = newActiveEndIndex;
       
   498 		    iActiveEndIndex = newActiveEndIndex;
       
   499 		    //SetFlags(EAnchorExists);
       
   500 		    if (Flags()&EMarkSelection)
       
   501             SelectItemL(newActiveEndIndex);
       
   502 		    else
       
   503             DeselectItem(newActiveEndIndex);
       
   504 			DrawItem(iCurrentItemIndex);
       
   505 		    break;
       
   506 		    
       
   507 		case EChangeMarkMode:
       
   508 		    {
       
   509 		    // Clear flags, correct flag will be set on later.   
       
   510         	ClearFlags(EMarkSelection);
       
   511         	ClearFlags(EUnmarkSelection);
       
   512         	
       
   513         	// If item is hidden, use next non-hidden item to decide markmode.
       
   514 			while( iItemDrawer->Properties(newActiveEndIndex).IsSelectionHidden() 
       
   515 			       && newActiveEndIndex != iActiveEndIndex )
       
   516 			    {
       
   517 			    if ( newActiveEndIndex > iActiveEndIndex )
       
   518 			        {
       
   519 			        newActiveEndIndex--;
       
   520 			        }
       
   521 			    else 
       
   522 			        {
       
   523                     newActiveEndIndex++;
       
   524 		            }
       
   525 			    }
       
   526 
       
   527 		    // Change Mark Mode to different than current mark is
       
   528 			if (ItemIsSelected(newActiveEndIndex)) 
       
   529 			    {
       
   530 			    SetFlags(EUnmarkSelection);
       
   531 			    }
       
   532 			else
       
   533 			    {
       
   534 			    SetFlags(EMarkSelection);
       
   535 			    }
       
   536 		    }
       
   537 		    break;
       
   538 		
       
   539 	    case EPenMultiselection:
       
   540 	        {
       
   541 	        TInt itemIndex=0;
       
   542 	        TBool mark = (Flags() & EMarkSelection);
       
   543 	        
       
   544 			if ((newActiveEndIndex < iActiveEndIndex) && (iActiveEndIndex <= iAnchorIndex))
       
   545 			    {	
       
   546 			    if ( mark )
       
   547 			        {			        
       
   548 				    SelectRangeL(iActiveEndIndex, newActiveEndIndex);
       
   549 			        }
       
   550 			    else 
       
   551 			        {
       
   552 				    DeselectRangeL(iActiveEndIndex, newActiveEndIndex);
       
   553 			        }
       
   554 			    }
       
   555 			else if ((newActiveEndIndex < iActiveEndIndex) && (iActiveEndIndex > iAnchorIndex))
       
   556 				{
       
   557 				itemIndex = iActiveEndIndex;
       
   558 				while ((itemIndex > newActiveEndIndex) && (itemIndex > iAnchorIndex))
       
   559 					{
       
   560 					if ( mark )
       
   561 			            {
       
   562                         DeselectItem(itemIndex);
       
   563 			            }
       
   564 			        else
       
   565 			            {
       
   566                         SelectItemL(itemIndex); 
       
   567 			            }
       
   568 					--itemIndex;
       
   569 					}
       
   570                 
       
   571 				if ( mark )
       
   572 		            {					
       
   573 			        SelectRangeL(iAnchorIndex, newActiveEndIndex);
       
   574 		            }
       
   575 			    else
       
   576 			        {
       
   577 				    DeselectRangeL(iAnchorIndex, newActiveEndIndex);			        
       
   578 			        }
       
   579 				}
       
   580 			else if ((newActiveEndIndex > iActiveEndIndex) && (iActiveEndIndex < iAnchorIndex))
       
   581 				{
       
   582 				itemIndex = iActiveEndIndex;
       
   583 				while ((itemIndex < newActiveEndIndex) && (itemIndex < iAnchorIndex))
       
   584 					{
       
   585 					if ( mark )
       
   586 			            {
       
   587                         DeselectItem(itemIndex);
       
   588 			            }
       
   589 			        else
       
   590 			            {
       
   591                         SelectItemL(itemIndex); 
       
   592 			            };
       
   593 			            
       
   594 					++itemIndex;
       
   595 					}
       
   596                 if ( mark )
       
   597 			        {					
       
   598 				    SelectRangeL(iAnchorIndex, newActiveEndIndex);
       
   599 			        }
       
   600 			    else
       
   601 			        {			        
       
   602 				    DeselectRangeL(iAnchorIndex, newActiveEndIndex);
       
   603 			        }
       
   604 				}
       
   605 				// "=" is necessary for Editkey + sigle tab on an item
       
   606 			else if ((newActiveEndIndex >= iActiveEndIndex) && (iActiveEndIndex >= iAnchorIndex))
       
   607 			    {
       
   608 			    if ( mark )
       
   609 			        {			    
       
   610 			    	SelectRangeL(iActiveEndIndex, newActiveEndIndex);
       
   611 				    }
       
   612 			    else
       
   613 			        {			        
       
   614 				    DeselectRangeL(iAnchorIndex, newActiveEndIndex);
       
   615 			        }
       
   616 			    }
       
   617 			    
       
   618 			iActiveEndIndex = newActiveEndIndex;
       
   619 			
       
   620 			DrawItem(iActiveEndIndex);        
       
   621 			
       
   622 	        break;
       
   623 	        }
       
   624 		 
       
   625 		default:
       
   626 			break;
       
   627 			}
       
   628 		}
       
   629 	_AKNTRACE_FUNC_EXIT;
       
   630 	}
       
   631 
       
   632 EXPORT_C void CListBoxView::CalcBottomItemIndex()
       
   633 /* called by listbox control when either the size of the listbox or the number of items in 
       
   634    its model changes
       
   635 */
       
   636 	{
       
   637 	_AKNTRACE_FUNC_ENTER;
       
   638 	TInt i = iTopItemIndex;
       
   639 	TInt totalHeight = 0;
       
   640 	TInt numberOfVisibleItems = 0;
       
   641 	// iVerticalOffset is negative (add this to view's height)
       
   642 	TInt viewHeight = iViewRect.Height();
       
   643     viewHeight -= iVerticalOffset;
       
   644 
       
   645 	ITEM_EXISTS_BEGIN;
       
   646 	while ((totalHeight < viewHeight) && (ITEM_EXISTS(i)))
       
   647 		{
       
   648 		totalHeight += iItemHeight;
       
   649 		++ i;
       
   650 		++ numberOfVisibleItems;
       
   651 		}
       
   652 		
       
   653     iBottomItemIndex = Max(0, iTopItemIndex + numberOfVisibleItems - 1);
       
   654     _AKNTRACE( "iBottomItemIndex is %d", iBottomItemIndex );
       
   655     _AKNTRACE_FUNC_EXIT;
       
   656 	}
       
   657 
       
   658 EXPORT_C TInt CListBoxView::NumberOfItemsThatFitInRect(const TRect& aRect) const
       
   659 	{
       
   660 	if (iItemHeight == 0)
       
   661 	    {
       
   662 	    _AKNTRACE( "Number of items is 0" );
       
   663 		return 0;
       
   664 	    }
       
   665     TInt items = aRect.Height() / iItemHeight;
       
   666 	if ( ( iVerticalOffset != 0 ) || ( (aRect.Height() - iVerticalOffset) % iItemHeight > 0 ) ) items++;
       
   667 	_AKNTRACE( "Number of items is %d", items );
       
   668 	return items;
       
   669 	}
       
   670 
       
   671 EXPORT_C void CListBoxView::DeselectRangeL(TInt aItemIndex1, TInt aItemIndex2)
       
   672 	{
       
   673 	TInt startItem, endItem;
       
   674 	startItem = Min(aItemIndex1, aItemIndex2);
       
   675 	endItem = Max(aItemIndex1, aItemIndex2);
       
   676 	for (TInt i = startItem; i <= endItem; i++)
       
   677 	    {	    
       
   678         DeselectItem(i);
       
   679 	    }
       
   680 	}
       
   681 
       
   682 EXPORT_C TBool CListBoxView::ItemIsVisible(TInt aItemIndex) const
       
   683 	{
       
   684 	if ((aItemIndex == 0) && !(ITEM_EXISTS_ONCE(aItemIndex)))
       
   685 		return EFalse;
       
   686 	
       
   687 	return ((aItemIndex >= iTopItemIndex) && (aItemIndex <= iBottomItemIndex));
       
   688 	}
       
   689 
       
   690 EXPORT_C TPoint CListBoxView::ItemPos(TInt aItemIndex) const
       
   691 	{
       
   692 	return TPoint(-iHScrollOffset + iViewRect.iTl.iX, iViewRect.iTl.iY + 
       
   693 		(aItemIndex - iTopItemIndex) * iItemHeight + iVerticalOffset);
       
   694 	}
       
   695 
       
   696 EXPORT_C TSize CListBoxView::ItemSize(TInt /*aItemIndex*/) const
       
   697 	{
       
   698 	/*This return value controls the actual size of item which the text may
       
   699 	or may not be clipped and truncated with an ellipse to fit into*/
       
   700 	return TSize(LafListBoxView::ItemWidth(iViewRect.Width(), DataWidth()), iItemHeight);
       
   701 	}
       
   702 
       
   703 EXPORT_C TBool CListBoxView::XYPosToItemIndex(TPoint aPosition, TInt& aItemIndex) const
       
   704 	{
       
   705 	// returns ETrue and sets aItemIndex to the index of the item whose bounding box contains aPosition
       
   706 	// returns EFalse if no such item exists 
       
   707 	_AKNTRACE_FUNC_ENTER;
       
   708 	TBool itemFound = EFalse;
       
   709 	if (iItemHeight == 0) 
       
   710 	    {
       
   711 	    _AKNTRACE_FUNC_EXIT;
       
   712 		return EFalse;
       
   713 	    }
       
   714 	if (iViewRect.Contains(aPosition))
       
   715 		{
       
   716 		// aPosition is inside the display area
       
   717 		TInt yOffsetFromViewRectOrigin = aPosition.iY - iViewRect.iTl.iY - iVerticalOffset;
       
   718 		TInt numberOfItemsFromTheTop = yOffsetFromViewRectOrigin / iItemHeight;
       
   719 		TInt itemAtSpecifiedPos = iTopItemIndex + numberOfItemsFromTheTop;
       
   720 		if (ITEM_EXISTS_ONCE(itemAtSpecifiedPos))
       
   721 			{
       
   722 			aItemIndex = itemAtSpecifiedPos;
       
   723 			itemFound = ETrue;
       
   724 			}
       
   725 		}
       
   726 	_AKNTRACE_FUNC_EXIT;
       
   727 	return itemFound;
       
   728 	}
       
   729 
       
   730 EXPORT_C void CListBoxView::MoveCursorL(TCursorMovement aCursorMovement, TSelectionMode aSelectionMode)
       
   731 	{
       
   732 	_AKNTRACE_FUNC_ENTER;
       
   733 	_AKNTRACE( "aSelectionMode is %d", aSelectionMode );
       
   734 	TInt pageSize = NumberOfItemsThatFitInRect(iViewRect);
       
   735 	TInt numOfItems = iModel->NumberOfItems(); 
       
   736 	switch (aCursorMovement)
       
   737 		{
       
   738 	case ECursorNextItem:
       
   739 		VerticalMoveToItemL(iCurrentItemIndex + 1, aSelectionMode);
       
   740 		break;
       
   741 	case ECursorPreviousItem:
       
   742 		VerticalMoveToItemL(iCurrentItemIndex - 1, aSelectionMode);
       
   743 		break;
       
   744 	case ECursorNextPage:
       
   745 		VerticalMoveToItemL(iCurrentItemIndex + Min((pageSize - 1), numOfItems - 1 - iCurrentItemIndex),
       
   746 							   aSelectionMode);
       
   747 		break;
       
   748 	case ECursorPreviousPage:
       
   749 		VerticalMoveToItemL(iCurrentItemIndex - Min((pageSize - 1), iCurrentItemIndex),
       
   750 						   aSelectionMode);
       
   751 		break;
       
   752 	case ECursorFirstItem:
       
   753 		VerticalMoveToItemL(0, aSelectionMode);
       
   754 		break;
       
   755 	case ECursorLastItem:
       
   756 		if (numOfItems > 0)
       
   757 			VerticalMoveToItemL(numOfItems-1, aSelectionMode);
       
   758 		break;
       
   759 		
       
   760 		case ECursorNextScreen:
       
   761 		    {
       
   762 		    TInt targetItem = iTopItemIndex + pageSize;
       
   763 		    if (targetItem > numOfItems - pageSize) targetItem = numOfItems - pageSize;
       
   764 		    if (targetItem < 0) targetItem = 0;
       
   765 		    VScrollTo(targetItem);
       
   766 		    SetCurrentItemIndex(targetItem);
       
   767 		    }
       
   768 		    break;
       
   769 		case ECursorPrevScreen:
       
   770 		    {
       
   771 		    TInt targetItem = iTopItemIndex - pageSize;
       
   772 		    if (targetItem < 0) targetItem = 0;
       
   773 		    VScrollTo(targetItem);
       
   774 		    SetCurrentItemIndex(targetItem);
       
   775 		    }
       
   776 	    break;
       
   777 	default:
       
   778 		break;
       
   779 		};
       
   780 	_AKNTRACE_FUNC_EXIT;
       
   781 	}
       
   782 
       
   783 EXPORT_C void CListBoxView::VerticalMoveToItemL(TInt aTargetItemIndex, TSelectionMode aSelectionMode)
       
   784 	{
       
   785 	// SERIES60 IMPLEMENTATION
       
   786 	_AKNTRACE_FUNC_ENTER;
       
   787 	if (ITEM_EXISTS_ONCE(aTargetItemIndex))
       
   788 	    {
       
   789 	    TInt oldCurrentItemIndex = iCurrentItemIndex;
       
   790 	    iCurrentItemIndex = aTargetItemIndex;
       
   791 
       
   792 	    
       
   793         TInt oldVerticalOffset = iVerticalOffset;
       
   794 	    TInt newTopItemIndex = CalcNewTopItemIndexSoItemIsVisible(aTargetItemIndex);
       
   795 	    if ( oldVerticalOffset != iVerticalOffset )
       
   796 	        {
       
   797 	        iFlags |= EOffsetChanged;
       
   798 	        }
       
   799 	    
       
   800 	    TInt oldVOffset = oldCurrentItemIndex - iTopItemIndex;
       
   801 	    TInt newVOffset = aTargetItemIndex    - newTopItemIndex;
       
   802         // We calculate if the change in highlight position moves highlight in screen
       
   803 	    TBool sameHighlightPos = oldVOffset == newVOffset;
       
   804 
       
   805         // When a partially visible item gets focus, it should be fully visible.
       
   806         // 'iFlags & EOffsetChanged' can be use to judge in this case.
       
   807         if ((ItemIsVisible(iCurrentItemIndex)) && !(iFlags & EOffsetChanged))     
       
   808 	        {	    
       
   809 	        if (!sameHighlightPos && 
       
   810 	                (!ItemIsSelected(oldCurrentItemIndex) ||
       
   811 	                        aSelectionMode != ESingleSelection))
       
   812 	            {
       
   813                 DrawItem(oldCurrentItemIndex);
       
   814 	            }	    
       
   815 	        }
       
   816 	    else // items will get redrawn anyway
       
   817 	        {
       
   818 	        ScrollToMakeItemVisible(iCurrentItemIndex);
       
   819 	        }
       
   820         UpdateSelectionL(aSelectionMode);
       
   821         iFlags &= ~EOffsetChanged;
       
   822 	    }
       
   823 	_AKNTRACE_FUNC_EXIT;
       
   824 	}
       
   825 
       
   826 EXPORT_C void CListBoxView::VScrollTo(TInt aNewTopItemIndex)
       
   827 	{
       
   828 	_AKNTRACE_FUNC_ENTER;
       
   829 	if (iTopItemIndex == aNewTopItemIndex && !(iFlags & EOffsetChanged))
       
   830 	    {
       
   831 	    _AKNTRACE_FUNC_EXIT;
       
   832 		return;
       
   833 	    }
       
   834 	if (RedrawDisabled())
       
   835 	    {
       
   836 	    SetTopItemIndex(aNewTopItemIndex);
       
   837 	    _AKNTRACE_FUNC_EXIT;
       
   838 		return;
       
   839 	    }
       
   840 	TRect minRedrawRect;
       
   841 	HideMatcherCursor();
       
   842 	VScrollTo(aNewTopItemIndex, minRedrawRect);
       
   843 
       
   844 
       
   845 	if (ItemIsVisible(iCurrentItemIndex))
       
   846 		DrawMatcherCursor();
       
   847 	_AKNTRACE_FUNC_EXIT;
       
   848 	}
       
   849 
       
   850 EXPORT_C void CListBoxView::VScrollTo(TInt aNewTopItemIndex, TRect& aMinRedrawRect)
       
   851 	{
       
   852 	_AKNTRACE_FUNC_ENTER;
       
   853     if (iTopItemIndex == aNewTopItemIndex && !(iFlags & EOffsetChanged))
       
   854         {
       
   855         _AKNTRACE_FUNC_EXIT;
       
   856 	    return;
       
   857         }
       
   858 	if (RedrawDisabled()) 
       
   859 	    {
       
   860 	    SetTopItemIndex(aNewTopItemIndex);   
       
   861 	    _AKNTRACE_FUNC_EXIT;
       
   862 	    return;
       
   863 	    }
       
   864 	aMinRedrawRect.SetRect(iViewRect.iTl,iViewRect.Size());
       
   865 	SetTopItemIndex(aNewTopItemIndex);
       
   866 	Draw(&aMinRedrawRect);
       
   867 	_AKNTRACE_FUNC_EXIT;
       
   868 	}
       
   869 
       
   870 EXPORT_C void CListBoxView::HScroll(TInt aHScrollAmount)
       
   871 	{
       
   872 	_AKNTRACE_FUNC_ENTER;
       
   873 	if (RedrawDisabled())
       
   874 	    {
       
   875 	    _AKNTRACE_FUNC_EXIT;
       
   876 		return;
       
   877 	    }
       
   878 	if (aHScrollAmount == 0)
       
   879 	    {
       
   880 	    _AKNTRACE_FUNC_EXIT;
       
   881 		return;
       
   882 	    }
       
   883 	TInt maxNumOfPixelsScrolledRight = DataWidth() - VisibleWidth(iViewRect);
       
   884 	if (maxNumOfPixelsScrolledRight <= 0)
       
   885 	    {
       
   886 	    _AKNTRACE_FUNC_EXIT;
       
   887 		return;
       
   888 	    }
       
   889 	TInt oldHScrollOffset = iHScrollOffset;
       
   890 	iHScrollOffset += aHScrollAmount;
       
   891 	iHScrollOffset = Max(0, Min(iHScrollOffset, maxNumOfPixelsScrolledRight));
       
   892 	DrawMatcherCursor();
       
   893 	TInt actualScrollAmount = iHScrollOffset - oldHScrollOffset;
       
   894 	iWin->Scroll(iViewRect, TPoint(-actualScrollAmount, 0));
       
   895 	TRect redrawRect(iViewRect.iTl+TPoint(iViewRect.Width()-actualScrollAmount,0),TSize(actualScrollAmount,iViewRect.Height()));
       
   896 	if (actualScrollAmount<0)
       
   897 		redrawRect.SetRect(iViewRect.iTl,TSize(-actualScrollAmount,iViewRect.Height()));
       
   898 	redrawRect.Intersection(iViewRect);
       
   899     iItemDrawer->Gc()->Clear( redrawRect );
       
   900 	iWin->Invalidate(redrawRect);
       
   901 	iWin->BeginRedraw(redrawRect);
       
   902 	Draw(&redrawRect);
       
   903 	iWin->EndRedraw();
       
   904 	_AKNTRACE_FUNC_EXIT;
       
   905 	}
       
   906 
       
   907 EXPORT_C TInt CListBoxView::HScrollOffset() const
       
   908 	{
       
   909 	return iHScrollOffset;
       
   910 	}
       
   911 
       
   912 EXPORT_C void CListBoxView::SetHScrollOffset(TInt aHScrollOffset)
       
   913 	{
       
   914 	iHScrollOffset = aHScrollOffset;
       
   915 	}
       
   916 
       
   917 EXPORT_C void CListBoxView::SetItemHeight(TInt aItemHeight)
       
   918 	{
       
   919 	_AKNTRACE_FUNC_ENTER;
       
   920 	_AKNTRACE( "aItemHeight is %d", aItemHeight );
       
   921 	SetItemOffsetInPixels( 0 );
       
   922 	iItemHeight = aItemHeight;
       
   923 	iItemDrawer->SetItemCellSize(ItemSize());
       
   924 	_AKNTRACE_FUNC_EXIT;
       
   925 	}
       
   926 	
       
   927 EXPORT_C void CListBoxView::SetViewRect(const TRect& aRect)
       
   928 	{
       
   929     if ( aRect != iViewRect && iViewRect != TRect::EUninitialized )
       
   930         {
       
   931         iGc->Deactivate();
       
   932         iGc->Activate( *iWin );
       
   933         }
       
   934 
       
   935 	iViewRect = aRect;
       
   936 	iItemDrawer->SetViewRect(iViewRect);
       
   937 	iItemDrawer->SetItemCellSize(ItemSize());
       
   938 	}
       
   939 
       
   940 EXPORT_C TRect CListBoxView::ViewRect() const
       
   941 	{
       
   942 	return iViewRect;
       
   943 	}
       
   944 
       
   945 EXPORT_C void CListBoxView::DrawItem(TInt aItemIndex) const
       
   946 	{
       
   947 	_AKNTRACE_FUNC_ENTER;
       
   948 	if (RedrawDisabled() || !IsVisible())
       
   949 	    {
       
   950 	    _AKNTRACE_FUNC_EXIT;
       
   951 		return;
       
   952 	    }
       
   953 
       
   954     TBool transparencyEnabled( CAknEnv::Static()->TransparencyEnabled() );
       
   955 
       
   956     if ((ITEM_EXISTS_ONCE(aItemIndex)) && ItemIsVisible(aItemIndex))
       
   957 		{
       
   958 		TBool drawingInitiated = ETrue;
       
   959 
       
   960 		if ( transparencyEnabled )
       
   961 		    {
       
   962 		    if ( iWin && iWin->GetDrawRect() == TRect::EUninitialized )
       
   963 			    {
       
   964 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   965                 MAknListBoxTfxInternal* transApi =
       
   966                     CAknListLoader::TfxApiInternal( iGc );
       
   967                 drawingInitiated = transApi && !transApi->EffectsDisabled();
       
   968 #else
       
   969                 drawingInitiated = EFalse;
       
   970 #endif			
       
   971                 }
       
   972 
       
   973             if ( !drawingInitiated )
       
   974 			    {
       
   975                 TRect rect( ItemPos(aItemIndex), ItemSize(aItemIndex) );
       
   976 			    rect.Intersection( iViewRect );
       
   977 			    iWin->Invalidate( rect );
       
   978 			    iWin->BeginRedraw( rect );
       
   979 			    }
       
   980 		    }
       
   981 		
       
   982 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   983         MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( iGc );
       
   984         if ( transApi )
       
   985             {
       
   986             TRect rect( ItemPos( aItemIndex ),
       
   987                                 ItemSize(aItemIndex) );
       
   988             transApi->BeginRedraw( MAknListBoxTfxInternal::EListItem, rect, aItemIndex );
       
   989             transApi->StartDrawing( MAknListBoxTfxInternal::EListItem );
       
   990             }
       
   991 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
   992         
       
   993         iGc->SetClippingRect( iViewRect );
       
   994 
       
   995 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   996         if ( transApi )
       
   997             {
       
   998             transApi->StopDrawing();
       
   999             }
       
  1000 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  1001         
       
  1002 		TBool currentItem = (aItemIndex == iCurrentItemIndex);
       
  1003 
       
  1004 		iItemDrawer->DrawItem(aItemIndex, ItemPos(aItemIndex), ItemIsSelected(aItemIndex),
       
  1005 			currentItem, (iFlags&EEmphasized)>0, (iFlags&EDimmed)>0 );
       
  1006 
       
  1007 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  1008         if ( transApi )
       
  1009             {
       
  1010             transApi->StartDrawing( MAknListBoxTfxInternal::EListItem );
       
  1011             }
       
  1012 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  1013             
       
  1014 		iGc->CancelClippingRect();
       
  1015 
       
  1016 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  1017         if ( transApi )
       
  1018             {
       
  1019             transApi->StopDrawing();
       
  1020             }
       
  1021 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  1022 		
       
  1023 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  1024         if ( transApi )
       
  1025             {
       
  1026             transApi->EndRedraw( MAknListBoxTfxInternal::EListItem, aItemIndex );
       
  1027             }
       
  1028 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  1029 
       
  1030 		if ( transparencyEnabled && !drawingInitiated )
       
  1031 			{
       
  1032 			iWin->EndRedraw();
       
  1033 			}
       
  1034 		}
       
  1035     _AKNTRACE_FUNC_EXIT;
       
  1036     }
       
  1037 
       
  1038 
       
  1039 EXPORT_C void CListBoxView::Draw( const TRect* /*aClipRect*/ ) const
       
  1040 	{
       
  1041 	_AKNTRACE_FUNC_ENTER;
       
  1042     if ( RedrawDisabled() || !IsVisible() )
       
  1043         {
       
  1044         _AKNTRACE_FUNC_EXIT;
       
  1045         return;
       
  1046         }
       
  1047 
       
  1048 	__ASSERT_DEBUG( iModel, Panic( EEikPanicListBoxNoModel ) );
       
  1049 
       
  1050 	if ( iModel->NumberOfItems() == 0 )
       
  1051 	    {
       
  1052 	    //DrawEmptyList();
       
  1053 	    }
       
  1054 	else
       
  1055 		{
       
  1056 		TInt firstPotentialItemIndex = iTopItemIndex;
       
  1057 		TInt lastPotentialItemIndex =
       
  1058             iTopItemIndex + NumberOfItemsThatFitInRect( iViewRect ) - 1;
       
  1059 		TInt i;
       
  1060         ITEM_EXISTS_BEGIN;
       
  1061         for ( i = firstPotentialItemIndex; i <= lastPotentialItemIndex; i++ )
       
  1062             {
       
  1063             if ( ITEM_EXISTS( i ) )
       
  1064                 {
       
  1065                 DrawItem( i );
       
  1066                 }
       
  1067             else
       
  1068                 {
       
  1069                 break;
       
  1070                 }
       
  1071             }
       
  1072 
       
  1073 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  1074         MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iGc );
       
  1075         if ( transApi )
       
  1076         	{
       
  1077         	transApi->StartDrawing( MAknListBoxTfxInternal::EListView );
       
  1078         	}
       
  1079 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  1080 
       
  1081         TBool backgroundDrawn( EFalse );
       
  1082         TRect usedPortionOfViewRect(
       
  1083             iViewRect.iTl,
       
  1084             TSize( iViewRect.Width(),
       
  1085                    ( i - firstPotentialItemIndex ) * iItemHeight ) );
       
  1086 
       
  1087         if ( iExtension && iExtension->iListBox )
       
  1088             {
       
  1089             MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  1090             MAknsControlContext* cc =
       
  1091                 AknsDrawUtils::ControlContext( iExtension->iListBox );
       
  1092 
       
  1093             if ( cc )
       
  1094                 {
       
  1095                 backgroundDrawn =
       
  1096                     AknsDrawUtils::BackgroundBetweenRects( skin,
       
  1097                                                            cc,
       
  1098                                                            iExtension->iListBox,
       
  1099                                                            *iItemDrawer->Gc(),
       
  1100                                                            iViewRect,
       
  1101                                                            usedPortionOfViewRect );
       
  1102                 }
       
  1103             }
       
  1104 
       
  1105         if ( !backgroundDrawn )
       
  1106             {
       
  1107             iItemDrawer->Gc()->SetBrushColor( iBackColor );
       
  1108             DrawUtils::ClearBetweenRects( *iItemDrawer->Gc(),
       
  1109                                           iViewRect,
       
  1110                                           usedPortionOfViewRect );
       
  1111             }
       
  1112 
       
  1113 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  1114         if ( transApi )
       
  1115             {
       
  1116             transApi->StopDrawing();
       
  1117             }
       
  1118 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  1119 		}
       
  1120 	_AKNTRACE_FUNC_EXIT;
       
  1121 	}
       
  1122 
       
  1123 
       
  1124 EXPORT_C void CListBoxView::SetTopItemIndex(TInt aNewTopItemIndex)
       
  1125 	{
       
  1126 	_AKNTRACE_FUNC_ENTER;
       
  1127 	TBool validIndex = (aNewTopItemIndex == 0) || (ITEM_EXISTS_ONCE(aNewTopItemIndex)); 
       
  1128 	__ASSERT_ALWAYS(validIndex, Panic(EEikPanicListBoxInvalidTopItemIndexSpecified));
       
  1129 	iTopItemIndex = aNewTopItemIndex;
       
  1130 	CalcBottomItemIndex();	
       
  1131 	_AKNTRACE_FUNC_EXIT;
       
  1132 	}
       
  1133 		
       
  1134 EXPORT_C void CListBoxView::SetCurrentItemIndex(TInt aItemIndex)
       
  1135 	{
       
  1136 	_AKNTRACE_FUNC_ENTER;
       
  1137 	TBool validIndex = (aItemIndex == 0) || (ITEM_EXISTS_ONCE(aItemIndex)); 
       
  1138 	__ASSERT_ALWAYS(validIndex, Panic(EEikPanicListBoxInvalidCurrentItemIndexSpecified));
       
  1139 	iCurrentItemIndex = aItemIndex;	
       
  1140 	_AKNTRACE_FUNC_EXIT;
       
  1141 	}
       
  1142 
       
  1143 EXPORT_C TInt CListBoxView::CurrentItemIndex() const
       
  1144 	{
       
  1145 	if (ITEM_EXISTS_ONCE(iCurrentItemIndex))
       
  1146 		return iCurrentItemIndex;
       
  1147 	else
       
  1148 		return -1;		// means there is no current item
       
  1149 	}
       
  1150 
       
  1151 EXPORT_C TBool CListBoxView::ScrollToMakeItemVisible(TInt aItemIndex)
       
  1152 	{
       
  1153 	_AKNTRACE_FUNC_ENTER;
       
  1154 	TInt oldVerticalOffset = iVerticalOffset;
       
  1155 	TInt newTopItemIndex = CalcNewTopItemIndexSoItemIsVisible( aItemIndex );
       
  1156 	
       
  1157 	if ( ( ItemIsVisible( aItemIndex ) || aItemIndex < 0 ) 
       
  1158 	        && iVerticalOffset == oldVerticalOffset
       
  1159 	        && !(iFlags & EOffsetChanged) )
       
  1160 	    {
       
  1161 	    _AKNTRACE_FUNC_EXIT;
       
  1162 	    return EFalse;
       
  1163 	    }
       
  1164 	
       
  1165 	if ( iVerticalOffset != oldVerticalOffset )
       
  1166 	    {
       
  1167 	    iFlags |= EOffsetChanged;
       
  1168 	    }
       
  1169 	
       
  1170     VScrollTo( newTopItemIndex );
       
  1171     
       
  1172     iFlags &= ~EOffsetChanged;
       
  1173     
       
  1174     _AKNTRACE_FUNC_EXIT;
       
  1175     return ETrue;
       
  1176 	}
       
  1177 
       
  1178 EXPORT_C TInt CListBoxView::CalcNewTopItemIndexSoItemIsVisible(TInt aItemIndex) const
       
  1179 	{
       
  1180 	_AKNTRACE_FUNC_ENTER;
       
  1181 #ifdef _DEBUG
       
  1182     RDebug::Print( _L( "CListBoxView::CalcNewTopItemIndexSoItemIsVisible" ) );
       
  1183 #endif // _DEBUG
       
  1184 	TInt newTopItemIndex=iTopItemIndex;
       
  1185 	const TInt numItemsThatFitInRect=NumberOfItemsThatFitInRect(iViewRect);
       
  1186 	if (aItemIndex < iTopItemIndex || numItemsThatFitInRect == 0)
       
  1187 		newTopItemIndex = aItemIndex;
       
  1188 	else if (aItemIndex > iBottomItemIndex)
       
  1189 		newTopItemIndex = aItemIndex - numItemsThatFitInRect + 1;
       
  1190 
       
  1191 	if (!ITEM_EXISTS_ONCE(newTopItemIndex) && newTopItemIndex != 0 )
       
  1192 		{ // if application fails to call HandleItemAdditionL(), we might go here.
       
  1193 		  // we dont want our OfferKeyEventL() to panic in that case.
       
  1194 		newTopItemIndex = iTopItemIndex;
       
  1195 		}
       
  1196 	
       
  1197 	CListBoxView* me = const_cast<CListBoxView*>( this );
       
  1198 	// change vertical offset value if needed
       
  1199 	if ( aItemIndex <= iTopItemIndex && iVerticalOffset < 0 )
       
  1200 	    {
       
  1201 	    me->SetItemOffsetInPixels( 0 );
       
  1202 	    }
       
  1203 	else if ( aItemIndex >= iBottomItemIndex && aItemIndex >= ( numItemsThatFitInRect - 1 ) ) 
       
  1204 	    {
       
  1205         TInt delta = iViewRect.Height() % iItemHeight;
       
  1206         
       
  1207         if ( delta > 0 )
       
  1208             {
       
  1209             me->SetItemOffsetInPixels( -( iItemHeight - delta ) );
       
  1210             }
       
  1211         else
       
  1212             {
       
  1213             me->SetItemOffsetInPixels( 0 );
       
  1214             }
       
  1215 	    }
       
  1216 
       
  1217 	_AKNTRACE_FUNC_EXIT;
       
  1218     return newTopItemIndex;
       
  1219 	}
       
  1220 
       
  1221 EXPORT_C void CListBoxView::DrawMatcherCursor()
       
  1222 	{
       
  1223     // DrawMatcherCursor code is broken in S60, it will crash some lists. There
       
  1224     // is no need to draw matcher cursor in S60 -> deprecated method.
       
  1225     }
       
  1226 
       
  1227 EXPORT_C void CListBoxView::HideMatcherCursor()
       
  1228 	{
       
  1229 	if (!(iFlags & EHasMatcherCursor))
       
  1230 		return;	
       
  1231     iGroupWin->CancelTextCursor(); 
       
  1232 	}
       
  1233 
       
  1234 EXPORT_C void CListBoxView::SetMatcherCursorPos(TInt aPosWithinCurrentItem)
       
  1235 	{
       
  1236 	iMatcherCursorPos = aPosWithinCurrentItem;
       
  1237 	}
       
  1238 
       
  1239 EXPORT_C TInt CListBoxView::MatcherCursorPos() const
       
  1240 	{
       
  1241 	return iMatcherCursorPos;
       
  1242 	}
       
  1243 
       
  1244 EXPORT_C void CListBoxView::SetMatcherCursorColor(TRgb aColor)
       
  1245 	{
       
  1246 	iMatcherCursorColor = aColor;
       
  1247 	}
       
  1248 
       
  1249 EXPORT_C void CListBoxView::SetMatcherCursor(TBool aMatcherCursor)
       
  1250 	{
       
  1251 	if (aMatcherCursor)
       
  1252 		SetFlags(EHasMatcherCursor);
       
  1253 	else
       
  1254 		ClearFlags(EHasMatcherCursor);
       
  1255 	}
       
  1256 
       
  1257 EXPORT_C void CListBoxView::SetEmphasized(TBool aEmphasized)
       
  1258 	{
       
  1259 	if (aEmphasized)
       
  1260 		SetFlags(EEmphasized);
       
  1261 	else
       
  1262 		ClearFlags(EEmphasized);
       
  1263 	}
       
  1264 
       
  1265 EXPORT_C void CListBoxView::SetDimmed(TBool aDimmed)
       
  1266 	{
       
  1267 	if (aDimmed)
       
  1268 		SetFlags(EDimmed);
       
  1269 	else
       
  1270 		ClearFlags(EDimmed);
       
  1271 	}
       
  1272 
       
  1273 EXPORT_C void CListBoxView::SetDisableRedraw(TBool aDisableRedraw)
       
  1274 	{
       
  1275 	if (aDisableRedraw)
       
  1276 		SetFlags(EDisableRedraw);
       
  1277 	else
       
  1278 		ClearFlags(EDisableRedraw);
       
  1279 	}
       
  1280 
       
  1281 EXPORT_C TBool CListBoxView::RedrawDisabled() const
       
  1282 	{
       
  1283 	return (iFlags & EDisableRedraw);
       
  1284 	}
       
  1285 
       
  1286 EXPORT_C void CListBoxView::SetPaintedSelection( TBool aPaintedSelection )
       
  1287     {
       
  1288 	if ( aPaintedSelection )
       
  1289 	    SetFlags( EPaintedSelection );
       
  1290 	else
       
  1291         ClearFlags( EPaintedSelection );
       
  1292     }
       
  1293 
       
  1294 EXPORT_C TInt CListBoxView::DataWidth() const
       
  1295 	{
       
  1296 	return iDataWidth;
       
  1297 	}
       
  1298 
       
  1299 EXPORT_C TInt CListBoxView::VisibleWidth(const TRect& aRect) const
       
  1300 	{
       
  1301 	return aRect.Width();
       
  1302 	}
       
  1303 
       
  1304 EXPORT_C void CListBoxView::CalcDataWidth()
       
  1305 	{
       
  1306     // The loop below causes HUGE performance problems for no reason
       
  1307     // with long lists. 
       
  1308 #if NOT_NEEDED_IN_SERIES60
       
  1309 	// assumes that iModel and iItemDrawer are both valid 
       
  1310 	// calculate data width (in pixels)
       
  1311 	TInt largestItemWidth = 0;
       
  1312 
       
  1313     TInt i = 0;
       
  1314     while (ITEM_EXISTS(i))
       
  1315         {
       
  1316         largestItemWidth = Max(largestItemWidth, iItemDrawer->ItemWidthInPixels(i)); 
       
  1317         ++ i;
       
  1318         }
       
  1319     iDataWidth = largestItemWidth;
       
  1320 	iDataWidth += LafListBox::InnerGutter();
       
  1321 	iItemDrawer->SetItemCellSize(ItemSize());
       
  1322 #endif
       
  1323 	}
       
  1324 
       
  1325 EXPORT_C TRgb CListBoxView::BackColor() const
       
  1326 	{
       
  1327 	return iBackColor;
       
  1328 	}
       
  1329 
       
  1330 EXPORT_C void CListBoxView::SetBackColor(TRgb aColor)
       
  1331 	{
       
  1332 	iBackColor = aColor;
       
  1333 	}
       
  1334 
       
  1335 EXPORT_C TRgb CListBoxView::TextColor() const
       
  1336 	{
       
  1337 	return iTextColor;
       
  1338 	}
       
  1339 
       
  1340 EXPORT_C void CListBoxView::SetTextColor(TRgb aColor)
       
  1341 	{
       
  1342 	iTextColor = aColor;
       
  1343 	}
       
  1344 
       
  1345 
       
  1346 EXPORT_C void CListBoxView::DrawEmptyList(const TRect & /*aClientRect*/) const
       
  1347     {
       
  1348     }
       
  1349 
       
  1350 void CListBoxView::DisableVerticalLineDrawing( TBool aDisable )
       
  1351     {
       
  1352     iDisableVerticalLineDrawing = aDisable;
       
  1353     }
       
  1354 
       
  1355 EXPORT_C void CListBoxView::SetItemOffsetInPixels(TInt aOffset)
       
  1356 	{
       
  1357 	if ( iExtension && !iExtension->iScrollingDisabled )
       
  1358 	    {
       
  1359 	    iVerticalOffset = aOffset;
       
  1360 	    }
       
  1361 	else
       
  1362 	    {
       
  1363 	    // Make sure that offset is 0 when
       
  1364 	    // panning is disabled
       
  1365 	    iVerticalOffset = 0;    
       
  1366 	    }    
       
  1367 
       
  1368 #ifdef _DEBUG
       
  1369     RDebug::Print( _L( "CListBoxView::SetItemOffsetInPixels, iVerticalOffset = %d" ), iVerticalOffset );
       
  1370 #endif // _DEBUG
       
  1371 	}
       
  1372 
       
  1373 EXPORT_C TInt CListBoxView::ItemOffsetInPixels() const
       
  1374     {
       
  1375     return iVerticalOffset;
       
  1376     }
       
  1377     
       
  1378 void CListBoxView::SetScrolling( TBool aIsScrolling )
       
  1379     {
       
  1380     if ( iExtension )
       
  1381         {
       
  1382         iExtension->iScrolling = aIsScrolling;
       
  1383         }
       
  1384     }
       
  1385     
       
  1386 void CListBoxView::SetItemIndex( TInt aItemIndex )
       
  1387     {
       
  1388     iCurrentItemIndex = aItemIndex;
       
  1389     }
       
  1390 
       
  1391 
       
  1392 // ---------------------------------------------------------------------------
       
  1393 // Returns ETrue if item is partially visible.
       
  1394 // ---------------------------------------------------------------------------
       
  1395 //
       
  1396 EXPORT_C TBool CListBoxView::ItemIsPartiallyVisible( TInt aItemIndex ) const
       
  1397     {
       
  1398     _AKNTRACE_FUNC_ENTER;
       
  1399     TPoint itemPosition( ItemPos( aItemIndex ) );
       
  1400     TBool itemPartiallyVisible =
       
  1401         ( itemPosition.iY < iViewRect.iTl.iY &&
       
  1402           itemPosition.iY + iItemHeight >= iViewRect.iTl.iY ) ||
       
  1403         ( itemPosition.iY <= iViewRect.iBr.iY &&
       
  1404           itemPosition.iY + iItemHeight > iViewRect.iBr.iY );
       
  1405     _AKNTRACE( "itemPartiallyVisible is %d", itemPartiallyVisible );
       
  1406     _AKNTRACE_FUNC_EXIT;
       
  1407     return itemPartiallyVisible;
       
  1408     }
       
  1409 
       
  1410 
       
  1411 
       
  1412 // class CSnakingListBoxView
       
  1413 
       
  1414 EXPORT_C CSnakingListBoxView::CSnakingListBoxView()
       
  1415     {
       
  1416 	iColumnWidth = 100;
       
  1417     }
       
  1418 
       
  1419 EXPORT_C CSnakingListBoxView::~CSnakingListBoxView()
       
  1420     {
       
  1421     }
       
  1422 
       
  1423 EXPORT_C void CSnakingListBoxView::CalcBottomItemIndex() 
       
  1424 	{
       
  1425 	_AKNTRACE_FUNC_ENTER;
       
  1426 	TInt i = iTopItemIndex;
       
  1427 	iBottomItemIndex = i;
       
  1428 	if ((iColumnWidth == 0) || (iItemHeight == 0))
       
  1429 	    {
       
  1430 	    _AKNTRACE_FUNC_EXIT;	    
       
  1431 		return;
       
  1432 	    }
       
  1433 	TInt xpos = iViewRect.iTl.iX;
       
  1434 	TInt ypos = iViewRect.iTl.iY;	 
       
  1435 	TInt maxXPos = xpos + (iViewRect.Width() / iColumnWidth) * iColumnWidth;
       
  1436 	TInt maxYPos = ypos + ((iViewRect.Height() / iItemHeight) * iItemHeight)- iItemHeight;
       
  1437 	ITEM_EXISTS_BEGIN;
       
  1438 	while ((xpos < maxXPos) && (ITEM_EXISTS(i+1)))
       
  1439 		{
       
  1440 		++ i;
       
  1441 		if (ypos == maxYPos)
       
  1442 			{
       
  1443 			ypos = iViewRect.iTl.iY;
       
  1444 			xpos += iColumnWidth;
       
  1445 			} 
       
  1446 		else
       
  1447 			ypos += iItemHeight;
       
  1448 		}
       
  1449 	if ((i > 0) && (xpos >= maxXPos))
       
  1450 		--i;
       
  1451 	iBottomItemIndex = i;
       
  1452 	_AKNTRACE_FUNC_EXIT;
       
  1453 	}
       
  1454 
       
  1455 EXPORT_C void CSnakingListBoxView::CalcRowAndColIndexesFromItemIndex(TInt aItemIndex, TInt& aRowIndex, TInt& aColIndex) const
       
  1456 	{
       
  1457 	// should panic if iItemHeight or iViewRect.Height() is 0
       
  1458 	// assumes specified item is currently visible
       
  1459 	_AKNTRACE_FUNC_ENTER;
       
  1460 	TInt numOfItemsFromFirstVisibleItem = (aItemIndex - iTopItemIndex);
       
  1461 	TInt numOfItemsPerColumn = NumberOfItemsPerColumn();
       
  1462 	aColIndex = numOfItemsFromFirstVisibleItem / numOfItemsPerColumn;
       
  1463 	aRowIndex = numOfItemsFromFirstVisibleItem % numOfItemsPerColumn;
       
  1464 	_AKNTRACE_FUNC_EXIT;
       
  1465 	}
       
  1466 
       
  1467 EXPORT_C TInt CSnakingListBoxView::NumberOfItemsPerColumn() const
       
  1468 	{
       
  1469 	TInt numOfItemsPerColumn = iViewRect.Height() / iItemHeight;
       
  1470 	return (numOfItemsPerColumn<1? 1: numOfItemsPerColumn);
       
  1471 	}
       
  1472 
       
  1473 EXPORT_C void CSnakingListBoxView::CalcItemIndexFromRowAndColIndexes(TInt& aItemIndex, TInt aRowIndex, TInt aColIndex) const
       
  1474 	{
       
  1475 	_AKNTRACE_FUNC_ENTER;
       
  1476 	__ASSERT_DEBUG((aRowIndex >= 0), Panic(EEikPanicListBoxInvalidRowIndexSpecified));
       
  1477 	__ASSERT_DEBUG((aColIndex >= 0), Panic(EEikPanicListBoxInvalidColIndexSpecified));
       
  1478 	// should panic if iItemHeight is 0
       
  1479 	TInt numOfItemsPerColumn = NumberOfItemsPerColumn();
       
  1480 	aItemIndex = iTopItemIndex + ((aColIndex * numOfItemsPerColumn) + aRowIndex); 
       
  1481 	_AKNTRACE_FUNC_EXIT;
       
  1482 	}
       
  1483 
       
  1484 EXPORT_C TPoint CSnakingListBoxView::ItemPos(TInt aItemIndex) const
       
  1485 	{
       
  1486 	TInt rowIndex, colIndex;
       
  1487 	CalcRowAndColIndexesFromItemIndex(aItemIndex, rowIndex, colIndex);
       
  1488 	return TPoint(iViewRect.iTl.iX + colIndex * iColumnWidth, iViewRect.iTl.iY + rowIndex * iItemHeight);
       
  1489 	}
       
  1490 
       
  1491 EXPORT_C TBool CSnakingListBoxView::XYPosToItemIndex(TPoint aPosition, TInt& aItemIndex) const
       
  1492 	{
       
  1493 	// returns ETrue and sets aItemIndex to the index of the item whose bounding box contains aPosition
       
  1494 	// returns EFalse if no such item exists 
       
  1495 	_AKNTRACE_FUNC_ENTER;
       
  1496 	TBool itemFound = EFalse;
       
  1497 	if ((iColumnWidth == 0) || (iItemHeight == 0))
       
  1498 	    {
       
  1499 	    _AKNTRACE_FUNC_EXIT;
       
  1500 		return EFalse;
       
  1501 	    }
       
  1502 	if (iViewRect.Contains(aPosition))
       
  1503 		{
       
  1504 		// aPosition is inside the display area
       
  1505 		TInt yOffsetFromViewRectOrigin = aPosition.iY - iViewRect.iTl.iY;
       
  1506 		TInt xOffsetFromViewRectOrigin = aPosition.iX - iViewRect.iTl.iX;
       
  1507 		TInt colIndex = xOffsetFromViewRectOrigin / iColumnWidth;
       
  1508 		TInt rowIndex = yOffsetFromViewRectOrigin / iItemHeight;
       
  1509 		// now work out the item index given that we know which row and column it is in 
       
  1510 		TInt itemIndex;
       
  1511 		CalcItemIndexFromRowAndColIndexes(itemIndex, rowIndex, colIndex);
       
  1512 		if ((ITEM_EXISTS_ONCE(itemIndex)) && (ItemIsVisible(itemIndex)))
       
  1513 			{
       
  1514 			aItemIndex = itemIndex;
       
  1515 			itemFound = ETrue;
       
  1516 			}
       
  1517 		}
       
  1518 	_AKNTRACE_FUNC_EXIT;
       
  1519 	return itemFound;
       
  1520 	}
       
  1521 
       
  1522 EXPORT_C void CSnakingListBoxView::MoveCursorL(TCursorMovement aCursorMovement, TSelectionMode aSelectionMode)
       
  1523 	{
       
  1524 	if (aCursorMovement == ECursorNextColumn)
       
  1525 		MoveToNextColumnL(aSelectionMode);
       
  1526 	else if (aCursorMovement == ECursorPreviousColumn)
       
  1527 		MoveToPreviousColumnL(aSelectionMode);
       
  1528 	else 
       
  1529 		CListBoxView::MoveCursorL(aCursorMovement, aSelectionMode);
       
  1530 	}
       
  1531 
       
  1532 EXPORT_C TSize CSnakingListBoxView::ItemSize(TInt /*aItemIndex*/) const
       
  1533 	{
       
  1534 	return TSize(iColumnWidth, iItemHeight);
       
  1535 	}
       
  1536 
       
  1537 EXPORT_C void CSnakingListBoxView::SetColumnWidth(TInt aColumnWidth)
       
  1538 	{
       
  1539 	TBool validColumnWidth = (aColumnWidth > 0);
       
  1540 	__ASSERT_ALWAYS(validColumnWidth, Panic(EEikPanicListBoxInvalidColumnWidthSpecified));
       
  1541 	iColumnWidth = aColumnWidth;
       
  1542 	CalcBottomItemIndex();
       
  1543 	iItemDrawer->SetItemCellSize(ItemSize());
       
  1544 	}
       
  1545 
       
  1546 EXPORT_C TInt CSnakingListBoxView::NumberOfItemsThatFitInRect(const TRect& aRect) const
       
  1547 	{
       
  1548 	_AKNTRACE_FUNC_ENTER;
       
  1549 	if ((iItemHeight == 0) || (iColumnWidth == 0))
       
  1550 	    {
       
  1551 	    _AKNTRACE_FUNC_EXIT;
       
  1552 		return 0;
       
  1553 	    }
       
  1554 	TInt numOfRows = aRect.Height() / iItemHeight;
       
  1555 	TInt numOfCols = aRect.Width() / iColumnWidth;
       
  1556 	_AKNTRACE_FUNC_EXIT;
       
  1557 	return (numOfRows * numOfCols);
       
  1558 	}
       
  1559 
       
  1560 EXPORT_C void CSnakingListBoxView::ClearUnusedItemSpace(TInt aStartItemIndex, TInt aEndItemIndex) const
       
  1561 	{
       
  1562 	TRect blankRect;
       
  1563 	for (TInt i = aStartItemIndex; i <= aEndItemIndex; i++)
       
  1564 		{
       
  1565 		blankRect.SetRect(ItemPos(i), ItemSize());
       
  1566 		iItemDrawer->ClearRect(blankRect);
       
  1567 		}
       
  1568 	}
       
  1569 
       
  1570 EXPORT_C void CSnakingListBoxView::MoveToPreviousColumnL(TSelectionMode aSelectionMode)
       
  1571 	{
       
  1572 	_AKNTRACE_FUNC_ENTER;
       
  1573 	TInt oldCurrentItemIndex = iCurrentItemIndex;
       
  1574 	TInt indexOfNewCurrentItem = iCurrentItemIndex;
       
  1575 	// TInt indexOfNewTopItem = iTopItemIndex;
       
  1576 	TInt numOfItemsPerColumn = NumberOfItemsPerColumn();
       
  1577 	indexOfNewCurrentItem = iCurrentItemIndex - numOfItemsPerColumn;
       
  1578 	if (indexOfNewCurrentItem < 0) 
       
  1579 	    {
       
  1580 	    _AKNTRACE_FUNC_EXIT;
       
  1581 		return;
       
  1582 	    }
       
  1583 	if (ITEM_EXISTS_ONCE(indexOfNewCurrentItem))
       
  1584 		{
       
  1585 		iCurrentItemIndex = indexOfNewCurrentItem;
       
  1586 		if (!(ItemIsSelected(oldCurrentItemIndex)) || (aSelectionMode != ESingleSelection)) 
       
  1587 			DrawItem(oldCurrentItemIndex);
       
  1588 		if (iCurrentItemIndex < iTopItemIndex)
       
  1589 			{
       
  1590 			UpdateSelectionL(aSelectionMode);
       
  1591 			ScrollToMakeItemVisible(iCurrentItemIndex);
       
  1592 			}
       
  1593 		else
       
  1594 			{
       
  1595 			ScrollToMakeItemVisible(iCurrentItemIndex);
       
  1596 			UpdateSelectionL(aSelectionMode);
       
  1597 			}
       
  1598 		}
       
  1599 	_AKNTRACE_FUNC_EXIT;
       
  1600 	}
       
  1601 
       
  1602 EXPORT_C void CSnakingListBoxView::MoveToNextColumnL(TSelectionMode aSelectionMode)
       
  1603 	{
       
  1604 	_AKNTRACE_FUNC_ENTER;
       
  1605 	TInt oldCurrentItemIndex = iCurrentItemIndex;
       
  1606 	TInt indexOfNewCurrentItem = iCurrentItemIndex;
       
  1607 	TInt numOfItemsPerColumn = NumberOfItemsPerColumn();
       
  1608 	indexOfNewCurrentItem = iCurrentItemIndex + numOfItemsPerColumn;
       
  1609 	ITEM_EXISTS_BEGIN;
       
  1610 	if (ITEM_EXISTS(indexOfNewCurrentItem) == EFalse)
       
  1611 		{
       
  1612 		TInt indexOfItemAtTopOfTargetCol = (indexOfNewCurrentItem / numOfItemsPerColumn) * numOfItemsPerColumn;
       
  1613 		if (! (ITEM_EXISTS(indexOfItemAtTopOfTargetCol)))
       
  1614 		    {
       
  1615 		    _AKNTRACE_FUNC_EXIT;
       
  1616 			return;		// no more columns of data to the right, so just return
       
  1617 		    }
       
  1618 		// there are more columns of data available to the right of the current column
       
  1619 		// since there is no item at the expected position, look for an item further up in the same column
       
  1620 		TInt i = indexOfNewCurrentItem;
       
  1621 		while (ITEM_EXISTS(i) == EFalse)
       
  1622 			--i;
       
  1623 		indexOfNewCurrentItem = i;
       
  1624 		}
       
  1625 	iCurrentItemIndex = indexOfNewCurrentItem;
       
  1626 	if (!(ItemIsSelected(oldCurrentItemIndex)) || (aSelectionMode != ESingleSelection)) 
       
  1627 		DrawItem(oldCurrentItemIndex);
       
  1628 	if (iCurrentItemIndex > iBottomItemIndex)
       
  1629 		{
       
  1630 		UpdateSelectionL(aSelectionMode);
       
  1631 		ScrollToMakeItemVisible(iCurrentItemIndex);
       
  1632 		}
       
  1633 	else 
       
  1634 		{
       
  1635 		ScrollToMakeItemVisible(iCurrentItemIndex);
       
  1636 		UpdateSelectionL(aSelectionMode);
       
  1637 		}
       
  1638 	_AKNTRACE_FUNC_EXIT;
       
  1639 	}
       
  1640 
       
  1641 EXPORT_C TInt CSnakingListBoxView::CalcNewTopItemIndexSoItemIsVisible(TInt aItemIndex) const
       
  1642 	{
       
  1643 	_AKNTRACE_FUNC_ENTER;
       
  1644 	if (aItemIndex == iTopItemIndex)
       
  1645 	    {
       
  1646 	    _AKNTRACE_FUNC_EXIT;
       
  1647 		return iTopItemIndex;
       
  1648 	    }
       
  1649 	TInt newTopItemIndex = iTopItemIndex;
       
  1650 	TInt numOfItemsPerColumn = NumberOfItemsPerColumn();
       
  1651 	TInt colIndexOfTargetItem = aItemIndex / numOfItemsPerColumn;
       
  1652 	TInt numOfColsThatFitInViewRect = VisibleWidth(iViewRect);
       
  1653 	if (aItemIndex < iTopItemIndex)
       
  1654 		newTopItemIndex = colIndexOfTargetItem * numOfItemsPerColumn;
       
  1655 	else if (aItemIndex > iBottomItemIndex)
       
  1656 		{
       
  1657 		TInt colIndexOfNewBottomItem = colIndexOfTargetItem;
       
  1658 		TInt colIndexOfNewTopItem = colIndexOfNewBottomItem - (numOfColsThatFitInViewRect - 1);
       
  1659 		newTopItemIndex = colIndexOfNewTopItem * numOfItemsPerColumn;
       
  1660 		}
       
  1661 	_AKNTRACE_FUNC_EXIT;
       
  1662 	return newTopItemIndex;
       
  1663 	}
       
  1664 
       
  1665 EXPORT_C void CSnakingListBoxView::HScroll(TInt aHScrollAmount)
       
  1666 	{
       
  1667 	// note: aHScrollAmount is assumed to be specified in terms of number of columns; 
       
  1668 	//       a negative value ==> we need to scroll view contents to the right
       
  1669 	_AKNTRACE_FUNC_ENTER;
       
  1670 	if ((aHScrollAmount == 0) || (iItemHeight == 0))
       
  1671 	    {
       
  1672 	    _AKNTRACE_FUNC_EXIT;
       
  1673 		return;
       
  1674 	    }
       
  1675 	if (RedrawDisabled())
       
  1676 	    {
       
  1677 	    _AKNTRACE_FUNC_EXIT;
       
  1678 		return;
       
  1679 	    }
       
  1680 	iHScrollOffset += aHScrollAmount;
       
  1681 	TInt numOfColsThatFitInViewRect = VisibleWidth(iViewRect);
       
  1682 	TInt numOfItemsPerColumn = NumberOfItemsPerColumn();
       
  1683 	if (Abs(aHScrollAmount) >= numOfColsThatFitInViewRect)
       
  1684 		{
       
  1685 		iTopItemIndex = iTopItemIndex + (numOfItemsPerColumn * aHScrollAmount);
       
  1686 		CalcBottomItemIndex();
       
  1687 		Draw();
       
  1688 		}
       
  1689 	else
       
  1690 		{
       
  1691 		TInt oldTopItemIndex = iTopItemIndex;
       
  1692 		TInt usedViewRectPortionWidth = VisibleWidth(iViewRect) * iColumnWidth;
       
  1693 		TInt usedViewRectPortionHeight = (iViewRect.Height() / iItemHeight) * iItemHeight;
       
  1694 		TRect usedPortionOfViewRect(iViewRect.iTl, TSize(usedViewRectPortionWidth, usedViewRectPortionHeight));
       
  1695 		iWin->Scroll(usedPortionOfViewRect, TPoint(-aHScrollAmount * iColumnWidth, 0));
       
  1696 		// iWin->Scroll(iViewRect, TPoint(-aHScrollAmount * iColumnWidth, 0));
       
  1697 		iTopItemIndex = iTopItemIndex + (numOfItemsPerColumn * aHScrollAmount);
       
  1698 		CalcBottomItemIndex();
       
  1699 		TInt colIndexOfOldTopItem = oldTopItemIndex / numOfItemsPerColumn;
       
  1700 		TRect redrawRect;
       
  1701 		TInt startColIndex;
       
  1702 		TInt endColIndex;
       
  1703 		if (aHScrollAmount > 0)
       
  1704 			{
       
  1705 			redrawRect.SetRect(TPoint((numOfColsThatFitInViewRect - aHScrollAmount) * iColumnWidth + iViewRect.iTl.iX, iViewRect.iTl.iY), iViewRect.iBr);
       
  1706 			startColIndex = colIndexOfOldTopItem + numOfColsThatFitInViewRect;
       
  1707 			endColIndex = startColIndex + aHScrollAmount - 1;
       
  1708 			}
       
  1709 		else
       
  1710 			{
       
  1711 			redrawRect.SetRect(iViewRect.iTl, TPoint(Abs(aHScrollAmount) * iColumnWidth + iViewRect.iTl.iX, iViewRect.iBr.iY));
       
  1712 			startColIndex = colIndexOfOldTopItem + aHScrollAmount;
       
  1713 			endColIndex = colIndexOfOldTopItem - 1;
       
  1714 			}
       
  1715 		redrawRect.Intersection(iViewRect);
       
  1716 		iWin->Invalidate(iViewRect);
       
  1717 		iWin->BeginRedraw(iViewRect);
       
  1718 		DrawColumnRange(startColIndex, endColIndex);
       
  1719 		iWin->EndRedraw();
       
  1720 		}
       
  1721 	_AKNTRACE_FUNC_EXIT;
       
  1722 	}
       
  1723 
       
  1724 EXPORT_C void CSnakingListBoxView::CalcDataWidth() 
       
  1725 	{
       
  1726 	// assumes that iModel and iItemDrawer are both valid
       
  1727 	// assumes that the model knows how many items there are...
       
  1728 	// calculate data width (in columns)
       
  1729 	iDataWidth = 0;
       
  1730 	if ((iViewRect.Height() == 0) || (iItemHeight == 0))
       
  1731 		return;
       
  1732 	TInt numOfItemsPerColumn = NumberOfItemsPerColumn();
       
  1733 	iDataWidth = iModel->NumberOfItems() / numOfItemsPerColumn;
       
  1734 	if (iModel->NumberOfItems() % numOfItemsPerColumn)
       
  1735 		iDataWidth++;	// add on one column if remainder != 0
       
  1736 	}
       
  1737 
       
  1738 EXPORT_C TInt CSnakingListBoxView::VisibleWidth(const TRect& aRect) const
       
  1739 	{
       
  1740 	return aRect.Width() / iColumnWidth;
       
  1741 	}
       
  1742 
       
  1743 EXPORT_C void CSnakingListBoxView::Draw(const TRect* aClipRect) const
       
  1744 	{
       
  1745 	// temporary: some code sharing with CListBoxView::Draw() is needed!
       
  1746 	_AKNTRACE_FUNC_ENTER;
       
  1747 	if (RedrawDisabled())
       
  1748 	    {
       
  1749 	    _AKNTRACE_FUNC_EXIT;
       
  1750 		return;
       
  1751 	    }
       
  1752 	__ASSERT_DEBUG(iModel, Panic(EEikPanicListBoxNoModel));
       
  1753 	if (iItemHeight == 0)
       
  1754 	    {
       
  1755 	    _AKNTRACE_FUNC_EXIT;
       
  1756 		return;
       
  1757 	    }
       
  1758 	if (! aClipRect)
       
  1759 		aClipRect = &iViewRect;
       
  1760 	iItemDrawer->ClearRect(iViewRect);
       
  1761 	if (iModel->NumberOfItems() == 0)
       
  1762 	    {
       
  1763 	    // call to this was moved to CEikListBox::Draw(), because we need the whole clientrect
       
  1764 	    // to do the drawing correctly.
       
  1765 	    //DrawEmptyList();
       
  1766 		}
       
  1767 	else
       
  1768 		{
       
  1769 		TInt firstPotentialItemIndex = iTopItemIndex;
       
  1770 		TInt lastPotentialItemIndex = iTopItemIndex + NumberOfItemsThatFitInRect(iViewRect) - 1;
       
  1771 		TInt i;
       
  1772 		ITEM_EXISTS_BEGIN;
       
  1773 		for (i = firstPotentialItemIndex; i <= lastPotentialItemIndex; i++)
       
  1774 			if (ITEM_EXISTS(i))
       
  1775 				DrawItem(i);
       
  1776 			else
       
  1777 				{
       
  1778 				ClearUnusedItemSpace(i, lastPotentialItemIndex);
       
  1779 				break;
       
  1780 				}
       
  1781 		// clear the unused portion of the viewing area
       
  1782 		TInt usedViewRectPortionWidth = VisibleWidth(iViewRect) * iColumnWidth;
       
  1783 		TInt usedViewRectPortionHeight = (iViewRect.Height() / iItemHeight) * iItemHeight;
       
  1784 		TRect usedPortionOfViewRect(iViewRect.iTl, TSize(usedViewRectPortionWidth, usedViewRectPortionHeight));
       
  1785         iItemDrawer->Gc()->SetBrushColor( BackColor() );
       
  1786         DrawUtils::ClearBetweenRects( *iItemDrawer->Gc(), iViewRect, usedPortionOfViewRect );
       
  1787 		// ((CSnakingListBoxView*)this)->iBottomItemIndex = i - 1;
       
  1788 		}
       
  1789 	_AKNTRACE_FUNC_EXIT;
       
  1790 	} 
       
  1791 
       
  1792 EXPORT_C void CSnakingListBoxView::DrawItemRange(TInt aStartItemIndex, TInt aEndItemIndex) const
       
  1793 	{
       
  1794 	// temporary: some code sharing with CSnakingListBoxView::Draw() is needed!
       
  1795 	_AKNTRACE_FUNC_ENTER;
       
  1796 	if (RedrawDisabled())
       
  1797 	    {
       
  1798 	    _AKNTRACE_FUNC_EXIT;
       
  1799 		return;
       
  1800 	    }
       
  1801 	if (iItemHeight == 0)
       
  1802 	    {
       
  1803 	    _AKNTRACE_FUNC_EXIT;
       
  1804 		return;
       
  1805 	    }
       
  1806 	TInt i;
       
  1807 	ITEM_EXISTS_BEGIN;
       
  1808 	for (i = aStartItemIndex; i <= aEndItemIndex; i++)
       
  1809 		if (ITEM_EXISTS(i))
       
  1810 			DrawItem(i);
       
  1811 		else
       
  1812 			{
       
  1813 			ClearUnusedItemSpace(i, aEndItemIndex);
       
  1814 			break;
       
  1815 			}
       
  1816 	TInt usedViewRectPortionWidth = VisibleWidth(iViewRect) * iColumnWidth;
       
  1817 	TInt usedViewRectPortionHeight = (iViewRect.Height() / iItemHeight) * iItemHeight;
       
  1818 	TRect usedPortionOfViewRect(iViewRect.iTl, TSize(usedViewRectPortionWidth, usedViewRectPortionHeight));
       
  1819     iItemDrawer->Gc()->SetBrushColor( BackColor() );
       
  1820     DrawUtils::ClearBetweenRects( *iItemDrawer->Gc(), iViewRect, usedPortionOfViewRect);
       
  1821     _AKNTRACE_FUNC_EXIT;
       
  1822 	}
       
  1823 
       
  1824 EXPORT_C void CSnakingListBoxView::DrawColumnRange(TInt aStartColIndex, TInt aEndColIndex) const
       
  1825 	{
       
  1826 	_AKNTRACE_FUNC_ENTER;
       
  1827 	if (RedrawDisabled())
       
  1828 	    {
       
  1829 	    _AKNTRACE_FUNC_EXIT;
       
  1830 		return;
       
  1831 	    }
       
  1832 	if (iItemHeight == 0)
       
  1833 	    {
       
  1834 	    _AKNTRACE_FUNC_EXIT;
       
  1835 		return;
       
  1836 	    }
       
  1837 	TInt numOfItemsPerColumn = NumberOfItemsPerColumn();
       
  1838 	TInt startItemIndex = aStartColIndex * numOfItemsPerColumn;
       
  1839 	TInt endItemIndex = aEndColIndex * numOfItemsPerColumn + numOfItemsPerColumn - 1;
       
  1840 	DrawItemRange(startItemIndex, endItemIndex);
       
  1841 	}
       
  1842 
       
  1843 EXPORT_C void CSnakingListBoxView::SetTopItemIndex(TInt aNewTopItemIndex)
       
  1844 	{
       
  1845 	if (iViewRect.Height() == 0)
       
  1846 		return;
       
  1847 	CListBoxView::SetTopItemIndex(aNewTopItemIndex);
       
  1848 	UpdateHScrollOffsetBasedOnTopItemIndex();
       
  1849 	}
       
  1850 
       
  1851 EXPORT_C void CSnakingListBoxView::SetItemHeight(TInt aItemHeight)
       
  1852 	{
       
  1853 	CListBoxView::SetItemHeight(aItemHeight);
       
  1854 	CalcBottomItemIndex();
       
  1855 	UpdateHScrollOffsetBasedOnTopItemIndex();
       
  1856 	}
       
  1857 
       
  1858 EXPORT_C void CSnakingListBoxView::UpdateHScrollOffsetBasedOnTopItemIndex()
       
  1859 	{
       
  1860 	TInt numOfItemsPerColumn = NumberOfItemsPerColumn();
       
  1861 	iHScrollOffset = iTopItemIndex / numOfItemsPerColumn;
       
  1862 	}
       
  1863 
       
  1864 EXPORT_C TBool CSnakingListBoxView::ScrollToMakeItemVisible(TInt aItemIndex)
       
  1865 	{
       
  1866 	_AKNTRACE_FUNC_ENTER;
       
  1867 	if ((RedrawDisabled()) || (ItemIsVisible(aItemIndex)) || (iViewRect.Height() == 0))
       
  1868 	    {
       
  1869 	    _AKNTRACE_FUNC_EXIT;
       
  1870 		return EFalse;
       
  1871 	    }
       
  1872 	HideMatcherCursor();
       
  1873 	TInt amountToScroll = CalculateHScrollOffsetSoItemIsVisible(aItemIndex);
       
  1874 	HScroll(amountToScroll);
       
  1875 	DrawMatcherCursor();
       
  1876 	_AKNTRACE_FUNC_EXIT;
       
  1877 	return ETrue;
       
  1878 	}
       
  1879 
       
  1880 EXPORT_C TInt CSnakingListBoxView::CalculateHScrollOffsetSoItemIsVisible(TInt aItemIndex) 
       
  1881 	{
       
  1882 	// returns the number of cols that we need to scroll, 0 if no scrolling is needed
       
  1883 	_AKNTRACE_FUNC_ENTER;
       
  1884 	TInt newTopItemIndex = CalcNewTopItemIndexSoItemIsVisible(aItemIndex);
       
  1885 	TInt numOfItemsPerColumn = NumberOfItemsPerColumn();
       
  1886 	TInt oldHScrollOffset = iHScrollOffset;
       
  1887 	TInt newHScrollOffset = newTopItemIndex / numOfItemsPerColumn;
       
  1888 	TInt numOfColsToScroll = newHScrollOffset - oldHScrollOffset;
       
  1889 	_AKNTRACE_FUNC_EXIT;
       
  1890 	return numOfColsToScroll;
       
  1891 	}
       
  1892 
       
  1893 EXPORT_C TAny* CSnakingListBoxView::Reserved_1()
       
  1894 	{
       
  1895 	return NULL;
       
  1896 	}
       
  1897 
       
  1898 
       
  1899