uifw/AvKon/src/akngrid.cpp
changeset 0 2f259fa3e83a
child 15 08e69e956a8c
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:  This is a concrete class for the handling of a grid.
       
    15 *                The class handles a rectangular grid arrangement of items
       
    16 *                held in any linear ordering i.e. cells ordered top to
       
    17 *                bottom and left, left to right and down etc.
       
    18 *
       
    19 */
       
    20 
       
    21 
       
    22 #include <AknGrid.h>
       
    23 #include <avkon.hrh>
       
    24 #include <avkon.rsg>
       
    25 
       
    26 #include <barsread.h>
       
    27 
       
    28 #include <AknGridView.h>
       
    29 #include <AknGridM.h>
       
    30 #include <eiklbm.h>
       
    31 #include <eiklbi.h>
       
    32 #include <eiklbx.h>
       
    33 
       
    34 #include <eikenv.h>
       
    35 #include <eiklbx.pan>
       
    36 #include <eikkeys.h>
       
    37 
       
    38 #include <AknsUtils.h>
       
    39 
       
    40 //formatted listbox
       
    41 #include <eikfrlbd.h>
       
    42 #include <eikfrlb.h>
       
    43 
       
    44 #include <AknDef.h>
       
    45 #include <aknlayoutscalable_avkon.cdl.h>
       
    46 #include <AknsControlContext.h>
       
    47 #include "layoutmetadata.cdl.h"
       
    48 #include <aknphysics.h>
       
    49 
       
    50 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
    51     #include <aknlistloadertfx.h>
       
    52     #include <aknlistboxtfxinternal.h>
       
    53 #endif //RD_UI_TRANSITION_EFFECTS_LIST
       
    54 
       
    55 #include <touchfeedback.h>
       
    56 #include "akntrace.h"
       
    57 
       
    58 const TInt KDefaultLineHeightForHorizontalGrid = 10;
       
    59 
       
    60 const TInt KEikListBoxPointerRepeatInterval = 100000;  // 0.1 seconds in micro seconds
       
    61 
       
    62 const TInt KEikListBoxInvalidIndex = -1;
       
    63 
       
    64 enum TGridOrientation
       
    65     {
       
    66     EGridOrientationHorizontal,
       
    67     EGridOrientationVertical
       
    68     };
       
    69 enum TGridHorizontal
       
    70     {
       
    71     EGridHorizontalRightToLeft,
       
    72     EGridHorizontalLeftToRight,
       
    73     EGridHorizontalWritingDirection,
       
    74     EGridHorizontalAntiWritingDirection
       
    75     };
       
    76 enum TGridVertical
       
    77     {
       
    78     EGridVerticalBottomToTop,
       
    79     EGridVerticalTopToBottom
       
    80     };
       
    81 
       
    82 
       
    83 /**
       
    84 * Local Panic Function and Panic Codes 
       
    85 */
       
    86 enum TAknGridPanicCodes
       
    87     {
       
    88     EAknPanicGridGeneralPanic,
       
    89     EAknPanicGridModelAlreadyExists,
       
    90     EAknPanicGridInvalidNumberOfPrimaryItems,
       
    91     EAknPanicGridNoView
       
    92     };
       
    93     
       
    94 
       
    95 enum TAknGridStateFlags
       
    96     {
       
    97     EAknGridStateButton1DownInGrid = 0x01
       
    98     };
       
    99 
       
   100 // ================= Extension class ========================
       
   101 NONSHARABLE_CLASS(CAknGridExtension) : public CBase
       
   102     {
       
   103     public:
       
   104         CAknGridExtension();
       
   105         ~CAknGridExtension();
       
   106     TInt GetScrollingSpeed( TBool aIsOverItem, TInt aItemIndex, CAknGridView& aView, 
       
   107                             const TPoint& aPoint ) const;
       
   108     
       
   109 
       
   110     public: // data 
       
   111         TInt iFlags;
       
   112         // EMMA-7A8B9F.Ugly hack. Prevent MopSupplyObject being invoked 
       
   113         // from CEikListBox::MopGetObject()
       
   114         TBool iIsFromBaseClass;
       
   115         TPoint iLastPoint;
       
   116         TBool iKineticScrolling;
       
   117         TBool iSingleClickEnabled;
       
   118     };
       
   119 
       
   120 CAknGridExtension::CAknGridExtension() 
       
   121     : 
       
   122     iFlags(0), 
       
   123     iIsFromBaseClass( EFalse ),
       
   124     iLastPoint( 0, 0 ), 
       
   125     iKineticScrolling( CAknPhysics::FeatureEnabled() ),
       
   126     iSingleClickEnabled( iAvkonAppUi->IsSingleClickCompatible() )
       
   127     {
       
   128     }
       
   129 
       
   130 CAknGridExtension::~CAknGridExtension()
       
   131     {
       
   132     }
       
   133     
       
   134 TInt CAknGridExtension::GetScrollingSpeed( TBool aIsOverItem, TInt aItemIndex, 
       
   135                                            CAknGridView& aView, const TPoint& aPoint ) const
       
   136     {
       
   137     TInt itemCountInRow = aView.NumberOfColsInView();
       
   138     TInt speed = 0;
       
   139     TInt y = aPoint.iY - iLastPoint.iY;
       
   140     if ( aIsOverItem )
       
   141         {
       
   142         if ( aView.BottomItemIndex() - aItemIndex < itemCountInRow 
       
   143             &&  y> 0 )
       
   144             {
       
   145             speed = 1;
       
   146             }
       
   147         else if ( aItemIndex - aView.TopItemIndex() < itemCountInRow 
       
   148             && y < 0 )
       
   149             {
       
   150             speed = -1;
       
   151             }
       
   152         }
       
   153     else
       
   154         {
       
   155         speed = 0;
       
   156         }
       
   157     return speed;
       
   158     }
       
   159     
       
   160     
       
   161 // ================= CAknGrid class ========================
       
   162 
       
   163 GLDEF_C void Panic(TAknGridPanicCodes aPanic)
       
   164     {
       
   165     _LIT(KPanicCat,"AknGrid");
       
   166     User::Panic(KPanicCat, aPanic);
       
   167     }
       
   168 
       
   169 
       
   170 EXPORT_C CAknGrid::CAknGrid()
       
   171     {
       
   172     }
       
   173 
       
   174 EXPORT_C CAknGrid::~CAknGrid()
       
   175     {
       
   176     delete iExtension;
       
   177     }
       
   178 
       
   179 /**
       
   180 * This function must only be called before ConstructL()
       
   181 */
       
   182 EXPORT_C void CAknGrid::SetModel(CAknGridM* aModel)
       
   183     {
       
   184     __ASSERT_ALWAYS(!iModel, Panic(EAknPanicGridModelAlreadyExists));
       
   185     iModel = aModel;
       
   186     }
       
   187 
       
   188 EXPORT_C void CAknGrid::ConstructL(const CCoeControl* aParent, TInt aFlags)
       
   189     {
       
   190     _AKNTRACE_FUNC_ENTER;
       
   191     if (!iModel)
       
   192         {
       
   193         iModel = new(ELeave) CAknGridM;
       
   194         }
       
   195     
       
   196     GridModel()->ConstructL();
       
   197 
       
   198     CreateItemDrawerL();
       
   199     ItemDrawer()->FormattedCellData()->SetControl(this);
       
   200     CEikListBox::ConstructL(aParent, aFlags);
       
   201     
       
   202     if ( !iExtension )
       
   203         {
       
   204         iExtension = new (ELeave) CAknGridExtension;    
       
   205         }
       
   206 
       
   207     // the default scrolling method is follows items
       
   208     SetPrimaryScrollingType( CAknGridView::EScrollFollowsItemsAndLoops );
       
   209     SetSecondaryScrollingType( CAknGridView::EScrollFollowsItemsAndLoops );
       
   210     _AKNTRACE_FUNC_EXIT;
       
   211     }
       
   212 
       
   213 EXPORT_C void CAknGrid::ConstructFromResourceL(TResourceReader& aReader)
       
   214     {
       
   215     _AKNTRACE_FUNC_ENTER;
       
   216     RestoreCommonListBoxPropertiesL(aReader);        
       
   217     TInt requiredCellCharWidth=aReader.ReadInt16();
       
   218  
       
   219     if (!iModel)
       
   220         iModel = new(ELeave) CAknGridM;
       
   221 
       
   222     TInt items=aReader.ReadInt32();
       
   223     if (!items)
       
   224         {
       
   225         STATIC_CAST(CAknGridM*,iModel)->ConstructL();
       
   226         }
       
   227     else
       
   228         {
       
   229         CDesCArray* desArray=iCoeEnv->ReadDesCArrayResourceL(items);
       
   230         CleanupStack::PushL(desArray);
       
   231 
       
   232         STATIC_CAST(CAknGridM*,iModel)->ConstructL(desArray);
       
   233         CleanupStack::Pop( desArray );
       
   234         }
       
   235  
       
   236     CreateItemDrawerL();
       
   237     iItemDrawer->SetDrawMark(EFalse);
       
   238     ItemDrawer()->FormattedCellData()->SetControl(this);
       
   239     STATIC_CAST(CFormattedCellListBoxItemDrawer*,iItemDrawer)->SetCellWidthInChars(requiredCellCharWidth);
       
   240     CreateViewL();
       
   241 
       
   242     // empty text
       
   243     HBufC* emptyGridText = aReader.ReadHBufCL();
       
   244     if (emptyGridText)
       
   245         {
       
   246         CleanupStack::PushL(emptyGridText);
       
   247         SetEmptyGridTextL(*emptyGridText);
       
   248         CleanupStack::PopAndDestroy( emptyGridText );
       
   249         }
       
   250 
       
   251     TInt gridStyle=aReader.ReadInt32();
       
   252 
       
   253     TResourceReader reader;
       
   254     if (!gridStyle)
       
   255         {
       
   256         iEikonEnv->CreateResourceReaderLC(reader,R_AVKON_GRID_STYLE_DEFAULT);
       
   257         }
       
   258     else
       
   259         {
       
   260         iEikonEnv->CreateResourceReaderLC(reader,gridStyle);
       
   261         }
       
   262 
       
   263     SetLayoutFromResourceL(reader);
       
   264     CleanupStack::PopAndDestroy(); // reader
       
   265     
       
   266     if ( !iExtension )
       
   267         {        
       
   268         iExtension = new (ELeave) CAknGridExtension;  
       
   269         }
       
   270     _AKNTRACE_FUNC_EXIT;
       
   271     }
       
   272 
       
   273 /**
       
   274 * This routine assumes that SetLayoutL has been called to set
       
   275 * up the grid.
       
   276 */
       
   277 EXPORT_C void CAknGrid::SizeChanged()
       
   278     {
       
   279     _AKNTRACE_FUNC_ENTER;
       
   280     TRect clientRect = iBorder.InnerRect(Rect());
       
   281 
       
   282     TInt currentDataIndex = 0;
       
   283     CAknGridView* gridView = GridView();
       
   284 
       
   285     // reset item offset
       
   286     gridView->SetItemOffsetInPixels( 0 );
       
   287 
       
   288     if (iCurrentIsValid) // appshell does not call HandleItemAddition!
       
   289         {                // so this is never called. See CAknAppStyleGrid::SizeChanged()
       
   290         // remember current position
       
   291         currentDataIndex = gridView->CurrentDataIndex();
       
   292         }
       
   293 
       
   294     TRect rect(clientRect);
       
   295     rect.SetRect(rect.iTl.iX + ListBoxMargins().iLeft, rect.iTl.iY + ListBoxMargins().iTop,
       
   296                  rect.iBr.iX - ListBoxMargins().iRight, rect.iBr.iY - ListBoxMargins().iBottom);
       
   297     iView->SetViewRect(rect);
       
   298     _AKNTRACE( "The rect of grid are ( %d, %d ) ( %d, %d )", 
       
   299     		   rect.iTl.iX, rect.iTl.iY, 
       
   300     		   rect.iBr.iX, rect.iBr.iY );
       
   301     TRAPD(err1, HandleViewRectSizeChangeL());
       
   302     if (err1)
       
   303         {
       
   304         if (iSBFrameOwned == ENotOwnedExternally)
       
   305             {
       
   306             delete iSBFrame;
       
   307             iSBFrame = 0;
       
   308             }
       
   309         }
       
   310 
       
   311     // check grid orientated to show current focus (item height
       
   312     // change may have moved the focus to a new page)
       
   313     if (iCurrentIsValid)
       
   314         {
       
   315         gridView->SetCurrentDataIndex(currentDataIndex);
       
   316         }
       
   317 
       
   318     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
   319     TRgb color;
       
   320     
       
   321     TInt error = AknsUtils::GetCachedColor( skin,
       
   322                                             color,
       
   323                                             KAknsIIDQsnTextColors,
       
   324                                             EAknsCIQsnTextColorsCG11 );
       
   325     if (!error)
       
   326         {
       
   327         ItemDrawer()->SetHighlightedTextColor( color );
       
   328         }
       
   329     _AKNTRACE_FUNC_EXIT;
       
   330     }
       
   331 
       
   332 /**
       
   333 * Protected routine used by functions to check/alter the dimensions
       
   334 * of the grid as data items are added or removed or the
       
   335 * size of the items are altered.
       
   336 * This routine assumes that SetLayoutL has been called.
       
   337 * This will not leave if scrollbars have both been turned off.
       
   338 */
       
   339 EXPORT_C void CAknGrid::CalcGridSizeL()
       
   340     {
       
   341     _AKNTRACE_FUNC_ENTER;
       
   342     __TEST_INVARIANT;
       
   343 
       
   344     CAknGridView* gridView = GridView();
       
   345     TSize gridSize = gridView->GridCellDimensions();
       
   346 
       
   347     TInt definedItems = GridModel()->IndexOfLastDataItem() + 1;
       
   348 
       
   349     if (definedItems > 0)
       
   350         {
       
   351         // item height determines iHeight
       
   352         if (iItemHeight < 1)
       
   353             {
       
   354             // item height must exist - so set to default value
       
   355             // for now
       
   356             CEikListBox::SetItemHeightL(KDefaultLineHeightForHorizontalGrid);
       
   357             }
       
   358 
       
   359         if(iOrientationFlags.IsSet(EGridOrientationVertical))
       
   360             {
       
   361             gridSize.iHeight = iNumOfRowsInView;
       
   362             gridSize.iWidth = definedItems / gridSize.iHeight; 
       
   363             if (definedItems % gridSize.iHeight)
       
   364                 gridSize.iWidth++;
       
   365             }
       
   366         else
       
   367             {
       
   368             gridSize.iWidth = iNumOfColsInView;
       
   369             gridSize.iHeight = definedItems / gridSize.iWidth; 
       
   370             if (definedItems % gridSize.iWidth)
       
   371                 gridSize.iHeight++;
       
   372             }
       
   373         }
       
   374     else
       
   375         {
       
   376         //no defined items so grid empty
       
   377         gridSize.iWidth = 1;
       
   378         gridSize.iHeight = 1;
       
   379         if (iOrientationFlags.IsSet(EGridOrientationVertical))
       
   380             gridSize.iHeight = iNumOfRowsInView;
       
   381         else
       
   382             gridSize.iWidth = iNumOfColsInView;
       
   383         }
       
   384     // set number of cells in grid
       
   385     gridView->SetGridCellDimensions(gridSize);
       
   386     _AKNTRACE_FUNC_EXIT;
       
   387     }
       
   388 
       
   389 
       
   390 /**
       
   391 * Creates a formatted list item drawer.
       
   392 */
       
   393 EXPORT_C void CAknGrid::CreateItemDrawerL()
       
   394     {
       
   395     CFormattedCellListBoxData* data=CFormattedCellGridData::NewL();
       
   396     CleanupStack::PushL(data);
       
   397 
       
   398     data->SetControl( this );
       
   399     data->CreatePictographInterfaceL();
       
   400 
       
   401     iItemDrawer=new(ELeave) CFormattedCellListBoxItemDrawer(Model(), iEikonEnv->NormalFont(), data);
       
   402     CleanupStack::Pop( data );
       
   403     }
       
   404 
       
   405 /**
       
   406 * Gives the formatted list item drawer being used by the grid.
       
   407 */
       
   408 EXPORT_C CFormattedCellListBoxItemDrawer* CAknGrid::ItemDrawer() const
       
   409     {
       
   410     return STATIC_CAST(CFormattedCellListBoxItemDrawer*,iItemDrawer);
       
   411     }
       
   412 
       
   413 /**
       
   414 * Informs the grid that the data in the model has altered.
       
   415 * It is assumed that the grid has been initialised by a call to SetLayoutL
       
   416 * before this function is called for the first time.
       
   417 */
       
   418 EXPORT_C void CAknGrid::HandleItemAdditionL()
       
   419     {
       
   420     _AKNTRACE_FUNC_ENTER;
       
   421     __TEST_INVARIANT;
       
   422 
       
   423     if (GridModel()->NumberOfData() <= 0)
       
   424         return;
       
   425 
       
   426     TInt currentDataIndex = 0;
       
   427 
       
   428     CAknGridView* gridView = GridView();
       
   429 
       
   430     if (iCurrentIsValid)
       
   431         {
       
   432         // remember current position
       
   433         currentDataIndex = gridView->CurrentDataIndex();
       
   434         }
       
   435 
       
   436     CalcGridSizeL();
       
   437 
       
   438     CEikListBox::HandleItemAdditionL();
       
   439 
       
   440     // check the current marker is set to the first item in the 
       
   441     // grid if it hasn't been set yet otherwise ensure current marker still
       
   442     // on cell item before new items were added. 
       
   443     if (!iCurrentIsValid)
       
   444         SetStartPositionL(PositionAtIndex(0));
       
   445     else
       
   446         gridView->SetCurrentDataIndex(currentDataIndex);
       
   447 
       
   448     iCurrentIsValid = ETrue;
       
   449 
       
   450     // redraw everything visible since all/most will have been affected
       
   451     DrawNow();
       
   452     UpdateScrollBarsL();
       
   453     _AKNTRACE_FUNC_EXIT;
       
   454     }
       
   455 
       
   456 /**
       
   457 * Informs the  grid that the data in the model has altered.
       
   458 * It is assumed that the grid has been initialised by a call to SetLayoutL
       
   459 * before this function is called for the first time.
       
   460 */
       
   461 EXPORT_C void CAknGrid::HandleItemRemovalL()
       
   462     {
       
   463     _AKNTRACE_FUNC_ENTER;
       
   464     __TEST_INVARIANT;
       
   465 
       
   466     if (!iCurrentIsValid)
       
   467         return;
       
   468 
       
   469     CAknGridView* gridView = GridView();
       
   470 
       
   471     TInt currentDataIndex = gridView->CurrentDataIndex();
       
   472 
       
   473     CalcGridSizeL();
       
   474 
       
   475     CEikListBox::HandleItemRemovalL();
       
   476 
       
   477     // check if need to reposition current index since may have been
       
   478     // on one of those just deleted.
       
   479     CAknGridM* gridModel = GridModel();
       
   480     if (!gridModel->IndexContainsData(currentDataIndex))
       
   481         currentDataIndex = gridModel->IndexOfLastDataItem();
       
   482 
       
   483     gridView->SetCurrentDataIndex(currentDataIndex);
       
   484 
       
   485     // redraw everything visible since all/most will have been affected
       
   486     DrawNow();
       
   487     UpdateScrollBarsL();
       
   488     _AKNTRACE_FUNC_EXIT;
       
   489     }
       
   490 
       
   491 /**
       
   492 * Sets the orientation of the grid, either vertical or horizontal, the
       
   493 * ordering of the data and the size of the primary dimension of the
       
   494 * grid.
       
   495 * Note: The value for the parameter aNumOfItemsInPrimaryOrient must be
       
   496 * greater than zero since this determines the number of items (be it rows
       
   497 * or columns) in the primary orientation of the grid.
       
   498 */
       
   499 EXPORT_C void CAknGrid::SetLayoutL(TBool aVerticalOrientation,
       
   500                                    TBool aLeftToRight,
       
   501                                    TBool aTopToBottom,
       
   502                                    TInt aNumOfItemsInPrimaryOrient,
       
   503                                    TInt aNumOfItemsInSecondaryOrient,
       
   504                                    TSize aSizeOfItems,
       
   505                                    TInt aWidthOfSpaceBetweenItems,
       
   506                                    TInt aHeightOfSpaceBetweenItems)
       
   507     {
       
   508     _AKNTRACE_FUNC_ENTER;
       
   509     TGridOrientation gridOrientation = EGridOrientationHorizontal;
       
   510     if (aVerticalOrientation)
       
   511         gridOrientation = EGridOrientationVertical;
       
   512 
       
   513     TGridHorizontal gridHorizontal = EGridHorizontalWritingDirection;
       
   514     if (aLeftToRight)
       
   515         gridHorizontal = EGridHorizontalLeftToRight;
       
   516     else
       
   517         gridHorizontal = EGridHorizontalRightToLeft;
       
   518 
       
   519     TGridVertical gridVertical = EGridVerticalBottomToTop;
       
   520     if (aTopToBottom)
       
   521         gridVertical = EGridVerticalTopToBottom;
       
   522     
       
   523     DoSetLayoutL(gridOrientation,
       
   524                  gridHorizontal,
       
   525                  gridVertical,
       
   526                  aNumOfItemsInPrimaryOrient,
       
   527                  aNumOfItemsInSecondaryOrient,
       
   528                  aSizeOfItems,
       
   529                  aWidthOfSpaceBetweenItems,
       
   530                  aHeightOfSpaceBetweenItems);
       
   531     _AKNTRACE_FUNC_EXIT;
       
   532 
       
   533     }
       
   534 
       
   535 void CAknGrid::DoSetLayoutL(TInt aOrientation,
       
   536                             TInt aHorizontal,
       
   537                             TInt aVertical,
       
   538                             TInt aNumOfItemsInPrimaryOrient,
       
   539                             TInt aNumOfItemsInSecondaryOrient,
       
   540                             TSize aSizeOfItems,
       
   541                             TInt aWidthOfSpaceBetweenItems,
       
   542                             TInt aHeightOfSpaceBetweenItems)
       
   543     {
       
   544     _AKNTRACE_FUNC_ENTER;
       
   545     // this must be the first method called after the construction of
       
   546     // the grid
       
   547     __TEST_INVARIANT;
       
   548 
       
   549     // number of primary items must be > 0
       
   550     __ASSERT_ALWAYS((aNumOfItemsInPrimaryOrient > 0), Panic(EAknPanicGridInvalidNumberOfPrimaryItems));
       
   551 
       
   552     // store number of items in primary in case of SizeChange
       
   553     // never used iNumOfItemsInPrimaryOrient = aNumOfItemsInPrimaryOrient;
       
   554 
       
   555     iSpaceBetweenItems.iWidth = aWidthOfSpaceBetweenItems;
       
   556     iSpaceBetweenItems.iHeight = aHeightOfSpaceBetweenItems;
       
   557 
       
   558     iOrientationFlags.ClearAll(); 
       
   559     iHorizontalFlags.ClearAll();
       
   560     iVerticalFlags.ClearAll();
       
   561     TInt gridFlags = 0;
       
   562 
       
   563     switch(aOrientation)
       
   564         {
       
   565         case EGridOrientationHorizontal:
       
   566             iOrientationFlags.Set(EGridOrientationHorizontal);
       
   567             iNumOfRowsInView = aNumOfItemsInSecondaryOrient;
       
   568             iNumOfColsInView = aNumOfItemsInPrimaryOrient;
       
   569             break;
       
   570         case EGridOrientationVertical: // drop through to default
       
   571         default: // use default to keep BC with old code
       
   572             iOrientationFlags.Set(EGridOrientationVertical);
       
   573             gridFlags |= CAknGridView::EPrimaryIsVertical;
       
   574             iNumOfRowsInView = aNumOfItemsInPrimaryOrient;
       
   575             iNumOfColsInView = aNumOfItemsInSecondaryOrient;
       
   576             break;
       
   577         }
       
   578 
       
   579     switch(aHorizontal)
       
   580         {
       
   581         case EGridHorizontalRightToLeft:      // drop through
       
   582         case EGridHorizontalLeftToRight:      // drop through
       
   583         case EGridHorizontalWritingDirection: // drop through
       
   584         case EGridHorizontalAntiWritingDirection:
       
   585             iHorizontalFlags.Set(aHorizontal);
       
   586             break;
       
   587         default: // use default to keep BC with old code
       
   588             iHorizontalFlags.Set(EGridHorizontalWritingDirection);
       
   589             break;
       
   590         }
       
   591 
       
   592     TBool isMirrored = AknLayoutUtils::LayoutMirrored();
       
   593     if (isMirrored)
       
   594         {
       
   595         if (iHorizontalFlags.IsSet(EGridHorizontalAntiWritingDirection)
       
   596             || iHorizontalFlags.IsSet(EGridHorizontalLeftToRight))
       
   597             gridFlags |= CAknGridView::ELeftToRight;
       
   598         }
       
   599     else
       
   600         {
       
   601         if (iHorizontalFlags.IsSet(EGridHorizontalWritingDirection)
       
   602             || iHorizontalFlags.IsSet(EGridHorizontalLeftToRight))
       
   603             gridFlags |= CAknGridView::ELeftToRight;
       
   604         }
       
   605 
       
   606     switch(aVertical)
       
   607         {
       
   608         case EGridVerticalBottomToTop:
       
   609             iVerticalFlags.Set(EGridVerticalBottomToTop);
       
   610             break;
       
   611         case EGridVerticalTopToBottom: // drop through to default
       
   612         default: // use default to keep BC with old code
       
   613             iVerticalFlags.Set(EGridVerticalTopToBottom);
       
   614             gridFlags |= CAknGridView::ETopToBottom;
       
   615             break;
       
   616         }
       
   617         
       
   618     CAknGridView* gridView = GridView();
       
   619 
       
   620     gridView->SetSpacesBetweenItems(iSpaceBetweenItems);
       
   621     CAknGridView::SGrid gridDetails;
       
   622     // define a single cell grid size to start with - the grid will only become
       
   623     // real after we've added some data and called HandleItemAdditionL. Because
       
   624     // this method is being called when dynamic layout switch is handled we
       
   625     // cannot set gridDetails.iGridDimensions = TSize(1,1). Instead, we use the
       
   626     // grid view's value -> a fully populated grid no longer loses its
       
   627     // dimension information. Default value TSize(1,1) is now set in grid
       
   628     // view's constructor.
       
   629     gridDetails.iGridDimensions = gridView->GridCellDimensions();
       
   630     gridDetails.iGridFlags = gridFlags;
       
   631     gridDetails.iPageSize = iNumOfColsInView*iNumOfRowsInView;
       
   632     gridDetails.iColsInView = iNumOfColsInView;
       
   633     gridDetails.iRowsInView = iNumOfRowsInView;
       
   634     gridDetails.iSizeBetweenItems = iSpaceBetweenItems;
       
   635     gridDetails.iSizeOfItems = aSizeOfItems;
       
   636     CalcGridSizeL();
       
   637     gridView->SetGridDetails(gridDetails);
       
   638 
       
   639     gridView->SetColumnWidth(aSizeOfItems.iWidth);
       
   640     SetItemHeightL(aSizeOfItems.iHeight);
       
   641     SetItemsInSingleLine(gridDetails.iColsInView);
       
   642 
       
   643     // Create the scroll bars
       
   644     _AKNTRACE( "Create scroll bar" );
       
   645     CreateScrollBarFrameL(ETrue, EFalse, ETrue);
       
   646     ScrollBarFrame()->SetScrollBarVisibilityL(CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto);
       
   647     UpdateScrollBarsL();
       
   648     _AKNTRACE_FUNC_EXIT;
       
   649     }
       
   650     
       
   651 EXPORT_C void CAknGrid::HandlePointerEventL(const TPointerEvent& aPointerEvent) 
       
   652     {     
       
   653     _AKNTRACE_FUNC_ENTER;
       
   654     if ( AknLayoutUtils::PenEnabled() ) 
       
   655         {
       
   656         // Scroll bar
       
   657         // Do not use iSBFrame->VerticalScrollBar()->Rect() to test, 
       
   658         // because of iSBFrame->VerticalScrollBar owning window.
       
   659         if( iSBFrame && TRect(iSBFrame->VerticalScrollBar()->Position(), 
       
   660             iSBFrame->VerticalScrollBar()->Size()).Contains ( aPointerEvent.iPosition ))
       
   661             {
       
   662             if ( !ScrollingDisabled()
       
   663                 && iExtension->iFlags & EAknGridStateButton1DownInGrid )
       
   664                 {
       
   665                 if ( aPointerEvent.iType == TPointerEvent::EButton1Up )
       
   666                     {
       
   667                     iExtension->iFlags &= ~EAknGridStateButton1DownInGrid;
       
   668                     }
       
   669                 CEikListBox::HandlePointerEventL( aPointerEvent );
       
   670                 }
       
   671             else
       
   672                 {
       
   673                 CCoeControl::HandlePointerEventL( aPointerEvent );
       
   674                 }
       
   675             return;
       
   676             }
       
   677         else
       
   678             {
       
   679             CAknGridView* gridView = GridView();
       
   680             TInt itemIndex = 0;
       
   681             
       
   682             TRect visibleItemsRect(gridView->ViewRect().iTl, 
       
   683                 TSize(gridView->ItemSize(itemIndex).iWidth * iNumOfColsInView, 
       
   684                 gridView->ItemSize(itemIndex).iHeight * iNumOfRowsInView));
       
   685         
       
   686         // switch pointer event type and set button 1 down in grid flag on and off depending where event happened.
       
   687             switch (aPointerEvent.iType)
       
   688                 {
       
   689                 case TPointerEvent::EButton1Down:
       
   690                     iExtension->iLastPoint = aPointerEvent.iPosition;
       
   691                     if ( visibleItemsRect.Contains(aPointerEvent.iPosition) )
       
   692                         {
       
   693                         iExtension->iFlags |= EAknGridStateButton1DownInGrid;                
       
   694                         }
       
   695                     _AKNTRACE( "TPointerEvent::EButton1Down" );
       
   696                     break;
       
   697 
       
   698                 case TPointerEvent::EButton1Up:
       
   699                     {
       
   700                     iExtension->iFlags &= ~EAknGridStateButton1DownInGrid;
       
   701                     _AKNTRACE( "TPointerEvent::EButton1Up" );
       
   702                     break;
       
   703                     }
       
   704 
       
   705                 default:
       
   706                     {
       
   707                     break;
       
   708                     }
       
   709                 }
       
   710 
       
   711             CEikListBox::HandlePointerEventL( aPointerEvent ); // eventually will call CAknGrid::HandleDragEventL if dragged
       
   712             }
       
   713         }
       
   714     _AKNTRACE_FUNC_EXIT;
       
   715     }
       
   716 
       
   717 EXPORT_C void* CAknGrid::ExtensionInterface( TUid /*aInterface*/ ) 
       
   718     { 
       
   719     return NULL;
       
   720     }
       
   721 
       
   722 /**
       
   723 * Sets the layout from a resource. Layout includes orientation 
       
   724 * (either vertical or horizontal), horizontal and vertical direction 
       
   725 * of numbering, the number of items in the primary and secondary
       
   726 * orientation, and the primary and secondary scrolling types.
       
   727 */
       
   728 EXPORT_C void CAknGrid::SetLayoutFromResourceL(TResourceReader& aReader)
       
   729     {
       
   730     _AKNTRACE_FUNC_ENTER;
       
   731     TInt layoutFlags = aReader.ReadInt16();
       
   732     TInt primaryScroll=aReader.ReadInt16();
       
   733     TInt secondaryScroll=aReader.ReadInt16();
       
   734     TInt numItemsInPrimaryOrient=aReader.ReadInt16();
       
   735     TInt numItemsInSecondaryOrient=aReader.ReadInt16();
       
   736     TInt height = aReader.ReadInt16();
       
   737     TInt width = aReader.ReadInt16();
       
   738     TInt gapWidth = aReader.ReadInt16();
       
   739     TInt gapHeight = aReader.ReadInt16();
       
   740 
       
   741     TGridOrientation gridOrientation = EGridOrientationHorizontal;
       
   742     if (layoutFlags & EAknGridVerticalOrientation)
       
   743         gridOrientation = EGridOrientationVertical;
       
   744 
       
   745     TGridHorizontal gridHorizontal = EGridHorizontalWritingDirection;
       
   746     if (layoutFlags & EAknGridLeftToRight)
       
   747         gridHorizontal = EGridHorizontalLeftToRight;
       
   748     else if (layoutFlags & EAknGridRightToLeft)
       
   749         gridHorizontal = EGridHorizontalRightToLeft;
       
   750 //        else if (layoutFlags & EAknGridHorizontalAntiWritingDirection)
       
   751 //                gridHorizontal = EGridHorizontalAntiWritingDirection;
       
   752     else if (layoutFlags & EAknGridLanguageSpecificHorizontalDirection)
       
   753         gridHorizontal = EGridHorizontalWritingDirection;
       
   754 
       
   755     TGridVertical gridVertical = EGridVerticalTopToBottom;
       
   756     if (layoutFlags & EAknGridBottomToTop)
       
   757         gridVertical = EGridVerticalBottomToTop;
       
   758 
       
   759     CAknGridView::TScrollingType prime = CAknGridView::EScrollFollowsItemsAndLoops;
       
   760     CAknGridView::TScrollingType second = CAknGridView::EScrollFollowsItemsAndLoops;
       
   761 
       
   762     switch(primaryScroll)
       
   763         {
       
   764         case EAknGridFollowsItemsAndStops:
       
   765             prime = CAknGridView::EScrollFollowsItemsAndStops;
       
   766             break;
       
   767         case EAknGridFollowsItemsAndLoops:
       
   768             prime = CAknGridView::EScrollFollowsItemsAndLoops;
       
   769             break;
       
   770         case EAknGridFollowsGrid:
       
   771             prime = CAknGridView::EScrollFollowsGrid;
       
   772             break;
       
   773         case EAknGridStops:
       
   774             prime = CAknGridView::EScrollStops;
       
   775             break;
       
   776         case EAknGridIncrementLineAndStops:
       
   777             prime = CAknGridView::EScrollIncrementLineAndStops;
       
   778             break;
       
   779         case EAknGridIncrementLineAndLoops:
       
   780             prime = CAknGridView::EScrollIncrementLineAndLoops;
       
   781             break;
       
   782         default:
       
   783             break;
       
   784         }
       
   785 
       
   786     switch(secondaryScroll)
       
   787         {
       
   788         case EAknGridFollowsItemsAndStops:
       
   789             second = CAknGridView::EScrollFollowsItemsAndStops;
       
   790             break;
       
   791         case EAknGridFollowsItemsAndLoops:
       
   792             second = CAknGridView::EScrollFollowsItemsAndLoops;
       
   793             break;
       
   794         case EAknGridFollowsGrid:
       
   795             second = CAknGridView::EScrollFollowsGrid;
       
   796             break;
       
   797         case EAknGridStops:
       
   798             second = CAknGridView::EScrollStops;
       
   799             break;
       
   800         case EAknGridIncrementLineAndStops:
       
   801             second = CAknGridView::EScrollIncrementLineAndStops;
       
   802             break;
       
   803         case EAknGridIncrementLineAndLoops:
       
   804             second = CAknGridView::EScrollIncrementLineAndLoops;
       
   805             break;
       
   806         default:
       
   807             break;
       
   808         }
       
   809     TSize itemSize(width,height);
       
   810     DoSetLayoutL(gridOrientation, gridHorizontal, gridVertical, numItemsInPrimaryOrient, numItemsInSecondaryOrient, itemSize, gapWidth, gapHeight);
       
   811     SetPrimaryScrollingType(prime);
       
   812     SetSecondaryScrollingType(second);
       
   813     _AKNTRACE_FUNC_EXIT;
       
   814     }
       
   815 
       
   816 
       
   817 /**
       
   818 * Sets the movement of the cursor with respect to scrolling when the
       
   819 * end item in the current row or column, whichever is the primary
       
   820 * orientation of the data items, is encountered. The movement maybe
       
   821 * either stop, loop back to same row or column or move onto the
       
   822 * next logical data item in the sequence.
       
   823 */
       
   824 EXPORT_C void CAknGrid::SetPrimaryScrollingType(CAknGridView::TScrollingType aScrollingType)
       
   825     {
       
   826     __TEST_INVARIANT;
       
   827     GridView()->SetPrimaryScrollingType(aScrollingType);
       
   828     }
       
   829 
       
   830 /**
       
   831 * Sets the movement of the cursor with respect to scrolling when the
       
   832 * end item in the secondary dimension of the grid is encountered.
       
   833 * The movement maybe either stop, loop back back to same row or column
       
   834 * or move onto the next logical data item in the sequence.
       
   835 */
       
   836 EXPORT_C void CAknGrid::SetSecondaryScrollingType(CAknGridView::TScrollingType aSecondaryScrolling)
       
   837     {
       
   838     __TEST_INVARIANT;
       
   839     GridView()->SetSecondaryScrollingType(aSecondaryScrolling);
       
   840     }
       
   841 
       
   842 /**
       
   843 * Returns the current grid data index.
       
   844 * Returns -1 if the grid is empty.
       
   845 */
       
   846 EXPORT_C TInt CAknGrid::CurrentDataIndex() const
       
   847     {
       
   848     _AKNTRACE_FUNC_ENTER;
       
   849     __TEST_INVARIANT;
       
   850     if (GridModel()->NumberOfData() < 1)
       
   851     	{
       
   852     	_AKNTRACE( "no data in model, return -1" );
       
   853     	_AKNTRACE_FUNC_EXIT;
       
   854         return -1;
       
   855     	}
       
   856     TInt startOffset = GridModel()->IndexOfFirstDataItem();
       
   857     _AKNTRACE_FUNC_EXIT;
       
   858     return (GridView()->CurrentDataIndex() - startOffset);
       
   859     }
       
   860 
       
   861 /**
       
   862 * Moves the cursor to the required grid data index.
       
   863 */
       
   864 EXPORT_C void CAknGrid::SetCurrentDataIndex(TInt aDataIndex)
       
   865     {
       
   866     _AKNTRACE_FUNC_ENTER;
       
   867     __TEST_INVARIANT;
       
   868     _AKNTRACE( "[%s] aDataIndex = %d", 
       
   869     		   __FUNCTION__, aDataIndex );
       
   870     TInt startOffset = GridModel()->IndexOfFirstDataItem();
       
   871 
       
   872     if (startOffset == -1)
       
   873     	{
       
   874     	_AKNTRACE_FUNC_EXIT;
       
   875         return; // there is no data yet
       
   876     	}
       
   877     TInt newIndex = aDataIndex + startOffset;
       
   878 
       
   879     GridView()->SetCurrentDataIndex(newIndex);
       
   880     UpdateScrollBarThumbs();
       
   881     _AKNTRACE_FUNC_EXIT;
       
   882     }
       
   883 
       
   884 /**
       
   885 * Sets the starting position of the data within the grid.
       
   886 * <p>
       
   887 * Note: a blank page cannot be accessed (since cannot move into empty cells)
       
   888 * so a totally blank page is the same as if the page never existed since
       
   889 * the user cannot scroll into it. For this reason it is suggested that
       
   890 * the start position be no more than one page into the grid.
       
   891 */
       
   892 EXPORT_C void CAknGrid::SetStartPositionL(TPoint aGridStartPosition)
       
   893     {
       
   894     _AKNTRACE_FUNC_ENTER;
       
   895     __TEST_INVARIANT;
       
   896 
       
   897     TInt dataIndex;
       
   898     CAknGridView* gridView = GridView();
       
   899     gridView->DataIndexFromLogicalPos(dataIndex,aGridStartPosition.iY,aGridStartPosition.iX);
       
   900 
       
   901     // set the number of blank start cells
       
   902     GridModel()->SetStartCells(dataIndex);
       
   903 
       
   904     // need to check grid size
       
   905     CalcGridSizeL();
       
   906 
       
   907     // check current item position
       
   908     gridView->SetCurrentDataIndex(dataIndex);
       
   909     iCurrentIsValid = ETrue;
       
   910     _AKNTRACE_FUNC_EXIT;
       
   911     }
       
   912 
       
   913 /**
       
   914 * Gives the data index at the grid position given.
       
   915 * The position must be given with respect to the top left corner
       
   916 * of the grid.
       
   917 * An index value of -1 is given if the grid position given is
       
   918 * invalid.
       
   919 */
       
   920 EXPORT_C TInt CAknGrid::IndexOfPosition(TPoint aGridPosition) const
       
   921     {
       
   922     _AKNTRACE_FUNC_ENTER;
       
   923     __TEST_INVARIANT;
       
   924 
       
   925     TInt indexValue = -1;
       
   926 
       
   927 
       
   928     CAknGridView* gridView = GridView();
       
   929     TSize gridSize = gridView->GridCellDimensions();
       
   930 
       
   931     if ((aGridPosition.iY >= 0)&&
       
   932         (aGridPosition.iX >= 0)&&
       
   933         (aGridPosition.iX < gridSize.iWidth)&&
       
   934         (aGridPosition.iY < gridSize.iHeight))
       
   935         {
       
   936         // grid position is valid
       
   937         gridView->DataIndexFromLogicalPos(indexValue, aGridPosition.iY, aGridPosition.iX);
       
   938 
       
   939         indexValue -= GridModel()->IndexOfFirstDataItem();
       
   940         }
       
   941         
       
   942     _AKNTRACE_FUNC_EXIT;    
       
   943     return indexValue;
       
   944     }
       
   945 
       
   946 /**
       
   947 * Gives the position of the data item required.
       
   948 * The logical position is given with respect to the top left 
       
   949 * hand corner of the grid.
       
   950 * A position of (-1,-1) is given if the data item is not valid.
       
   951 */
       
   952 EXPORT_C TPoint CAknGrid::PositionAtIndex(TInt aItemIndex) const
       
   953     {
       
   954     _AKNTRACE_FUNC_ENTER;
       
   955     __TEST_INVARIANT;
       
   956     _AKNTRACE(" [%s] aItemIndex = %d", 
       
   957         		  __FUNCTION__, aItemIndex );
       
   958     
       
   959     TPoint gridPosition(-1,-1);
       
   960 
       
   961     CAknGridM* gridModel = GridModel();
       
   962 
       
   963     TInt startOffset = gridModel->IndexOfFirstDataItem();
       
   964     TInt newIndex = aItemIndex + startOffset;
       
   965 
       
   966     if (ItemExists(newIndex))
       
   967         {
       
   968         if (gridModel->IndexContainsData(newIndex))
       
   969             {
       
   970             GridView()->
       
   971                 LogicalPosFromDataIndex(newIndex, gridPosition.iY, gridPosition.iX);
       
   972             }
       
   973         }
       
   974 
       
   975     _AKNTRACE_FUNC_EXIT;
       
   976     return gridPosition;
       
   977     }
       
   978 
       
   979 
       
   980 EXPORT_C CListBoxView* CAknGrid::MakeViewClassInstanceL() 
       
   981     {
       
   982     return (new(ELeave) CAknGridView);
       
   983     }
       
   984 
       
   985 /**
       
   986 * Sets the column width of the grid.
       
   987 * Column width cannot be set in a horizontal grid since the number
       
   988 * of columns in the grid is defined by the initialising call to
       
   989 * SetLayoutL.
       
   990 * The column width cannot be larger than the width of the viewing
       
   991 * rectangle.
       
   992 */
       
   993 EXPORT_C void CAknGrid::SetColumnWidth(TInt aColumnWidth)
       
   994     {
       
   995     _AKNTRACE_FUNC_ENTER;
       
   996     __TEST_INVARIANT;
       
   997     _AKNTRACE(" [%s] aColumnWidth = %d", 
       
   998     		  __FUNCTION__, aColumnWidth );
       
   999     
       
  1000     if (aColumnWidth < 1)
       
  1001         return;
       
  1002 
       
  1003     TInt currentDataIndex = 0;
       
  1004 
       
  1005     CAknGridView* gridView = GridView();
       
  1006     if (iCurrentIsValid)
       
  1007         {
       
  1008         // remember current position
       
  1009         currentDataIndex = gridView->CurrentDataIndex();
       
  1010         }
       
  1011 
       
  1012     // hold the users value in case needed in the method
       
  1013     // HandleItemAdditionL
       
  1014     iMinColWidth = aColumnWidth;
       
  1015 
       
  1016     gridView->SetColumnWidth(aColumnWidth);
       
  1017 
       
  1018     // check grid orientated to show current focus (item height
       
  1019     // change may have moved the focus to a new page)
       
  1020     if (iCurrentIsValid)
       
  1021         gridView->SetCurrentDataIndex(currentDataIndex);
       
  1022     _AKNTRACE_FUNC_EXIT;
       
  1023     }
       
  1024 
       
  1025 /**
       
  1026 * Sets the row height of the grid.
       
  1027 * Row height cannot be set in a vertical grid since the number
       
  1028 * of rows in the grid is defined by the initialising call to
       
  1029 * SetLayoutL.
       
  1030 * The row height cannot be larger than the height of the viewing
       
  1031 * rectangle.
       
  1032 */
       
  1033 EXPORT_C void CAknGrid::SetItemHeightL(TInt aHeight)
       
  1034     {
       
  1035     _AKNTRACE_FUNC_ENTER;
       
  1036     __TEST_INVARIANT;
       
  1037     _AKNTRACE(" [%s] aHeight = %d", 
       
  1038     		  __FUNCTION__, aHeight );
       
  1039 
       
  1040     if (aHeight < 1)
       
  1041         return;
       
  1042 
       
  1043     TInt currentDataIndex = 0;
       
  1044 
       
  1045     CAknGridView* gridView = GridView();
       
  1046     if (iCurrentIsValid)
       
  1047         {
       
  1048         // remember current position
       
  1049         currentDataIndex = gridView->CurrentDataIndex();
       
  1050         }
       
  1051 
       
  1052     // this ensures that if user changes the item height then the
       
  1053     // grid details will change in line as well
       
  1054     iItemHeight = aHeight;
       
  1055 
       
  1056     gridView->SetItemHeight(aHeight);
       
  1057 
       
  1058     CalcGridSizeL();
       
  1059 
       
  1060     // check grid orientated to show current focus (item height
       
  1061     // change may have moved the focus to a new page)
       
  1062     if (iCurrentIsValid)
       
  1063         gridView->SetCurrentDataIndex(currentDataIndex);
       
  1064     _AKNTRACE_FUNC_EXIT;
       
  1065     }
       
  1066 
       
  1067 /**
       
  1068 * Processes the user key events or passes them onto the underlying
       
  1069 * listbox code.
       
  1070 */
       
  1071 EXPORT_C TKeyResponse CAknGrid::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
       
  1072     {
       
  1073     _AKNTRACE_FUNC_ENTER;
       
  1074     // SERIES60 LAF
       
  1075     CListBoxView::TSelectionMode selectionMode = CListBoxView::ENoSelection;
       
  1076 
       
  1077     TBool shiftKeyPressed = (aKeyEvent.iModifiers & EModifierShift);
       
  1078     if (iListBoxFlags & EMultipleSelection)
       
  1079         {
       
  1080         if (shiftKeyPressed && iListBoxFlags & EShiftEnterMarks)
       
  1081             {
       
  1082             View()->SetAnchor(View()->CurrentItemIndex());
       
  1083             selectionMode = CListBoxView::EDisjointMarkSelection;
       
  1084             }
       
  1085         else
       
  1086             selectionMode = CListBoxView::ENoSelection;
       
  1087         }
       
  1088         
       
  1089     // With single click first key event enables highlight
       
  1090     if ( iExtension->iSingleClickEnabled
       
  1091             && ItemDrawer()->Flags()
       
  1092             &  CListItemDrawer::ESingleClickDisabledHighlight )
       
  1093         {
       
  1094         if ( aKeyEvent.iCode == EKeyUpArrow || 
       
  1095              aKeyEvent.iCode == EKeyDownArrow ||
       
  1096              aKeyEvent.iCode == EKeyLeftArrow || 
       
  1097              aKeyEvent.iCode == EKeyRightArrow ||   
       
  1098              aKeyEvent.iCode == EKeyEnter || 
       
  1099              aKeyEvent.iCode == EKeyOK )
       
  1100             {
       
  1101             _AKNTRACE_FUNC_EXIT;
       
  1102             return CEikListBox::OfferKeyEventL( aKeyEvent, aType );
       
  1103             }
       
  1104         }
       
  1105     
       
  1106     switch (aKeyEvent.iCode)
       
  1107         {
       
  1108         case EKeyUpArrow:
       
  1109             iView->MoveCursorL(CListBoxView::ECursorPreviousItem, selectionMode);
       
  1110             ClearMatchBuffer();
       
  1111             _AKNTRACE( "EKeyUpArrow" );
       
  1112             break;
       
  1113         case EKeyDownArrow:
       
  1114             iView->MoveCursorL(CListBoxView::ECursorNextItem, selectionMode);
       
  1115             ClearMatchBuffer();
       
  1116             _AKNTRACE( "EKeyDownArrow" );
       
  1117             break;
       
  1118 
       
  1119         case EKeyPrevious:
       
  1120             {
       
  1121             const TBool disableRedraw = aKeyEvent.iRepeats;
       
  1122             TBool redrawDisabled = iView->RedrawDisabled();
       
  1123             if ( disableRedraw )
       
  1124                 {
       
  1125                 iView->SetDisableRedraw(ETrue);
       
  1126                 }
       
  1127             
       
  1128             ((CAknGridView*)iView)->
       
  1129                 MoveCursorWithRepeatsL( EFalse, selectionMode, 1 + aKeyEvent.iRepeats );
       
  1130             ClearMatchBuffer();
       
  1131                 
       
  1132             if ( disableRedraw )
       
  1133                 {
       
  1134                 iView->SetDisableRedraw(redrawDisabled);
       
  1135                 if ( !redrawDisabled )
       
  1136                     {
       
  1137                     DrawNow();
       
  1138                     }
       
  1139                 }
       
  1140             }
       
  1141             _AKNTRACE( "EKeyPrevious" );
       
  1142             break;
       
  1143 
       
  1144         case EKeyLeftArrow:
       
  1145             iView->MoveCursorL(CListBoxView::ECursorPreviousColumn, selectionMode);
       
  1146             ClearMatchBuffer();
       
  1147             _AKNTRACE( "EKeyLeftArrow" );
       
  1148             break;
       
  1149             
       
  1150         case EKeyNext:
       
  1151             {
       
  1152             const TBool disableRedraw = aKeyEvent.iRepeats;
       
  1153             TBool redrawDisabled = iView->RedrawDisabled();
       
  1154             if ( disableRedraw )
       
  1155                 {
       
  1156                 iView->SetDisableRedraw(ETrue);
       
  1157                 }
       
  1158 
       
  1159             ((CAknGridView*)iView)->
       
  1160                 MoveCursorWithRepeatsL( ETrue, selectionMode, 1 + aKeyEvent.iRepeats );
       
  1161             ClearMatchBuffer();
       
  1162                 
       
  1163             if ( disableRedraw )
       
  1164                 {
       
  1165                 iView->SetDisableRedraw(redrawDisabled);
       
  1166                 if ( !redrawDisabled )
       
  1167                     {
       
  1168                     DrawNow();
       
  1169                     }
       
  1170                 }
       
  1171             }
       
  1172             _AKNTRACE( "EKeyNext" );
       
  1173             break;
       
  1174 
       
  1175         case EKeyRightArrow:
       
  1176             iView->MoveCursorL(CListBoxView::ECursorNextColumn, selectionMode);
       
  1177             ClearMatchBuffer();
       
  1178             _AKNTRACE( "EKeyRightArrow" );
       
  1179             break;
       
  1180 
       
  1181 #if defined(_DEBUG) // only needed when debuging
       
  1182         case EKeyPageUp:
       
  1183             iView->MoveCursorL(CListBoxView::ECursorPreviousPage, selectionMode);
       
  1184             ClearMatchBuffer();
       
  1185             break;
       
  1186         case EKeyPageDown:
       
  1187             iView->MoveCursorL(CListBoxView::ECursorNextPage, selectionMode);
       
  1188             ClearMatchBuffer();
       
  1189             break;
       
  1190         case EKeyHome:
       
  1191             iView->MoveCursorL(CListBoxView::ECursorFirstItem, selectionMode);
       
  1192             ClearMatchBuffer();
       
  1193             break;
       
  1194         case EKeyEnd:
       
  1195             iView->MoveCursorL(CListBoxView::ECursorLastItem, selectionMode);
       
  1196             ClearMatchBuffer();
       
  1197             break;
       
  1198 #endif// end of debug code
       
  1199         default:
       
  1200         	_AKNTRACE_FUNC_EXIT;
       
  1201             return CEikListBox::OfferKeyEventL(aKeyEvent,aType);
       
  1202         }
       
  1203 
       
  1204     UpdateScrollBarThumbs();
       
  1205 
       
  1206     // matcher cursor code maybe needed here if matcher cursors
       
  1207     // supported in future versions, refer to CEikListBox::OfferKeyEventL
       
  1208 
       
  1209     if (iListBoxFlags & EStateChanged)
       
  1210         {
       
  1211         ReportEventL(MCoeControlObserver::EEventStateChanged);
       
  1212         iListBoxFlags &= (~EStateChanged);
       
  1213         }
       
  1214 
       
  1215     _AKNTRACE_FUNC_EXIT;
       
  1216     return EKeyWasConsumed;
       
  1217     }
       
  1218 /**
       
  1219 * @return Model
       
  1220 */
       
  1221 EXPORT_C CTextListBoxModel* CAknGrid::Model() const
       
  1222     {
       
  1223     return STATIC_CAST(CTextListBoxModel*,iModel);
       
  1224     }
       
  1225 
       
  1226 /**
       
  1227 * Sets the viewable rect
       
  1228 */
       
  1229 EXPORT_C void CAknGrid::SetRect(const TRect& aRect)
       
  1230     {
       
  1231     _AKNTRACE_FUNC_ENTER;
       
  1232     
       
  1233     CCoeControl::SetRect(aRect);
       
  1234         
       
  1235     TRect rect(aRect);
       
  1236     rect.SetRect(rect.iTl.iX + ListBoxMargins().iLeft, rect.iTl.iY + ListBoxMargins().iTop,
       
  1237                  rect.iBr.iX - ListBoxMargins().iRight, rect.iBr.iY - ListBoxMargins().iBottom);
       
  1238     _AKNTRACE( "The rect of grid are ( %d, %d ) ( %d, %d )", 
       
  1239     		   rect.iTl.iX, rect.iTl.iY, 
       
  1240     		   rect.iBr.iX, rect.iBr.iY );
       
  1241     iView->SetViewRect(rect);
       
  1242 
       
  1243     // basically, this is redundant call, but leaving it out breaks at
       
  1244     // least camcorder's colorburstgrid, because SizeChanged() trusts
       
  1245     // margin values
       
  1246     TRAP_IGNORE( HandleViewRectSizeChangeL() );  
       
  1247     _AKNTRACE_FUNC_EXIT;
       
  1248     }
       
  1249 
       
  1250 /**
       
  1251 * Called when the view rect changes size
       
  1252 */
       
  1253 EXPORT_C void CAknGrid::HandleViewRectSizeChangeL()
       
  1254     {
       
  1255     _AKNTRACE_FUNC_ENTER;
       
  1256     iView->CalcBottomItemIndex();
       
  1257     TInt oldTopItemIndex = TopItemIndex();// store old top item index
       
  1258     TInt newTopItemIndex = oldTopItemIndex;// set new same as old
       
  1259 
       
  1260     TInt currentItemIndex = CurrentItemIndex();// get the current item index
       
  1261 
       
  1262     if (currentItemIndex < 0)// check valid
       
  1263     	{
       
  1264     	_AKNTRACE_FUNC_EXIT;
       
  1265         return;
       
  1266     	}
       
  1267 
       
  1268     iNumOfRowsInView = Max(1, iNumOfRowsInView);// make iNumOfRowsInView > 1
       
  1269     iNumOfColsInView = Max(1, iNumOfColsInView);// make iNumOfColsInView > 1
       
  1270 
       
  1271     if ( iOrientationFlags.IsClear( EGridOrientationVertical )&&
       
  1272          ( AknLayoutUtils::LayoutMirrored()
       
  1273            ? iHorizontalFlags.IsClear( EGridHorizontalLeftToRight )
       
  1274            : iHorizontalFlags.IsSet(   EGridHorizontalLeftToRight ) ) &&
       
  1275          iVerticalFlags.IsSet(EGridVerticalTopToBottom) )
       
  1276         {
       
  1277         // CAknAppStyleGrid uses this combination of flags
       
  1278         AdjustTopItemIndex();
       
  1279         }
       
  1280     else
       
  1281         {
       
  1282         // this version is likely to contain bugs.
       
  1283         if (currentItemIndex != oldTopItemIndex)
       
  1284             {
       
  1285             TInt colIndexOfTargetItem = currentItemIndex / iNumOfRowsInView;// iNumOfRowsInView != 0
       
  1286             TInt adjustment = newTopItemIndex % iNumOfRowsInView;// iNumOfRowsInView != 0
       
  1287             if (adjustment != 0)
       
  1288                 {
       
  1289                 // adjust newTopItemIndex till it refers to the index of an item at the top of a column
       
  1290                 newTopItemIndex -= adjustment;
       
  1291                 }
       
  1292             TInt newBottomItemIndex = newTopItemIndex + (iNumOfColsInView * iNumOfRowsInView) - 1;
       
  1293             if (currentItemIndex < newTopItemIndex)
       
  1294                 newTopItemIndex = colIndexOfTargetItem * iNumOfRowsInView;
       
  1295             else if (currentItemIndex > newBottomItemIndex)
       
  1296                 {
       
  1297                 TInt colIndexOfNewBottomItem = colIndexOfTargetItem;
       
  1298                 TInt colIndexOfNewTopItem = colIndexOfNewBottomItem - (iNumOfColsInView - 1);
       
  1299                 newTopItemIndex = colIndexOfNewTopItem * iNumOfRowsInView;
       
  1300                 }
       
  1301             }
       
  1302         else if ((newTopItemIndex != 0) && (iNumOfRowsInView != 0))
       
  1303             {
       
  1304             TInt adjustment = newTopItemIndex % iNumOfRowsInView;// iNumOfRowsInView != 0
       
  1305             if (adjustment != 0)
       
  1306                 {// adjust newTopItemIndex till it refers to the index of an item at the top of a column
       
  1307                 newTopItemIndex -= adjustment;
       
  1308                 }
       
  1309             }
       
  1310         SetTopItemIndex(newTopItemIndex);
       
  1311         }
       
  1312     
       
  1313     iView->CalcDataWidth();
       
  1314     UpdateScrollBarsL();
       
  1315     iView->CalcBottomItemIndex();
       
  1316     _AKNTRACE_FUNC_EXIT;
       
  1317     }
       
  1318 
       
  1319 /**
       
  1320 * Set the empty grid text
       
  1321 */
       
  1322 EXPORT_C void CAknGrid::SetEmptyGridTextL(const TDesC& aText)
       
  1323     {
       
  1324     GridView()->SetListEmptyTextL(aText);
       
  1325     }
       
  1326 
       
  1327 /////////////////////////////////////////////////////
       
  1328 /////////////////////////////////////////////////////
       
  1329 
       
  1330 EXPORT_C void CAknGrid::SetTopItemIndex(TInt aItemIndex) const
       
  1331     {
       
  1332     __ASSERT_DEBUG(iView, Panic(EAknPanicGridNoView));
       
  1333     iView->SetTopItemIndex(aItemIndex);
       
  1334     }
       
  1335 
       
  1336 EXPORT_C void CAknGrid::HandleResourceChange(TInt aType)
       
  1337     {
       
  1338     _AKNTRACE_FUNC_ENTER;
       
  1339     // Need to do this to set up the scroll bar model
       
  1340     TRAP_IGNORE( UpdateScrollBarsL() );
       
  1341     
       
  1342     if (aType==KEikDynamicLayoutVariantSwitch)
       
  1343         {
       
  1344         CAknGridView* gridView = GridView();
       
  1345         
       
  1346         gridView->SetItemOffsetInPixels( 0 );
       
  1347         
       
  1348         TSize sizeOfItems;
       
  1349         sizeOfItems.iWidth = ( Rect().iBr.iX - Rect().iTl.iX ) / iNumOfColsInView;
       
  1350         sizeOfItems.iHeight = ( Rect().iBr.iY - Rect().iTl.iY ) / iNumOfRowsInView;
       
  1351         
       
  1352         CAknGridView::SGrid gridDetails;
       
  1353         gridDetails.iGridDimensions = gridView->GridCellDimensions();
       
  1354         gridDetails.iPageSize = iNumOfColsInView*iNumOfRowsInView;
       
  1355 
       
  1356         gridDetails.iColsInView = iNumOfColsInView;
       
  1357         gridDetails.iRowsInView = iNumOfRowsInView;
       
  1358         gridDetails.iSizeBetweenItems = iSpaceBetweenItems;
       
  1359         //gridDetails.iSizeOfItems = gridView->ItemSize();
       
  1360         gridDetails.iSizeOfItems = sizeOfItems;
       
  1361         
       
  1362         gridView->SetColumnWidth(gridDetails.iSizeOfItems.iWidth);
       
  1363         TRAP_IGNORE( SetItemHeightL(gridDetails.iSizeOfItems.iHeight) );
       
  1364 
       
  1365         gridDetails.iGridFlags = 0;
       
  1366         if (iOrientationFlags.IsSet(EGridOrientationVertical))
       
  1367             gridDetails.iGridFlags |= CAknGridView::EPrimaryIsVertical;
       
  1368         if (iVerticalFlags.IsSet(EGridVerticalTopToBottom))
       
  1369             gridDetails.iGridFlags |= CAknGridView::ETopToBottom;
       
  1370         
       
  1371         TBool isMirrored = AknLayoutUtils::LayoutMirrored();
       
  1372         if (isMirrored)
       
  1373             {
       
  1374             if (iHorizontalFlags.IsSet(EGridHorizontalAntiWritingDirection)
       
  1375                 || iHorizontalFlags.IsSet(EGridHorizontalLeftToRight))
       
  1376                 gridDetails.iGridFlags |= CAknGridView::ELeftToRight;
       
  1377             }
       
  1378         else
       
  1379             {
       
  1380             if (iHorizontalFlags.IsSet(EGridHorizontalWritingDirection)
       
  1381                 || iHorizontalFlags.IsSet(EGridHorizontalLeftToRight))
       
  1382                 gridDetails.iGridFlags |= CAknGridView::ELeftToRight;
       
  1383             }
       
  1384         gridView->SetGridDetails(gridDetails);
       
  1385               
       
  1386         SetItemsInSingleLine( gridDetails.iColsInView );
       
  1387         }
       
  1388     
       
  1389     CEikListBox::HandleResourceChange(aType);
       
  1390     
       
  1391     TRAP_IGNORE( ItemDrawer()->FormattedCellData()->SetupSkinContextL());
       
  1392     // Data extension has animations which will change when skin changes.
       
  1393     ItemDrawer()->FormattedCellData()->HandleResourceChange( aType );
       
  1394 
       
  1395     // Need to do this to set up the scroll bar model
       
  1396     TRAP_IGNORE( UpdateScrollBarsL() );
       
  1397     _AKNTRACE_FUNC_EXIT;
       
  1398     }
       
  1399 
       
  1400 
       
  1401 EXPORT_C void CAknGrid::FocusChanged( TDrawNow aDrawNow )
       
  1402     {
       
  1403     _AKNTRACE_FUNC_ENTER;
       
  1404     CEikListBox::FocusChanged( aDrawNow );
       
  1405 
       
  1406     // Grid data needs focus change information to control animations.
       
  1407     if( IsFocused() )
       
  1408         {
       
  1409         ItemDrawer()->FormattedCellData()->FocusGained();
       
  1410         }
       
  1411     else
       
  1412         {
       
  1413         ItemDrawer()->FormattedCellData()->FocusLost();
       
  1414         }
       
  1415     _AKNTRACE_FUNC_EXIT;
       
  1416     }
       
  1417 
       
  1418 EXPORT_C TInt CAknGrid::ColumnWidth() const
       
  1419     {
       
  1420     __ASSERT_DEBUG(iView, Panic(EAknPanicGridNoView));
       
  1421     return ((CAknGridView*)iView)->ColumnWidth();
       
  1422     }
       
  1423 
       
  1424 EXPORT_C TInt CAknGrid::HorizontalNudgeValue() const
       
  1425     {
       
  1426     return 1;        // scroll horizontal by one column when the left/right scroll arrows (i.e. the nudge buttons) are tapped
       
  1427     }
       
  1428 
       
  1429 EXPORT_C TInt CAknGrid::HorizScrollGranularityInPixels() const
       
  1430     {
       
  1431     return ColumnWidth(); // horiz scrollbar model set in columns for snaking list box
       
  1432     }
       
  1433 
       
  1434 EXPORT_C void CAknGrid::AdjustTopItemIndex() const
       
  1435     {
       
  1436 
       
  1437     _AKNTRACE_FUNC_ENTER;
       
  1438     /*
       
  1439     * make sure, that topitemindex points to topmost leftmost visible item
       
  1440     * This hackish solution is only valid for appstyle grid & similar grids
       
  1441     */
       
  1442      if ( iOrientationFlags.IsClear( EGridOrientationVertical )&&
       
  1443           ( AknLayoutUtils::LayoutMirrored()
       
  1444             ? iHorizontalFlags.IsClear( EGridHorizontalLeftToRight )
       
  1445             : iHorizontalFlags.IsSet(   EGridHorizontalLeftToRight ) ) &&
       
  1446          iVerticalFlags.IsSet(EGridVerticalTopToBottom) )
       
  1447         {
       
  1448         if ( !iNumOfColsInView )
       
  1449             {  // just in case
       
  1450             _AKNTRACE_FUNC_EXIT;
       
  1451             return;
       
  1452             }
       
  1453 
       
  1454         TPoint topIndexPoint = iView->ItemPos( TopItemIndex() );
       
  1455         TInt bottomOrdinate = topIndexPoint.iY + iItemHeight;
       
  1456         if ( TopItemIndex() % iNumOfColsInView == 0 
       
  1457              && ( bottomOrdinate > 0
       
  1458              && bottomOrdinate <= ( iView->ViewRect().iTl.iY + iItemHeight ) )
       
  1459              && iView->ViewRect().Contains( iView->ItemPos( CurrentItemIndex() ) ) )
       
  1460         {
       
  1461         _AKNTRACE_FUNC_EXIT;
       
  1462         return;
       
  1463         }
       
  1464 
       
  1465         // get row of topmost item relative to the whole grid - 0 based indexing
       
  1466         TInt topRow = TopItemIndex() / iNumOfColsInView;
       
  1467 
       
  1468         // get row of current item relative to the whole grid - 0 based indexing
       
  1469         TInt currRow = CurrentItemIndex() / iNumOfColsInView;
       
  1470         
       
  1471         // top item will be col 0 in topmost row - find out new top item's row
       
  1472         TInt newTopRow( topRow );  // prefer minimum adjustment
       
  1473         TInt reminder = iView->ViewRect().Height() % ( iItemHeight + iSpaceBetweenItems.iHeight );
       
  1474         TInt rowsFitInView = iNumOfRowsInView;
       
  1475         if ( reminder > 0 )
       
  1476             {
       
  1477             rowsFitInView ++;
       
  1478             }
       
  1479         newTopRow = currRow - rowsFitInView + 1; 
       
  1480         newTopRow = Max( 0, newTopRow );
       
  1481         
       
  1482         // and calculate new top item index
       
  1483         TInt topItemIndex = newTopRow * iNumOfColsInView ;
       
  1484         iView->SetItemOffsetInPixels(0);
       
  1485         SetTopItemIndex(topItemIndex);
       
  1486         }
       
  1487     _AKNTRACE_FUNC_EXIT;
       
  1488     }
       
  1489 
       
  1490 EXPORT_C void CAknGrid::HandleDragEventL(TPoint aPointerPos)
       
  1491     {
       
  1492     _AKNTRACE_FUNC_ENTER;
       
  1493     // No drag event handling if kinetic scrolling is enabled
       
  1494     if ( !ScrollingDisabled() )
       
  1495         {
       
  1496         _AKNTRACE_FUNC_EXIT;
       
  1497         return;     
       
  1498         }
       
  1499     
       
  1500     if ( AknLayoutUtils::PenEnabled() )
       
  1501         {
       
  1502         if ( !(iExtension->iFlags & EAknGridStateButton1DownInGrid) )
       
  1503             {
       
  1504             _AKNTRACE_FUNC_EXIT;
       
  1505             return;
       
  1506             }
       
  1507 
       
  1508         CAknGridView* gridView = GridView();
       
  1509         TRect maxRect(TPoint( KMinTInt, KMinTInt ), TPoint(KMaxTInt, KMaxTInt));
       
  1510         TRect ignoreDragRect;
       
  1511         TRect viewRect(gridView->ViewRect());
       
  1512         TInt itemIndex = KEikListBoxInvalidIndex ;
       
  1513         TBool pointerIsOverAnItem = gridView->XYPosToItemIndex(aPointerPos, itemIndex);
       
  1514         // SERIES60 LAF
       
  1515         CListBoxView::TSelectionMode selectionMode = CListBoxView::ENoSelection;
       
  1516         //        CListBoxView::TSelectionMode selectionMode = (iListBoxFlags & EMultipleSelection) ? CListBoxView::EContiguousSelection : CListBoxView::ESingleSelection;
       
  1517         // END OF SERIES60 LAF
       
  1518         TInt speed = iExtension->GetScrollingSpeed( pointerIsOverAnItem, itemIndex, 
       
  1519                                                     *gridView, aPointerPos );
       
  1520         
       
  1521         TInt oldCurrentItemIndex = CurrentItemIndex();
       
  1522         TRect currentItemRect(gridView->ItemPos(oldCurrentItemIndex), gridView->ItemSize(oldCurrentItemIndex));       
       
  1523         TInt numOfRows =  Max(GridView()->GridCellDimensions().iHeight,1);
       
  1524         const TInt placesInGrid = numOfRows * iNumOfColsInView;   
       
  1525         TBool currItemIsInLastRow = ((placesInGrid - iNumOfColsInView) <= itemIndex) && (placesInGrid > itemIndex); 
       
  1526         TBool currItemIsInFirstRow = itemIndex >= iNumOfColsInView;
       
  1527             
       
  1528         TRect visibleItemsRect(viewRect.iTl, 
       
  1529                                TPoint(gridView->ItemSize(itemIndex).iWidth * iNumOfColsInView, 
       
  1530                                       gridView->ItemSize(itemIndex).iHeight * iNumOfRowsInView));   
       
  1531 
       
  1532         if ( speed != 0 )
       
  1533             {
       
  1534             TInt itemCountInRow = iNumOfColsInView;
       
  1535             TInt dest = itemIndex + speed * itemCountInRow;
       
  1536             TInt offset = 0;
       
  1537             TInt newTopIndex = dest / itemCountInRow * itemCountInRow;
       
  1538             TInt upperBound = iModel->NumberOfItems() - 1;
       
  1539             
       
  1540             if ( speed > 0 )
       
  1541                 {
       
  1542 
       
  1543                 if ( gridView->ActualDataIndex( dest ) <= upperBound )
       
  1544                     {
       
  1545                     offset = -itemCountInRow;
       
  1546                     }
       
  1547                 else
       
  1548                     {
       
  1549                     dest = gridView->ListBoxIndex( upperBound );
       
  1550                     offset = itemIndex - dest; // Don't make focus jump.
       
  1551                     }
       
  1552                 newTopIndex -= ( iNumOfRowsInView - 1) * itemCountInRow ;
       
  1553                 }
       
  1554             else if ( speed < 0 )
       
  1555                 {
       
  1556                 if ( dest > 0 )
       
  1557                     {
       
  1558                     offset = itemCountInRow;
       
  1559                     }
       
  1560                 else
       
  1561                     {
       
  1562                     offset = itemIndex - dest;
       
  1563                     newTopIndex = 0;
       
  1564                     }
       
  1565                 }
       
  1566 
       
  1567             if ((iListBoxFlags & ES60StyleMarkable) && 
       
  1568                 ( (EventModifiers() & EModifierShift) ||
       
  1569                   (EventModifiers() & EModifierCtrl) ))
       
  1570                 {
       
  1571                 selectionMode = CListBoxView::EPenMultiselection;
       
  1572                 iListBoxFlags |= EStateChanged;
       
  1573                 }
       
  1574             TInt oldtop = gridView->TopItemIndex();
       
  1575             if ( !gridView->ItemIsVisible( dest ))
       
  1576                 {
       
  1577                 gridView->VScrollTo( newTopIndex );
       
  1578                 UpdateScrollBarThumbs();
       
  1579                 if ( pointerIsOverAnItem )
       
  1580                     {
       
  1581                     Window().RequestPointerRepeatEvent( 
       
  1582                         KEikListBoxPointerRepeatInterval, viewRect );
       
  1583                     }
       
  1584                 }
       
  1585             itemIndex = dest + offset;
       
  1586             }
       
  1587                 
       
  1588                               
       
  1589         // if pointer is over some new item. 
       
  1590         if ( pointerIsOverAnItem )
       
  1591             {
       
  1592 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  1593             MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal(
       
  1594                                                 iView->ItemDrawer()->Gc() );
       
  1595             if ( transApi && !transApi->EffectsDisabled() )
       
  1596                 {
       
  1597                 transApi->SetMoveType( itemIndex < oldCurrentItemIndex ?
       
  1598                                        MAknListBoxTfxInternal::EListMoveUp :
       
  1599                                        MAknListBoxTfxInternal::EListMoveDown );
       
  1600                 }
       
  1601 #endif
       
  1602             if ((iListBoxFlags & ES60StyleMarkable) && 
       
  1603                     ( (EventModifiers() & EModifierShift) ||
       
  1604                     (EventModifiers() & EModifierCtrl) ))
       
  1605                 {
       
  1606                 selectionMode = CListBoxView::EPenMultiselection;
       
  1607                 iListBoxFlags |= EStateChanged;
       
  1608                 }            
       
  1609             
       
  1610             gridView->MoveToItemIndexL(itemIndex, selectionMode);
       
  1611             }     
       
  1612         else if ((aPointerPos.iY < visibleItemsRect.iTl.iY) && 
       
  1613                     (aPointerPos.iX > visibleItemsRect.iTl.iX) && 
       
  1614                     (aPointerPos.iX < visibleItemsRect.iBr.iX) &&
       
  1615                      !currItemIsInFirstRow) // Dragged upwards from the grid.               
       
  1616             {
       
  1617             ignoreDragRect = TRect(maxRect.iTl, TPoint(maxRect.iBr.iX, visibleItemsRect.iTl.iY));
       
  1618 
       
  1619             MoveToNextOrPreviousItemL(aPointerPos);                 
       
  1620             
       
  1621             if ( (iListBoxFlags & ES60StyleMarkable) && 
       
  1622                 ( (EventModifiers() & EModifierShift) ||
       
  1623                   (EventModifiers() & EModifierCtrl) ))
       
  1624                 {
       
  1625                 iView->UpdateSelectionL(CListBoxView::EPenMultiselection);          
       
  1626                 iListBoxFlags |= EStateChanged;
       
  1627                 }  
       
  1628                             
       
  1629             UpdateScrollBarThumbs();
       
  1630             
       
  1631             Window().RequestPointerRepeatEvent(KEikListBoxPointerRepeatInterval, ignoreDragRect);
       
  1632             }     
       
  1633         else if (aPointerPos.iY > visibleItemsRect.iBr.iY && 
       
  1634                     (aPointerPos.iX > visibleItemsRect.iTl.iX) && 
       
  1635                     (aPointerPos.iX < visibleItemsRect.iBr.iX) &&
       
  1636                      !currItemIsInLastRow) // Dragged downwards from the grid.         
       
  1637             {        
       
  1638             ignoreDragRect = TRect(TPoint( maxRect.iTl.iX, visibleItemsRect.iBr.iY), maxRect.iBr );
       
  1639 
       
  1640             MoveToNextOrPreviousItemL(aPointerPos);                
       
  1641             
       
  1642             if ( (iListBoxFlags & ES60StyleMarkable) && 
       
  1643                     ( (EventModifiers() & EModifierShift) ||
       
  1644                       (EventModifiers() & EModifierCtrl) ))
       
  1645                 {
       
  1646                 iView->UpdateSelectionL(CListBoxView::EPenMultiselection);          
       
  1647                 iListBoxFlags |= EStateChanged;
       
  1648                 }
       
  1649                 
       
  1650             UpdateScrollBarThumbs();
       
  1651             
       
  1652             Window().RequestPointerRepeatEvent(KEikListBoxPointerRepeatInterval, ignoreDragRect);
       
  1653             }       
       
  1654             
       
  1655         if (CurrentItemIndex() != oldCurrentItemIndex)
       
  1656             {
       
  1657             ReportListBoxEventL(MEikListBoxObserver::EEventItemDraggingActioned);
       
  1658             iListBoxFlags |= EStateChanged;
       
  1659             if (IsMatchBuffer())
       
  1660                 {
       
  1661                 ClearMatchBuffer();
       
  1662                 DrawMatcherCursor();
       
  1663                 }
       
  1664             }
       
  1665         }
       
  1666     else
       
  1667         {
       
  1668         if (!(iListBoxFlags & ELeftDownInViewRect))
       
  1669         	{
       
  1670         	_AKNTRACE_FUNC_EXIT;
       
  1671             return;
       
  1672         	}
       
  1673 
       
  1674         CAknGridView* gridView = GridView();
       
  1675         const TInt clickableBorder = 20; // distance in pixels of area around grid that can see pointer events.
       
  1676         TRect ignoreDragRect(TPoint(aPointerPos.iX-clickableBorder, aPointerPos.iY-clickableBorder), TPoint(aPointerPos.iX+clickableBorder, aPointerPos.iY+clickableBorder));
       
  1677         TRect viewRect(gridView->ViewRect());
       
  1678         TInt itemIndex;
       
  1679         TBool pointerIsOverAnItem = gridView->XYPosToItemIndex(aPointerPos, itemIndex);
       
  1680         // SERIES60 LAF
       
  1681         CListBoxView::TSelectionMode selectionMode = CListBoxView::ENoSelection;
       
  1682     //        CListBoxView::TSelectionMode selectionMode = (iListBoxFlags & EMultipleSelection) ? CListBoxView::EContiguousSelection : CListBoxView::ESingleSelection;
       
  1683         // END OF SERIES60 LAF
       
  1684 
       
  1685         TInt oldCurrentItemIndex = CurrentItemIndex();
       
  1686         TRect currentItemRect(gridView->ItemPos(oldCurrentItemIndex), gridView->ItemSize(oldCurrentItemIndex));
       
  1687         if (pointerIsOverAnItem)
       
  1688             {
       
  1689             gridView->MoveToItemIndexL(itemIndex, selectionMode);
       
  1690             }
       
  1691         else if ((aPointerPos.iX < viewRect.iTl.iX) || (aPointerPos.iX > viewRect.iBr.iX))
       
  1692             {
       
  1693             // drag event occurred outside the listbox's viewRect
       
  1694             if (aPointerPos.iX < viewRect.iTl.iX)
       
  1695                 gridView->MoveCursorL(CListBoxView::ECursorPreviousColumn, selectionMode);
       
  1696             else if (aPointerPos.iX > viewRect.iBr.iX)
       
  1697                 gridView->MoveCursorL(CListBoxView::ECursorNextColumn, selectionMode);
       
  1698             MoveToNextOrPreviousItemL(aPointerPos);                
       
  1699             UpdateScrollBarThumbs();
       
  1700             Window().RequestPointerRepeatEvent(KEikListBoxPointerRepeatInterval, ignoreDragRect);
       
  1701             }
       
  1702         else
       
  1703             {
       
  1704             // find item nearest to the pointer pos and make that the current item
       
  1705             if (viewRect.Contains(aPointerPos))
       
  1706                 {
       
  1707                 }
       
  1708             else
       
  1709                 {
       
  1710                 if (aPointerPos.iX > currentItemRect.iBr.iX)
       
  1711                     gridView->MoveCursorL(CListBoxView::ECursorNextColumn, selectionMode);
       
  1712                 else if (aPointerPos.iX < currentItemRect.iTl.iX)
       
  1713                     gridView->MoveCursorL(CListBoxView::ECursorPreviousColumn, selectionMode);
       
  1714                 MoveToNextOrPreviousItemL(aPointerPos);
       
  1715                 UpdateScrollBarThumbs();
       
  1716                 Window().RequestPointerRepeatEvent(KEikListBoxPointerRepeatInterval, ignoreDragRect);
       
  1717                 }
       
  1718             }
       
  1719         if (CurrentItemIndex() != oldCurrentItemIndex)
       
  1720             {
       
  1721             iListBoxFlags |= EStateChanged;
       
  1722             if (IsMatchBuffer())
       
  1723                 {
       
  1724                 ClearMatchBuffer();
       
  1725                 DrawMatcherCursor();
       
  1726                 }
       
  1727             }
       
  1728         }
       
  1729     _AKNTRACE_FUNC_EXIT;
       
  1730     }
       
  1731 
       
  1732 EXPORT_C void CAknGrid::RestoreClientRectFromViewRect(TRect& aClientRect) const
       
  1733     {
       
  1734     _AKNTRACE_FUNC_ENTER;
       
  1735     aClientRect=iView->ViewRect();
       
  1736     aClientRect.SetRect(aClientRect.iTl.iX - ListBoxMargins().iLeft, aClientRect.iTl.iY - ListBoxMargins().iTop,
       
  1737                         aClientRect.iBr.iX + ListBoxMargins().iRight, aClientRect.iBr.iY + ListBoxMargins().iBottom);
       
  1738     if (!ViewRectHeightAdjustment())
       
  1739     	{
       
  1740     	_AKNTRACE_FUNC_EXIT;
       
  1741         return;
       
  1742     	}
       
  1743     aClientRect.iBr.iY += ViewRectHeightAdjustment();
       
  1744     _AKNTRACE( "The rect of grid are ( %d, %d ) ( %d, %d )", 
       
  1745     		   aClientRect.iTl.iX, aClientRect.iTl.iY, 
       
  1746     		   aClientRect.iBr.iX, aClientRect.iBr.iY );
       
  1747     _AKNTRACE_FUNC_EXIT;
       
  1748     }
       
  1749 
       
  1750 EXPORT_C TInt CAknGrid::AdjustRectHeightToWholeNumberOfItems(TRect& aRect) const
       
  1751     {
       
  1752     _AKNTRACE_FUNC_ENTER;
       
  1753     TInt remainder = aRect.Height() % (iItemHeight + iSpaceBetweenItems.iHeight);
       
  1754     if (remainder >= iItemHeight)
       
  1755         remainder -= iItemHeight;
       
  1756     if (remainder != 0) 
       
  1757         aRect.iBr.iY -= remainder;
       
  1758     _AKNTRACE_FUNC_EXIT;
       
  1759     return remainder;
       
  1760     }
       
  1761 
       
  1762 EXPORT_C void CAknGrid::MoveToNextOrPreviousItemL(TPoint aPointerPos)
       
  1763     {
       
  1764     _AKNTRACE_FUNC_ENTER;
       
  1765     // SERIES60 LAF
       
  1766     CListBoxView::TSelectionMode selectionMode = CListBoxView::ENoSelection;
       
  1767 //        CListBoxView::TSelectionMode selectionMode = (iListBoxFlags & EMultipleSelection) ? CListBoxView::EContiguousSelection : CListBoxView::ESingleSelection;
       
  1768     // END OF SERIES60 LAF
       
  1769 
       
  1770     TInt cix = CurrentItemIndex();
       
  1771     TRect currentItemRect(iView->ItemPos(cix), iView->ItemSize(cix));
       
  1772     TInt numOfRows =  Max(GridView()->GridCellDimensions().iHeight,1);
       
  1773     
       
  1774     TBool currItemIsInLastRow;
       
  1775     TBool currItemIsInFirstRow;
       
  1776     
       
  1777     if ( AknLayoutUtils::PenEnabled() )  
       
  1778         {
       
  1779         const TInt placesInGrid = numOfRows * iNumOfColsInView;    
       
  1780     
       
  1781         // calculate is the item in first or last row. 
       
  1782         currItemIsInLastRow = ((placesInGrid - iNumOfColsInView) <= cix) && (placesInGrid > cix);    
       
  1783         currItemIsInFirstRow = (cix >= 0 && cix < iNumOfColsInView);
       
  1784         }
       
  1785     else
       
  1786         {
       
  1787         currItemIsInLastRow = ((cix % numOfRows) == (numOfRows-1));
       
  1788         currItemIsInFirstRow = ((cix % numOfRows) == 0);
       
  1789         }
       
  1790 
       
  1791     TBool currItemIsLastItem = (cix == (iModel->NumberOfItems()-1));
       
  1792 
       
  1793     if ((aPointerPos.iY > currentItemRect.iBr.iY) && (! (currItemIsInLastRow || currItemIsLastItem)))
       
  1794         {
       
  1795         iView->MoveCursorL(CListBoxView::ECursorNextItem, selectionMode);
       
  1796         }
       
  1797     else if ((aPointerPos.iY < currentItemRect.iTl.iY) && (! currItemIsInFirstRow))
       
  1798         {
       
  1799         iView->MoveCursorL(CListBoxView::ECursorPreviousItem, selectionMode);
       
  1800         }
       
  1801     _AKNTRACE_FUNC_EXIT;
       
  1802     }
       
  1803 
       
  1804 EXPORT_C void CAknGrid::UpdateScrollBarsL()
       
  1805     {
       
  1806     _AKNTRACE_FUNC_ENTER;
       
  1807     if (!iSBFrame)
       
  1808     	{
       
  1809     	_AKNTRACE_FUNC_EXIT;
       
  1810         return;
       
  1811     	}
       
  1812     TEikScrollBarModel hSbarModel;
       
  1813     TEikScrollBarModel vSbarModel;
       
  1814     CAknGridView* gridView = GridView();
       
  1815     TRect rect=gridView->ViewRect();
       
  1816     if (!(iListBoxFlags & EScrollBarSizeExcluded))
       
  1817         {
       
  1818         // Ignore scrollbars presence to set the model, Scrollbar Frame will change it as required
       
  1819         rect = iBorder.InnerRect(Rect());
       
  1820         rect.SetRect(rect.iTl.iX + ListBoxMargins().iLeft, rect.iTl.iY + ListBoxMargins().iTop,
       
  1821                      rect.iBr.iX - ListBoxMargins().iRight, rect.iBr.iY - ListBoxMargins().iBottom);
       
  1822         AdjustRectHeightToWholeNumberOfItems(rect);
       
  1823         // rect is now viewRect when ignoring scrollbars
       
  1824         }
       
  1825     if (iSBFrame->VScrollBarVisibility()!=CEikScrollBarFrame::EOff)
       
  1826         {
       
  1827         TInt currentIndex = CurrentItemIndex();
       
  1828         if (currentIndex < 0)
       
  1829         	{
       
  1830         	_AKNTRACE_FUNC_EXIT;
       
  1831             return; // current item is not defined
       
  1832         	}
       
  1833         TInt row = 0;
       
  1834         TInt col = 0;
       
  1835         gridView->LogicalPosFromListBoxIndex(currentIndex, row, col);
       
  1836         row *= iView->ItemHeight();
       
  1837         row -= iView->ItemOffsetInPixels();
       
  1838 
       
  1839         TSize gridSize = gridView->GridCellDimensions();
       
  1840         gridSize.iHeight = Max(gridSize.iHeight,1);//check gridSize != 0
       
  1841 
       
  1842         vSbarModel.iThumbPosition = row;
       
  1843         // EHXA-7AQ8N4. Only set it to 0 can make scrollbar empty.
       
  1844         vSbarModel.iScrollSpan = GridModel()->NumberOfItems() >0 ? 
       
  1845             gridSize.iHeight : 0;
       
  1846         vSbarModel.iThumbSpan = gridView->NumberOfRowsInView();
       
  1847         vSbarModel.iScrollSpan = GridModel()->NumberOfItems() >0 ? 
       
  1848             gridSize.iHeight*iView->ItemHeight() : 0;
       
  1849         vSbarModel.iThumbSpan = rect.Height();
       
  1850 
       
  1851         if (iSBFrame->TypeOfVScrollBar() == CEikScrollBarFrame::EDoubleSpan)
       
  1852             {
       
  1853             TInt topRow = 0;
       
  1854             TInt topCol = 0;
       
  1855             gridView->LogicalPosFromListBoxIndex(TopItemIndex(), topRow, topCol);
       
  1856             topRow *= iView->ItemHeight();
       
  1857             topRow -= iView->ItemOffsetInPixels();
       
  1858             vSbarModel.iThumbPosition = topRow;
       
  1859             }
       
  1860         if (vSbarModel.iScrollSpan-vSbarModel.iThumbPosition<vSbarModel.iThumbSpan)
       
  1861             {
       
  1862             vSbarModel.iThumbPosition=Max(0,vSbarModel.iScrollSpan-vSbarModel.iThumbSpan);
       
  1863             gridView->MoveToItemIndexL(currentIndex,CListBoxView::ENoSelection); // force a scroll if neccessary
       
  1864             }
       
  1865         }
       
  1866     if (iSBFrame->ScrollBarVisibility(CEikScrollBar::EHorizontal)!=CEikScrollBarFrame::EOff)
       
  1867         {
       
  1868         GridView()->CalcDataWidth();
       
  1869         hSbarModel.iThumbPosition = gridView->HScrollOffset();
       
  1870         hSbarModel.iScrollSpan = gridView->DataWidth();
       
  1871         }
       
  1872     
       
  1873     if (iSBFrame->TypeOfVScrollBar() == CEikScrollBarFrame::EDoubleSpan)
       
  1874         {
       
  1875         //same scrollbar data within landscape & portraid
       
  1876         TInt varietyIndex = Layout_Meta_Data::IsLandscapeOrientation() ? 1: 0;
       
  1877         TAknWindowComponentLayout layout = TAknWindowComponentLayout::Compose( 
       
  1878             AknLayoutScalable_Avkon::listscroll_app_pane(0),  
       
  1879             AknLayoutScalable_Avkon::scroll_pane_cp15(varietyIndex));
       
  1880             
       
  1881         CEikAppUi* appUi = iEikonEnv->EikAppUi();
       
  1882         TRect clientRect = appUi->ClientRect();      
       
  1883         TRect mainPaneRect;
       
  1884         AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane, mainPaneRect);
       
  1885 
       
  1886         TRect scrollBarParent = TRect( TPoint(0, 0), mainPaneRect.Size());
       
  1887         AknLayoutUtils::LayoutVerticalScrollBar(iSBFrame, scrollBarParent, layout.LayoutLine());
       
  1888         
       
  1889 
       
  1890         TRect inclusiveRect=Rect();
       
  1891         
       
  1892         TEikScrollBarFrameLayout layoutSB;
       
  1893         layoutSB.SetClientMargin(0);
       
  1894         layoutSB.SetInclusiveMargin(0);
       
  1895         layoutSB.iTilingMode=TEikScrollBarFrameLayout::EInclusiveRectConstant;
       
  1896         
       
  1897         iSBFrame->Tile(&hSbarModel, &vSbarModel );
       
  1898         }
       
  1899     else
       
  1900         {
       
  1901         TRect clientRect;
       
  1902         RestoreClientRectFromViewRect(clientRect);
       
  1903         TRect inclusiveRect=Rect();
       
  1904         TEikScrollBarFrameLayout layout;
       
  1905         CreateScrollBarFrameLayout(layout);
       
  1906         TBool sizeChanged=iSBFrame->TileL(&hSbarModel, &vSbarModel, clientRect, inclusiveRect, layout);
       
  1907         if (!sizeChanged)
       
  1908         	{
       
  1909         	_AKNTRACE_FUNC_EXIT;
       
  1910             return;
       
  1911         	}
       
  1912         // else size of client/inclusive rect has changed
       
  1913         if (layout.iTilingMode==TEikScrollBarFrameLayout::EClientRectConstant)
       
  1914             SetSizeWithoutNotification(inclusiveRect.Size());
       
  1915         else
       
  1916             {
       
  1917             SetViewRectFromClientRect(clientRect);
       
  1918             ClearMargins();
       
  1919             }        
       
  1920         }
       
  1921     AdjustTopItemIndex();
       
  1922     _AKNTRACE_FUNC_EXIT;
       
  1923     }
       
  1924 
       
  1925 EXPORT_C void CAknGrid::UpdateScrollBarThumbs() const
       
  1926     {
       
  1927     _AKNTRACE_FUNC_ENTER;
       
  1928     if (!iSBFrame)
       
  1929     	{
       
  1930     	_AKNTRACE_FUNC_EXIT;
       
  1931         return;
       
  1932     	}
       
  1933     CAknGridView* gridView = GridView();
       
  1934     TInt currentDataIndex = gridView->CurrentDataIndex();
       
  1935     TInt row = 0;
       
  1936     TInt col = 0;
       
  1937     gridView->LogicalPosFromDataIndex(currentDataIndex, row, col);
       
  1938     iSBFrame->MoveHorizThumbTo(col);
       
  1939     if (iSBFrame->TypeOfVScrollBar() == CEikScrollBarFrame::EArrowHead)
       
  1940         {
       
  1941         iSBFrame->MoveVertThumbTo(row);
       
  1942         iSBFrame->DrawScrollBarsNow(); 
       
  1943         }
       
  1944     else
       
  1945         {
       
  1946         TInt topRow = 0;
       
  1947         TInt topCol = 0;
       
  1948         gridView->LogicalPosFromListBoxIndex(TopItemIndex(), topRow, topCol);
       
  1949         topRow *= iView->ItemHeight();
       
  1950         topRow -= iView->ItemOffsetInPixels();
       
  1951         iSBFrame->MoveVertThumbTo(topRow);
       
  1952         }
       
  1953     _AKNTRACE_FUNC_EXIT;
       
  1954     }
       
  1955 
       
  1956 EXPORT_C TInt CAknGrid::CountComponentControls() const
       
  1957     {
       
  1958     if (GridModel()->NumberOfItems()<=0) return 0;
       
  1959     return CEikListBox::CountComponentControls();
       
  1960     }
       
  1961 
       
  1962 
       
  1963 // debug only invariant function
       
  1964 EXPORT_C void CAknGrid::__DbgTestInvariant() const          
       
  1965     {
       
  1966 #if defined(_DEBUG)
       
  1967     TBool invalid = EFalse;
       
  1968 
       
  1969     if ( !iModel )
       
  1970         {
       
  1971         invalid = ETrue;
       
  1972         }
       
  1973 
       
  1974     if ( !iView )
       
  1975         {
       
  1976         invalid = ETrue;
       
  1977         }
       
  1978 
       
  1979     if ( invalid )
       
  1980         {
       
  1981         User::Invariant();
       
  1982         }
       
  1983 #endif
       
  1984     }
       
  1985 
       
  1986 EXPORT_C TAny*  CAknGrid::MListBoxModel_Reserved() 
       
  1987     {
       
  1988     return NULL;
       
  1989     }
       
  1990 
       
  1991 
       
  1992 //----------------------------------------------------------------------------
       
  1993 // Handles scroll events received from the scroll bar.
       
  1994 // Function reads thumb position from model and updates view by these values.
       
  1995 // One thumb step is actually one row in list, not item in list. 
       
  1996 //----------------------------------------------------------------------------
       
  1997 //
       
  1998 EXPORT_C void CAknGrid::HandleScrollEventL( CEikScrollBar* aScrollBar,
       
  1999                                             TEikScrollEvent aEventType ) 
       
  2000     {
       
  2001     _AKNTRACE_FUNC_ENTER;
       
  2002     if ( AknLayoutUtils::PenEnabled() )
       
  2003         {
       
  2004         // Read values from model.
       
  2005         TInt oldThumbPos = iView->TopItemIndex() / iNumOfColsInView * iView->ItemHeight() - iView->ItemOffsetInPixels();
       
  2006         TInt newThumbPos = aScrollBar->ThumbPosition();
       
  2007         TInt pageSize = aScrollBar->Model()->iThumbSpan;
       
  2008         TInt maxThumbPos = aScrollBar->Model()->MaxThumbPos();
       
  2009         TBool update = EFalse;
       
  2010 
       
  2011         switch ( aEventType & KEikScrollEventBarMask )
       
  2012             { 
       
  2013             case KEikScrollEventFromHBar:
       
  2014                 {
       
  2015                 switch ( aEventType )
       
  2016                     {
       
  2017                     case EEikScrollLeft:
       
  2018                         {
       
  2019                         newThumbPos -= HorizontalNudgeValue();
       
  2020                         break;
       
  2021                         }
       
  2022                         
       
  2023                     case EEikScrollRight:
       
  2024                         {
       
  2025                         newThumbPos += HorizontalNudgeValue();
       
  2026                         break;
       
  2027                         }
       
  2028                         
       
  2029                     case EEikScrollPageLeft:
       
  2030                         {
       
  2031                         newThumbPos -= pageSize;
       
  2032                         break;
       
  2033                         }
       
  2034                         
       
  2035                     case EEikScrollPageRight:
       
  2036                         {
       
  2037                         newThumbPos += pageSize;
       
  2038                         break;
       
  2039                         }
       
  2040                         
       
  2041                     case EEikScrollThumbDragVert:
       
  2042                         {
       
  2043                         // In the case of drag events, the scrollbar
       
  2044                         // automatically updates its thumb pos...
       
  2045                         SuspendEffects( ETrue );
       
  2046                         break;
       
  2047                         }
       
  2048                         
       
  2049                     case EEikScrollThumbReleaseVert:
       
  2050                         {
       
  2051                         // In the case of drag events, the scrollbar
       
  2052                         // automatically updates its thumb pos...
       
  2053                         SuspendEffects( EFalse );
       
  2054                         break;
       
  2055                         }
       
  2056                         
       
  2057                     default:
       
  2058                         {
       
  2059                         // Do nothing
       
  2060                         break;
       
  2061                         }
       
  2062                     }
       
  2063                     
       
  2064                 newThumbPos = Max( 0, Min( newThumbPos, maxThumbPos ) );
       
  2065                 
       
  2066                 if ( aEventType != EEikScrollThumbDragHoriz )
       
  2067                     {               
       
  2068                     iView->HScroll( newThumbPos - oldThumbPos );
       
  2069                     aScrollBar->SetModelThumbPosition( iView->HScrollOffset() );
       
  2070                     }
       
  2071                 break;
       
  2072                 }
       
  2073                 
       
  2074             case KEikScrollEventFromVBar:
       
  2075                 {
       
  2076                 switch ( aEventType )
       
  2077                     {
       
  2078                     case EEikScrollUp:
       
  2079                         {
       
  2080                         if ( oldThumbPos == 0 && (iListBoxFlags & ELoopScrolling) )
       
  2081                             {
       
  2082                             // move thumb to downmost site if current is upmost
       
  2083                             newThumbPos = maxThumbPos;
       
  2084                             update = ETrue;
       
  2085                             }
       
  2086                         break;
       
  2087                         }
       
  2088                         
       
  2089                     case EEikScrollDown:
       
  2090                         {
       
  2091                         if ( oldThumbPos == maxThumbPos && (iListBoxFlags & ELoopScrolling) )
       
  2092                             {
       
  2093                             // move thumb to upmost site if current is downmost
       
  2094                             newThumbPos = 0;
       
  2095                             update = ETrue;
       
  2096                             }
       
  2097                         break;
       
  2098                         }
       
  2099                         
       
  2100                     case EEikScrollThumbDragVert:
       
  2101                         {
       
  2102                         SuspendEffects( ETrue );
       
  2103                         break;
       
  2104                         }
       
  2105                         
       
  2106                     case EEikScrollThumbReleaseVert:
       
  2107                         {
       
  2108                         SuspendEffects( EFalse );
       
  2109                         break;
       
  2110                         }
       
  2111                         
       
  2112                     default:
       
  2113                         {
       
  2114                         // Do nothing
       
  2115                         break;
       
  2116                         }
       
  2117                     }
       
  2118                     
       
  2119 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  2120                 MAknListBoxTfxInternal* transApi =
       
  2121                     CAknListLoader::TfxApiInternal(
       
  2122                         iView->ItemDrawer()->Gc() );
       
  2123                 TBool effects = newThumbPos != oldThumbPos &&
       
  2124                                     transApi && !transApi->EffectsDisabled();
       
  2125                 if ( effects )
       
  2126                     {
       
  2127                     transApi->SetMoveType( newThumbPos < oldThumbPos ?
       
  2128                                     MAknListBoxTfxInternal::EListScrollUp :
       
  2129                                     MAknListBoxTfxInternal::EListScrollDown );
       
  2130                     }
       
  2131 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  2132  
       
  2133                 if ( iExtension && !ScrollingDisabled() )
       
  2134                     {
       
  2135                     HandlePhysicsScrollEventL( newThumbPos - oldThumbPos );
       
  2136                     }
       
  2137                 else
       
  2138                     {
       
  2139                     // Do normal scrolling if physics are not enabled.
       
  2140                     iView->VScrollTo( newThumbPos/iView->ItemHeight() * iNumOfColsInView );
       
  2141                     }
       
  2142 
       
  2143 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  2144                 if ( effects )
       
  2145                     {
       
  2146                     transApi->Draw( Rect() );
       
  2147                     }
       
  2148 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  2149                 
       
  2150                 // If event has changed thumb position to different than in
       
  2151                 // model do by default, then update scroll bar to
       
  2152                 // correct values. 
       
  2153                 if ( update )
       
  2154                     {               
       
  2155                     aScrollBar->SetModelThumbPosition(
       
  2156                         iView->TopItemIndex() / iNumOfColsInView*iView->ItemHeight() - iView->ItemOffsetInPixels() );
       
  2157                     
       
  2158                     UpdateScrollBarThumbs();
       
  2159                     }
       
  2160                 else
       
  2161                     {
       
  2162                     aScrollBar->DrawNow();                      
       
  2163                     }
       
  2164                 }
       
  2165             
       
  2166             default:
       
  2167                 {
       
  2168                 // Do nothing
       
  2169                 break;
       
  2170                 }
       
  2171             }
       
  2172         }
       
  2173     else
       
  2174         {
       
  2175         CEikListBox::HandleScrollEventL( aScrollBar, aEventType );
       
  2176         }   
       
  2177     _AKNTRACE_FUNC_EXIT;
       
  2178     } 
       
  2179 
       
  2180 
       
  2181 EXPORT_C TTypeUid::Ptr CAknGrid::MopSupplyObject(TTypeUid aId)
       
  2182     {
       
  2183     if ( iExtension && iExtension->iIsFromBaseClass )
       
  2184         {
       
  2185         iExtension->iIsFromBaseClass = EFalse;
       
  2186         return CEikListBox::MopSupplyObject( aId );
       
  2187         }
       
  2188 
       
  2189     if (  iExtension && aId.iUid == MAknsControlContext::ETypeId )
       
  2190         {
       
  2191         MAknsControlContext* cc = NULL;
       
  2192         iExtension->iIsFromBaseClass = ETrue;
       
  2193         if ( !CEikListBox::MopGetObject( cc ))
       
  2194             {
       
  2195             cc = ItemDrawer()->FormattedCellData()->SkinBackgroundContext();
       
  2196             }
       
  2197         return MAknsControlContext::SupplyMopObject( aId, cc);
       
  2198         }
       
  2199     return CEikListBox::MopSupplyObject( aId );
       
  2200     }