landmarksui/uicontrols/src/lmkiconmap.cpp
branchRCL_3
changeset 18 870918037e16
parent 0 522cd55cc3d7
equal deleted inserted replaced
17:1fc85118c3ae 18:870918037e16
       
     1 /*
       
     2  * Copyright (c) 2002-2010 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:    LandmarksUi Content File - Landmarks icon selector map
       
    15  *
       
    16  */
       
    17 
       
    18 // INCLUDE FILES
       
    19 #include <eikenv.h>
       
    20 #include <eiksbfrm.h>
       
    21 #include <eikscrlb.h>
       
    22 #include <bidivisual.h>
       
    23 #include <avkon.rsg>
       
    24 #include <AknPanic.h>
       
    25 #include <avkon.hrh>
       
    26 #include <AknUtils.h>
       
    27 #include <aknlayoutscalable_avkon.cdl.h>
       
    28 #include <layoutmetadata.cdl.h>
       
    29 #include <AknLayout.lag>
       
    30 
       
    31 #include <aknappui.h>
       
    32 #include <aknconsts.h>
       
    33 #include <AknDef.h>
       
    34 #include <PUAcodes.hrh>
       
    35 #include <s32file.h>
       
    36 
       
    37 #ifdef RD_TACTILE_FEEDBACK
       
    38 #include <touchfeedback.h>
       
    39 #endif //RD_TACTILE_FEEDBACK
       
    40 // For the TEikScrollBarModelType
       
    41 #include <eikscrlb.h>
       
    42 
       
    43 #include <AknsDrawUtils.h>
       
    44 #include <featmgr.h>
       
    45 
       
    46 #include <AknsFrameBackgroundControlContext.h>
       
    47 
       
    48 #include <lmkui.mbg>
       
    49 
       
    50 #include "lmkiconmap.h"
       
    51 #include "CLmkUiUtils.h"
       
    52 #include <lmkerrors.h>
       
    53 
       
    54 // The offset because of CEikDialogPage
       
    55 const TInt KHorizontalDialogMargin = 0;
       
    56 const TInt KVerticalDialogMargin = 0;
       
    57 const TInt KAknSctCBaButtonDirections = 3; // bottom, right and left
       
    58 
       
    59 
       
    60 /// Unnamed namespace for local definitions
       
    61 namespace
       
    62     {
       
    63     const TInt KNumOfIcons(16);
       
    64     _LIT( KPanicMsg, "CLmkIconMap" );
       
    65 
       
    66     void Panic(TPanicCode aReason)
       
    67         {
       
    68         User::Panic(KPanicMsg, aReason);
       
    69         }
       
    70     } // namespace
       
    71 
       
    72 // ============================ EXTENSION CLASS ===============================
       
    73 //Class Declaration
       
    74 NONSHARABLE_CLASS(CLmkIconMapExtension) : public CBase,
       
    75 public MObjectProvider
       
    76     {
       
    77 public:
       
    78     CLmkIconMapExtension();
       
    79     ~CLmkIconMapExtension();
       
    80 
       
    81 protected:
       
    82     TTypeUid::Ptr MopSupplyObject(TTypeUid aId);
       
    83     MObjectProvider* MopNext();
       
    84 
       
    85 public:
       
    86     // data
       
    87     MCoeControlObserver *iObserver;
       
    88 
       
    89     TUint iFlags;
       
    90     MObjectProvider* iIconMap;
       
    91     TInt iMaxVisibleRows;
       
    92     CAknsFrameBackgroundControlContext* iBgContext;
       
    93     };
       
    94 
       
    95 // ============================ MEMBER FUNCTIONS OF CLmkIconMapExtension ===============================
       
    96 
       
    97 // -----------------------------------------------------------------------------
       
    98 // CLmkIconMapExtension::CLmkIconMapExtension
       
    99 // C++ default constructor can NOT contain any code, that
       
   100 // might leave.
       
   101 // -----------------------------------------------------------------------------
       
   102 //
       
   103 CLmkIconMapExtension::CLmkIconMapExtension() :
       
   104     iMaxVisibleRows(0)
       
   105     {
       
   106     iObserver = NULL;
       
   107     }
       
   108 
       
   109 // -----------------------------------------------------------------------------
       
   110 // CLmkIconMapExtension::MopSupplyObject()
       
   111 // -----------------------------------------------------------------------------
       
   112 //
       
   113 TTypeUid::Ptr CLmkIconMapExtension::MopSupplyObject(TTypeUid aId)
       
   114     {
       
   115     return MAknsControlContext::SupplyMopObject(aId, iBgContext);
       
   116     }
       
   117 
       
   118 // -----------------------------------------------------------------------------
       
   119 // CLmkIconMapExtension::MopNext()
       
   120 // -----------------------------------------------------------------------------
       
   121 //
       
   122 MObjectProvider* CLmkIconMapExtension::MopNext()
       
   123     {
       
   124     return iIconMap;
       
   125     }
       
   126 
       
   127 // -----------------------------------------------------------------------------
       
   128 // CLmkIconMapExtension::~CLmkIconMapExtension()
       
   129 // -----------------------------------------------------------------------------
       
   130 //
       
   131 CLmkIconMapExtension::~CLmkIconMapExtension()
       
   132     {
       
   133 
       
   134     delete iBgContext;
       
   135     }
       
   136 
       
   137 // ============================ MEMBER FUNCTIONS OF CLmkIconMap ===============================
       
   138 
       
   139 // -----------------------------------------------------------------------------
       
   140 // CLmkIconMap::CLmkIconMap
       
   141 // C++ default constructor can NOT contain any code, that
       
   142 // might leave.
       
   143 // -----------------------------------------------------------------------------
       
   144 //
       
   145 CLmkIconMap::CLmkIconMap() :
       
   146     iCursorPos(TPoint(0, 0)), iOldCursorPos(TPoint(0, 0)), iMaxColumns(-1),
       
   147             iCurrentPage(0), iNumPages(0)
       
   148     {
       
   149     iConsArray = (CArrayPtr<CGulIcon>*) NULL;
       
   150     }
       
   151 
       
   152 // -----------------------------------------------------------------------------
       
   153 // CLmkIconMap::NewL
       
   154 // Two-phased constructor.
       
   155 // -----------------------------------------------------------------------------
       
   156 //
       
   157 CLmkIconMap* CLmkIconMap::NewL()
       
   158     {
       
   159     CLmkIconMap* self = new (ELeave) CLmkIconMap();
       
   160 
       
   161     CleanupStack::PushL(self);
       
   162     self->ConstructL();
       
   163     CleanupStack::Pop(self); //self
       
   164     return self;
       
   165     }
       
   166 
       
   167 // -----------------------------------------------------------------------------
       
   168 // CLmkIconMap::ConstructL
       
   169 // Symbian 2nd phase constructor can leave.
       
   170 // -----------------------------------------------------------------------------
       
   171 //
       
   172 void CLmkIconMap::ConstructL()
       
   173     {
       
   174     // Must be created here to get the member variables available
       
   175     iExtension = new (ELeave) CLmkIconMapExtension;
       
   176     iExtension->iIconMap = this;
       
   177 
       
   178     iConsArray = new (ELeave) CAknIconArray(KNumOfIcons);
       
   179 
       
   180     iExtension->iFlags = 0x00;
       
   181 
       
   182     DoLayout();
       
   183     }
       
   184 
       
   185 // -----------------------------------------------------------------------------
       
   186 // CLmkIconMap::~CLmkIconMap()
       
   187 // -----------------------------------------------------------------------------
       
   188 //
       
   189 CLmkIconMap::~CLmkIconMap()
       
   190     {
       
   191     delete iSBFrame;
       
   192     iSBFrame = (CEikScrollBarFrame*) NULL;
       
   193 
       
   194     delete iOffscreenBg;
       
   195     delete iBitmapDevice;
       
   196     delete iBitmapGc;
       
   197 
       
   198     delete iExtension;
       
   199     iExtension = (CLmkIconMapExtension*) NULL;
       
   200 
       
   201     if (iConsArray)
       
   202         {
       
   203         iConsArray->ResetAndDestroy();
       
   204         delete iConsArray;
       
   205         iConsArray = (CArrayPtr<CGulIcon>*) NULL;
       
   206         }
       
   207     }
       
   208 
       
   209 // -----------------------------------------------------------------------------
       
   210 // CLmkIconMap::DoLayout()
       
   211 // -----------------------------------------------------------------------------
       
   212 //
       
   213 void CLmkIconMap::DoLayout()
       
   214     {
       
   215     TRAPD(err, LoadIconL());
       
   216     if (err)
       
   217         return;
       
   218 
       
   219     iIsMirrored = AknLayoutUtils::LayoutMirrored();
       
   220     iDrawnBefore = EFalse;
       
   221     CountMaxColumnsAndCellSizes();
       
   222     SizeChanged();
       
   223     }
       
   224 
       
   225 // -----------------------------------------------------------------------------
       
   226 // CLmkIconMap::ConstructFromResourceL()
       
   227 // -----------------------------------------------------------------------------
       
   228 //
       
   229 void CLmkIconMap::ConstructFromResourceL(TResourceReader& /*aReader*/)
       
   230     {
       
   231     LoadIconL();
       
   232     CreateScrollBarAndIconRowL();
       
   233 
       
   234     Extension()->iBgContext = CAknsFrameBackgroundControlContext::NewL(
       
   235             KAknsIIDQsnFrPopup, TRect(0, 0, 1, 1), TRect(0, 0, 1, 1), EFalse);
       
   236 
       
   237     if (DrawableWindow() && AknLayoutUtils::PenEnabled())
       
   238         {
       
   239         EnableDragEvents();
       
   240         SetGloballyCapturing( ETrue);
       
   241         SetPointerCapture(ETrue);
       
   242         }
       
   243     }
       
   244 
       
   245 // -----------------------------------------------------------------------------
       
   246 // CLmkIconMap::LoadIcons()
       
   247 // This actually load the all icons to be shown on dialog from icon file
       
   248 // -----------------------------------------------------------------------------
       
   249 //
       
   250 void CLmkIconMap::LoadIconL()
       
   251     {
       
   252     if (iConsArray)
       
   253         {
       
   254         iConsArray->ResetAndDestroy();
       
   255         }
       
   256     // Draw all the Icons.
       
   257     TFileName* iconFile = CLmkUiUtils::LmkUiIconFileLC();
       
   258 
       
   259     // Create icon bitmap and mask.
       
   260     for (TInt i(0); i < (KNumOfIcons * 2); i++)
       
   261         {
       
   262         CFbsBitmap* bitmap = NULL;
       
   263         CFbsBitmap* bitmapMask = NULL;
       
   264         AknIconUtils::CreateIconLC(bitmap, bitmapMask, *iconFile,
       
   265                 EMbmLmkuiQgn_prop_lm_transport + i,
       
   266                 EMbmLmkuiQgn_prop_lm_transport + i + 1);
       
   267         i++;
       
   268         AknIconUtils::SetSize(bitmap, TSize(iGridItemWidth, iGridItemHeight)); //fix
       
   269         AknIconUtils::SetSize(bitmapMask, TSize(iGridItemWidth,
       
   270                 iGridItemHeight)); //fix
       
   271         CGulIcon* icon = CGulIcon::NewL(bitmap, bitmapMask);
       
   272         CleanupStack::PushL(icon);
       
   273         if (iConsArray)
       
   274             iConsArray->AppendL(icon);
       
   275         CleanupStack::Pop(icon); // icon
       
   276         CleanupStack::Pop(bitmapMask); // mask
       
   277         CleanupStack::Pop(bitmap); // bitmap
       
   278         }
       
   279     CleanupStack::PopAndDestroy();// iconFile
       
   280     }
       
   281 
       
   282 // -----------------------------------------------------------------------------
       
   283 // CLmkIconMap::HeightInRows()
       
   284 // This actually returns the no of rows to be shown on a page
       
   285 // Depends upon the Layout size
       
   286 // -----------------------------------------------------------------------------
       
   287 //
       
   288 TInt CLmkIconMap::HeightInRows()
       
   289     {
       
   290     return (iRows);
       
   291     }
       
   292 
       
   293 // -----------------------------------------------------------------------------
       
   294 // CLmkIconMap::CreateScrollBarAndIconRowL()
       
   295 // This actually creates the scroll bar sets the number of
       
   296 // pages and rows on a page to be shown
       
   297 // -----------------------------------------------------------------------------
       
   298 //
       
   299 void CLmkIconMap::CreateScrollBarAndIconRowL()
       
   300     {
       
   301     __ASSERT_DEBUG(iExtension, Panic(KLmkPanicInvalidResourceData));
       
   302 
       
   303     __ASSERT_ALWAYS(iConsArray, Panic(KLmkPanicInvalidResourceData));
       
   304 
       
   305     iRows = ((iConsArray->Count() - 1) / iMaxColumns) + 1;
       
   306     iFirstVisibleRow = 0;
       
   307     iAnimated = EFalse;
       
   308     iCursorPos = TPoint(0, 0);
       
   309     iNumPages = (iRows / iExtension->iMaxVisibleRows) + (iRows
       
   310             % iExtension->iMaxVisibleRows ? 1 : 0);
       
   311     iCurrentPage = 1;
       
   312 
       
   313     // Create and set the scb visible even though there is nothing to scroll
       
   314     delete iSBFrame;
       
   315     iSBFrame = NULL;
       
   316 
       
   317     if (AknLayoutUtils::PenEnabled())
       
   318         {
       
   319         iSBFrame = new (ELeave) CEikScrollBarFrame(this, this, ETrue);
       
   320         }
       
   321     else
       
   322         {
       
   323         iSBFrame = new (ELeave) CEikScrollBarFrame(this, NULL, ETrue);
       
   324         }
       
   325     // Decide which type of scrollbar is shown
       
   326     CAknAppUi* appUi = iAvkonAppUi;
       
   327     if (AknLayoutUtils::DefaultScrollBarType(appUi)
       
   328             == CEikScrollBarFrame::EDoubleSpan)
       
   329         {
       
   330         // For EDoubleSpan type scrollbar
       
   331         if (AknLayoutUtils::PenEnabled())
       
   332             {
       
   333             iSBFrame->CreateDoubleSpanScrollBarsL(ETrue, EFalse, ETrue,
       
   334                     EFalse); // window owning scrollbar
       
   335             }
       
   336         else
       
   337             {
       
   338             iSBFrame->CreateDoubleSpanScrollBarsL(EFalse, EFalse, ETrue,
       
   339                     EFalse); // non-window owning scrollbar
       
   340             }
       
   341         iSBFrame->SetTypeOfVScrollBar(CEikScrollBarFrame::EDoubleSpan);
       
   342         }
       
   343     else
       
   344         {
       
   345         // For EArrowHead type scrollbar
       
   346         iSBFrame->SetTypeOfVScrollBar(CEikScrollBarFrame::EArrowHead);
       
   347         }
       
   348 
       
   349     iSBFrame->SetScrollBarVisibilityL(CEikScrollBarFrame::EOff,
       
   350             CEikScrollBarFrame::EAuto);
       
   351     iSBFrame->VerticalScrollBar()->SetMopParent(iExtension);
       
   352     UpdateScrollIndicatorL();
       
   353     }
       
   354 
       
   355 // -----------------------------------------------------------------------------
       
   356 // CLmkIconMap::SetIndex
       
   357 // set the reference of the selected icon index from the table
       
   358 // -----------------------------------------------------------------------------
       
   359 //
       
   360 void CLmkIconMap::SetIndex(TInt& aIconIndex)
       
   361     {
       
   362     iIconIndex = &aIconIndex;
       
   363     }
       
   364 
       
   365 // -----------------------------------------------------------------------------
       
   366 // CLmkIconMap::MinimumSize
       
   367 //
       
   368 // -----------------------------------------------------------------------------
       
   369 //
       
   370 TSize CLmkIconMap::MinimumSize()
       
   371     {
       
   372     iIsMirrored = AknLayoutUtils::LayoutMirrored();
       
   373     CountMaxColumnsAndCellSizes();
       
   374 
       
   375     TRect rect;
       
   376     // Used the set rect, but resolution changes cannot be handled when it is used
       
   377 
       
   378     TAknLayoutRect dialogLayRect;
       
   379 
       
   380     // Main pane without softkeys
       
   381     TRect mainPaneRect;
       
   382     if (!AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane,
       
   383             mainPaneRect))
       
   384         {
       
   385         mainPaneRect = iAvkonAppUi->ClientRect();
       
   386         }
       
   387 
       
   388     // Dialog layout, check variety first
       
   389     TAknLayoutScalableParameterLimits iconMapDialogVariety =
       
   390             AknLayoutScalable_Avkon::popup_grid_graphic_window_ParamLimits();
       
   391 
       
   392     // Calc the variety
       
   393     TInt maxVariety = iconMapDialogVariety.LastVariety();
       
   394 
       
   395     // Check the CBA, if the orientation is not landscape
       
   396     // there is not so much varieties
       
   397     AknLayoutUtils::TAknCbaLocation location = AknLayoutUtils::CbaLocation();
       
   398     TInt maxVarietyOffset = 0; // the offset for the certain cba location variety
       
   399     TInt varietyOffset = maxVariety + 1; // the number of varieties
       
   400 
       
   401     // landscape variety number must be calculated offset == number of varieties
       
   402     // same applies to the variety number for the biggest sized layout for the variety
       
   403     if (Layout_Meta_Data::IsLandscapeOrientation())
       
   404         {
       
   405         varietyOffset = (maxVariety + 1) / KAknSctCBaButtonDirections; // the offset for one variety
       
   406         }
       
   407 
       
   408     // for right and left cba buttons the max variety is not zero
       
   409     // the varities are ordered by the location of the cba and the descending order
       
   410     // e.g the biggest sized layout first, the smallest last
       
   411     if (location == AknLayoutUtils::EAknCbaLocationRight)
       
   412         {
       
   413         maxVarietyOffset = varietyOffset;
       
   414         }
       
   415     else if (location == AknLayoutUtils::EAknCbaLocationLeft)
       
   416         {
       
   417         maxVarietyOffset = varietyOffset + varietyOffset; // 2*
       
   418         }
       
   419 
       
   420     TInt varietyNumber = varietyOffset - iRows - 1;
       
   421 
       
   422     // if more lines than possible to show, use the default
       
   423     // (the biggest grid) variety
       
   424     if (varietyNumber < 0)
       
   425         varietyNumber = 0;
       
   426     // if zero rows, use the minimum
       
   427     else if (iRows <= 0)
       
   428         varietyNumber -= 1;
       
   429 
       
   430     //add the varietyoffset
       
   431     varietyNumber += maxVarietyOffset;
       
   432 
       
   433     if (Layout_Meta_Data::IsLandscapeOrientation() && (location
       
   434             == AknLayoutUtils::EAknCbaLocationRight))
       
   435         {
       
   436         varietyNumber = 10;
       
   437         }
       
   438     else
       
   439         {
       
   440         if (iRows == 0)
       
   441             {
       
   442             varietyNumber = 5;
       
   443             }
       
   444         else
       
   445             {
       
   446             varietyNumber = 3;
       
   447             }
       
   448         }
       
   449     // Layout the dialog size
       
   450     dialogLayRect.LayoutRect(mainPaneRect,
       
   451             AknLayoutScalable_Avkon::popup_grid_graphic_window(varietyNumber));
       
   452 
       
   453     // Layout the grid
       
   454     TAknLayoutRect gridWithScrollLayRect;
       
   455     gridWithScrollLayRect.LayoutRect(dialogLayRect.Rect(),
       
   456             AknLayoutScalable_Avkon::listscroll_popup_graphic_pane());
       
   457 
       
   458     return TSize(dialogLayRect.Rect().Width(),
       
   459             gridWithScrollLayRect.Rect().Height());
       
   460     }
       
   461 
       
   462 // -----------------------------------------------------------------------------
       
   463 // CLmkIconMap::ActivateL()
       
   464 // This method is needed to set correct initial value to scroll indicator.
       
   465 // -----------------------------------------------------------------------------
       
   466 //
       
   467 void CLmkIconMap::ActivateL()
       
   468     {
       
   469     CCoeControl::ActivateL();
       
   470     if (iRows > Extension()->iMaxVisibleRows)
       
   471         {
       
   472         UpdateScrollIndicatorL();
       
   473         }
       
   474     }
       
   475 
       
   476 // -----------------------------------------------------------------------------
       
   477 // CLmkIconMap::OfferKeyEventL
       
   478 // Handles all the Keypad events
       
   479 // -----------------------------------------------------------------------------
       
   480 //
       
   481 TKeyResponse CLmkIconMap::OfferKeyEventL(const TKeyEvent& aKeyEvent,
       
   482         TEventCode /*aModifiers*/)
       
   483     {
       
   484     TUint code = aKeyEvent.iCode;
       
   485 
       
   486     switch (code)
       
   487         {
       
   488         case EKeyLeftArrow:
       
   489         case '4':
       
   490             MoveCursorL(-1, 0);
       
   491             break;
       
   492         case EKeyRightArrow:
       
   493         case '6':
       
   494             MoveCursorL(1, 0);
       
   495             break;
       
   496         case EKeyUpArrow:
       
   497         case '2':
       
   498             MoveCursorL(0, -1);
       
   499             break;
       
   500         case EKeyDownArrow:
       
   501         case '8':
       
   502             MoveCursorL(0, 1);
       
   503             break;
       
   504         case EKeyOK:
       
   505         case '5':
       
   506         case EKeySpace:
       
   507         case EKeyEnter:
       
   508             {
       
   509             if (iConsArray)
       
   510                 {
       
   511                 TInt ret = iMaxColumns * (iFirstVisibleRow + iCursorPos.iY)
       
   512                         + iCursorPos.iX;
       
   513                 if (ret <= iConsArray->Count())
       
   514                     {
       
   515                     *iIconIndex = ret;
       
   516                     }
       
   517                 else
       
   518                     {
       
   519                     *iIconIndex = -1;
       
   520                     }
       
   521                 }
       
   522 
       
   523             }
       
   524             break;
       
   525         default:
       
   526             return EKeyWasNotConsumed;
       
   527 
       
   528         }
       
   529     return EKeyWasConsumed;
       
   530     }
       
   531 
       
   532 // -----------------------------------------------------------------------------
       
   533 // CLmkIconMap::InputCapabilities()
       
   534 //
       
   535 // -----------------------------------------------------------------------------
       
   536 //
       
   537 TCoeInputCapabilities CLmkIconMap::InputCapabilities() const
       
   538     {
       
   539     return TCoeInputCapabilities(TCoeInputCapabilities::EAllText);
       
   540     }
       
   541 
       
   542 // -----------------------------------------------------------------------------
       
   543 // CLmkIconMap::SizeChanged()
       
   544 // Control position of this control is registered for skin library when necessary
       
   545 // in CEikDialogPage::SetDataPosition, so we do not do that in this method.
       
   546 // -----------------------------------------------------------------------------
       
   547 //
       
   548 void CLmkIconMap::SizeChanged()
       
   549     {
       
   550     // Get the layout
       
   551 
       
   552     // Main pane without softkeys
       
   553     TRect mainPaneRect;
       
   554 
       
   555     if (!AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane,
       
   556             mainPaneRect))
       
   557         {
       
   558         mainPaneRect = iAvkonAppUi->ClientRect();
       
   559         }
       
   560 
       
   561     // Dialog layout, check variety first
       
   562     TAknLayoutScalableParameterLimits iconMapDialogVariety =
       
   563             AknLayoutScalable_Avkon::popup_grid_graphic_window_ParamLimits();
       
   564 
       
   565     TInt maxVariety = iconMapDialogVariety.LastVariety();
       
   566 
       
   567     // Check the CBA, if the orientation is not landscape
       
   568     // there is not so much varieties
       
   569     AknLayoutUtils::TAknCbaLocation location = AknLayoutUtils::CbaLocation();
       
   570     TInt maxVarietyOffset = 0; // the offset for the certain cba location variety
       
   571     TInt varietyOffset = maxVariety + 1;
       
   572 
       
   573     // landscape variety number must be calculated offset == number of varieties
       
   574     // same applies to the variety number for the biggest sized layout for the variety
       
   575     if (Layout_Meta_Data::IsLandscapeOrientation())
       
   576         {
       
   577         varietyOffset = (maxVariety + 1) / KAknSctCBaButtonDirections; // the offset for one variety
       
   578         }
       
   579 
       
   580     // for right and left cba buttons the max variety is not zero
       
   581     // the varities are ordered by the location of the cba and the descending order
       
   582     // e.g the biggest sized layout first, the smallest last
       
   583     if (location == AknLayoutUtils::EAknCbaLocationRight)
       
   584         {
       
   585         maxVarietyOffset = varietyOffset;
       
   586         }
       
   587     else if (location == AknLayoutUtils::EAknCbaLocationLeft)
       
   588         {
       
   589         maxVarietyOffset = varietyOffset + varietyOffset; // 2*
       
   590         }
       
   591 
       
   592     TInt varietyNumber = varietyOffset - iRows - 1;
       
   593 
       
   594     // if more lines than possible to show, use the default
       
   595     // (the biggest grid) variety
       
   596     if (varietyNumber < 0)
       
   597         varietyNumber = 0;
       
   598     // if zero rows, use the minimum
       
   599     else if (iRows <= 0)
       
   600         varietyNumber -= 1;
       
   601 
       
   602     //add the varietyoffset
       
   603     varietyNumber += maxVarietyOffset;
       
   604 
       
   605     if (Layout_Meta_Data::IsLandscapeOrientation() && (location
       
   606             == AknLayoutUtils::EAknCbaLocationRight))
       
   607         {
       
   608         varietyNumber = 10;
       
   609         }
       
   610     else
       
   611         {
       
   612         if (iRows == 0)
       
   613             {
       
   614             varietyNumber = 5;
       
   615             }
       
   616         else
       
   617             {
       
   618             varietyNumber = 3;
       
   619             }
       
   620 
       
   621         }
       
   622 
       
   623     TAknLayoutRect popupGridLayRect;
       
   624     popupGridLayRect.LayoutRect(mainPaneRect,
       
   625             AknLayoutScalable_Avkon::popup_grid_graphic_window(varietyNumber));
       
   626 
       
   627     // Calculate the size relatively
       
   628     TRect relativeDialog(TPoint(0, 0), popupGridLayRect.Rect().Size());
       
   629 
       
   630     // Get the layout of the actual icon grid with scrollbar
       
   631     TAknLayoutRect gridWithScrollLayRect;
       
   632     gridWithScrollLayRect.LayoutRect(relativeDialog,
       
   633             AknLayoutScalable_Avkon::listscroll_popup_graphic_pane());
       
   634 
       
   635     // Then the grid area without scrollbar
       
   636     // NOTE: The grid with scroll bar is used as reference
       
   637     TAknLayoutRect gridLayRect;
       
   638     gridLayRect.LayoutRect(gridWithScrollLayRect.Rect(),
       
   639             AknLayoutScalable_Avkon::grid_graphic_popup_pane(0));
       
   640 
       
   641     // Different parent if SCT inside editing menu.
       
   642     TRect contentRect = gridLayRect.Rect();
       
   643 
       
   644     // The x coordinate is 3 pixels to right and y coordinate 3 pixels up
       
   645     // so substract from x coordinate and add to y coordinate
       
   646     if (iIsMirrored)
       
   647         {
       
   648         iOffset = TPoint(contentRect.iBr.iX - KHorizontalDialogMargin
       
   649                 - iGridItemWidth + 1, contentRect.iTl.iY
       
   650                 - KVerticalDialogMargin + 1);
       
   651         iGridTopLeft.iX = contentRect.iBr.iX - KHorizontalDialogMargin
       
   652                 - (iMaxColumns * iGridItemWidth);
       
   653         iGridTopLeft.iY = contentRect.iTl.iY - KVerticalDialogMargin;
       
   654         }
       
   655     else // not mirrored
       
   656         {
       
   657         iOffset = TPoint(contentRect.iTl.iX - KHorizontalDialogMargin + 1,
       
   658                 contentRect.iTl.iY - KVerticalDialogMargin + 1);
       
   659         iGridTopLeft.iX = contentRect.iTl.iX - KHorizontalDialogMargin;
       
   660         iGridTopLeft.iY = contentRect.iTl.iY - KVerticalDialogMargin;
       
   661         }
       
   662 
       
   663     // The last, update background context
       
   664     if (Extension()->iBgContext)
       
   665         {
       
   666         TInt bgVariety = 0;
       
   667         if (Layout_Meta_Data::IsLandscapeOrientation())
       
   668             bgVariety = 1;
       
   669 
       
   670         TAknLayoutRect innerRect;
       
   671         innerRect.LayoutRect(relativeDialog,
       
   672                 AknLayoutScalable_Avkon::bg_popup_window_pane_g1(bgVariety));
       
   673 
       
   674         Extension()->iBgContext->SetFrameRects(relativeDialog,
       
   675                 innerRect.Rect());
       
   676         }
       
   677     TRAPD(err, UpdateScrollIndicatorL());
       
   678     if (err)
       
   679         return;
       
   680     }
       
   681 
       
   682 // -----------------------------------------------------------------------------
       
   683 // CLmkIconMap::HandleResourceChange()
       
   684 //
       
   685 // -----------------------------------------------------------------------------
       
   686 //
       
   687 void CLmkIconMap::HandleResourceChange(TInt aType)
       
   688     {
       
   689     if (aType == KEikDynamicLayoutVariantSwitch)
       
   690         {
       
   691         // save the old info for the magnitudes of the SCT grid
       
   692         TInt oldMaxColumns = iMaxColumns;
       
   693         //TInt oldMaxRows = 0;
       
   694         //oldMaxRows = iRows;
       
   695         // calculate the new magnitudes
       
   696         DoLayout();
       
   697 
       
   698         // then calculate the index position of the cursor in the icon table
       
   699         // and update the x and y positions for the new grid with it
       
   700 
       
   701         TInt oldCursorPosition = (iFirstVisibleRow + iOldCursorPos.iY)
       
   702                 * oldMaxColumns + iOldCursorPos.iX;
       
   703 
       
   704         TInt currentCursorPosition = (iFirstVisibleRow + iCursorPos.iY)
       
   705                 * oldMaxColumns + iCursorPos.iX;
       
   706 
       
   707         // the new first row is the top row on the page where the new focus is
       
   708         iFirstVisibleRow = Extension()->iMaxVisibleRows
       
   709                 * (currentCursorPosition / (iMaxColumns
       
   710                         * Extension()->iMaxVisibleRows));
       
   711 
       
   712         // the cursor positions are relative to current page
       
   713         iCursorPos.iY = (currentCursorPosition - (iMaxColumns
       
   714                 * iFirstVisibleRow)) / iMaxColumns;
       
   715         iCursorPos.iX = currentCursorPosition - (iMaxColumns
       
   716                 * iFirstVisibleRow) - (iMaxColumns * iCursorPos.iY);
       
   717 
       
   718         iOldCursorPos.iY = (oldCursorPosition - (iMaxColumns
       
   719                 * iFirstVisibleRow)) / iMaxColumns;
       
   720         iOldCursorPos.iX = oldCursorPosition - (iMaxColumns
       
   721                 * iFirstVisibleRow) - (iMaxColumns * iOldCursorPos.iY);
       
   722         }
       
   723 
       
   724     if (aType == KAknsMessageSkinChange)
       
   725         {
       
   726         iOffscreenBgDrawn = EFalse;
       
   727         }
       
   728     CCoeControl::HandleResourceChange(aType);
       
   729 
       
   730     }
       
   731 
       
   732 // -----------------------------------------------------------------------------
       
   733 // CLmkIconMap::Draw()
       
   734 //
       
   735 // -----------------------------------------------------------------------------
       
   736 //
       
   737 void CLmkIconMap::Draw(const TRect& /*aRect*/) const
       
   738     {
       
   739 
       
   740     TInt cursorPos = 0;
       
   741     CWindowGc& gc = SystemGc();
       
   742 
       
   743     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
   744     MAknsControlContext* cc = AknsDrawUtils::ControlContext(this);
       
   745 
       
   746     TRect rect = Rect();
       
   747 
       
   748     // Main pane without softkeys
       
   749     TRect mainPaneRect;
       
   750     if (!AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane,
       
   751             mainPaneRect))
       
   752         {
       
   753         mainPaneRect = iAvkonAppUi->ClientRect();
       
   754         }
       
   755 
       
   756     // Dialog layout, check variety first
       
   757     TAknLayoutScalableParameterLimits iconMapDialogVariety =
       
   758             AknLayoutScalable_Avkon::popup_grid_graphic_window_ParamLimits();
       
   759 
       
   760     // The variety starts from 0 so add +1
       
   761     TInt maxVariety = iconMapDialogVariety.LastVariety();
       
   762 
       
   763     // Check the CBA, if the orientation is not landscape
       
   764     // there is not so much varieties
       
   765     AknLayoutUtils::TAknCbaLocation location = AknLayoutUtils::CbaLocation();
       
   766     TInt maxVarietyOffset = 0; // the offset for the certain cba location variety
       
   767     TInt varietyOffset = maxVariety + 1;
       
   768 
       
   769     // landscape variety number must be calculated offset == number of varieties
       
   770     // same applies to the variety number for the biggest sized layout for the variety
       
   771     if (Layout_Meta_Data::IsLandscapeOrientation())
       
   772         {
       
   773         varietyOffset = (maxVariety + 1) / KAknSctCBaButtonDirections; // the offset for one variety
       
   774         }
       
   775 
       
   776     // for right and left cba buttons the max variety is not zero
       
   777     // the varities are ordered by the location of the cba and the descending order
       
   778     // e.g the biggest sized layout first, the smallest last
       
   779     if (location == AknLayoutUtils::EAknCbaLocationRight)
       
   780         {
       
   781         maxVarietyOffset = varietyOffset;
       
   782         }
       
   783     else if (location == AknLayoutUtils::EAknCbaLocationLeft)
       
   784         {
       
   785         maxVarietyOffset = varietyOffset + varietyOffset; // 2*
       
   786         }
       
   787 
       
   788     TInt varietyNumber = varietyOffset - iRows - 1;
       
   789 
       
   790     // if more lines than possible to show, use the default
       
   791     // (the biggest grid) variety
       
   792     if (varietyNumber < 0)
       
   793         varietyNumber = 0;
       
   794     // if zero rows, use the minimum
       
   795     else if (iRows <= 0)
       
   796         varietyNumber -= 1;
       
   797 
       
   798     //add the varietyoffset
       
   799     varietyNumber += maxVarietyOffset;
       
   800 
       
   801     if (Layout_Meta_Data::IsLandscapeOrientation() && (location
       
   802             == AknLayoutUtils::EAknCbaLocationRight))
       
   803         {
       
   804         varietyNumber = 10;
       
   805         }
       
   806     else
       
   807         {
       
   808         varietyNumber = 3;
       
   809         }
       
   810     // Layout the dialog size
       
   811     TAknLayoutRect dialogLayRect;
       
   812     dialogLayRect.LayoutRect(mainPaneRect,
       
   813             AknLayoutScalable_Avkon::popup_grid_graphic_window(varietyNumber));
       
   814 
       
   815     // Get the missing height for the background
       
   816     TInt backgroundHeightOffset = dialogLayRect.Rect().Height() - rect.iBr.iY;
       
   817 
       
   818     rect.iBr.iY += backgroundHeightOffset;
       
   819 
       
   820     // Check if we got an offscreen bitmap allocated for skin background and
       
   821     // there is bitmap background in the current skin.
       
   822     if (iOffscreenBg && iHasBitmapBackground)
       
   823         {
       
   824         DrawOffscreenBackgroundIfRequired();
       
   825         gc.BitBlt(rect.iTl, iOffscreenBg);
       
   826         }
       
   827     else
       
   828         {
       
   829         AknsDrawUtils::Background(skin, cc, this, gc, rect);
       
   830         }
       
   831 
       
   832     TInt numberOfIconsToBeDrawn = iConsArray->Count();
       
   833     numberOfIconsToBeDrawn -= (iFirstVisibleRow * iMaxColumns);
       
   834     if (numberOfIconsToBeDrawn > 0)
       
   835         {
       
   836         if (numberOfIconsToBeDrawn > (Extension()->iMaxVisibleRows
       
   837                 * iMaxColumns))
       
   838             {
       
   839             numberOfIconsToBeDrawn = Extension()->iMaxVisibleRows
       
   840                     * iMaxColumns;
       
   841             }
       
   842         __ASSERT_DEBUG( numberOfIconsToBeDrawn >= 1, Panic( KLmkPanicOutOfRange ) );
       
   843 
       
   844         gc.SetPenStyle(CGraphicsContext::ESolidPen);
       
   845         gc.SetBrushStyle(CGraphicsContext::ENullBrush);
       
   846         gc.SetPenSize(TSize(1, 1));
       
   847 
       
   848         // 2) Draw the grid
       
   849         const TSize gridItemRectSize(iGridItemWidth + 1, iGridItemHeight + 1);
       
   850 
       
   851         TInt numberOfGridCellsToBeDrawn = numberOfIconsToBeDrawn;
       
   852 
       
   853         TRgb colorLine = AKN_LAF_COLOR(219);
       
   854         AknsUtils::GetCachedColor(skin, colorLine, KAknsIIDQsnLineColors,
       
   855                 EAknsCIQsnLineColorsCG5);
       
   856         TRgb colorRecentLine = AKN_LAF_COLOR(215);
       
   857         AknsUtils::GetCachedColor(skin, colorRecentLine,
       
   858                 KAknsIIDQsnLineColors, EAknsCIQsnLineColorsCG7);
       
   859 
       
   860         // default pen color
       
   861         gc.SetPenColor(colorLine);
       
   862 
       
   863         TInt fullRows = numberOfGridCellsToBeDrawn / iMaxColumns;
       
   864 
       
   865         // how many left after the full rows
       
   866         numberOfGridCellsToBeDrawn -= fullRows * iMaxColumns;
       
   867 
       
   868         TPoint pos = iGridTopLeft;
       
   869 
       
   870         TInt endX = pos.iX + iGridItemWidth * iMaxColumns + 1;
       
   871         TInt endY = pos.iY + iGridItemHeight * fullRows;
       
   872 
       
   873         TInt ii = 0;
       
   874 
       
   875         if (fullRows)
       
   876             {
       
   877             // Draw full vertical lines
       
   878             for (ii = 0; ii <= iMaxColumns; ii++)
       
   879                 {
       
   880                 gc.SetPenColor(colorLine);
       
   881                 gc.SetPenSize(TSize(1, 1));
       
   882                 gc.DrawLine(pos, TPoint(pos.iX, endY));
       
   883                 pos.iX += iGridItemWidth;
       
   884                 }
       
   885 
       
   886             pos = iGridTopLeft;
       
   887 
       
   888             // Draw full horizontal lines
       
   889             for (ii = 0; ii <= fullRows; ii++)
       
   890                 {
       
   891                 gc.SetPenSize(TSize(1, 1));
       
   892                 gc.SetPenColor(colorLine);
       
   893                 gc.DrawLine(pos, TPoint(endX, pos.iY));
       
   894                 pos.iY += iGridItemHeight;
       
   895                 }
       
   896             gc.SetPenColor(colorLine);
       
   897             gc.SetPenSize(TSize(1, 1));
       
   898             }
       
   899 
       
   900         if (numberOfGridCellsToBeDrawn)
       
   901             {
       
   902             // Remaining cells in the last, non-full row
       
   903             pos = iOffset;
       
   904             pos.iX--; // iOffset is cell area topLeft, grid is not included in it
       
   905             pos.iY--;
       
   906 
       
   907             pos.iY += iGridItemHeight * fullRows;
       
   908 
       
   909             for (ii = 0; ii < numberOfGridCellsToBeDrawn; ii++)
       
   910                 {
       
   911                 gc.DrawRect(TRect(pos, gridItemRectSize));
       
   912 
       
   913                 if (iIsMirrored)
       
   914                     pos.iX -= iGridItemWidth;
       
   915                 else
       
   916                     // not mirrored
       
   917                     pos.iX += iGridItemWidth;
       
   918                 }
       
   919             }
       
   920 
       
   921         TInt iconIndex = (iCurrentPage - 1) * (iMaxColumns
       
   922                 * Extension()->iMaxVisibleRows);
       
   923         TInt lCnt = iConsArray->Count();
       
   924         cursorPos = iCursorPos.iX + iCursorPos.iY * iMaxColumns;
       
   925         if (lCnt > 0)
       
   926             {
       
   927             TRect cellRect(TPoint(0, 0), TSize(iGridItemWidth - 1,
       
   928                     iGridItemHeight - 1));
       
   929             for (TInt j = iconIndex, i = 0; j < lCnt && (i
       
   930                     < numberOfIconsToBeDrawn); j++, i++)
       
   931                 {
       
   932                 DrawItem(gc, CursorRect(i), j, (cursorPos == i), EFalse);
       
   933                 }
       
   934             }
       
   935 
       
   936         }
       
   937     iDrawnBefore = ETrue;
       
   938     gc.DiscardFont();
       
   939     }
       
   940 
       
   941 // -----------------------------------------------------------------------------
       
   942 // CLmkIconMap::DrawItem()
       
   943 //
       
   944 // -----------------------------------------------------------------------------
       
   945 //
       
   946 void CLmkIconMap::DrawItem(CWindowGc& aGc, const TRect& aSctPosition,
       
   947         TInt aIconIndex, TBool aHighlighted, TBool aDrawBackground) const
       
   948     {
       
   949     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
   950     MAknsControlContext* cc = AknsDrawUtils::ControlContext(this);
       
   951 
       
   952     TBool skins = AknsDrawUtils::Background(skin, cc, aGc, aSctPosition);
       
   953     TRgb color;
       
   954     if (!skins)
       
   955         aGc.SetBrushStyle(CGraphicsContext::ESolidBrush);
       
   956     if (aHighlighted)
       
   957         {
       
   958         TRgb colorHightLightRect = AKN_LAF_COLOR(215);
       
   959         AknsUtils::GetCachedColor(skin, colorHightLightRect,
       
   960                 KAknsIIDQsnLineColors, EAknsCIQsnLineColorsCG7);
       
   961         aGc.SetPenColor(colorHightLightRect);
       
   962         aGc.DrawRect(aSctPosition);
       
   963 
       
   964         // Shrink by one pixel in all directions.
       
   965         TRect innerRect = aSctPosition;
       
   966         innerRect.Shrink(1, 1);
       
   967 
       
   968         color = AKN_LAF_COLOR(210);
       
   969         AknsUtils::GetCachedColor(skin, color, KAknsIIDQsnHighlightColors,
       
   970                 EAknsCIQsnHighlightColorsCG1);
       
   971         aGc.SetBrushColor(color);
       
   972         aGc.Clear(innerRect);
       
   973         }
       
   974     else if (aDrawBackground)
       
   975         {
       
   976         TRect innerRect = aSctPosition;
       
   977         aGc.SetBrushColor(AKN_LAF_COLOR(0));
       
   978         if (!skins)
       
   979             aGc.Clear(innerRect);
       
   980         else
       
   981             AknsDrawUtils::Background(skin, cc, this, aGc, innerRect);
       
   982         }
       
   983 
       
   984     if (iConsArray)
       
   985         {
       
   986         TInt lCnt = iConsArray->Count();
       
   987         if (lCnt > 0 && aIconIndex < lCnt && aIconIndex >= 0)
       
   988             {
       
   989             TRect cellRect(TPoint(0, 0), TSize(iGridItemWidth - 1,
       
   990                     iGridItemHeight - 1));
       
   991 
       
   992             CGulIcon* bitmap = NULL;
       
   993             bitmap = iConsArray->At(aIconIndex);
       
   994             TInt numIconsInaPage = Extension()->iMaxVisibleRows * iMaxColumns;
       
   995             TInt cellIndex = aIconIndex;
       
   996             if (aIconIndex >= numIconsInaPage)
       
   997                 {
       
   998                 cellIndex = aIconIndex % numIconsInaPage;
       
   999                 }
       
  1000             aGc.BitBltMasked(CursorPoint(cellIndex), bitmap->Bitmap(),
       
  1001                     cellRect, bitmap->Mask(), EFalse);
       
  1002             }
       
  1003         }
       
  1004     }
       
  1005 
       
  1006 // -----------------------------------------------------------------------------
       
  1007 // CLmkIconMap::DrawCursor()
       
  1008 // Optimizes drawing. Only cursor is drawn.
       
  1009 // -----------------------------------------------------------------------------
       
  1010 void CLmkIconMap::DrawCursor() const
       
  1011     {
       
  1012     // Whole Icon Map has to be drawn at least once.
       
  1013     // If the user presses arrow key before Icon Map has been drawn,
       
  1014     // only cursor position is drawn without this check.
       
  1015     if (!iDrawnBefore)
       
  1016         {
       
  1017         DrawNow();
       
  1018         }
       
  1019     // Only redraw old and new cursor position cells
       
  1020     ActivateGc();
       
  1021     CWindowGc& gc = SystemGc();
       
  1022 
       
  1023     TInt cursorPos = iOldCursorPos.iX + iOldCursorPos.iY * iMaxColumns;
       
  1024     if (cursorPos >= 0)
       
  1025         {
       
  1026         DrawCell(cursorPos, EFalse);
       
  1027 
       
  1028         cursorPos = iCursorPos.iX + iCursorPos.iY * iMaxColumns;
       
  1029         DrawCell(cursorPos, ETrue);
       
  1030         }
       
  1031 
       
  1032     gc.DiscardFont();
       
  1033     DeactivateGc();
       
  1034     }
       
  1035 
       
  1036 // -----------------------------------------------------------------------------
       
  1037 // CLmkIconMap::DrawCell
       
  1038 // -----------------------------------------------------------------------------
       
  1039 //
       
  1040 void CLmkIconMap::DrawCell(TInt aCursorPos, TBool aHighLighted) const
       
  1041     {
       
  1042     // calculate icon index
       
  1043     TInt iconIndex = aCursorPos + iFirstVisibleRow * iMaxColumns;
       
  1044 
       
  1045     // If we are only redrawing for animations, no need to draw non-animated items.
       
  1046     TRect rect = CursorRect(aCursorPos);
       
  1047 
       
  1048     Window().Invalidate(rect);
       
  1049     Window().BeginRedraw(rect);
       
  1050     DrawItem(SystemGc(), rect, iconIndex, aHighLighted, ETrue);
       
  1051     Window().EndRedraw();
       
  1052     SystemGc().DiscardFont();
       
  1053     }
       
  1054 
       
  1055 // -----------------------------------------------------------------------------
       
  1056 // CLmkIconMap::CursorRect
       
  1057 // -----------------------------------------------------------------------------
       
  1058 //
       
  1059 TRect CLmkIconMap::CursorRect(TInt aCursorPos) const
       
  1060     {
       
  1061     TPoint pos = iOffset;
       
  1062 
       
  1063     if (iIsMirrored)
       
  1064         {
       
  1065         pos.iX -= (aCursorPos % iMaxColumns) * iGridItemWidth;
       
  1066         }
       
  1067     else // Not mirrored
       
  1068         {
       
  1069         pos.iX += (aCursorPos % iMaxColumns) * iGridItemWidth;
       
  1070         }
       
  1071 
       
  1072     pos.iY += (aCursorPos / iMaxColumns) * iGridItemHeight;
       
  1073     return TRect(pos, TSize(iGridItemWidth - 1, iGridItemHeight - 1));
       
  1074     }
       
  1075 
       
  1076 // -----------------------------------------------------------------------------
       
  1077 // CLmkIconMap::CursorPoint
       
  1078 // -----------------------------------------------------------------------------
       
  1079 //
       
  1080 TPoint CLmkIconMap::CursorPoint(TInt aCursorPos) const
       
  1081     {
       
  1082     TPoint pos = iOffset;
       
  1083 
       
  1084     if (iIsMirrored)
       
  1085         {
       
  1086         pos.iX -= (aCursorPos % iMaxColumns) * iGridItemWidth;
       
  1087         }
       
  1088     else // Not mirrored
       
  1089         {
       
  1090         pos.iX += (aCursorPos % iMaxColumns) * iGridItemWidth;
       
  1091         }
       
  1092 
       
  1093     pos.iY += (aCursorPos / iMaxColumns) * iGridItemHeight;
       
  1094     return pos;
       
  1095     }
       
  1096 
       
  1097 // -----------------------------------------------------------------------------
       
  1098 // CLmkIconMap::MoveCursorL
       
  1099 // -----------------------------------------------------------------------------
       
  1100 //
       
  1101 void CLmkIconMap::MoveCursorL(TInt aDeltaX, TInt aDeltaY)
       
  1102     {
       
  1103     __ASSERT_DEBUG((aDeltaX <= 1) && (aDeltaX >= -1) && (aDeltaY <= 1)
       
  1104             && (aDeltaY >= -1) && ((aDeltaX * aDeltaY) == 0), Panic(
       
  1105             KLmkPanicOutOfRange));
       
  1106 
       
  1107     if (iIsMirrored)
       
  1108         aDeltaX = -aDeltaX;
       
  1109 
       
  1110     if ((iConsArray->Count() < 8))
       
  1111         return;
       
  1112 
       
  1113     iOldCursorPos = iCursorPos;
       
  1114     TInt oldFirstVisibleRow = iFirstVisibleRow;
       
  1115 
       
  1116     TInt globalYPos = iCursorPos.iY + iFirstVisibleRow;
       
  1117     TInt lastColumnOnLastRow = ((iConsArray->Count() - 1) % iMaxColumns);
       
  1118 
       
  1119     TInt skipicon = aDeltaX != 0 ? 1 : 0;
       
  1120 
       
  1121     if (aDeltaX < 0)
       
  1122         {
       
  1123         // Cursor was moved to left.
       
  1124         if (iCursorPos.iX > skipicon - 1)
       
  1125             {
       
  1126             iCursorPos.iX -= skipicon;
       
  1127             }
       
  1128         else
       
  1129             {
       
  1130             if (skipicon > iMaxColumns)
       
  1131                 {
       
  1132                 globalYPos--;
       
  1133                 iCursorPos.iX = iMaxColumns;
       
  1134                 }
       
  1135             // Go to previous line
       
  1136             globalYPos--;
       
  1137             if (globalYPos < 0)
       
  1138                 {
       
  1139                 // Cursor was on the first line - go to last line.
       
  1140                 globalYPos = iRows - 1;
       
  1141                 // x - position to the last item on the last row.
       
  1142                 iCursorPos.iX = lastColumnOnLastRow;
       
  1143                 }
       
  1144             else
       
  1145                 {
       
  1146                 // x - position to last column.
       
  1147                 iCursorPos.iX = iMaxColumns - skipicon;
       
  1148                 }
       
  1149             }
       
  1150         }
       
  1151 
       
  1152     if (aDeltaX > 0)
       
  1153         {
       
  1154         // Cursor was moved to right.
       
  1155         if (globalYPos < iRows - 1)
       
  1156             {
       
  1157             // Not in the last row.
       
  1158             if (iCursorPos.iX < iMaxColumns - skipicon)
       
  1159                 {
       
  1160                 // If not on the last columns, move cursor to next column.
       
  1161                 iCursorPos.iX += skipicon;
       
  1162                 }
       
  1163             else
       
  1164                 {
       
  1165                 // Cursor was on last column,
       
  1166                 // move to first column of the next line.
       
  1167                 iCursorPos.iX = 0;
       
  1168                 globalYPos++;
       
  1169                 }
       
  1170             }
       
  1171         else
       
  1172             {
       
  1173             // Currently on the last row.
       
  1174             if (iCursorPos.iX < lastColumnOnLastRow)
       
  1175                 {
       
  1176                 // If there are more items on this row, move cursor to next item.
       
  1177                 iCursorPos.iX++;
       
  1178                 }
       
  1179             else
       
  1180                 {
       
  1181                 // No more item on the current row.
       
  1182                 // Move to first item on the first row.
       
  1183                 iCursorPos.iX = 0;
       
  1184                 globalYPos = 0;
       
  1185                 }
       
  1186             }
       
  1187         }
       
  1188 
       
  1189     if (aDeltaY < 0)
       
  1190         {
       
  1191         iCursorPos.iX -= skipicon;
       
  1192         if (iCursorPos.iX < 0)
       
  1193             {
       
  1194             iCursorPos.iX += (iMaxColumns - 1);
       
  1195             globalYPos--;
       
  1196             }
       
  1197         // Cursor was moved to up.
       
  1198         if (globalYPos > 0)
       
  1199             {
       
  1200             // Cursor was not on the first line - move it to previous row.
       
  1201             globalYPos--;
       
  1202             }
       
  1203         else
       
  1204             {
       
  1205             // Move cursot to last to row.
       
  1206             globalYPos = iRows - 1;
       
  1207             if (iCursorPos.iX > lastColumnOnLastRow)
       
  1208                 {
       
  1209                 // No items in the current column on the last row -
       
  1210                 // move cursor to last item on the row.
       
  1211                 iCursorPos.iX = lastColumnOnLastRow;
       
  1212                 }
       
  1213             }
       
  1214         }
       
  1215 
       
  1216     if (aDeltaY > 0)
       
  1217         {
       
  1218         iCursorPos.iX = (iCursorPos.iX + skipicon) % iMaxColumns;
       
  1219         globalYPos += (iCursorPos.iX + skipicon) / iMaxColumns;
       
  1220         // Cursor was moved to down.
       
  1221         if (globalYPos < iRows - 1)
       
  1222             {
       
  1223             // Cursor is not on the last row. Move cursor to next row.
       
  1224             globalYPos++;
       
  1225             if (globalYPos == iRows - 1 && iCursorPos.iX
       
  1226                     > lastColumnOnLastRow)
       
  1227                 {
       
  1228                 // No items in the current column on the last row -
       
  1229                 // move cursor to last item on the row.
       
  1230                 iCursorPos.iX = lastColumnOnLastRow;
       
  1231                 }
       
  1232             }
       
  1233         else
       
  1234             {
       
  1235             // Cursor was at the last row - move it to the first row.
       
  1236             globalYPos = 0;
       
  1237             }
       
  1238         }
       
  1239     iCursorPos.iY = globalYPos - iFirstVisibleRow;
       
  1240 
       
  1241     if (globalYPos < iFirstVisibleRow)
       
  1242         {
       
  1243         // Cursor was moved from the top row.
       
  1244         if (globalYPos <= 0)
       
  1245             {
       
  1246             iFirstVisibleRow = 0;
       
  1247             iCursorPos = TPoint(iCursorPos.iX, 0);
       
  1248             }
       
  1249         else
       
  1250             {
       
  1251             // If cursor was moved up out of the visible area - show it again.
       
  1252             iFirstVisibleRow -= Extension()->iMaxVisibleRows;
       
  1253             iCursorPos = TPoint(iCursorPos.iX, Extension()->iMaxVisibleRows
       
  1254                     - 1);
       
  1255             }
       
  1256         }
       
  1257 
       
  1258     if (globalYPos > iFirstVisibleRow + Extension()->iMaxVisibleRows - 1)
       
  1259         {
       
  1260         if (globalYPos == iRows - 1)
       
  1261             {
       
  1262             // When cursor has moved from the top line,
       
  1263             // it is adjusted to a page boundary.
       
  1264             iCursorPos = TPoint(iCursorPos.iX, (iRows - 1)
       
  1265                     % Extension()->iMaxVisibleRows);
       
  1266             iFirstVisibleRow = ((iRows - 1) / Extension()->iMaxVisibleRows)
       
  1267                     * Extension()->iMaxVisibleRows;
       
  1268             }
       
  1269         else
       
  1270             {
       
  1271             // If cursor was moved down out of the visible area - show it again.
       
  1272             iFirstVisibleRow += Extension()->iMaxVisibleRows;
       
  1273             iCursorPos = TPoint(iCursorPos.iX, 0);
       
  1274             }
       
  1275         }
       
  1276 
       
  1277     //TInt increment(1);
       
  1278     //if (aDeltaY < 0 || aDeltaX < 0)
       
  1279     //    {
       
  1280     ////    increment = -1;
       
  1281     //    }
       
  1282     if ((iRows > Extension()->iMaxVisibleRows) && (iOldCursorPos.iY
       
  1283             + oldFirstVisibleRow != iCursorPos.iY + iFirstVisibleRow))
       
  1284         {
       
  1285         UpdateScrollIndicatorL();
       
  1286         }
       
  1287 
       
  1288     if (oldFirstVisibleRow == iFirstVisibleRow)
       
  1289         {
       
  1290         // Draw only cursor if the view to the content was not scrolled.
       
  1291         DrawCursor();
       
  1292         }
       
  1293     else
       
  1294         {
       
  1295         DrawNow();
       
  1296         }
       
  1297 
       
  1298     }
       
  1299 
       
  1300 // -----------------------------------------------------------------------------
       
  1301 // CLmkIconMap::UpdateScrollIndicatorL()
       
  1302 //
       
  1303 // -----------------------------------------------------------------------------
       
  1304 //
       
  1305 void CLmkIconMap::UpdateScrollIndicatorL()
       
  1306     {
       
  1307     if (!iSBFrame)
       
  1308         {
       
  1309         return;
       
  1310         }
       
  1311     TEikScrollBarModel hSbarModel;
       
  1312     TEikScrollBarModel vSbarModel;
       
  1313 
       
  1314     TEikScrollBarFrameLayout layout;
       
  1315 
       
  1316     // Main pane without softkeys
       
  1317     TRect mainPaneRect;
       
  1318     if (!AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane,
       
  1319             mainPaneRect))
       
  1320         {
       
  1321         mainPaneRect = iAvkonAppUi->ClientRect();
       
  1322         }
       
  1323 
       
  1324     // Dialog layout, check variety first
       
  1325     TAknLayoutScalableParameterLimits iconMapDialogVariety =
       
  1326             AknLayoutScalable_Avkon::popup_grid_graphic_window_ParamLimits();
       
  1327 
       
  1328     TInt maxVariety = iconMapDialogVariety.LastVariety();
       
  1329 
       
  1330     // Check the CBA, if the orientation is not landscape
       
  1331     // there is not so much varieties
       
  1332     AknLayoutUtils::TAknCbaLocation location = AknLayoutUtils::CbaLocation();
       
  1333     TInt maxVarietyOffset = 0; // the offset for the certain cba location variety
       
  1334     TInt varietyOffset = maxVariety + 1;
       
  1335 
       
  1336     // landscape variety number must be calculated offset == number of varieties
       
  1337     // same applies to the variety number for the biggest sized layout for the variety
       
  1338     if (Layout_Meta_Data::IsLandscapeOrientation())
       
  1339         {
       
  1340         varietyOffset = (maxVariety + 1) / KAknSctCBaButtonDirections; // the offset for one variety
       
  1341         }
       
  1342 
       
  1343     // for right and left cba buttons the max variety is not zero
       
  1344     // the varities are ordered by the location of the cba and the descending order
       
  1345     // e.g the biggest sized layout first, the smallest last
       
  1346     if (location == AknLayoutUtils::EAknCbaLocationRight)
       
  1347         {
       
  1348         maxVarietyOffset = varietyOffset;
       
  1349         }
       
  1350     else if (location == AknLayoutUtils::EAknCbaLocationLeft)
       
  1351         {
       
  1352         maxVarietyOffset = varietyOffset + varietyOffset; // 2*
       
  1353         }
       
  1354 
       
  1355     TInt varietyNumber = varietyOffset - iRows - 1;
       
  1356 
       
  1357     // if more lines than possible to show, use the default
       
  1358     // (the biggest grid) variety
       
  1359     if (varietyNumber < 0)
       
  1360         varietyNumber = 0;
       
  1361     // if zero rows, use the minimum
       
  1362     else if (iRows <= 0)
       
  1363         varietyNumber -= 1;
       
  1364 
       
  1365     //add the varietyoffset
       
  1366     varietyNumber += maxVarietyOffset;
       
  1367 
       
  1368     if (Layout_Meta_Data::IsLandscapeOrientation() && (location
       
  1369             == AknLayoutUtils::EAknCbaLocationRight))
       
  1370         {
       
  1371         varietyNumber = 10;
       
  1372         }
       
  1373     else
       
  1374         {
       
  1375         varietyNumber = 3;
       
  1376         }
       
  1377     // Layout the dialog size
       
  1378     TAknLayoutRect dialogLayRect;
       
  1379     dialogLayRect.LayoutRect(mainPaneRect,
       
  1380             AknLayoutScalable_Avkon::popup_grid_graphic_window(varietyNumber));
       
  1381 
       
  1382     TRect dialogRect = dialogLayRect.Rect();
       
  1383 
       
  1384     // Get the layout of the actual icon grid with scrollbar
       
  1385     TAknLayoutRect gridWithScrollLayRect;
       
  1386 
       
  1387     gridWithScrollLayRect.LayoutRect(TRect(TPoint(0, 0), TSize(
       
  1388             dialogRect.Size())),
       
  1389             AknLayoutScalable_Avkon::listscroll_popup_graphic_pane());
       
  1390 
       
  1391     // Calculate the relative rect for the grid
       
  1392     TRect parent = gridWithScrollLayRect.Rect();
       
  1393 
       
  1394     TAknWindowComponentLayout scrollbarLayout =
       
  1395             AknLayoutScalable_Avkon::scroll_pane_cp5();
       
  1396 
       
  1397     iCurrentPage = (iFirstVisibleRow / Extension()->iMaxVisibleRows) + 1;
       
  1398 
       
  1399     vSbarModel.iScrollSpan = iNumPages * Extension()->iMaxVisibleRows;
       
  1400     vSbarModel.iThumbSpan = Extension()->iMaxVisibleRows;
       
  1401 
       
  1402     if (iSBFrame && iSBFrame->TypeOfVScrollBar()
       
  1403             == CEikScrollBarFrame::EDoubleSpan)
       
  1404         {
       
  1405         // For EDoubleSpan type scrollbar
       
  1406         vSbarModel.iThumbPosition = (iCurrentPage - 1)
       
  1407                 * Extension()->iMaxVisibleRows;
       
  1408         TAknDoubleSpanScrollBarModel hDsSbarModel(hSbarModel);
       
  1409         TAknDoubleSpanScrollBarModel vDsSbarModel(vSbarModel);
       
  1410 
       
  1411         // The y coordinate must be sifted 3 pixels up and x 3 to left
       
  1412         parent.iTl.iY -= KVerticalDialogMargin;
       
  1413         parent.iBr.iY -= KVerticalDialogMargin;
       
  1414         parent.iTl.iX -= KHorizontalDialogMargin;
       
  1415         parent.iBr.iX -= KHorizontalDialogMargin;
       
  1416 
       
  1417         layout.iTilingMode = TEikScrollBarFrameLayout::EInclusiveRectConstant;
       
  1418         iSBFrame->Tile(&vDsSbarModel);
       
  1419         AknLayoutUtils::LayoutVerticalScrollBar(iSBFrame, parent,
       
  1420                 scrollbarLayout);
       
  1421         iSBFrame->SetVFocusPosToThumbPos(vDsSbarModel.FocusPosition());
       
  1422         }
       
  1423     else
       
  1424         {
       
  1425         // For EArrowHead type scrollbar
       
  1426         vSbarModel.iThumbPosition = iCursorPos.iY + iFirstVisibleRow;
       
  1427         iSBFrame->TileL(&hSbarModel, &vSbarModel, parent, parent, layout);
       
  1428         iSBFrame->SetVFocusPosToThumbPos(vSbarModel.iThumbPosition);
       
  1429         }
       
  1430     }
       
  1431 
       
  1432 // -----------------------------------------------------------------------------
       
  1433 // CLmkIconMap::Reserved_1()
       
  1434 //
       
  1435 // -----------------------------------------------------------------------------
       
  1436 //
       
  1437 void CLmkIconMap::Reserved_1()
       
  1438     {
       
  1439     }
       
  1440 
       
  1441 // -----------------------------------------------------------------------------
       
  1442 // CLmkIconMap::Reserved_2()
       
  1443 //
       
  1444 // -----------------------------------------------------------------------------
       
  1445 //
       
  1446 void CLmkIconMap::Reserved_2()
       
  1447     {
       
  1448     }
       
  1449 
       
  1450 // -----------------------------------------------------------------------------
       
  1451 // CLmkIconMap::DrawOffscreenBackgroundIfRequired
       
  1452 //
       
  1453 // -----------------------------------------------------------------------------
       
  1454 //
       
  1455 void CLmkIconMap::DrawOffscreenBackgroundIfRequired() const
       
  1456     {
       
  1457     if (iOffscreenBg && iHasBitmapBackground)
       
  1458         {
       
  1459         if (!iOffscreenBgDrawn)
       
  1460             {
       
  1461             TRect mainPaneRect;
       
  1462             if (!AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane,
       
  1463                     mainPaneRect))
       
  1464                 {
       
  1465                 mainPaneRect = iAvkonAppUi->ClientRect();
       
  1466                 }
       
  1467 
       
  1468             // Dialog layout, check variety first
       
  1469             TAknLayoutScalableParameterLimits
       
  1470                     iconMapDialogVariety =
       
  1471                             AknLayoutScalable_Avkon::popup_grid_graphic_window_ParamLimits();
       
  1472 
       
  1473             TInt maxVariety = iconMapDialogVariety.LastVariety();
       
  1474 
       
  1475             // Check the CBA, if the orientation is not landscape
       
  1476             // there is not so much varieties
       
  1477             AknLayoutUtils::TAknCbaLocation location =
       
  1478                     AknLayoutUtils::CbaLocation();
       
  1479             TInt maxVarietyOffset = 0; // the offset for the certain cba location variety
       
  1480             TInt varietyOffset = maxVariety + 1;
       
  1481 
       
  1482             // landscape variety number must be calculated offset == number of varieties
       
  1483             // same applies to the variety number for the biggest sized layout for the variety
       
  1484             if (Layout_Meta_Data::IsLandscapeOrientation())
       
  1485                 {
       
  1486                 varietyOffset = (maxVariety + 1) / KAknSctCBaButtonDirections; // the offset for one variety
       
  1487                 }
       
  1488 
       
  1489             // for right and left cba buttons the max variety is not zero
       
  1490             // the varities are ordered by the location of the cba and the descending order
       
  1491             // e.g the biggest sized layout first, the smallest last
       
  1492             if (location == AknLayoutUtils::EAknCbaLocationRight)
       
  1493                 {
       
  1494                 maxVarietyOffset = varietyOffset;
       
  1495                 }
       
  1496             else if (location == AknLayoutUtils::EAknCbaLocationLeft)
       
  1497                 {
       
  1498                 maxVarietyOffset = varietyOffset + varietyOffset; // 2*
       
  1499                 }
       
  1500             TInt varietyNumber = varietyOffset - iRows - 1;
       
  1501 
       
  1502             // if more lines than possible to show, use the default
       
  1503             // (the biggest grid) variety
       
  1504             if (varietyNumber < 0)
       
  1505                 varietyNumber = 0;
       
  1506             // if zero rows, use the minimum
       
  1507             else if (iRows <= 0)
       
  1508                 varietyNumber -= 1;
       
  1509 
       
  1510             //add the varietyoffset
       
  1511             varietyNumber += maxVarietyOffset;
       
  1512 
       
  1513             TAknLayoutRect popupGridLayRect;
       
  1514             popupGridLayRect.LayoutRect(mainPaneRect,
       
  1515                     AknLayoutScalable_Avkon::popup_grid_graphic_window(5));
       
  1516 
       
  1517             TRect popupGridRect = popupGridLayRect.Rect();
       
  1518 
       
  1519             // set the top left height as the control starting point
       
  1520             popupGridRect.iTl.iY = Rect().iTl.iY;
       
  1521 
       
  1522             //if(popupGridRect.iBr.iY < mainPaneRect.iBr.iY)
       
  1523             //	popupGridRect.iBr.iY = mainPaneRect.iBr.iY
       
  1524             MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  1525             MAknsControlContext* cc = AknsDrawUtils::ControlContext(this);
       
  1526 
       
  1527             // draw to upper left corner, and normalize the retangle to
       
  1528             // fact that the dialog starts from coordinates (0,0),
       
  1529             // so the y-coordinate is correct (heading pane)
       
  1530             // but x must be set to zero
       
  1531             TPoint point = TPoint(0, 0);
       
  1532             popupGridRect.Move(-popupGridRect.iTl.iX, 0);
       
  1533 
       
  1534             AknsDrawUtils::DrawBackground(skin, cc, this, *iBitmapGc, point,
       
  1535                     popupGridRect, KAknsDrawParamDefault);
       
  1536 
       
  1537             iOffscreenBgDrawn = ETrue;
       
  1538             }
       
  1539         }
       
  1540     }
       
  1541 
       
  1542 // -----------------------------------------------------------------------------
       
  1543 // CLmkIconMap::ComponentControl(TInt aIndex) const
       
  1544 // Return the controll pointer
       
  1545 // -----------------------------------------------------------------------------
       
  1546 //
       
  1547 CCoeControl* CLmkIconMap::ComponentControl(TInt aIndex) const
       
  1548     {
       
  1549     if (aIndex == 0 && iSBFrame && iSBFrame->TypeOfVScrollBar()
       
  1550             == CEikScrollBarFrame::EDoubleSpan)
       
  1551         {
       
  1552         return iSBFrame->VerticalScrollBar();
       
  1553         }
       
  1554     else
       
  1555         {
       
  1556         return NULL;
       
  1557         }
       
  1558     }
       
  1559 
       
  1560 // -----------------------------------------------------------------------------
       
  1561 // CLmkIconMap::CountComponentControls()
       
  1562 // Return no of controll to be placed on the container control
       
  1563 // -----------------------------------------------------------------------------
       
  1564 //
       
  1565 TInt CLmkIconMap::CountComponentControls() const
       
  1566     {
       
  1567     if (iSBFrame && iSBFrame->TypeOfVScrollBar()
       
  1568             == CEikScrollBarFrame::EDoubleSpan)
       
  1569         {
       
  1570         return 1;
       
  1571         }
       
  1572     else
       
  1573         {
       
  1574         return 0;
       
  1575         }
       
  1576     }
       
  1577 
       
  1578 // -----------------------------------------------------------------------------
       
  1579 // CLmkIconMap::CountMaxColumnsAndCellSizes
       
  1580 // Counts no of columns and the cell size will be displayed in the icon table
       
  1581 // -----------------------------------------------------------------------------
       
  1582 //
       
  1583 void CLmkIconMap::CountMaxColumnsAndCellSizes()
       
  1584     {
       
  1585 
       
  1586     TRect cellRect; // retangle of one item in grid
       
  1587     TRect gridRect; // retangle of the grid contaning the items
       
  1588 
       
  1589     // 1. Get the layout
       
  1590 
       
  1591     // Get the parent rect
       
  1592     TRect mainPaneRect;
       
  1593     if (!AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane,
       
  1594             mainPaneRect))
       
  1595         {
       
  1596         mainPaneRect = iAvkonAppUi->ClientRect();
       
  1597         }
       
  1598 
       
  1599     // Calculate the layout of the whole popup with the biggest possible -> 0
       
  1600     // Dialog layout, check variety first
       
  1601 
       
  1602     // Get the layout rect of the dialog
       
  1603 
       
  1604     // Check variety first
       
  1605     TAknLayoutScalableParameterLimits iconMapDialogVariety =
       
  1606             AknLayoutScalable_Avkon::popup_grid_graphic_window_ParamLimits();
       
  1607 
       
  1608     TInt maxVariety = iconMapDialogVariety.LastVariety();
       
  1609 
       
  1610     // Check the CBA, if the orientation is not landscape
       
  1611     // there is not so much varieties
       
  1612     AknLayoutUtils::TAknCbaLocation location = AknLayoutUtils::CbaLocation();
       
  1613     TInt maxVarietyOffset = 0; // the offset for the certain cba location variety
       
  1614     TInt varietyOffset = maxVariety + 1; // the number of varieties
       
  1615 
       
  1616     // landscape variety number must be calculated offset == number of varieties
       
  1617     // same applies to the variety number for the biggest sized layout for the variety
       
  1618     if (Layout_Meta_Data::IsLandscapeOrientation())
       
  1619         {
       
  1620         varietyOffset = (maxVariety + 1) / KAknSctCBaButtonDirections; // the offset for one variety
       
  1621         }
       
  1622 
       
  1623     if (location == AknLayoutUtils::EAknCbaLocationRight)
       
  1624         {
       
  1625         maxVarietyOffset = varietyOffset;
       
  1626         }
       
  1627     else if (location == AknLayoutUtils::EAknCbaLocationLeft)
       
  1628         {
       
  1629         maxVarietyOffset = varietyOffset + varietyOffset; // 2*
       
  1630         }
       
  1631 
       
  1632     TAknLayoutRect popupGridLayRect;
       
  1633     popupGridLayRect.LayoutRect(mainPaneRect,
       
  1634             AknLayoutScalable_Avkon::popup_grid_graphic_window(
       
  1635                     maxVarietyOffset));
       
  1636 
       
  1637     // Get the layout of the actual icon grid with scrollbar
       
  1638     TAknLayoutRect gridWithScrollLayRect;
       
  1639     gridWithScrollLayRect.LayoutRect(popupGridLayRect.Rect(),
       
  1640             AknLayoutScalable_Avkon::listscroll_popup_graphic_pane());
       
  1641 
       
  1642     // Then the grid area without scrollbar
       
  1643     // NOTE: The grid with scroll bar is used as reference
       
  1644     TAknLayoutRect gridLayRect;
       
  1645     gridLayRect.LayoutRect(gridWithScrollLayRect.Rect(),
       
  1646             AknLayoutScalable_Avkon::grid_graphic_popup_pane(0));
       
  1647 
       
  1648     // Different parent if SCT inside editing menu.
       
  1649     TRect rect = Rect();
       
  1650     gridRect = gridLayRect.Rect();
       
  1651     // cell size, AGAIN 7 item
       
  1652     TAknLayoutRect cellLayRect;
       
  1653     cellLayRect.LayoutRect(gridRect,
       
  1654             AknLayoutScalable_Avkon::cell_graphic_popup_pane(0, 0, 0));
       
  1655 
       
  1656     cellRect = cellLayRect.Rect();
       
  1657 
       
  1658     // 2. Calculate width related
       
  1659     // - item width
       
  1660     // - max number of columns
       
  1661 
       
  1662     // Width of the items area
       
  1663     TInt gridWidth = gridRect.Width();
       
  1664 
       
  1665     // Width of one item
       
  1666     TInt cellWidth = cellRect.Width();
       
  1667 
       
  1668     // ensure the item width and store it
       
  1669     TAknLayoutRect secondCellLayRect;
       
  1670     secondCellLayRect.LayoutRect(gridRect,
       
  1671             AknLayoutScalable_Avkon::cell_graphic_popup_pane(0, 1, 0));
       
  1672 
       
  1673     iGridItemWidth = secondCellLayRect.Rect().iTl.iX
       
  1674             - cellLayRect.Rect().iTl.iX;
       
  1675 
       
  1676     if (iGridItemWidth < 0)
       
  1677         {
       
  1678         // The result is negative with lay file data if the layout is mirrored.
       
  1679         iGridItemWidth = -iGridItemWidth;
       
  1680         }
       
  1681 
       
  1682     // Calculate the amount of columns
       
  1683     iMaxColumns = gridWidth / cellWidth;
       
  1684 
       
  1685     // 2. Calculate height related
       
  1686     // - item height
       
  1687     // - max number of rows
       
  1688 
       
  1689     // Get the grid height
       
  1690     // NOTE: in landscape the LAF is wrong so use the main panes height
       
  1691     TInt gridHeight = gridRect.Height();
       
  1692 
       
  1693     // get the item height
       
  1694     TInt cellHeight = cellRect.Height();
       
  1695 
       
  1696     // calculate the number of items fitting to grid
       
  1697     Extension()->iMaxVisibleRows = 3;//gridHeight / cellHeight;
       
  1698 
       
  1699 
       
  1700     // Store the item height
       
  1701     TAknLayoutRect secondRowLayRect;
       
  1702     secondRowLayRect.LayoutRect(gridLayRect.Rect(),
       
  1703             AknLayoutScalable_Avkon::cell_graphic_popup_pane(0, 0, 1));
       
  1704 
       
  1705     iGridItemHeight = secondRowLayRect.Rect().iTl.iY
       
  1706             - cellLayRect.Rect().iTl.iY;
       
  1707     }
       
  1708 
       
  1709 // -----------------------------------------------------------------------------
       
  1710 // CLmkIconMap::HandleScrollEventL
       
  1711 // Handles the different scroll events so that the map reacts accordingly.
       
  1712 // -----------------------------------------------------------------------------
       
  1713 //
       
  1714 void CLmkIconMap::HandleScrollEventL(CEikScrollBar* aScrollBar,
       
  1715         TEikScrollEvent aEventType)
       
  1716     {
       
  1717     TBool update = EFalse;
       
  1718 
       
  1719     switch (aEventType)
       
  1720         {
       
  1721         case EEikScrollUp:
       
  1722         case EEikScrollPageUp:
       
  1723             {
       
  1724             // nothing done if we are already on the first page.
       
  1725             if (iFirstVisibleRow != 0)
       
  1726                 {
       
  1727                 iFirstVisibleRow -= Extension()->iMaxVisibleRows;
       
  1728                 update = ETrue;
       
  1729                 }
       
  1730             UpdateScrollIndicatorL();
       
  1731             }
       
  1732             break;
       
  1733         case EEikScrollDown:
       
  1734         case EEikScrollPageDown:
       
  1735             {
       
  1736             // nothing done if we are already on the last page.
       
  1737             if (iFirstVisibleRow != (iRows / Extension()->iMaxVisibleRows)
       
  1738                     * Extension()->iMaxVisibleRows)
       
  1739                 {
       
  1740                 iFirstVisibleRow += Extension()->iMaxVisibleRows;
       
  1741                 update = ETrue;
       
  1742                 }
       
  1743             UpdateScrollIndicatorL();
       
  1744             }
       
  1745             break;
       
  1746         case EEikScrollThumbDragVert:
       
  1747             {
       
  1748             TInt thumbPosition;
       
  1749             TInt halfPage = Extension()->iMaxVisibleRows / 2;
       
  1750             // Ask which type of scrollbar is shown
       
  1751             //CAknAppUi* appUi = iAvkonAppUi;
       
  1752             TBool isDoubleSpan = CEikScrollBarFrame::EDoubleSpan
       
  1753                     == iSBFrame->TypeOfVScrollBar();
       
  1754             if (isDoubleSpan)
       
  1755                 {
       
  1756                 thumbPosition
       
  1757                         = static_cast<const TAknDoubleSpanScrollBarModel*> (aScrollBar->Model())->FocusPosition();
       
  1758                 }
       
  1759             else
       
  1760                 {
       
  1761                 thumbPosition = aScrollBar->Model()->iThumbPosition;
       
  1762                 }
       
  1763 
       
  1764             // If the slider is in the range of less then a half page from a possible correct thumb position.
       
  1765             // thus 0 <= iFirstVisibleRow - thumbPosition < halfPage. Or in the other direction:
       
  1766             // 0 <= thumbPosition - iFirstVisibleRow < halfPage
       
  1767             if (!((0 <= iFirstVisibleRow - thumbPosition && iFirstVisibleRow
       
  1768                     - thumbPosition < halfPage) || (0 <= thumbPosition
       
  1769                     - iFirstVisibleRow && thumbPosition - iFirstVisibleRow
       
  1770                     < halfPage)))
       
  1771                 {
       
  1772                 TReal toRound = thumbPosition
       
  1773                         / (TReal) Extension()->iMaxVisibleRows;
       
  1774                 if (toRound * 2 > (TInt) toRound * 2 + 1)
       
  1775                     {
       
  1776                     toRound++;
       
  1777                     }
       
  1778                 iFirstVisibleRow = (TInt) toRound
       
  1779                         * Extension()->iMaxVisibleRows;
       
  1780                 iCurrentPage = (iFirstVisibleRow
       
  1781                         / Extension()->iMaxVisibleRows) + 1;
       
  1782                 update = ETrue;
       
  1783                 }
       
  1784             }
       
  1785             break;
       
  1786         case EEikScrollThumbReleaseVert:
       
  1787             {
       
  1788             UpdateScrollIndicatorL();
       
  1789             }
       
  1790             break;
       
  1791         case EEikScrollLeft: // flow through
       
  1792         case EEikScrollRight: // flow through
       
  1793         case EEikScrollPageLeft: // flow through
       
  1794         case EEikScrollPageRight: // flow through
       
  1795         case EEikScrollThumbDragHoriz: // flow through
       
  1796         case EEikScrollThumbReleaseHoriz: // flow through
       
  1797             // do nothing
       
  1798             break;
       
  1799         default:
       
  1800             // do nothing
       
  1801             break;
       
  1802         }
       
  1803 
       
  1804     // If we have moved down to the last page we check that the cursor is in a place where it can be
       
  1805     // drawn.
       
  1806     if (iFirstVisibleRow == (iRows / Extension()->iMaxVisibleRows)
       
  1807             * Extension()->iMaxVisibleRows)
       
  1808         {
       
  1809         // the old cursor is set to a "safe" position where it at least can be.
       
  1810         iOldCursorPos.iX = 0;
       
  1811         iOldCursorPos.iY = 0;
       
  1812         // if the last page has only one line which isn't filled complitely.
       
  1813         if (iConsArray->Count() % iMaxColumns - 1 < iCursorPos.iX && iRows
       
  1814                 % Extension()->iMaxVisibleRows == 1)
       
  1815             {
       
  1816             TInt xVal = iConsArray->Count() % iMaxColumns - 1;
       
  1817             if (xVal >= 0)
       
  1818                 iCursorPos.iX = xVal;
       
  1819             }
       
  1820         // If the cursor is in a position where it would go unto a spot with out
       
  1821         // a icon when scrolled.
       
  1822         if (iCursorPos.iY + iFirstVisibleRow >= iRows)
       
  1823             {
       
  1824             if (iConsArray->Count() % iMaxColumns > iCursorPos.iX)
       
  1825                 {
       
  1826                 TInt yVal = iRows - 1 - iFirstVisibleRow;
       
  1827                 if (yVal >= 0)
       
  1828                     iCursorPos.iY = yVal;
       
  1829                 }
       
  1830             else
       
  1831                 {
       
  1832                 TInt yVal = iRows - 2 - iFirstVisibleRow;
       
  1833                 if (yVal >= 0)
       
  1834                     iCursorPos.iY = yVal;
       
  1835                 }
       
  1836             }
       
  1837         // If the cursor is actually on the last row, but is still in the
       
  1838         // area where there is now icons. (the rest of the last row)
       
  1839         if (iConsArray->Count() <= (iFirstVisibleRow + iCursorPos.iY)
       
  1840                 * iMaxColumns + iCursorPos.iX && iCursorPos.iY
       
  1841                 + iFirstVisibleRow + 1 == iRows)
       
  1842             {
       
  1843             iCursorPos.iY--;
       
  1844             }
       
  1845         // if the corrections did not help and the cursor is in the area
       
  1846         // where there is a valid row, but no icons anymore
       
  1847         }
       
  1848 
       
  1849     // to avoid flicker we draw only if there really was something new to draw.
       
  1850     if (update)
       
  1851         {
       
  1852         if (Extension()->iObserver)
       
  1853             {
       
  1854             Extension()->iObserver->HandleControlEventL(this,
       
  1855                     MCoeControlObserver::EEventRequestFocus);
       
  1856             }
       
  1857         DrawDeferred();
       
  1858         }
       
  1859     }
       
  1860 
       
  1861 // -----------------------------------------------------------------------------
       
  1862 // CLmkIconMap::Extension
       
  1863 // Asserts that extension object has been created.
       
  1864 // -----------------------------------------------------------------------------
       
  1865 //
       
  1866 CLmkIconMapExtension* CLmkIconMap::Extension() const
       
  1867     {
       
  1868     __ASSERT_ALWAYS(iExtension, Panic(KLmkPanicNullPointer));
       
  1869     return iExtension;
       
  1870     }
       
  1871 
       
  1872 #ifdef RD_SCALABLE_UI_V2
       
  1873 //--------------------------------------------------------------------------
       
  1874 // void CLmkIconMap::HandlePointerEventL()
       
  1875 //--------------------------------------------------------------------------
       
  1876 void CLmkIconMap::HandlePointerEventL(const TPointerEvent& aPointerEvent)
       
  1877     {
       
  1878     if (AknLayoutUtils::PenEnabled())
       
  1879         {
       
  1880         TInt newGridX; // For the whole
       
  1881         TInt newGridY; // For the whole grid.
       
  1882         TInt yInPixels = aPointerEvent.iPosition.iY - iGridTopLeft.iY;
       
  1883         newGridY = yInPixels / iGridItemHeight;
       
  1884         if ((aPointerEvent.iPosition.iX - iGridTopLeft.iX) < 0)
       
  1885             {
       
  1886             newGridX = -1;
       
  1887             }
       
  1888         else
       
  1889             {
       
  1890             newGridX = (aPointerEvent.iPosition.iX - iGridTopLeft.iX)
       
  1891                     / iGridItemWidth;
       
  1892             }
       
  1893         TInt previousRows = (iRows / iExtension->iMaxVisibleRows)
       
  1894                 * iExtension->iMaxVisibleRows;
       
  1895         TUint lastRowsLength = iConsArray->Count() % iMaxColumns;
       
  1896 
       
  1897         // The pointer has been set down or dragged into the area of the grid. (it might be in
       
  1898         // the "white space" at the end of the grid)
       
  1899         if ((yInPixels >= 0 && yInPixels < iGridItemHeight
       
  1900                 * iExtension->iMaxVisibleRows) &&
       
  1901         // When the pointer is in rows except the recent icon row
       
  1902                 ((((newGridY + iFirstVisibleRow) != 0) && newGridX
       
  1903                         < iMaxColumns && newGridX >= 0) ||
       
  1904                 // When the pointer is in the recent icon row
       
  1905                         ((newGridY + iFirstVisibleRow == 0) && (newGridX
       
  1906                                 < iMaxColumns))))
       
  1907             {
       
  1908             // For any action to be taken, the pointer event must either be a Button1Down or a drag event
       
  1909             // which has originated from a Button1Down in to the grid.
       
  1910             if (aPointerEvent.iType == TPointerEvent::EButton1Down)
       
  1911                 {
       
  1912                 TUint globalY = newGridY + iFirstVisibleRow;
       
  1913                 // The user tapps a cell which has no icon. it is ignored.
       
  1914                 if (iConsArray->Count() > globalY * iMaxColumns + newGridX)
       
  1915                     {
       
  1916                     //If icon is already selected then on single tap it should change the icon.
       
  1917                     if (iCursorPos.iY == newGridY && iCursorPos.iX
       
  1918                             == newGridX)
       
  1919                         {
       
  1920 #ifdef RD_TACTILE_FEEDBACK
       
  1921                         // The user tapps a cell which has icon, selection has been accepted
       
  1922                         MTouchFeedback* feedback = MTouchFeedback::Instance();
       
  1923                         if (feedback)
       
  1924                             {
       
  1925                             feedback->InstantFeedback(this,
       
  1926                                     ETouchFeedbackBasic);
       
  1927                             }
       
  1928 #endif //RD_TACTILE_FEEDBACK
       
  1929                         //iIsChangeIcon = ETrue;
       
  1930                         }
       
  1931                     else if (iCursorPos.iX + (iCursorPos.iY
       
  1932                                     + iFirstVisibleRow) * iMaxColumns
       
  1933                             < iConsArray->Count())
       
  1934                         {
       
  1935 #ifdef RD_TACTILE_FEEDBACK
       
  1936                         // The user tapps a cell which has icon, send feedback if position has changed
       
  1937                         MTouchFeedback* feedback = MTouchFeedback::Instance();
       
  1938                         const TBool feedbackNeeded = (iCursorPos.iY
       
  1939                                 != newGridY) || (iCursorPos.iX != newGridX);
       
  1940                         if (feedback && feedbackNeeded)
       
  1941                             {
       
  1942                             feedback->InstantFeedback(this,
       
  1943                                     ETouchFeedbackBasic);
       
  1944                             }
       
  1945 #endif //RD_TACTILE_FEEDBACK
       
  1946                         iOldCursorPos = iCursorPos;
       
  1947                         iCursorPos.iY = newGridY;
       
  1948                         iCursorPos.iX = newGridX;
       
  1949                         DrawCursor();
       
  1950                         }
       
  1951                     else
       
  1952                         {
       
  1953                         iOldCursorPos = iCursorPos;
       
  1954                         iCursorPos.iY = newGridY;
       
  1955                         iCursorPos.iX = newGridX;
       
  1956                         DrawCursor();
       
  1957                         }
       
  1958                     }
       
  1959                 }
       
  1960             else if (aPointerEvent.iType == TPointerEvent::EDrag)
       
  1961                 {
       
  1962                 //Handle drag event only if the icon is not already selected, if already selected then do nothing for EDrag event
       
  1963                 if (iCursorPos.iY != newGridY || iCursorPos.iX != newGridX)
       
  1964                     {
       
  1965                     //iIsChangeIcon = EFalse;
       
  1966                     TUint globalY = newGridY + iFirstVisibleRow;
       
  1967                     // The user tapps a cell which has no icon. it is ignored.
       
  1968                     if (iConsArray->Count() > globalY * iMaxColumns
       
  1969                             + newGridX)
       
  1970                         {
       
  1971                         if (iCursorPos.iX
       
  1972                                 + (iCursorPos.iY + iFirstVisibleRow)
       
  1973                                 * iMaxColumns < iConsArray->Count())
       
  1974                             {
       
  1975 #ifdef RD_TACTILE_FEEDBACK
       
  1976                             // While dragging cell is changed, give sensitive feedback
       
  1977                             MTouchFeedback* feedback =
       
  1978                             MTouchFeedback::Instance();
       
  1979                             const TBool feedbackNeeded = (iCursorPos.iY
       
  1980                                     != newGridY) || (iCursorPos.iX
       
  1981                                     != newGridX);
       
  1982                             if (feedback && feedbackNeeded)
       
  1983                                 {
       
  1984                                 feedback->InstantFeedback(this,
       
  1985                                         ETouchFeedbackSensitive);
       
  1986                                 }
       
  1987 #endif //RD_TACTILE_FEEDBACK
       
  1988                             iOldCursorPos = iCursorPos;
       
  1989                             iCursorPos.iY = newGridY;
       
  1990                             iCursorPos.iX = newGridX;
       
  1991                             DrawCursor();
       
  1992                             }
       
  1993                         else
       
  1994                             {
       
  1995                             iOldCursorPos.iX = 0;
       
  1996                             iOldCursorPos.iY = 0;
       
  1997                             }
       
  1998                         }
       
  1999                     }
       
  2000 
       
  2001                 }
       
  2002             else if (aPointerEvent.iType == TPointerEvent::EButton1Up)
       
  2003                 {
       
  2004                 //if (iIsChangeIcon)
       
  2005 
       
  2006                     {
       
  2007                     iExtension->iObserver->HandleControlEventL(this,
       
  2008                             MCoeControlObserver::EEventStateChanged);
       
  2009                     //iIsChangeIcon = EFalse;
       
  2010                     }
       
  2011                 }
       
  2012             }
       
  2013         // Events: Drag and repeat pointer events which are not on the scrollbar are handled here.
       
  2014 
       
  2015         else if (iConsArray->Count() > iMaxColumns
       
  2016                 * iExtension->iMaxVisibleRows && newGridX < iMaxColumns
       
  2017                 && newGridX >= 0 && newGridY < iExtension->iMaxVisibleRows
       
  2018                 && newGridY >= 0)
       
  2019             {
       
  2020             TRect ignoreUpRect(TPoint(KMinTInt, KMinTInt), TPoint(KMaxTInt,
       
  2021                             iGridTopLeft.iY));
       
  2022             TRect ignoreDownRect(TPoint(KMinTInt, (iGridTopLeft.iY
       
  2023                                     + iGridItemHeight * iExtension->iMaxVisibleRows)),
       
  2024                     TPoint(KMaxTInt, KMaxTInt));
       
  2025             // Drag events
       
  2026             if (aPointerEvent.iType == TPointerEvent::EDrag
       
  2027                     || aPointerEvent.iType == TPointerEvent::EButtonRepeat)
       
  2028                 {
       
  2029                 // The pointer is dragged upwards from map
       
  2030                 if (aPointerEvent.iPosition.iY < iGridTopLeft.iY
       
  2031                         && aPointerEvent.iPosition.iX < iGridTopLeft.iX) //scroll up
       
  2032                     {
       
  2033                     // focus on first page
       
  2034                     if (iFirstVisibleRow == 0)
       
  2035                         {
       
  2036                         iFirstVisibleRow = previousRows;
       
  2037                         // if the last page contains only one partial row.
       
  2038                         if (lastRowsLength - 1 < iCursorPos.iX && iRows
       
  2039                                 % iExtension->iMaxVisibleRows == 1)
       
  2040                             {
       
  2041                             iCursorPos.iX = lastRowsLength - 1;
       
  2042                             }
       
  2043                         }
       
  2044                     // focus on some other page than first
       
  2045                     else
       
  2046                         {
       
  2047                         iFirstVisibleRow -= iExtension->iMaxVisibleRows;
       
  2048                         }
       
  2049                     // For odd reason the user has been able to induce upward dragging with out moving
       
  2050                     // up through the grid.
       
  2051                     if (iCursorPos.iY + iExtension->iMaxVisibleRows
       
  2052                             != iFirstVisibleRow)
       
  2053                         {
       
  2054                         iCursorPos.iY = 0;
       
  2055                         }
       
  2056                     UpdateScrollIndicatorL();
       
  2057                     if (iExtension->iObserver)
       
  2058                         {
       
  2059                         iExtension->iObserver->HandleControlEventL(this,
       
  2060                                 MCoeControlObserver::EEventRequestFocus);
       
  2061                         }
       
  2062                     DrawDeferred();
       
  2063                     }
       
  2064                 // the pointer is dragged downwards from the map.
       
  2065                 else if (yInPixels >= iGridItemHeight
       
  2066                         * iExtension->iMaxVisibleRows) //scroll down
       
  2067                     {
       
  2068                     // The focus is on the last page
       
  2069                     if (iFirstVisibleRow == previousRows)
       
  2070                         {
       
  2071                         iFirstVisibleRow = 0;
       
  2072                         iCursorPos.iY = iExtension->iMaxVisibleRows - 1;
       
  2073                         }
       
  2074                     // The focus is on some other page than the last one.
       
  2075                     else
       
  2076                         {
       
  2077                         iFirstVisibleRow += iExtension->iMaxVisibleRows;
       
  2078                         // if the next page is the last page
       
  2079                         if (iFirstVisibleRow == previousRows)
       
  2080                             {
       
  2081                             // the old cursor is set to a "safe" position where it at least can be.
       
  2082                             iOldCursorPos.iX = 0;
       
  2083                             iOldCursorPos.iY = 0;
       
  2084 
       
  2085                             // if the last page has only one line which isn't filled complitely.
       
  2086                             if (lastRowsLength - 1 < iCursorPos.iX && iRows
       
  2087                                     % iExtension->iMaxVisibleRows == 1)
       
  2088                                 {
       
  2089                                 iCursorPos.iX = lastRowsLength - 1;
       
  2090                                 }
       
  2091                             // If the cursor is in a position where it would go unto a spot with out
       
  2092                             // a icon when scrolled.
       
  2093                             if (lastRowsLength > iCursorPos.iX)
       
  2094                                 {
       
  2095                                 //
       
  2096                                 iCursorPos.iY = iRows - 1 - iFirstVisibleRow;
       
  2097                                 }
       
  2098                             else
       
  2099                                 {
       
  2100                                 //
       
  2101                                 iCursorPos.iY = iRows - 2 - iFirstVisibleRow;
       
  2102                                 }
       
  2103                             }
       
  2104                         }
       
  2105                     UpdateScrollIndicatorL();
       
  2106                     if (iExtension->iObserver)
       
  2107                         {
       
  2108                         iExtension->iObserver->HandleControlEventL(this,
       
  2109                                 MCoeControlObserver::EEventRequestFocus);
       
  2110                         }
       
  2111                     DrawDeferred();
       
  2112                     }
       
  2113                 }
       
  2114             }
       
  2115 
       
  2116         else // For a non window owning scrollbar.
       
  2117             {
       
  2118             CCoeControl::HandlePointerEventL(aPointerEvent);
       
  2119             }
       
  2120         }
       
  2121     }
       
  2122 
       
  2123 // -----------------------------------------------------------------------------
       
  2124 // CLmkIconMap::SetObserver
       
  2125 // Sets the observer.
       
  2126 // -----------------------------------------------------------------------------
       
  2127 //
       
  2128 void CLmkIconMap::SetObserver( MCoeControlObserver* aObserver )
       
  2129     {
       
  2130     if (iExtension)
       
  2131         {
       
  2132         iExtension->iObserver = aObserver;
       
  2133         }
       
  2134     }
       
  2135 
       
  2136 #endif //RD_SCALABLE_UI_V2
       
  2137 //  End of File