uifw/AvKon/src/akngridview.cpp
changeset 0 2f259fa3e83a
child 4 8ca85d2f0db7
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 /*
       
     2 * Copyright (c) 2002-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:  CAknGridView handles the drawing, the mapping
       
    15 *                of the grid data index to the underlying listbox index (and
       
    16 *                vice versa) as well as the movement around the grid.
       
    17 *
       
    18 */
       
    19 
       
    20 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    21 #include <uikon/eikdefmacros.h>
       
    22 #endif
       
    23 #include <AknGridView.h>
       
    24 #include <AknGridM.h>
       
    25 #include <AknUtils.h>
       
    26 
       
    27 #include <eikenv.h>
       
    28 #include <gulutil.h>
       
    29 #include <eiklbv.h>
       
    30 #include <eiklbi.h>
       
    31 #include <eiklbm.h>
       
    32 #include <eiklbx.h>
       
    33 #include <eiklbx.pan>
       
    34 #include <eikpanic.h>
       
    35 #include <eikfrlb.h>
       
    36 #include <gulutil.h>
       
    37 #include <eikfrlbd.h>
       
    38 
       
    39 #include <AknsDrawUtils.h>
       
    40 #include <AknsControlContext.h>
       
    41 #include <aknphysics.h>
       
    42 
       
    43 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
    44 #include <aknlistloadertfx.h>
       
    45 #include <aknlistboxtfxinternal.h>
       
    46 #endif //RD_UI_TRANSITION_EFFECTS_LIST
       
    47 #include "akntrace.h"
       
    48 
       
    49 /**
       
    50  * Local Panic Function and Panic Codes
       
    51  */
       
    52 enum TAknGridViewPanicCodes
       
    53     {
       
    54     EAknPanicGridViewGeneralPanic,
       
    55     EAknPanicGridViewInvalidRowIndex,
       
    56     EAknPanicGridViewInvalidColumnIndex,
       
    57     EAknPanicGridViewNoGraphicsContext,
       
    58     EAknPanicGridViewNoModel,
       
    59     EAknPanicGridViewInvalidNumberOfRows,
       
    60     EAknPanicGridViewInvalidNumberOfColumns,
       
    61     EAknPanicGridViewInvalidItemWidth,
       
    62     EAknPanicGridViewInvalidItemHeight
       
    63     };
       
    64 
       
    65 GLDEF_C void Panic(TAknGridViewPanicCodes aPanic)
       
    66     {
       
    67     _LIT(KPanicCat,"AknGridView");
       
    68     User::Panic(KPanicCat, aPanic);
       
    69     }
       
    70 
       
    71 
       
    72 /**
       
    73  * Constructor
       
    74  */
       
    75 EXPORT_C CAknGridView::CAknGridView()
       
    76     {
       
    77     iScrollingType = EScrollFollowsItemsAndLoops;
       
    78     iScrollInSecondaryDimension = EScrollFollowsItemsAndLoops;
       
    79     iGridDetails.iGridDimensions = TSize(1,1);
       
    80     }
       
    81 
       
    82 /**
       
    83  * Destructor
       
    84  */
       
    85 EXPORT_C CAknGridView::~CAknGridView()
       
    86     {
       
    87     }
       
    88 
       
    89 // data index <-> row/column calculation
       
    90 
       
    91 /**
       
    92  * Converts a logical position on the grid, where the coordinates are with respect to
       
    93  * the top left hand corner of the grid, to an index for the cell with respect to the
       
    94  * ordering of the cells in the grid.
       
    95  */
       
    96 EXPORT_C void CAknGridView::DataIndexFromLogicalPos(
       
    97     TInt& aItemIndex,
       
    98     TInt aRowIndex,
       
    99     TInt aColIndex) const
       
   100     {
       
   101     _AKNTRACE_FUNC_ENTER;
       
   102     // row and column orientated from  top left corner which is (0,0)
       
   103 
       
   104     // check minimums
       
   105     __ASSERT_ALWAYS((aRowIndex >= 0), Panic(EAknPanicGridViewInvalidRowIndex));
       
   106     __ASSERT_ALWAYS((aColIndex >= 0), Panic(EAknPanicGridViewInvalidColumnIndex));
       
   107 
       
   108     _AKNTRACE( "[%s] aItemIndex = %d aRowIndex = %d aColIndex = %d", 
       
   109     		   __FUNCTION__, aItemIndex, aRowIndex, aColIndex );
       
   110     // calculate number of cells from lowest index corner
       
   111     if (IsPrimaryVertical())
       
   112         {
       
   113         // work out how many complete columns from lowest index
       
   114         // to required position
       
   115         TInt numOfCols = aColIndex;
       
   116         if (!(iGridDetails.iGridFlags & ELeftToRight))
       
   117             numOfCols = (iGridDetails.iGridDimensions.iWidth - 1) - numOfCols;
       
   118 
       
   119         // process the row to calculate final index value depending
       
   120         // on orientation of lowest index with respect to the top to
       
   121         // bottom numbering of the rows.
       
   122         TInt adjustment = aRowIndex;
       
   123         if (!(iGridDetails.iGridFlags & ETopToBottom))
       
   124             {
       
   125             adjustment = -(adjustment + 1);
       
   126             numOfCols++;
       
   127             }
       
   128 
       
   129         aItemIndex = numOfCols * NumberOfRowsInView();
       
   130         aItemIndex += adjustment;
       
   131         }
       
   132     else
       
   133         {
       
   134         TInt numOfRows = aRowIndex;
       
   135         if (!(iGridDetails.iGridFlags & ETopToBottom))
       
   136             numOfRows = (iGridDetails.iGridDimensions.iHeight - 1) - numOfRows;
       
   137 
       
   138         TInt numOfCols  = aColIndex;
       
   139         if (!(iGridDetails.iGridFlags & ELeftToRight))
       
   140             {
       
   141             numOfCols = (NumberOfColsInView() - 1) - numOfCols;
       
   142             }
       
   143 
       
   144         aItemIndex = numOfRows * NumberOfColsInView();
       
   145         aItemIndex += numOfCols;
       
   146         }
       
   147     _AKNTRACE_FUNC_EXIT;
       
   148     }
       
   149 
       
   150 /**
       
   151  * Converts an index for a cell in the grid, given with respect to the ordering
       
   152  * of the cells in the grid, to a logical position on the grid, where the coordinates
       
   153  * are with respect to the top left hand corner of the grid.
       
   154  */
       
   155 EXPORT_C void CAknGridView::LogicalPosFromDataIndex(
       
   156     TInt aItemIndex,
       
   157     TInt& aRowIndex,
       
   158     TInt& aColIndex) const
       
   159     {
       
   160     _AKNTRACE_FUNC_ENTER;
       
   161     _AKNTRACE( "[%s] aItemIndex = %d aRowIndex = %d aColIndex = %d", 
       
   162     		   __FUNCTION__, aItemIndex, aRowIndex, aColIndex );
       
   163     // refer to DataIndexFromLogicalPos above for explanation of mapping of data indexes
       
   164     if (aItemIndex > 0)
       
   165         {
       
   166         if (IsPrimaryVertical())
       
   167             {
       
   168             aColIndex = aItemIndex / NumberOfRowsInView();
       
   169             aRowIndex = aItemIndex % NumberOfRowsInView();
       
   170             }
       
   171         else
       
   172             {
       
   173             aRowIndex = aItemIndex / NumberOfColsInView();
       
   174             aColIndex = aItemIndex % NumberOfColsInView();
       
   175             }
       
   176         }
       
   177     else
       
   178         {
       
   179         aRowIndex = 0;
       
   180         aColIndex = 0;
       
   181         }
       
   182 
       
   183     if (!(iGridDetails.iGridFlags & ELeftToRight))
       
   184         aColIndex = (iGridDetails.iGridDimensions.iWidth - 1) - aColIndex;
       
   185 
       
   186     if (!(iGridDetails.iGridFlags & ETopToBottom))
       
   187         aRowIndex = (iGridDetails.iGridDimensions.iHeight - 1) - aRowIndex;
       
   188 
       
   189     if (aColIndex < 0)
       
   190         aColIndex = 0;
       
   191     if (aRowIndex < 0)
       
   192         aRowIndex = 0;
       
   193     _AKNTRACE_FUNC_EXIT;
       
   194     }
       
   195 
       
   196 /**
       
   197  * Converts a CEikListBox index for a cell in the grid, given with respect to the
       
   198  * snaking listbox top down, left to right structure underlying the grid
       
   199  * structure, to a logical position on the grid, where the coordinates are with
       
   200  * respect to the top left hand corner of the grid.
       
   201  */
       
   202 EXPORT_C void CAknGridView::ListBoxIndexFromLogicalPos(
       
   203     TInt& aItemIndex,
       
   204     TInt aRowIndex,
       
   205     TInt aColIndex) const
       
   206     {
       
   207     _AKNTRACE_FUNC_ENTER;
       
   208     _AKNTRACE( "[%s] aItemIndex = %d aRowIndex = %d aColIndex = %d", 
       
   209     		   __FUNCTION__, aItemIndex, aRowIndex, aColIndex );
       
   210     // check minimums
       
   211     __ASSERT_DEBUG((aRowIndex >= 0), Panic(EAknPanicGridViewInvalidRowIndex));
       
   212     __ASSERT_DEBUG((aColIndex >= 0), Panic(EAknPanicGridViewInvalidColumnIndex));
       
   213 
       
   214     if(IsPrimaryVertical())
       
   215         {
       
   216         aItemIndex = aColIndex * NumberOfRowsInView();
       
   217         aItemIndex += aRowIndex;
       
   218         }
       
   219     else
       
   220         {
       
   221         aItemIndex = aRowIndex * NumberOfColsInView();
       
   222         aItemIndex += aColIndex;
       
   223         }
       
   224     _AKNTRACE_FUNC_EXIT;
       
   225     }
       
   226 
       
   227 /**
       
   228  * Converts a logical position on the grid, where the coordinates are with respect to
       
   229  * the top left hand corner of the grid, to a CEikListBox index for the cell with
       
   230  * respect to the snaking listbox top down, left to right structure underlying the
       
   231  * grid structure.
       
   232  */
       
   233 EXPORT_C void CAknGridView::LogicalPosFromListBoxIndex(TInt aItemIndex, TInt& aRowIndex, TInt& aColIndex) const
       
   234     {
       
   235     _AKNTRACE_FUNC_ENTER;
       
   236     _AKNTRACE( "[%s] aItemIndex = %d aRowIndex = %d aColIndex = %d", 
       
   237     		   __FUNCTION__, aItemIndex, aRowIndex, aColIndex );
       
   238     aColIndex = 0;
       
   239     aRowIndex = 0;
       
   240 
       
   241     if (aItemIndex)
       
   242         {
       
   243         if(IsPrimaryVertical())
       
   244             {
       
   245             aColIndex = aItemIndex / NumberOfRowsInView();
       
   246             aRowIndex = aItemIndex % NumberOfRowsInView();
       
   247             }
       
   248         else
       
   249             {
       
   250             aColIndex = aItemIndex % NumberOfColsInView();
       
   251             aRowIndex = aItemIndex / NumberOfColsInView();
       
   252             }
       
   253         }
       
   254     _AKNTRACE_FUNC_EXIT;
       
   255     }
       
   256 
       
   257 // data index <-> listbox index conversion routines
       
   258 
       
   259 /**
       
   260  * Converts an underlying CEikListBox index into the equivalent grid
       
   261  * cell index given with respect to the ordering of the cells in the grid.
       
   262  */
       
   263 EXPORT_C TInt CAknGridView::ActualDataIndex(TInt aListBoxIndex) const
       
   264     {
       
   265     _AKNTRACE_FUNC_ENTER;
       
   266     _AKNTRACE( "[%s] aListBoxIndex = %d", 
       
   267     		   __FUNCTION__, aListBoxIndex );
       
   268     TInt logicalRow = 0;
       
   269     TInt logicalCol = 0;
       
   270     LogicalPosFromListBoxIndex(aListBoxIndex, logicalRow, logicalCol);
       
   271 
       
   272     TInt dataIndex = 0;
       
   273     DataIndexFromLogicalPos(dataIndex, logicalRow, logicalCol);
       
   274 
       
   275     _AKNTRACE_FUNC_EXIT;
       
   276     return dataIndex;
       
   277     }
       
   278 
       
   279 /**
       
   280  * Converts a grid cell index into the equivalent CEikListBox index for
       
   281  * the underlying snaking listbox top down, left to right structure.
       
   282  */
       
   283 EXPORT_C TInt CAknGridView::ListBoxIndex(TInt aDataIndex) const
       
   284     {
       
   285     _AKNTRACE_FUNC_ENTER;
       
   286     _AKNTRACE( "[%s] aDataIndex = %d", 
       
   287     		   __FUNCTION__, aDataIndex );
       
   288     TInt logicalRow = 0;
       
   289     TInt logicalCol = 0;
       
   290     LogicalPosFromDataIndex(aDataIndex, logicalRow, logicalCol);
       
   291 
       
   292     TInt listBoxIndex = 0;
       
   293     ListBoxIndexFromLogicalPos(listBoxIndex, logicalRow, logicalCol);
       
   294 
       
   295     _AKNTRACE_FUNC_EXIT;
       
   296     return listBoxIndex;
       
   297     }
       
   298 
       
   299 // the current data item
       
   300 /**
       
   301  * Returns the current data index with respect to the ordering of the cells in
       
   302  * the grid.
       
   303  */
       
   304 EXPORT_C TInt CAknGridView::CurrentDataIndex() const
       
   305     {
       
   306     return ActualDataIndex(iCurrentItemIndex);
       
   307     }
       
   308 
       
   309 /**
       
   310  * Sets the current data index with a value given with respect to the ordering of
       
   311  * the cells in the grid.
       
   312  */
       
   313 EXPORT_C void CAknGridView::SetCurrentDataIndex(TInt aDataIndex)
       
   314     {
       
   315     _AKNTRACE( "[%s] aDataIndex = %d", 
       
   316     		   __FUNCTION__, aDataIndex );
       
   317     TRAP_IGNORE(MoveToItemIndexL(ListBoxIndex(aDataIndex),ENoSelection));
       
   318     }
       
   319 
       
   320 // grid functions
       
   321 
       
   322 /**
       
   323  * Checks that number of cells in the grid is always enough to fill the
       
   324  * current grid dimensions. This method should be called after any
       
   325  * method that may alter the amount of data within the grid.
       
   326  *
       
   327  */
       
   328 EXPORT_C void CAknGridView::SetGridCellDimensions(TSize aGridDimensions)
       
   329     {
       
   330     // set the new grid size
       
   331     iGridDetails.iGridDimensions = aGridDimensions;
       
   332     }
       
   333 
       
   334 /**
       
   335  * Returns the current grid dimensions.
       
   336  */
       
   337 EXPORT_C TSize CAknGridView::GridCellDimensions() const
       
   338     {
       
   339     return iGridDetails.iGridDimensions;
       
   340     }
       
   341 
       
   342 /**
       
   343  * Sets the size of the spaces between items.
       
   344  */
       
   345 EXPORT_C void CAknGridView::SetSpacesBetweenItems(TSize aSizeOfSpaceBetweenItems)
       
   346     {
       
   347     iGridDetails.iSizeBetweenItems = TSize(0,0);
       
   348     if (aSizeOfSpaceBetweenItems.iWidth > 0)
       
   349         {
       
   350         iGridDetails.iSizeBetweenItems.iWidth=aSizeOfSpaceBetweenItems.iWidth;
       
   351         }
       
   352     if (aSizeOfSpaceBetweenItems.iHeight > 0)
       
   353         {
       
   354         iGridDetails.iSizeBetweenItems.iHeight=aSizeOfSpaceBetweenItems.iHeight;
       
   355         }
       
   356     }
       
   357 
       
   358 /**
       
   359  * Sets the form of scroll to activate upon reaching the limit when moving in
       
   360  * the primary direction of grid, primary meaning whether the items are
       
   361  * organised vertically or horizontally.
       
   362  */
       
   363 EXPORT_C void CAknGridView::SetPrimaryScrollingType(TScrollingType aScrollingType)
       
   364     {
       
   365     iScrollingType = aScrollingType;
       
   366     }
       
   367 
       
   368 /**
       
   369  * Sets the form of scroll to activate upon reaching the limit when moving in
       
   370  * the secondary direction of grid.
       
   371  */
       
   372 EXPORT_C void CAknGridView::SetSecondaryScrollingType(TScrollingType aSecondaryScrolling)
       
   373     {
       
   374     iScrollInSecondaryDimension = aSecondaryScrolling;
       
   375     }
       
   376 
       
   377 
       
   378 /**
       
   379  * Returns true if the primary dimension of the grid is
       
   380  * vertical.
       
   381  */
       
   382 EXPORT_C TBool CAknGridView::IsPrimaryVertical() const
       
   383     {
       
   384     return (iGridDetails.iGridFlags & EPrimaryIsVertical);
       
   385     }
       
   386 
       
   387 /**
       
   388  * Returns ETrue if the CEikListBox index given exists.
       
   389  */
       
   390 EXPORT_C TBool CAknGridView::ItemExists(TInt aListBoxIndex) const
       
   391     {
       
   392     TInt totalpossibleitems = iGridDetails.iGridDimensions.iHeight * iGridDetails.iGridDimensions.iWidth;
       
   393 
       
   394     return ((aListBoxIndex > -1) && (aListBoxIndex < totalpossibleitems));
       
   395     }
       
   396 
       
   397 
       
   398 /**
       
   399  * This has been overloaded to ensure that only valid cells are drawn
       
   400  * and not the empty cells.
       
   401  */
       
   402 EXPORT_C void CAknGridView::DrawItem( TInt aItemIndex ) const
       
   403     {
       
   404     _AKNTRACE_FUNC_ENTER;
       
   405     _AKNTRACE( "[%s] aItemIndex = %d", 
       
   406     		   __FUNCTION__, aItemIndex );
       
   407     if ( RedrawDisabled() || !IsVisible() )
       
   408         {
       
   409         _AKNTRACE_FUNC_EXIT;
       
   410         return;
       
   411         }
       
   412 
       
   413     if ( ItemExists( aItemIndex ) )
       
   414         {
       
   415         TBool transparencyEnabled( CAknEnv::Static()->TransparencyEnabled() );
       
   416         TBool drawingInitiated = ETrue;
       
   417         TPoint itemPosition( ItemPos( aItemIndex ) );
       
   418 
       
   419 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   420         MAknListBoxTfxInternal* transApi =
       
   421             CAknListLoader::TfxApiInternal( iGc );
       
   422 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
   423 
       
   424         if ( transparencyEnabled )
       
   425             {
       
   426             if ( iWin && iWin->GetDrawRect() == TRect::EUninitialized )
       
   427                 {
       
   428 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   429                 drawingInitiated = transApi && !transApi->EffectsDisabled();
       
   430 #else
       
   431                 drawingInitiated = EFalse;
       
   432 #endif
       
   433                 }
       
   434 
       
   435             if ( !drawingInitiated )
       
   436                 {
       
   437                 TRect itemRect( itemPosition, ItemSize( aItemIndex ) );
       
   438                 itemRect.Intersection( iViewRect );
       
   439                 iWin->Invalidate( itemRect );
       
   440                 iWin->BeginRedraw( itemRect );
       
   441                 }
       
   442             }
       
   443 
       
   444         // convert to actual data index
       
   445         TInt dataIndex = ActualDataIndex( aItemIndex );
       
   446 
       
   447         __ASSERT_DEBUG( (iGc), Panic( EAknPanicGridViewNoGraphicsContext ) );
       
   448 
       
   449         if ( GridModel()->IndexContainsData( dataIndex ) )
       
   450             {
       
   451             // It must be ensured here that an item isn't drawn outside
       
   452             // the view rectangle.
       
   453 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   454             if ( transApi )
       
   455                 {
       
   456                 transApi->StartDrawing( MAknListBoxTfxInternal::EListNotSpecified );
       
   457                 }
       
   458 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
   459 
       
   460             iGc->SetClippingRect( iViewRect );
       
   461             
       
   462 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   463             if ( transApi )
       
   464                 {
       
   465                 transApi->StopDrawing();
       
   466                 }
       
   467 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
   468 
       
   469             iItemDrawer->DrawItem(
       
   470                 dataIndex,
       
   471                 itemPosition,
       
   472                 ItemIsSelected( aItemIndex ),
       
   473                 aItemIndex == iCurrentItemIndex,
       
   474                 ( iFlags & EEmphasized ) == EEmphasized,
       
   475                 ( iFlags & EDimmed ) == EDimmed );
       
   476 
       
   477 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   478             if ( transApi )
       
   479                 {
       
   480                 transApi->StartDrawing( MAknListBoxTfxInternal::EListNotSpecified );
       
   481                 }
       
   482 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
   483 
       
   484             iGc->CancelClippingRect();
       
   485             
       
   486 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   487             if ( transApi )
       
   488                 {
       
   489                 transApi->StopDrawing();
       
   490                 }
       
   491 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
   492             }
       
   493         else
       
   494             {
       
   495             static_cast<CFormattedCellListBoxItemDrawer*>( iItemDrawer )->
       
   496                 DrawEmptyItem( dataIndex,
       
   497                                ItemPos( aItemIndex ),
       
   498                                ( iFlags & EDimmed ) == EDimmed );
       
   499             }
       
   500 
       
   501         if ( transparencyEnabled && !drawingInitiated )
       
   502             {
       
   503             iWin->EndRedraw();
       
   504             }
       
   505         }
       
   506     _AKNTRACE_FUNC_EXIT;
       
   507     }
       
   508 
       
   509 
       
   510 /**
       
   511  * This has been overloaded to ensure that if no cells exist in the
       
   512  * grid then an empty grid is displayed. And also to correct drawing.
       
   513  */
       
   514 EXPORT_C void CAknGridView::Draw( const TRect* aClipRect ) const
       
   515     {
       
   516     _AKNTRACE_FUNC_ENTER;
       
   517     _AKNTRACE( "The rect of grid are ( %d, %d ) ( %d, %d )", 
       
   518     		   aClipRect->iTl.iX, aClipRect->iTl.iY, 
       
   519     		   aClipRect->iBr.iX, aClipRect->iBr.iY );
       
   520     if ( RedrawDisabled() || iItemHeight == 0 || ColumnWidth() == 0 )
       
   521         {
       
   522         _AKNTRACE_FUNC_EXIT;
       
   523         return;
       
   524         }
       
   525 
       
   526     if ( GridModel()->NumberOfData() == 0 )
       
   527         {
       
   528         DrawEmptyList();
       
   529         }
       
   530     else
       
   531         {
       
   532         if (RedrawDisabled())
       
   533         	{
       
   534         	_AKNTRACE_FUNC_EXIT;
       
   535             return;
       
   536         	}
       
   537         __ASSERT_DEBUG(iModel, Panic(EAknPanicGridViewNoModel));
       
   538         if (iItemHeight == 0)
       
   539         	{
       
   540         	_AKNTRACE_FUNC_EXIT;
       
   541             return;
       
   542         	}
       
   543         if ( !aClipRect )
       
   544             {
       
   545             aClipRect = &iViewRect;
       
   546             }
       
   547         
       
   548 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   549         MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iGc );
       
   550         if ( transApi )
       
   551             {
       
   552             aClipRect = &iViewRect;
       
   553             transApi->SetListType( MAknListBoxTfxInternal::EListBoxTypeGrid );    
       
   554             transApi->StartDrawing( MAknListBoxTfxInternal::EListNotSpecified );
       
   555             }
       
   556 #endif //RD_UI_TRANSITION_EFFECTS_LIST
       
   557 
       
   558         iGc->SetClippingRect( *aClipRect );
       
   559 
       
   560 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   561     if ( transApi )
       
   562         {
       
   563         transApi->StopDrawing();
       
   564         }
       
   565 #endif
       
   566 
       
   567         TInt numberOfItems( iModel->NumberOfItems() );
       
   568         TInt numberOfCols( NumberOfColsInView() );
       
   569         TInt numberOfCells( numberOfItems );
       
   570         TInt emptyCellsAtEnd( numberOfItems % numberOfCols );
       
   571         if ( emptyCellsAtEnd )
       
   572             {
       
   573             // Add empty cells to the last row if it's not full so
       
   574             // that the whole row gets it's background drawn.
       
   575             numberOfCells += ( numberOfCols - emptyCellsAtEnd );
       
   576             }
       
   577         TInt numberOfRows( numberOfCells / numberOfCols );
       
   578         TInt firstPotentialItemIndex = iTopItemIndex >= numberOfCols ? iTopItemIndex - numberOfCols : iTopItemIndex;
       
   579         TInt lastPotentialItemIndex = iTopItemIndex + 
       
   580             ( NumberOfItemsThatFitInRect(iViewRect) * numberOfCols - 1 ) + numberOfCols;
       
   581 
       
   582         if ( lastPotentialItemIndex / numberOfCols > numberOfRows )
       
   583             {
       
   584             // Check that there isn't an empty row at the bottom.
       
   585             lastPotentialItemIndex -= numberOfCols;
       
   586             }
       
   587 
       
   588         // Clear the unused portion of the viewing area.
       
   589         DrawUnusedViewPortion();
       
   590 
       
   591         for ( TInt i = firstPotentialItemIndex; i <= lastPotentialItemIndex; i++ )
       
   592             {
       
   593             if ( ItemExists( i ) )
       
   594                 {
       
   595                 DrawItem( i );
       
   596                 }
       
   597             else
       
   598                 {
       
   599 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   600                 if ( transApi )
       
   601                     {
       
   602                     transApi->StartDrawing( MAknListBoxTfxInternal::EListView );
       
   603                     }
       
   604 #endif
       
   605 
       
   606                 iGc->SetClippingRect( *aClipRect );
       
   607                 ClearUnusedItemSpace( i, lastPotentialItemIndex );
       
   608 
       
   609 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   610                 if ( transApi )
       
   611                     {
       
   612                     transApi->StopDrawing();
       
   613                     }
       
   614 #endif
       
   615                 break;
       
   616                 }
       
   617             }
       
   618 
       
   619 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   620         if ( transApi )
       
   621             {
       
   622             transApi->StartDrawing( MAknListBoxTfxInternal::EListView );
       
   623             }
       
   624 #endif
       
   625 
       
   626 
       
   627         iGc->CancelClippingRect();
       
   628         
       
   629 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   630 	    if ( transApi )
       
   631 	        {
       
   632             transApi->StopDrawing();
       
   633             }
       
   634 #endif //RD_UI_TRANSITION_EFFECTS_LIST
       
   635         }
       
   636     _AKNTRACE_FUNC_EXIT;
       
   637     }
       
   638 
       
   639 
       
   640 // ---------------------------------------------------------------------------
       
   641 // This function has been overloaded to draw items correctly.
       
   642 // ---------------------------------------------------------------------------
       
   643 //
       
   644 EXPORT_C TPoint CAknGridView::ItemPos( TInt aItemIndex ) const
       
   645     {
       
   646     _AKNTRACE_FUNC_ENTER;
       
   647     _AKNTRACE( "[%s] aItemIndex = %d", 
       
   648     		   __FUNCTION__, aItemIndex );
       
   649     TInt rowIndex = 0;
       
   650     TInt colIndex = 0;
       
   651     CalcRowAndColIndexesFromItemIndex( aItemIndex, rowIndex, colIndex );
       
   652     
       
   653     TPoint itemPos(
       
   654         iViewRect.iTl.iX + colIndex *
       
   655             ( ColumnWidth() + iGridDetails.iSizeBetweenItems.iWidth ),
       
   656         iViewRect.iTl.iY + rowIndex *
       
   657             ( iItemHeight + iGridDetails.iSizeBetweenItems.iHeight ) + iVerticalOffset );
       
   658     
       
   659     _AKNTRACE_FUNC_EXIT;
       
   660     return itemPos;
       
   661     }
       
   662 
       
   663 
       
   664 // ---------------------------------------------------------------------------
       
   665 // This function has been overloaded to draw items correctly.
       
   666 // ---------------------------------------------------------------------------
       
   667 //
       
   668 EXPORT_C void CAknGridView::CalcBottomItemIndex()
       
   669     {
       
   670     _AKNTRACE_FUNC_ENTER;
       
   671     TInt numberOfItems( iModel->NumberOfItems() );
       
   672     iBottomItemIndex =
       
   673         iTopItemIndex + iGridDetails.iPageSize - 1 + iGridDetails.iColsInView;
       
   674     if ( iBottomItemIndex - iGridDetails.iColsInView >= numberOfItems - 1 )
       
   675         {
       
   676         iBottomItemIndex -= iGridDetails.iColsInView;
       
   677         }
       
   678     _AKNTRACE_FUNC_EXIT;
       
   679     }
       
   680 
       
   681 
       
   682 // ---------------------------------------------------------------------------
       
   683 // This function has been overloaded to draw items correctly.
       
   684 // ---------------------------------------------------------------------------
       
   685 //
       
   686 EXPORT_C TInt CAknGridView::CalcNewTopItemIndexSoItemIsVisible(
       
   687     TInt aItemIndex ) const
       
   688     {
       
   689     _AKNTRACE_FUNC_ENTER;
       
   690     _AKNTRACE( "[%s] aItemIndex = %d", 
       
   691     		   __FUNCTION__, aItemIndex );
       
   692     TInt newTopItemIndex = iTopItemIndex;
       
   693 
       
   694     if ( aItemIndex != iTopItemIndex )
       
   695         {
       
   696         if ( IsPrimaryVertical() )
       
   697             {
       
   698             TInt numOfRowsInView = NumberOfRowsInView();
       
   699             TInt colIndexOfTargetItem = aItemIndex / numOfRowsInView;
       
   700             TInt numOfColsInView = NumberOfColsInView();
       
   701             if ( aItemIndex < iTopItemIndex )
       
   702                 {
       
   703                 newTopItemIndex = colIndexOfTargetItem * numOfRowsInView;
       
   704                 }
       
   705             else if ( aItemIndex > iBottomItemIndex )
       
   706                 {
       
   707                 TInt colIndexOfNewBottomItem = colIndexOfTargetItem;
       
   708                 TInt colIndexOfNewTopItem =
       
   709                     colIndexOfNewBottomItem - ( numOfColsInView - 1 );
       
   710                 newTopItemIndex = colIndexOfNewTopItem * numOfRowsInView;
       
   711                 }
       
   712             }
       
   713         else
       
   714             {
       
   715             TInt numOfColsInView = NumberOfColsInView();
       
   716             TInt rowIndexOfTargetItem = aItemIndex / numOfColsInView;
       
   717             TInt numOfRowsInView = NumberOfRowsInView();
       
   718             
       
   719 			if ( aItemIndex < iTopItemIndex )
       
   720                 {
       
   721                 newTopItemIndex = rowIndexOfTargetItem * numOfColsInView;
       
   722                 }
       
   723             else if ( aItemIndex > iBottomItemIndex - numOfColsInView )
       
   724                 {
       
   725                 TInt rowIndexOfNewBottomItem = rowIndexOfTargetItem;
       
   726                 TInt rowIndexOfNewTopItem =
       
   727                     rowIndexOfNewBottomItem - ( numOfRowsInView - 1 );
       
   728                 newTopItemIndex = rowIndexOfNewTopItem * numOfColsInView;
       
   729                 }
       
   730             }
       
   731         }
       
   732 
       
   733     _AKNTRACE_FUNC_EXIT;
       
   734     return newTopItemIndex;
       
   735     }
       
   736 
       
   737 
       
   738 /**
       
   739  * This function has been overloaded to draw items correctly.
       
   740  */
       
   741 EXPORT_C void CAknGridView::DrawItemRange( TInt aStartItemIndex,
       
   742                                            TInt aEndItemIndex ) const
       
   743     {
       
   744     _AKNTRACE_FUNC_ENTER;
       
   745     _AKNTRACE( "[%s] aStartItemIndex = %d aEndItemIndex = %d", 
       
   746     		   __FUNCTION__, aStartItemIndex, aEndItemIndex );
       
   747     if ( RedrawDisabled() || iItemHeight == 0 )
       
   748         {
       
   749         _AKNTRACE_FUNC_EXIT;
       
   750         return;
       
   751         }
       
   752 
       
   753 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   754     MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iGc );
       
   755 #endif
       
   756     // Clear the unused portion of the viewing area.
       
   757     DrawUnusedViewPortion();
       
   758 
       
   759     for ( TInt i = aStartItemIndex; i <= aEndItemIndex; i++ )
       
   760         {
       
   761         if ( ItemExists( i ) )
       
   762             {
       
   763             DrawItem( i );
       
   764             }
       
   765         else
       
   766             {
       
   767 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   768             if ( transApi )
       
   769                 {
       
   770                 transApi->StartDrawing( MAknListBoxTfxInternal::EListView );
       
   771                 }
       
   772 #endif
       
   773             ClearUnusedItemSpace( i, aEndItemIndex );
       
   774 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   775             if ( transApi )
       
   776                 {
       
   777                 transApi->StopDrawing();
       
   778                 }
       
   779 #endif
       
   780             break;
       
   781             }
       
   782         }
       
   783 
       
   784 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   785     if ( transApi )
       
   786         {
       
   787         transApi->StartDrawing( MAknListBoxTfxInternal::EListView );
       
   788         }
       
   789 #endif
       
   790 
       
   791 
       
   792 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   793     if ( transApi )
       
   794         {
       
   795         transApi->StopDrawing();
       
   796         }
       
   797 #endif
       
   798     _AKNTRACE_FUNC_EXIT;
       
   799 	}
       
   800 
       
   801 /**
       
   802  * This function may be overloaded to detail an empty grid as required.
       
   803  */
       
   804 EXPORT_C void CAknGridView::DrawEmptyList() const
       
   805 	{
       
   806 	_AKNTRACE_FUNC_ENTER;
       
   807 	iGc->SetClippingRect(iViewRect);
       
   808 	iItemDrawer->ClearRect(iViewRect);
       
   809 
       
   810 	if (EmptyListText())
       
   811 		{
       
   812 		// display empty grid message
       
   813 		CFormattedCellListBoxItemDrawer *id = (CFormattedCellListBoxItemDrawer*)ItemDrawer();
       
   814 		AknDrawWithSkins::DrawEmptyList(iViewRect, *iGc, *EmptyListText(), id->FormattedCellData()->Control());
       
   815 		}
       
   816 	iGc->CancelClippingRect();
       
   817 	_AKNTRACE_FUNC_EXIT;
       
   818 	}
       
   819 
       
   820 /**
       
   821  * Grid initialisation function. Should only be called by SetLayoutL of
       
   822  * grid box.
       
   823  */
       
   824 EXPORT_C void CAknGridView::SetGridDetails(SGrid aGridDetails)
       
   825 	{
       
   826 	SGrid details = aGridDetails;
       
   827 
       
   828 	if (details.iSizeBetweenItems.iHeight < 0)
       
   829 		{
       
   830 		details.iSizeBetweenItems.iHeight = 0;
       
   831 		}
       
   832 	if (details.iSizeBetweenItems.iWidth < 0)
       
   833 		{
       
   834 		details.iSizeBetweenItems.iWidth = 0;
       
   835 		}
       
   836 
       
   837 	iGridDetails = details;
       
   838 	}
       
   839 
       
   840 
       
   841 // ---------------------------------------------------------------------------
       
   842 // This set the current item index and moves the highlight to the specified
       
   843 // item index and and scrolls the grid if necessary.
       
   844 // ---------------------------------------------------------------------------
       
   845 //
       
   846 EXPORT_C void CAknGridView::MoveToItemIndexL( TInt aItemIndex,
       
   847                                               TSelectionMode aSelectionMode )
       
   848 	{
       
   849 	_AKNTRACE_FUNC_ENTER;
       
   850 	if ( !ItemExists( aItemIndex ) )
       
   851 	    {
       
   852 	    _AKNTRACE_FUNC_EXIT;
       
   853 		return; // nothing to do
       
   854 	    }
       
   855 	_AKNTRACE( "[%s] aItemIndex = %d TSelectionMode = %d", 
       
   856 			   __FUNCTION__, aItemIndex, aSelectionMode );
       
   857 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   858     MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iGc );
       
   859     if ( transApi )
       
   860         {
       
   861         transApi->SetMoveType( MAknListBoxTfxInternal::EListStartUnknownMove );
       
   862         }
       
   863 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
   864     
       
   865     TInt oldItemIndex = iCurrentItemIndex;
       
   866     
       
   867     if ( !ScrollToMakeItemVisible( aItemIndex ) )
       
   868         {
       
   869         if ( ItemIsPartiallyVisible( aItemIndex ) )
       
   870             {
       
   871             // ScrollToMakeItemVisible doesn't scroll the view for
       
   872             // partial items, so for key events the scrolling is done here.
       
   873             
       
   874             TInt amountToScroll =
       
   875                 CalculateHScrollOffsetSoItemIsVisible( aItemIndex );
       
   876         
       
   877             iHScrollOffset += amountToScroll;        
       
   878             iCurrentItemIndex = aItemIndex;
       
   879             
       
   880             if ( iExtension && !iExtension->iScrollingDisabled )
       
   881                 {
       
   882                 CFormattedCellListBoxItemDrawer* itemDrawer =
       
   883                     static_cast<CFormattedCellListBoxItemDrawer*>( iItemDrawer );
       
   884                 CEikListBox* listBox =
       
   885                     static_cast<CEikListBox*>(
       
   886                         itemDrawer->FormattedCellData()->Control() );
       
   887                 listBox->HandlePhysicsScrollEventL(
       
   888                     amountToScroll * iItemHeight + ItemOffsetInPixels() );
       
   889                 }
       
   890             else
       
   891                 {
       
   892                 // Do normal scrolling if physics are not enabled.
       
   893                 VScrollTo( CalcNewTopItemIndexSoItemIsVisible( aItemIndex ) );
       
   894                 }
       
   895             }
       
   896         else
       
   897             {
       
   898             // View was not scrolled, so item is already visible.
       
   899             iCurrentItemIndex = aItemIndex;
       
   900             DrawItem( oldItemIndex );
       
   901             }
       
   902         }
       
   903 
       
   904 	UpdateSelectionL( aSelectionMode ); // this draws iCurrentItemIndex
       
   905 
       
   906 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   907     if ( transApi )
       
   908         {
       
   909         transApi->SetMoveType( MAknListBoxTfxInternal::EListStopUnknownMove );
       
   910         }
       
   911 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
   912     _AKNTRACE_FUNC_EXIT;
       
   913 	}
       
   914 
       
   915 
       
   916 // ---------------------------------------------------------------------------
       
   917 // Returns the number of visible columns.
       
   918 // ---------------------------------------------------------------------------
       
   919 //
       
   920 EXPORT_C TInt CAknGridView::NumberOfColsInView() const
       
   921 	{
       
   922 	__ASSERT_ALWAYS( ( iGridDetails.iColsInView > 0 ),
       
   923 	                 Panic( EAknPanicGridViewInvalidNumberOfColumns ) );
       
   924 	return iGridDetails.iColsInView;
       
   925 	}
       
   926 
       
   927 
       
   928 // ---------------------------------------------------------------------------
       
   929 // Returns the number of visible rows.
       
   930 // ---------------------------------------------------------------------------
       
   931 //
       
   932 EXPORT_C TInt CAknGridView::NumberOfRowsInView() const
       
   933 	{
       
   934 	__ASSERT_ALWAYS( ( iGridDetails.iRowsInView > 0 ),
       
   935 	                 Panic( EAknPanicGridViewInvalidNumberOfRows ) );
       
   936 	TInt rows = iGridDetails.iRowsInView;
       
   937 
       
   938 	return rows;
       
   939 	}
       
   940 
       
   941 
       
   942 void CAknGridView::MoveCursorWithRepeatsL( 
       
   943         TBool aNextOrPrev, TSelectionMode aSelectionMode, TInt aAmount )
       
   944     {  
       
   945     _AKNTRACE_FUNC_ENTER;
       
   946     TBool singleColumn = EFalse;
       
   947     if ( IsPrimaryVertical() )
       
   948         {
       
   949         singleColumn = iGridDetails.iGridDimensions.iHeight < 2;
       
   950         }
       
   951     else
       
   952         {
       
   953         singleColumn = iGridDetails.iGridDimensions.iWidth < 2;
       
   954         }
       
   955     
       
   956     TCursorMovement cursorMovement;
       
   957     if ( aNextOrPrev )
       
   958         {
       
   959         cursorMovement = CListBoxView::ECursorNextColumn;
       
   960         if ( singleColumn )
       
   961             {
       
   962             cursorMovement = CListBoxView::ECursorNextItem;
       
   963             }
       
   964         }
       
   965     else
       
   966         {
       
   967         cursorMovement = CListBoxView::ECursorPreviousColumn;
       
   968         if ( singleColumn )
       
   969             {
       
   970             cursorMovement = CListBoxView::ECursorPreviousItem;
       
   971             }
       
   972         }
       
   973         
       
   974     TInt step = aAmount;   
       
   975     if ( !singleColumn )
       
   976         {
       
   977         // Stop looping in grids. Looping is still allowed in list like grid.
       
   978         TInt maxIndex = GridModel()->NumberOfData() - 1;
       
   979         TInt dataIndex = CurrentDataIndex();        
       
   980         TBool isToTail = iGridDetails.iGridFlags & ELeftToRight ?
       
   981             aNextOrPrev : !aNextOrPrev;
       
   982 
       
   983         if ( dataIndex + step > maxIndex && isToTail )
       
   984             {
       
   985             step = maxIndex - dataIndex;
       
   986             }
       
   987 
       
   988         if ( dataIndex < step && !isToTail )
       
   989             {
       
   990             step = dataIndex;
       
   991             }
       
   992         }
       
   993     
       
   994     for ( TInt ii = 0; ii < step; ii++ )
       
   995         {
       
   996         MoveCursorL( cursorMovement, aSelectionMode );
       
   997         }  
       
   998     _AKNTRACE_FUNC_EXIT;
       
   999     }
       
  1000 
       
  1001 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  1002 // -----------------------------------------------------------------------------
       
  1003 // LISTBOX EFFECTS IMPLEMENTATION
       
  1004 // 
       
  1005 // Sets movement type in the transition controller
       
  1006 //
       
  1007 // This function is called from DoMoveL before MoveToItemIndexL is called.
       
  1008 // -----------------------------------------------------------------------------
       
  1009 //
       
  1010 void SetMoveType( CWindowGc* aGc,
       
  1011                   CAknGridView::TCursorMovement aCursorMovement )
       
  1012     {
       
  1013     MAknListBoxTfxInternal* api = CAknListLoader::TfxApiInternal( aGc );
       
  1014     if ( api )
       
  1015 	    {
       
  1016 	    if ( aCursorMovement == CAknGridView::ECursorNextColumn)
       
  1017 	        {
       
  1018             api->SetMoveType( MAknListBoxTfxInternal::EListMoveRight );
       
  1019 	        }
       
  1020 	    else if ( aCursorMovement == CAknGridView::ECursorNextItem )
       
  1021 	        {
       
  1022             api->SetMoveType( MAknListBoxTfxInternal::EListMoveDown );
       
  1023 	        }
       
  1024 	    else if ( aCursorMovement == CAknGridView::ECursorPreviousItem )
       
  1025 	        {
       
  1026             api->SetMoveType( MAknListBoxTfxInternal::EListMoveUp );
       
  1027 	        }
       
  1028 	    else if ( aCursorMovement == CAknGridView::ECursorPreviousColumn )
       
  1029 	        {
       
  1030             api->SetMoveType( MAknListBoxTfxInternal::EListMoveLeft );
       
  1031 	            }
       
  1032 	        else
       
  1033 	            {
       
  1034             api->SetMoveType( MAknListBoxTfxInternal::EListNoMovement );
       
  1035 	            }
       
  1036 	        }
       
  1037     }
       
  1038 #endif //RD_UI_TRANSITION_EFFECTS_LIST
       
  1039 
       
  1040 EXPORT_C void CAknGridView::DoMoveL(TCursorMovement aCursorMovement, TSelectionMode aSelectionMode)
       
  1041 	{
       
  1042 	_AKNTRACE_FUNC_ENTER;
       
  1043 	TInt rowIndex = 0;
       
  1044 	TInt colIndex = 0;
       
  1045 	LogicalPosFromListBoxIndex(iCurrentItemIndex, rowIndex, colIndex);
       
  1046 
       
  1047 	TBool moveDown = IsMoveDown(aCursorMovement);
       
  1048 	TBool moveRight = IsMoveRight(aCursorMovement);
       
  1049 
       
  1050 	TInt newIndex = 0;
       
  1051 	TScrollingType scrollingType = EScrollStops;
       
  1052 	TBool moveIsVert = (aCursorMovement==ECursorNextItem)||(aCursorMovement==ECursorPreviousItem);
       
  1053 	TBool moveInPrim = COMPARE_BOOLS(IsPrimaryVertical(),(moveIsVert));
       
  1054 	if (moveInPrim)
       
  1055 		scrollingType = iScrollingType;
       
  1056 	else
       
  1057 		scrollingType = iScrollInSecondaryDimension;
       
  1058 
       
  1059 	switch(scrollingType)
       
  1060 		{
       
  1061 		case EScrollStops: // drop through
       
  1062 		case EScrollFollowsGrid: // drop through
       
  1063 		case EScrollFollowsItemsAndStops: // drop through
       
  1064 		case EScrollFollowsItemsAndLoops:
       
  1065 			newIndex = SearchByLines(colIndex, rowIndex, aCursorMovement);
       
  1066 			break;
       
  1067 		case EScrollIncrementLineAndStops: // drop through
       
  1068 		case EScrollIncrementLineAndLoops:
       
  1069 			{
       
  1070 			TBool edgePassed = IsEdgePassed(iCurrentItemIndex, moveDown, moveRight, !moveIsVert, EFalse, newIndex);
       
  1071 			if (!moveInPrim && edgePassed && (newIndex >=0))
       
  1072 				{// special scroll
       
  1073 				TBool specialMoveNeeded = EFalse;
       
  1074 				LogicalPosFromListBoxIndex(newIndex, rowIndex, colIndex);
       
  1075 				if (moveIsVert)
       
  1076 					if ((rowIndex != 0) && (rowIndex != iGridDetails.iGridDimensions.iHeight - 1))
       
  1077 						specialMoveNeeded = ETrue;
       
  1078 				else
       
  1079 					if ((colIndex != 0) && (colIndex != iGridDetails.iGridDimensions.iWidth - 1))
       
  1080 						specialMoveNeeded = ETrue;
       
  1081 				if (specialMoveNeeded)
       
  1082 					{// fake being at the far edge of the grid
       
  1083 					if (moveRight)
       
  1084 						colIndex = 0;
       
  1085 					else
       
  1086 						colIndex = iGridDetails.iGridDimensions.iWidth - 1;
       
  1087 
       
  1088 					if (moveDown)
       
  1089 						rowIndex = 0;
       
  1090 					else
       
  1091 						rowIndex = iGridDetails.iGridDimensions.iHeight - 1;
       
  1092 
       
  1093 					TInt newIndex2 = 0; // fake index
       
  1094 					ListBoxIndexFromLogicalPos(newIndex2, rowIndex, colIndex);
       
  1095 					iTopItemIndex = CalcNewTopItemIndexSoItemIsVisible(newIndex2);
       
  1096 					CalcBottomItemIndex();
       
  1097 					iCurrentItemIndex = newIndex; // set current to actual index we want to move to
       
  1098 					iHScrollOffset += CalculateHScrollOffsetSoItemIsVisible(newIndex);
       
  1099 					DrawItemRange(iTopItemIndex, iBottomItemIndex); // draw range for fake index
       
  1100 					if (ItemIsVisible(newIndex))
       
  1101 						return; // moved and drawn
       
  1102 					// need to scroll some more to make the newIndex visable
       
  1103 					}
       
  1104 				}
       
  1105 			}
       
  1106 			break;
       
  1107 		default:
       
  1108 			break;
       
  1109 		}
       
  1110 	
       
  1111 	if (newIndex >=0)
       
  1112 		{ // found next item to move to
       
  1113 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  1114             SetMoveType( iGc, aCursorMovement );
       
  1115 #endif //RD_UI_TRANSITION_EFFECTS_LIST
       
  1116 		MoveToItemIndexL(newIndex, aSelectionMode);
       
  1117 		_AKNTRACE_FUNC_EXIT;
       
  1118 		return;
       
  1119 		}
       
  1120 
       
  1121 	TInt oldRowIndex = rowIndex;
       
  1122 	TInt oldColIndex = colIndex;
       
  1123 	if (moveRight)
       
  1124 		colIndex = 0;
       
  1125 	else
       
  1126 		colIndex = iGridDetails.iGridDimensions.iWidth - 1;
       
  1127 
       
  1128 	if (moveDown)
       
  1129 		rowIndex = 0;
       
  1130 	else
       
  1131 		rowIndex = iGridDetails.iGridDimensions.iHeight - 1;
       
  1132 
       
  1133 	switch(scrollingType)
       
  1134 		{// we are at an edge
       
  1135 		case EScrollStops:
       
  1136 			{
       
  1137 			_AKNTRACE_FUNC_EXIT;
       
  1138 			return; // easy
       
  1139 			}
       
  1140 		case EScrollFollowsGrid:
       
  1141 			newIndex = SearchByLines((moveIsVert ? oldColIndex : colIndex),(moveIsVert ? rowIndex : oldRowIndex), aCursorMovement, ETrue);
       
  1142 			break;
       
  1143 		case EScrollFollowsItemsAndStops:
       
  1144 		case EScrollFollowsItemsAndLoops:
       
  1145 			newIndex = FindNextItem(iCurrentItemIndex, moveDown, moveRight, !IsPrimaryVertical());
       
  1146 			if (moveInPrim)
       
  1147 				{// move in the primary direction of the grid
       
  1148 				if (newIndex >=0)
       
  1149 					{ // found next item to move to
       
  1150 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  1151                         SetMoveType( iGc, aCursorMovement );
       
  1152 #endif //RD_UI_TRANSITION_EFFECTS_LIST
       
  1153 					MoveToItemIndexL(newIndex, aSelectionMode);
       
  1154 					_AKNTRACE_FUNC_EXIT;
       
  1155 					return;
       
  1156 					}
       
  1157 				// did not find anything
       
  1158 				if (iScrollingType == EScrollFollowsItemsAndStops)
       
  1159 					{
       
  1160 					_AKNTRACE_FUNC_EXIT;
       
  1161 					return; // do nothing
       
  1162 					}
       
  1163 
       
  1164 				// then must be EScrollFollowsItemsAndLoops
       
  1165 				ListBoxIndexFromLogicalPos(newIndex, rowIndex, colIndex);
       
  1166 				newIndex = FindNextItem(newIndex, moveDown, moveRight, !moveIsVert, ETrue);
       
  1167 				}
       
  1168 			else
       
  1169 				{// move in scondary
       
  1170 				if (newIndex < 0)
       
  1171 					{ // no more items
       
  1172 					if (iScrollInSecondaryDimension == EScrollFollowsItemsAndStops)
       
  1173 						{
       
  1174 						_AKNTRACE_FUNC_EXIT;
       
  1175 						return;
       
  1176 						}
       
  1177 					//must be EScrollFollowsItemsAndLoops
       
  1178 					}
       
  1179 				else
       
  1180 					{ // some more items before the end
       
  1181 					if (moveIsVert)
       
  1182 						{
       
  1183 						if (moveRight)
       
  1184 							colIndex = oldColIndex + 1;
       
  1185 						else
       
  1186 							colIndex = oldColIndex - 1;
       
  1187 						}
       
  1188 					else
       
  1189 						{
       
  1190 						if (moveDown)
       
  1191 							rowIndex = oldRowIndex + 1;
       
  1192 						else
       
  1193 							rowIndex = oldRowIndex - 1;
       
  1194 						}
       
  1195 					}
       
  1196 				newIndex = SearchByLines(colIndex, rowIndex, aCursorMovement, ETrue);
       
  1197 				}
       
  1198 			break;
       
  1199 		case EScrollIncrementLineAndStops:
       
  1200 			_AKNTRACE_FUNC_EXIT;
       
  1201 			return; // do nothing
       
  1202 		case EScrollIncrementLineAndLoops:
       
  1203 			{
       
  1204 			ListBoxIndexFromLogicalPos(newIndex, rowIndex, colIndex);
       
  1205 			newIndex = FindNextItem(newIndex, moveDown, moveRight, !moveIsVert, ETrue);
       
  1206 			if (!moveInPrim && newIndex >=0)
       
  1207 				{// may need to have a special scroll
       
  1208 				TBool specialMoveNeeded = EFalse;
       
  1209 				LogicalPosFromListBoxIndex(newIndex, rowIndex, colIndex);
       
  1210 				if (moveIsVert)
       
  1211 					if ((rowIndex != 0) && (rowIndex != iGridDetails.iGridDimensions.iHeight - 1))
       
  1212 						specialMoveNeeded = ETrue;
       
  1213 				else
       
  1214 					if ((colIndex != 0) && (colIndex != iGridDetails.iGridDimensions.iWidth - 1))
       
  1215 						specialMoveNeeded = ETrue;
       
  1216 				if (specialMoveNeeded)
       
  1217 					{// first fake being at the far edge of the grid
       
  1218 					if (moveRight)
       
  1219 						colIndex = 0;
       
  1220 					else
       
  1221 						colIndex = iGridDetails.iGridDimensions.iWidth - 1;
       
  1222 
       
  1223 					if (moveDown)
       
  1224 						rowIndex = 0;
       
  1225 					else
       
  1226 						rowIndex = iGridDetails.iGridDimensions.iHeight - 1;
       
  1227 
       
  1228 					TInt newIndex2 = 0; // fake index
       
  1229 					ListBoxIndexFromLogicalPos(newIndex2, rowIndex, colIndex);
       
  1230 					iTopItemIndex = CalcNewTopItemIndexSoItemIsVisible(newIndex2);
       
  1231 					CalcBottomItemIndex();
       
  1232 					iCurrentItemIndex = newIndex; // set current to actual index we want to move to
       
  1233 					iHScrollOffset += CalculateHScrollOffsetSoItemIsVisible(newIndex);
       
  1234 					DrawItemRange(iTopItemIndex, iBottomItemIndex); // draw range for fake index
       
  1235 					if (ItemIsVisible(newIndex))
       
  1236 						{
       
  1237 						_AKNTRACE_FUNC_EXIT;
       
  1238 						return; // moved and drawn
       
  1239 						}
       
  1240 					// need to scroll some more to make the newIndex visable
       
  1241 					}
       
  1242 				}
       
  1243 			}
       
  1244 			break;
       
  1245 		default:
       
  1246 			break; // should never get here
       
  1247 		}
       
  1248 
       
  1249 	if (newIndex >=0)
       
  1250 		{ // found next item to move to
       
  1251 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  1252             SetMoveType( iGc, aCursorMovement );
       
  1253 #endif //RD_UI_TRANSITION_EFFECTS_LIST
       
  1254 		MoveToItemIndexL(newIndex, aSelectionMode);
       
  1255 		}
       
  1256 	_AKNTRACE_FUNC_EXIT;
       
  1257 	}
       
  1258 
       
  1259 /**
       
  1260  * Used with grids which contain empty items
       
  1261  * returns the new listbox index of the next item
       
  1262  * returns -1 if there is nothing to move to.
       
  1263  */
       
  1264 EXPORT_C TInt CAknGridView::SearchByLines(TInt aX, TInt aY, TCursorMovement aCursorMovement, TBool aBeginSearchOnIndex)
       
  1265 	{
       
  1266 	_AKNTRACE_FUNC_ENTER;
       
  1267 	TInt xMax = iGridDetails.iGridDimensions.iWidth;
       
  1268 	TInt yMax = iGridDetails.iGridDimensions.iHeight;
       
  1269 
       
  1270 	TInt xIteration = 0;
       
  1271 	TInt yIteration = 0;
       
  1272 	switch(aCursorMovement)
       
  1273 		{
       
  1274 		case ECursorNextColumn:
       
  1275 				xIteration = 1;
       
  1276 			break;
       
  1277 		case ECursorPreviousColumn:
       
  1278 				xIteration = -1;
       
  1279 			break;
       
  1280 		case ECursorNextItem:
       
  1281 				yIteration = 1;
       
  1282 			break;
       
  1283 		case ECursorPreviousItem:
       
  1284 				yIteration = -1;
       
  1285 			break;
       
  1286 		default:
       
  1287 			break;
       
  1288 		}
       
  1289 	// set up first for a Horizontal grid
       
  1290 	TInt primaryIteration = xIteration;
       
  1291 	TInt secondaryIteration = yIteration;
       
  1292 	TInt primaryMax = xMax;
       
  1293 	TInt secondaryMax = yMax;
       
  1294 	TInt p = aX;
       
  1295 	TInt s = aY;
       
  1296 	// now change variables if it is a Vertical grid
       
  1297 	if (IsPrimaryVertical())
       
  1298 		{
       
  1299 		primaryIteration = yIteration;
       
  1300 		secondaryIteration = xIteration;
       
  1301 		primaryMax = yMax;
       
  1302 		secondaryMax = xMax;
       
  1303 		p = aY;
       
  1304 		s = aX;
       
  1305 		}
       
  1306 
       
  1307 	if (!aBeginSearchOnIndex)
       
  1308 		s += secondaryIteration;
       
  1309 
       
  1310 	TInt index = 0;
       
  1311 	for ( ; (s < secondaryMax) && (s >= 0) ; s += secondaryIteration)
       
  1312 		{
       
  1313 		for (TInt primaryOffset = 0;(p - primaryOffset >= 0) || (p + primaryOffset < primaryMax) ; primaryOffset++)
       
  1314 			{
       
  1315 			TInt x = 0;
       
  1316 			TInt y = 0;
       
  1317 			if (secondaryIteration == 0)
       
  1318 				{// then we are moving in the primary orientation of the grid 
       
  1319 				 // so just find the next item in this direction.
       
  1320 				TInt offSet = (aBeginSearchOnIndex ? primaryOffset : primaryOffset+1);
       
  1321 				x = p + (primaryIteration * (offSet));
       
  1322 				if (x < 0 || x >= primaryMax)
       
  1323 					break;
       
  1324 				y = s;
       
  1325 				if (IsPrimaryVertical())
       
  1326 					{//swap them
       
  1327 					y = x;
       
  1328 					x = s;
       
  1329 					}
       
  1330 				DataIndexFromLogicalPos(index,y,x);
       
  1331 				if (GridModel()->IndexContainsData(index))
       
  1332 					{
       
  1333 					_AKNTRACE_FUNC_EXIT;
       
  1334 					return ListBoxIndex(index);
       
  1335 					}
       
  1336 				}
       
  1337 			else
       
  1338 				{
       
  1339 				TInt newOffset = p+(primaryOffset);
       
  1340 				if ((newOffset >= 0) && (newOffset < primaryMax))
       
  1341 					{
       
  1342 					x = newOffset;
       
  1343 					y = s;
       
  1344 					if (IsPrimaryVertical())
       
  1345 						{
       
  1346 						x = s;
       
  1347 						y = newOffset;
       
  1348 						}
       
  1349 					DataIndexFromLogicalPos(index,y,x);
       
  1350 					if (GridModel()->IndexContainsData(index))
       
  1351 						{
       
  1352 						_AKNTRACE_FUNC_EXIT;
       
  1353 						return ListBoxIndex(index);
       
  1354 						}
       
  1355 					}
       
  1356 				newOffset = p-(primaryOffset);
       
  1357 				if ((newOffset >= 0) && (newOffset < primaryMax))
       
  1358 					{
       
  1359 					x = newOffset;
       
  1360 					y = s;
       
  1361 					if (IsPrimaryVertical())
       
  1362 						{
       
  1363 						x = s;
       
  1364 						y = newOffset;
       
  1365 						}
       
  1366 					DataIndexFromLogicalPos(index,y,x);
       
  1367 					if (GridModel()->IndexContainsData(index))
       
  1368 						{
       
  1369 						_AKNTRACE_FUNC_EXIT;
       
  1370 						return ListBoxIndex(index);
       
  1371 						}
       
  1372 					}
       
  1373 				}
       
  1374 			}
       
  1375 		if (secondaryIteration == 0)
       
  1376 			{// no more items
       
  1377 			_AKNTRACE_FUNC_EXIT;
       
  1378 			return -1;
       
  1379 			}
       
  1380 		}
       
  1381 	_AKNTRACE_FUNC_EXIT;
       
  1382 	// no more items
       
  1383 	return -1;
       
  1384 	}
       
  1385 
       
  1386 EXPORT_C TInt CAknGridView::FindNextItem(TInt aItemIndex, TBool aLookDown, TBool aLookRight, TBool aFirstLookHorizontal, TBool aBeginSearchOnIndex)
       
  1387 	{
       
  1388 	TInt newIndex = 0;
       
  1389 	IsEdgePassed(aItemIndex, aLookDown, aLookRight, aFirstLookHorizontal, aBeginSearchOnIndex, newIndex);
       
  1390 	return newIndex;
       
  1391 	}
       
  1392 
       
  1393 TBool CAknGridView::IsEdgePassed(TInt aItemIndex, TBool aLookDown, TBool aLookRight, TBool aFirstLookHorizontal, TBool aBeginSearchOnIndex, TInt& aNewIndex)
       
  1394 	{
       
  1395 	_AKNTRACE_FUNC_ENTER;
       
  1396 	TInt rowIndex = 0;
       
  1397 	TInt colIndex = 0;
       
  1398 
       
  1399 	LogicalPosFromListBoxIndex(aItemIndex, rowIndex, colIndex);
       
  1400 
       
  1401 	TInt x = 0;
       
  1402 	TInt y = 0;
       
  1403 	TBool edgePassed = EFalse;
       
  1404 
       
  1405 	CAknGridM* gridModel = GridModel();
       
  1406 	TInt newDataIndex = -1;
       
  1407 	if (aFirstLookHorizontal)
       
  1408 		{
       
  1409 		x = (aBeginSearchOnIndex ? colIndex : (aLookRight ? colIndex + 1 : colIndex - 1));
       
  1410 		for (y = rowIndex; (y>=0) && (y < iGridDetails.iGridDimensions.iHeight); y = (aLookDown ? y+1 : y-1))
       
  1411 			{
       
  1412 			for ( ; (x>=0) && (x<iGridDetails.iGridDimensions.iWidth); x = (aLookRight ? x+1 : x-1))
       
  1413 				{
       
  1414 				DataIndexFromLogicalPos(newDataIndex,y,x);
       
  1415 				if (gridModel->IndexContainsData(newDataIndex))
       
  1416 					{
       
  1417 					aNewIndex = ListBoxIndex(newDataIndex);
       
  1418 					_AKNTRACE_FUNC_EXIT;
       
  1419 					return edgePassed;
       
  1420 					}
       
  1421 				}
       
  1422 			edgePassed = ETrue;
       
  1423 			if (aLookRight)
       
  1424 				x = 0;
       
  1425 			else
       
  1426 				x = iGridDetails.iGridDimensions.iWidth - 1;
       
  1427 			}
       
  1428 		}
       
  1429 	else
       
  1430 		{
       
  1431 		y = (aBeginSearchOnIndex ? rowIndex : (aLookDown ? rowIndex + 1 : rowIndex - 1));
       
  1432 		for (x = colIndex; (x>=0) && (x < iGridDetails.iGridDimensions.iWidth); x = (aLookRight ? x+1 : x-1))
       
  1433 			{
       
  1434 			for ( ; (y>=0) && (y<iGridDetails.iGridDimensions.iHeight); y = (aLookDown ? y+1 : y-1))
       
  1435 				{
       
  1436 				DataIndexFromLogicalPos(newDataIndex,y,x);
       
  1437 				if (gridModel->IndexContainsData(newDataIndex))
       
  1438 					{
       
  1439 					aNewIndex = ListBoxIndex(newDataIndex);
       
  1440 					_AKNTRACE_FUNC_EXIT;
       
  1441 					return edgePassed;
       
  1442 					}
       
  1443 				}
       
  1444 			edgePassed = ETrue;
       
  1445 			if (aLookDown)
       
  1446 				y = 0;
       
  1447 			else
       
  1448 				y = iGridDetails.iGridDimensions.iHeight - 1;
       
  1449 			}
       
  1450 		}
       
  1451 
       
  1452 	aNewIndex = -1;
       
  1453 	_AKNTRACE_FUNC_EXIT;
       
  1454 	return edgePassed;
       
  1455 	}
       
  1456 
       
  1457 
       
  1458 TBool CAknGridView::IsMoveRight(TCursorMovement aCursorMovement)
       
  1459 	{
       
  1460 	_AKNTRACE_FUNC_ENTER;
       
  1461 	TBool moveRight = EFalse;
       
  1462 	switch(aCursorMovement)
       
  1463 		{
       
  1464 		case ECursorNextItem:
       
  1465 			moveRight = COMPARE_BOOLS((iGridDetails.iGridFlags & ETopToBottom),(iGridDetails.iGridFlags & ELeftToRight));
       
  1466 			break;
       
  1467 		case ECursorPreviousItem:
       
  1468 			moveRight = !COMPARE_BOOLS((iGridDetails.iGridFlags & ETopToBottom),(iGridDetails.iGridFlags & ELeftToRight));
       
  1469 			break;
       
  1470 		case ECursorNextColumn:
       
  1471 			moveRight = ETrue;
       
  1472 			break;
       
  1473 		case ECursorPreviousColumn:
       
  1474 			moveRight = EFalse;
       
  1475 			break;
       
  1476 		default:
       
  1477 			break;
       
  1478 		}
       
  1479 	_AKNTRACE_FUNC_EXIT;
       
  1480 	return moveRight;
       
  1481 	}
       
  1482 
       
  1483 TBool CAknGridView::IsMoveDown(TCursorMovement aCursorMovement)
       
  1484 	{
       
  1485 	_AKNTRACE_FUNC_ENTER;
       
  1486 	TBool moveDown = EFalse;
       
  1487 	switch(aCursorMovement)
       
  1488 		{
       
  1489 		case ECursorNextItem:
       
  1490 			moveDown = ETrue;
       
  1491 			break;
       
  1492 		case ECursorPreviousItem:
       
  1493 			moveDown = EFalse;
       
  1494 			break;
       
  1495 		case ECursorNextColumn:
       
  1496 			moveDown = COMPARE_BOOLS((iGridDetails.iGridFlags & ETopToBottom),(iGridDetails.iGridFlags & ELeftToRight));
       
  1497 			break;
       
  1498 		case ECursorPreviousColumn:
       
  1499 			moveDown = !COMPARE_BOOLS((iGridDetails.iGridFlags & ETopToBottom),(iGridDetails.iGridFlags & ELeftToRight));
       
  1500 			break;
       
  1501 		default:
       
  1502 			break;
       
  1503 		}
       
  1504 	_AKNTRACE_FUNC_EXIT;
       
  1505 	return moveDown;
       
  1506 	}
       
  1507 
       
  1508 
       
  1509 /**
       
  1510  * Overloaded MoveCursorL method to process cursor movement according to
       
  1511  * orientation of the grid.
       
  1512  */
       
  1513 EXPORT_C void CAknGridView::MoveCursorL(TCursorMovement aCursorMovement, TSelectionMode aSelectionMode)
       
  1514 	{ 
       
  1515 	_AKNTRACE_FUNC_ENTER;
       
  1516 	// This is driving method for all movement around the grid
       
  1517 
       
  1518 	// check that actually some data in the grid
       
  1519 	if (GridModel()->NumberOfData() == 0)
       
  1520 		{
       
  1521 		_AKNTRACE_FUNC_EXIT;
       
  1522 		return;
       
  1523 		}
       
  1524 
       
  1525 #if defined(_DEBUG)
       
  1526 	switch (aCursorMovement)
       
  1527 		{
       
  1528 		// page movements
       
  1529 		case ECursorFirstItem: // go back first index
       
  1530 			MoveToItemIndexL(0, aSelectionMode);
       
  1531 			_AKNTRACE_FUNC_EXIT;
       
  1532 			return;
       
  1533 		case ECursorLastItem: // go to last index
       
  1534 			MoveToItemIndexL(GridModel()->IndexOfLastDataItem(), aSelectionMode);
       
  1535 			_AKNTRACE_FUNC_EXIT;
       
  1536 			return;
       
  1537 		case ECursorNextPage: 
       
  1538 			MoveToItemIndexL((iCurrentItemIndex+iGridDetails.iPageSize < GridModel()->NumberOfData() ? iCurrentItemIndex+iGridDetails.iPageSize : GridModel()->NumberOfData() - 1), aSelectionMode);
       
  1539 			_AKNTRACE_FUNC_EXIT;
       
  1540 			return;
       
  1541 		case ECursorPreviousPage: 
       
  1542 			MoveToItemIndexL((iCurrentItemIndex-iGridDetails.iPageSize >= 0 ? iCurrentItemIndex-iGridDetails.iPageSize : 0 ), aSelectionMode);
       
  1543 			_AKNTRACE_FUNC_EXIT;
       
  1544 			return;
       
  1545 		default: 
       
  1546 			break;
       
  1547 		}
       
  1548 #endif
       
  1549 	// perform movement required
       
  1550 	DoMoveL(aCursorMovement, aSelectionMode);
       
  1551 	_AKNTRACE_FUNC_EXIT;
       
  1552 	}
       
  1553 
       
  1554 /**
       
  1555  * Sets the width of the grid column. This should only be called via
       
  1556  * the selection box class's SetColumnWidth method.
       
  1557  */
       
  1558 EXPORT_C void CAknGridView::SetColumnWidth(TInt aColumnWidth)
       
  1559 	{
       
  1560 	__ASSERT_ALWAYS((aColumnWidth > 0), Panic(EAknPanicGridViewInvalidItemWidth));
       
  1561 
       
  1562 	_AKNTRACE( " [%s] aColumnWidth = %d", 
       
  1563 			   __FUNCTION__, aColumnWidth );
       
  1564 	iGridDetails.iSizeOfItems.iWidth = aColumnWidth;
       
  1565 
       
  1566 	iItemDrawer->SetItemCellSize(ItemSize());
       
  1567 	}
       
  1568 
       
  1569 /////////////////////////////////////////////////
       
  1570 //////////////////////////////////////////////////
       
  1571 
       
  1572 EXPORT_C void CAknGridView::SetTopItemIndex(TInt aNewTopItemIndex)
       
  1573 	{
       
  1574 	_AKNTRACE( "[%s] aNewTopItemIndex = %d", 
       
  1575 			   __FUNCTION__, aNewTopItemIndex );
       
  1576 	if (iViewRect.Height() == 0)
       
  1577 		return;
       
  1578 	CListBoxView::SetTopItemIndex(aNewTopItemIndex);
       
  1579 	UpdateHScrollOffsetBasedOnTopItemIndex();
       
  1580 	}
       
  1581 
       
  1582 EXPORT_C void CAknGridView::SetItemHeight(TInt aItemHeight)
       
  1583 	{
       
  1584 	_AKNTRACE( "[%s] aItemHeight = %d", 
       
  1585 			   __FUNCTION__, aItemHeight );
       
  1586 	CListBoxView::SetItemHeight(aItemHeight);
       
  1587 	iGridDetails.iSizeOfItems.iHeight = aItemHeight;
       
  1588 	CalcBottomItemIndex();
       
  1589 	UpdateHScrollOffsetBasedOnTopItemIndex();
       
  1590 	}
       
  1591 
       
  1592 
       
  1593 // ---------------------------------------------------------------------------
       
  1594 // Returns ETrue and sets aItemIndex to the index of the item whose
       
  1595 // bounding box contains aPosition, or EFalse if no such item exists. 
       
  1596 // ---------------------------------------------------------------------------
       
  1597 //
       
  1598 EXPORT_C TBool CAknGridView::XYPosToItemIndex( TPoint aPosition,
       
  1599                                                TInt& aItemIndex ) const
       
  1600 	{
       
  1601 	_AKNTRACE_FUNC_ENTER;
       
  1602 	TBool itemFound = EFalse;
       
  1603 
       
  1604 	if ( ColumnWidth() == 0 || iItemHeight == 0 )
       
  1605 	    {
       
  1606 		return EFalse;
       
  1607 	    }
       
  1608 
       
  1609 	if ( iViewRect.Contains( aPosition ) )
       
  1610 		{
       
  1611 		// aPosition is inside the display area
       
  1612 		TInt yOffsetFromViewRectOrigin = aPosition.iY - iViewRect.iTl.iY - iVerticalOffset;
       
  1613 		TInt xOffsetFromViewRectOrigin = aPosition.iX - iViewRect.iTl.iX;
       
  1614 		TInt xItemPlusGap = ColumnWidth() + iGridDetails.iSizeBetweenItems.iWidth;
       
  1615 		TInt yItemPlusGap = iItemHeight + iGridDetails.iSizeBetweenItems.iHeight;
       
  1616 		TInt colIndex = xOffsetFromViewRectOrigin / xItemPlusGap;
       
  1617 		TInt rowIndex = yOffsetFromViewRectOrigin / yItemPlusGap;
       
  1618 		TInt numberOfRowsInView = NumberOfRowsInView();
       
  1619 		
       
  1620 		if ( yOffsetFromViewRectOrigin < 0 )
       
  1621 		    {
       
  1622 		    rowIndex = -1;
       
  1623 		    }
       
  1624 		else if ( yOffsetFromViewRectOrigin > iViewRect.Height() )
       
  1625 		    {
       
  1626             // Ensure it will not go out of boundary...
       
  1627 		    rowIndex = Min( rowIndex, numberOfRowsInView);
       
  1628 		    }
       
  1629 		
       
  1630         // If column or row is bigger than there are in view,
       
  1631         // then item is not found.
       
  1632         if ( colIndex >= NumberOfColsInView() ||
       
  1633              rowIndex > numberOfRowsInView ||
       
  1634              colIndex < 0 ||
       
  1635              rowIndex < -1 )
       
  1636             {
       
  1637             itemFound = EFalse;
       
  1638             }
       
  1639         else
       
  1640             {
       
  1641             // Need to take into account the gaps.
       
  1642             TInt yItemOffset = yOffsetFromViewRectOrigin % yItemPlusGap;
       
  1643             TInt xItemOffset = xOffsetFromViewRectOrigin % xItemPlusGap;
       
  1644             if ( yItemOffset > iItemHeight || xItemOffset > ColumnWidth() )
       
  1645                 {
       
  1646                 _AKNTRACE_FUNC_EXIT;
       
  1647                 return EFalse;
       
  1648                 }
       
  1649 
       
  1650             // Now work out the item index given that we know which
       
  1651             // row and column it is in.
       
  1652             TInt itemIndex;
       
  1653             CalcItemIndexFromRowAndColIndexes( itemIndex,
       
  1654                                                rowIndex,
       
  1655                                                colIndex );
       
  1656 
       
  1657             // Error correction that becomes tapping partially
       
  1658             // filled colour selection grid.
       
  1659             if ( ItemExists( itemIndex ) &&
       
  1660                  GridModel()->IndexContainsData( ActualDataIndex( itemIndex ) ) )
       
  1661                 {
       
  1662                 aItemIndex = itemIndex;
       
  1663                 itemFound = ETrue;
       
  1664                 }
       
  1665             }
       
  1666         }
       
  1667 
       
  1668 	_AKNTRACE_FUNC_EXIT;
       
  1669     return itemFound;
       
  1670     }
       
  1671 
       
  1672 
       
  1673 EXPORT_C void CAknGridView::CalcDataWidth() 
       
  1674 	{
       
  1675 	iDataWidth = iGridDetails.iGridDimensions.iWidth;
       
  1676 	}
       
  1677 
       
  1678 EXPORT_C TInt CAknGridView::VisibleWidth(const TRect& aRect) const
       
  1679 	{
       
  1680 	return aRect.Width() / ColumnWidth();
       
  1681 	}
       
  1682 
       
  1683 
       
  1684 // ---------------------------------------------------------------------------
       
  1685 // Scrolls the view so that the item with the given index becomes visible
       
  1686 // if it's currently outside of the view rectangle.
       
  1687 // ---------------------------------------------------------------------------
       
  1688 //
       
  1689 EXPORT_C TBool CAknGridView::ScrollToMakeItemVisible( TInt aItemIndex )
       
  1690 	{
       
  1691 	_AKNTRACE_FUNC_ENTER;
       
  1692 	_AKNTRACE( "[%s] aItemIndex = %d", 
       
  1693 			   __FUNCTION__, aItemIndex );
       
  1694 	if ( iViewRect.Height() == 0 || iItemHeight == 0 )
       
  1695 	    {
       
  1696 	    _AKNTRACE_FUNC_EXIT;
       
  1697 	    return EFalse;
       
  1698 	    }
       
  1699 	
       
  1700     const TBool redrawDisabled = RedrawDisabled();
       
  1701     TPoint itemPosition( ItemPos( aItemIndex ) );
       
  1702     TBool itemPartiallyVisible = ItemIsPartiallyVisible( aItemIndex );
       
  1703 
       
  1704     if ( itemPartiallyVisible || ItemIsVisible( aItemIndex ) )
       
  1705         {
       
  1706         _AKNTRACE_FUNC_EXIT;
       
  1707         // Item is already visible, so no scrolling required.
       
  1708         return EFalse;
       
  1709         }
       
  1710     
       
  1711     // Item is partially visible or not visible.
       
  1712 
       
  1713 	HideMatcherCursor();
       
  1714 	TInt amountToScroll = CalculateHScrollOffsetSoItemIsVisible( aItemIndex );
       
  1715 
       
  1716 	if ( amountToScroll == 0 && !itemPartiallyVisible )
       
  1717 	    {
       
  1718 	    _AKNTRACE_FUNC_EXIT;
       
  1719 		return EFalse;
       
  1720 	    }
       
  1721 
       
  1722 	iHScrollOffset += amountToScroll;
       
  1723 	TBool gridVertical = IsPrimaryVertical();
       
  1724 
       
  1725 	// assume horizontal
       
  1726 	TInt numOfLinesInViewOrientated = gridVertical ? NumberOfColsInView() :
       
  1727                                                      NumberOfRowsInView();
       
  1728 	TInt numOfLinesInViewOrthogonal = gridVertical ? NumberOfRowsInView() :
       
  1729                                                      NumberOfColsInView();
       
  1730 
       
  1731 	if ( Abs( amountToScroll ) >= numOfLinesInViewOrientated )
       
  1732 		{ // Entire view content is changed, so don't bother scrolling.
       
  1733 		iTopItemIndex += numOfLinesInViewOrthogonal * amountToScroll;
       
  1734 		CalcBottomItemIndex();
       
  1735 		iCurrentItemIndex = aItemIndex;
       
  1736 		iVerticalOffset = 0;
       
  1737 		
       
  1738 		if ( !redrawDisabled )
       
  1739 		    {
       
  1740 		    Draw();
       
  1741 		    DrawMatcherCursor();
       
  1742 		    }
       
  1743 
       
  1744 		_AKNTRACE_FUNC_EXIT;
       
  1745 		return ETrue;
       
  1746 		}
       
  1747 
       
  1748 	iCurrentItemIndex = aItemIndex;
       
  1749 	
       
  1750 	if ( iExtension && !iExtension->iScrollingDisabled )
       
  1751 	    {
       
  1752         CFormattedCellListBoxItemDrawer* itemDrawer =
       
  1753             static_cast<CFormattedCellListBoxItemDrawer*>( iItemDrawer );
       
  1754         CEikListBox* listBox =
       
  1755             static_cast<CEikListBox*>(
       
  1756                 itemDrawer->FormattedCellData()->Control() );
       
  1757         TRAP_IGNORE( listBox->HandlePhysicsScrollEventL(
       
  1758                          amountToScroll * iItemHeight + ItemOffsetInPixels() ) );
       
  1759 	    }
       
  1760     else
       
  1761         {
       
  1762         // Do normal scrolling if physics are not enabled.
       
  1763         VScrollTo( CalcNewTopItemIndexSoItemIsVisible( aItemIndex ) );
       
  1764         }
       
  1765 	
       
  1766 	_AKNTRACE_FUNC_EXIT;
       
  1767 	return ETrue;
       
  1768 	}
       
  1769 
       
  1770 
       
  1771 //////////////////////////////////////////////////
       
  1772 EXPORT_C TInt CAknGridView::CalculateHScrollOffsetSoItemIsVisible(TInt aItemIndex) 
       
  1773 	{
       
  1774 	_AKNTRACE_FUNC_ENTER;
       
  1775 	_AKNTRACE( "[%s] aItemIndex = %d", 
       
  1776 			   __FUNCTION__, aItemIndex );
       
  1777 	// returns the number of cols or rows that we need to scroll, 0 if no scrolling is needed
       
  1778 	TInt newTopItemIndex = CalcNewTopItemIndexSoItemIsVisible(aItemIndex);
       
  1779 	TInt numToScroll = 0;
       
  1780 	if (IsPrimaryVertical())
       
  1781 		{
       
  1782 		TInt numOfRowsInView = NumberOfRowsInView();
       
  1783 		TInt oldHScrollOffset = iHScrollOffset;
       
  1784 		TInt newHScrollOffset = newTopItemIndex / numOfRowsInView;
       
  1785 		numToScroll = newHScrollOffset - oldHScrollOffset;
       
  1786 		}
       
  1787 	else
       
  1788 		{
       
  1789 		TInt logicalRow = 0;
       
  1790 		TInt logicalCol = 0;
       
  1791 		LogicalPosFromListBoxIndex(iTopItemIndex, logicalRow, logicalCol);
       
  1792 		TInt oldHScrollOffset = logicalRow;
       
  1793 		LogicalPosFromListBoxIndex(newTopItemIndex, logicalRow, logicalCol);
       
  1794 		TInt newHScrollOffset = logicalRow;
       
  1795 		numToScroll = newHScrollOffset - oldHScrollOffset;
       
  1796 		}
       
  1797 	_AKNTRACE_FUNC_EXIT;
       
  1798 	return numToScroll;
       
  1799 	}
       
  1800 
       
  1801 EXPORT_C TSize CAknGridView::ItemSize(TInt /*aItemIndex*/) const
       
  1802 	{
       
  1803 	return TSize(ColumnWidth(), iItemHeight);
       
  1804 	}
       
  1805 
       
  1806 
       
  1807 EXPORT_C void CAknGridView::CalcRowAndColIndexesFromItemIndex( TInt aItemIndex,
       
  1808                                                                TInt& aRowIndex,
       
  1809                                                                TInt& aColIndex ) const
       
  1810 	{
       
  1811 	_AKNTRACE_FUNC_ENTER;
       
  1812 	_AKNTRACE( "[%s] aItemIndex = %d aRowIndex = %d aColIndex = %d", 
       
  1813 			   __FUNCTION__, aItemIndex, aRowIndex, aColIndex );
       
  1814 	// Should panic if iItemHeight or iViewRect.Height() is 0.
       
  1815 	// Assumes specified item is currently visible.
       
  1816 	TInt numOfItemsFromFirstVisibleItem = (aItemIndex - iTopItemIndex);
       
  1817 
       
  1818 	if ( IsPrimaryVertical() )
       
  1819 		{
       
  1820 		TInt numOfRowsInView = NumberOfRowsInView();
       
  1821 		aColIndex = numOfItemsFromFirstVisibleItem / numOfRowsInView;
       
  1822 		aRowIndex = numOfItemsFromFirstVisibleItem % numOfRowsInView;
       
  1823 		}
       
  1824 	else
       
  1825 		{
       
  1826 		TInt numOfColsInView = NumberOfColsInView();
       
  1827 
       
  1828 		if ( numOfItemsFromFirstVisibleItem < 0 )
       
  1829             {
       
  1830             // This is possible the visible topmost row is partially drawn
       
  1831             // and iTopItemIndex has already moved to the next row.
       
  1832             // So this handling is required for the top row to be drawn
       
  1833             // correctly.
       
  1834             aColIndex = ( numOfItemsFromFirstVisibleItem + numOfColsInView ) % numOfColsInView;
       
  1835             aRowIndex = -1;
       
  1836             }
       
  1837 		else
       
  1838 		    {
       
  1839             aColIndex = numOfItemsFromFirstVisibleItem % numOfColsInView;
       
  1840             aRowIndex = numOfItemsFromFirstVisibleItem / numOfColsInView;
       
  1841 		    }
       
  1842 		}
       
  1843 	_AKNTRACE_FUNC_EXIT;
       
  1844 	}
       
  1845 
       
  1846 
       
  1847 // ---------------------------------------------------------------------------
       
  1848 // Calculates the item index that is on the given row and column indices.
       
  1849 // ---------------------------------------------------------------------------
       
  1850 //
       
  1851 EXPORT_C void CAknGridView::CalcItemIndexFromRowAndColIndexes( TInt& aItemIndex,
       
  1852                                                                TInt aRowIndex,
       
  1853                                                                TInt aColIndex ) const
       
  1854 	{
       
  1855 	_AKNTRACE_FUNC_ENTER;
       
  1856 	_AKNTRACE( "[%s] aItemIndex = %d aRowIndex = %d aColIndex = %d", 
       
  1857 			   __FUNCTION__, aItemIndex, aRowIndex, aColIndex );
       
  1858 	// Row index can be -1 if the row above top item index is partially
       
  1859 	// visible.
       
  1860 	__ASSERT_DEBUG( aRowIndex >= -1, Panic( EAknPanicGridViewInvalidRowIndex ) );
       
  1861 	__ASSERT_DEBUG( aColIndex >= 0, Panic( EAknPanicGridViewInvalidColumnIndex ) );
       
  1862 
       
  1863 	// Should panic if iItemHeight is 0.
       
  1864 	if ( IsPrimaryVertical() )
       
  1865 		{
       
  1866 		TInt numOfRowsInView = NumberOfRowsInView();
       
  1867 		aItemIndex = iTopItemIndex + ((aColIndex * numOfRowsInView) + aRowIndex); 
       
  1868 		}
       
  1869 	else
       
  1870 		{
       
  1871 		TInt numOfColsInView = NumberOfColsInView();
       
  1872 		aItemIndex = iTopItemIndex + ((aRowIndex * numOfColsInView) + aColIndex); 
       
  1873 		}
       
  1874 	_AKNTRACE_FUNC_EXIT;
       
  1875 	}
       
  1876 
       
  1877 
       
  1878 EXPORT_C void CAknGridView::DrawMatcherCursor()
       
  1879 	{
       
  1880 	}
       
  1881 
       
  1882 // ---------------------------------------------------------------------------
       
  1883 // Returns the item index of the currently highlighted item.
       
  1884 // ---------------------------------------------------------------------------
       
  1885 //
       
  1886 EXPORT_C TInt CAknGridView::CurrentItemIndex() const
       
  1887 	{
       
  1888 	if ( ItemExists( iCurrentItemIndex ) )
       
  1889 	    {
       
  1890 		return iCurrentItemIndex;
       
  1891 	    }
       
  1892 	else
       
  1893 	    {
       
  1894 	    // Means there is no current item.
       
  1895 		return KErrNotFound;
       
  1896 	    }
       
  1897 	}
       
  1898 	
       
  1899 ////////////////////////////////// protect
       
  1900 
       
  1901 // ---------------------------------------------------------------------------
       
  1902 // Draws a range of columns.
       
  1903 // ---------------------------------------------------------------------------
       
  1904 //
       
  1905 EXPORT_C void CAknGridView::DrawColumnRange( TInt aStartColIndex,
       
  1906                                              TInt aEndColIndex ) const
       
  1907 	{
       
  1908 	_AKNTRACE_FUNC_ENTER;
       
  1909 	if ( !RedrawDisabled() && iItemHeight > 0 )
       
  1910 	    {
       
  1911         TInt numOfRowsInView = NumberOfRowsInView();
       
  1912         TInt startItemIndex = aStartColIndex * numOfRowsInView;
       
  1913         TInt endItemIndex = aEndColIndex * numOfRowsInView + numOfRowsInView - 1;
       
  1914         DrawItemRange( startItemIndex, endItemIndex );
       
  1915 	    }
       
  1916 	_AKNTRACE_FUNC_EXIT;
       
  1917 	}
       
  1918 
       
  1919 
       
  1920 EXPORT_C void CAknGridView::ClearUnusedItemSpace(TInt aStartItemIndex, TInt aEndItemIndex) const
       
  1921 	{
       
  1922 	_AKNTRACE_FUNC_ENTER;
       
  1923 	TRect blankRect;
       
  1924 	for (TInt i = aStartItemIndex; i <= aEndItemIndex; i++)
       
  1925 		{
       
  1926 		blankRect.SetRect(ItemPos(i), ItemSize());
       
  1927 		blankRect.Intersection(iViewRect);
       
  1928 
       
  1929 		MAknsSkinInstance *skin = AknsUtils::SkinInstance();
       
  1930 		CFormattedCellListBoxItemDrawer *id = (CFormattedCellListBoxItemDrawer*)ItemDrawer();
       
  1931 		if (id->FormattedCellData()->Control())
       
  1932 			{
       
  1933 			MAknsControlContext *cc = AknsDrawUtils::ControlContext( id->FormattedCellData()->Control() );
       
  1934 			if ( !cc )
       
  1935 			    {
       
  1936 			    cc = id->FormattedCellData()->SkinBackgroundContext();
       
  1937 			    }
       
  1938 			AknsDrawUtils::Background( skin, cc, id->FormattedCellData()->Control(), *iGc, blankRect );
       
  1939 			}
       
  1940 		else
       
  1941 			{
       
  1942 			iGc->Clear(blankRect);
       
  1943 			}
       
  1944 		}
       
  1945 	_AKNTRACE_FUNC_EXIT;
       
  1946 	}
       
  1947 
       
  1948 EXPORT_C void CAknGridView::UpdateHScrollOffsetBasedOnTopItemIndex()
       
  1949 	{
       
  1950 	TInt numOfRowsInView = iGridDetails.iRowsInView;
       
  1951 	if (numOfRowsInView > 0)
       
  1952 		iHScrollOffset = iTopItemIndex / numOfRowsInView;
       
  1953 	}
       
  1954 
       
  1955 
       
  1956 EXPORT_C TAny* CAknGridView::Reserved_1()
       
  1957 	{
       
  1958 	return NULL;
       
  1959 	}
       
  1960 
       
  1961 
       
  1962 // ---------------------------------------------------------------------------
       
  1963 // Draws the part of the view rectangle in which no items are drawn.  
       
  1964 // ---------------------------------------------------------------------------
       
  1965 //
       
  1966 void CAknGridView::DrawUnusedViewPortion() const
       
  1967     {
       
  1968     _AKNTRACE_FUNC_ENTER;
       
  1969     TInt gapWidth = iGridDetails.iSizeBetweenItems.iWidth;
       
  1970     TInt numberOfCols  = iGridDetails.iColsInView;
       
  1971     TInt usedViewRectPortionWidth = 
       
  1972                 numberOfCols * ( ColumnWidth() + gapWidth ) - gapWidth;
       
  1973     TRect itemUsedRect;
       
  1974     //if the gapWidth > 0, the entire background should be drawn.
       
  1975     //So use default value of itemUsedRect (0,0,0,0).
       
  1976     //And vice versa the view rect except items used should 
       
  1977     //draw background 
       
  1978     if ( gapWidth <= 0 )
       
  1979         {
       
  1980         TPoint endPos( CAknGridView::ItemPos( iBottomItemIndex ).iX + ColumnWidth(),
       
  1981         		       CAknGridView::ItemPos( iBottomItemIndex ).iY + iItemHeight );
       
  1982         itemUsedRect.SetRect( CAknGridView::ItemPos(iTopItemIndex), endPos );
       
  1983         if ( iViewRect.Intersects( itemUsedRect ) )
       
  1984             {
       
  1985             TRect viewRect( iViewRect );
       
  1986             viewRect.Intersection( itemUsedRect );
       
  1987             }
       
  1988         }
       
  1989     iGc->SetBrushColor( BackColor() );
       
  1990     CFormattedCellListBoxItemDrawer* itemDrawer =
       
  1991         static_cast<CFormattedCellListBoxItemDrawer*>( iItemDrawer );
       
  1992     MAknsSkinInstance *skin = AknsUtils::SkinInstance();
       
  1993 
       
  1994     CWindowGc* gc = itemDrawer->Gc();
       
  1995     if ( !gc )
       
  1996         {
       
  1997         gc = iGc;
       
  1998         }
       
  1999 
       
  2000     CCoeControl* listBoxControl = itemDrawer->FormattedCellData()->Control();
       
  2001 
       
  2002     if ( listBoxControl )
       
  2003         {
       
  2004         MAknsControlContext *cc = AknsDrawUtils::ControlContext(
       
  2005             listBoxControl );
       
  2006         if ( !cc )
       
  2007             {
       
  2008             cc = itemDrawer->FormattedCellData()->SkinBackgroundContext();
       
  2009             }
       
  2010 
       
  2011         if ( CAknEnv::Static()->TransparencyEnabled() )
       
  2012             {
       
  2013             AknsDrawUtils::BackgroundBetweenRects( 
       
  2014                 skin,
       
  2015                 cc,
       
  2016                 listBoxControl, 
       
  2017                 *iGc,
       
  2018                 iViewRect,
       
  2019                 itemUsedRect, 
       
  2020                 KAknsDrawParamNoClearUnderImage );
       
  2021             }
       
  2022         else
       
  2023             {
       
  2024             AknsDrawUtils::BackgroundBetweenRects(
       
  2025                 skin,
       
  2026                 cc,
       
  2027                 listBoxControl,
       
  2028                 *iGc,
       
  2029                 iViewRect,
       
  2030                 itemUsedRect ); 
       
  2031             }        
       
  2032         }
       
  2033     else
       
  2034         {
       
  2035         DrawUtils::ClearBetweenRects( *gc, iViewRect, itemUsedRect );
       
  2036         }
       
  2037     _AKNTRACE_FUNC_EXIT;
       
  2038     }
       
  2039 
       
  2040 // End of File