landmarksui/uicontrols/src/lmkiconmap.cpp
branchRCL_3
changeset 18 870918037e16
parent 0 522cd55cc3d7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/landmarksui/uicontrols/src/lmkiconmap.cpp	Wed Sep 01 12:31:27 2010 +0100
@@ -0,0 +1,2137 @@
+/*
+ * Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Nokia Corporation - initial contribution.
+ *
+ * Contributors:
+ *
+ * Description:    LandmarksUi Content File - Landmarks icon selector map
+ *
+ */
+
+// INCLUDE FILES
+#include <eikenv.h>
+#include <eiksbfrm.h>
+#include <eikscrlb.h>
+#include <bidivisual.h>
+#include <avkon.rsg>
+#include <AknPanic.h>
+#include <avkon.hrh>
+#include <AknUtils.h>
+#include <aknlayoutscalable_avkon.cdl.h>
+#include <layoutmetadata.cdl.h>
+#include <AknLayout.lag>
+
+#include <aknappui.h>
+#include <aknconsts.h>
+#include <AknDef.h>
+#include <PUAcodes.hrh>
+#include <s32file.h>
+
+#ifdef RD_TACTILE_FEEDBACK
+#include <touchfeedback.h>
+#endif //RD_TACTILE_FEEDBACK
+// For the TEikScrollBarModelType
+#include <eikscrlb.h>
+
+#include <AknsDrawUtils.h>
+#include <featmgr.h>
+
+#include <AknsFrameBackgroundControlContext.h>
+
+#include <lmkui.mbg>
+
+#include "lmkiconmap.h"
+#include "CLmkUiUtils.h"
+#include <lmkerrors.h>
+
+// The offset because of CEikDialogPage
+const TInt KHorizontalDialogMargin = 0;
+const TInt KVerticalDialogMargin = 0;
+const TInt KAknSctCBaButtonDirections = 3; // bottom, right and left
+
+
+/// Unnamed namespace for local definitions
+namespace
+    {
+    const TInt KNumOfIcons(16);
+    _LIT( KPanicMsg, "CLmkIconMap" );
+
+    void Panic(TPanicCode aReason)
+        {
+        User::Panic(KPanicMsg, aReason);
+        }
+    } // namespace
+
+// ============================ EXTENSION CLASS ===============================
+//Class Declaration
+NONSHARABLE_CLASS(CLmkIconMapExtension) : public CBase,
+public MObjectProvider
+    {
+public:
+    CLmkIconMapExtension();
+    ~CLmkIconMapExtension();
+
+protected:
+    TTypeUid::Ptr MopSupplyObject(TTypeUid aId);
+    MObjectProvider* MopNext();
+
+public:
+    // data
+    MCoeControlObserver *iObserver;
+
+    TUint iFlags;
+    MObjectProvider* iIconMap;
+    TInt iMaxVisibleRows;
+    CAknsFrameBackgroundControlContext* iBgContext;
+    };
+
+// ============================ MEMBER FUNCTIONS OF CLmkIconMapExtension ===============================
+
+// -----------------------------------------------------------------------------
+// CLmkIconMapExtension::CLmkIconMapExtension
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CLmkIconMapExtension::CLmkIconMapExtension() :
+    iMaxVisibleRows(0)
+    {
+    iObserver = NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMapExtension::MopSupplyObject()
+// -----------------------------------------------------------------------------
+//
+TTypeUid::Ptr CLmkIconMapExtension::MopSupplyObject(TTypeUid aId)
+    {
+    return MAknsControlContext::SupplyMopObject(aId, iBgContext);
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMapExtension::MopNext()
+// -----------------------------------------------------------------------------
+//
+MObjectProvider* CLmkIconMapExtension::MopNext()
+    {
+    return iIconMap;
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMapExtension::~CLmkIconMapExtension()
+// -----------------------------------------------------------------------------
+//
+CLmkIconMapExtension::~CLmkIconMapExtension()
+    {
+
+    delete iBgContext;
+    }
+
+// ============================ MEMBER FUNCTIONS OF CLmkIconMap ===============================
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::CLmkIconMap
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CLmkIconMap::CLmkIconMap() :
+    iCursorPos(TPoint(0, 0)), iOldCursorPos(TPoint(0, 0)), iMaxColumns(-1),
+            iCurrentPage(0), iNumPages(0)
+    {
+    iConsArray = (CArrayPtr<CGulIcon>*) NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CLmkIconMap* CLmkIconMap::NewL()
+    {
+    CLmkIconMap* self = new (ELeave) CLmkIconMap();
+
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self); //self
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CLmkIconMap::ConstructL()
+    {
+    // Must be created here to get the member variables available
+    iExtension = new (ELeave) CLmkIconMapExtension;
+    iExtension->iIconMap = this;
+
+    iConsArray = new (ELeave) CAknIconArray(KNumOfIcons);
+
+    iExtension->iFlags = 0x00;
+
+    DoLayout();
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::~CLmkIconMap()
+// -----------------------------------------------------------------------------
+//
+CLmkIconMap::~CLmkIconMap()
+    {
+    delete iSBFrame;
+    iSBFrame = (CEikScrollBarFrame*) NULL;
+
+    delete iOffscreenBg;
+    delete iBitmapDevice;
+    delete iBitmapGc;
+
+    delete iExtension;
+    iExtension = (CLmkIconMapExtension*) NULL;
+
+    if (iConsArray)
+        {
+        iConsArray->ResetAndDestroy();
+        delete iConsArray;
+        iConsArray = (CArrayPtr<CGulIcon>*) NULL;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::DoLayout()
+// -----------------------------------------------------------------------------
+//
+void CLmkIconMap::DoLayout()
+    {
+    TRAPD(err, LoadIconL());
+    if (err)
+        return;
+
+    iIsMirrored = AknLayoutUtils::LayoutMirrored();
+    iDrawnBefore = EFalse;
+    CountMaxColumnsAndCellSizes();
+    SizeChanged();
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::ConstructFromResourceL()
+// -----------------------------------------------------------------------------
+//
+void CLmkIconMap::ConstructFromResourceL(TResourceReader& /*aReader*/)
+    {
+    LoadIconL();
+    CreateScrollBarAndIconRowL();
+
+    Extension()->iBgContext = CAknsFrameBackgroundControlContext::NewL(
+            KAknsIIDQsnFrPopup, TRect(0, 0, 1, 1), TRect(0, 0, 1, 1), EFalse);
+
+    if (DrawableWindow() && AknLayoutUtils::PenEnabled())
+        {
+        EnableDragEvents();
+        SetGloballyCapturing( ETrue);
+        SetPointerCapture(ETrue);
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::LoadIcons()
+// This actually load the all icons to be shown on dialog from icon file
+// -----------------------------------------------------------------------------
+//
+void CLmkIconMap::LoadIconL()
+    {
+    if (iConsArray)
+        {
+        iConsArray->ResetAndDestroy();
+        }
+    // Draw all the Icons.
+    TFileName* iconFile = CLmkUiUtils::LmkUiIconFileLC();
+
+    // Create icon bitmap and mask.
+    for (TInt i(0); i < (KNumOfIcons * 2); i++)
+        {
+        CFbsBitmap* bitmap = NULL;
+        CFbsBitmap* bitmapMask = NULL;
+        AknIconUtils::CreateIconLC(bitmap, bitmapMask, *iconFile,
+                EMbmLmkuiQgn_prop_lm_transport + i,
+                EMbmLmkuiQgn_prop_lm_transport + i + 1);
+        i++;
+        AknIconUtils::SetSize(bitmap, TSize(iGridItemWidth, iGridItemHeight)); //fix
+        AknIconUtils::SetSize(bitmapMask, TSize(iGridItemWidth,
+                iGridItemHeight)); //fix
+        CGulIcon* icon = CGulIcon::NewL(bitmap, bitmapMask);
+        CleanupStack::PushL(icon);
+        if (iConsArray)
+            iConsArray->AppendL(icon);
+        CleanupStack::Pop(icon); // icon
+        CleanupStack::Pop(bitmapMask); // mask
+        CleanupStack::Pop(bitmap); // bitmap
+        }
+    CleanupStack::PopAndDestroy();// iconFile
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::HeightInRows()
+// This actually returns the no of rows to be shown on a page
+// Depends upon the Layout size
+// -----------------------------------------------------------------------------
+//
+TInt CLmkIconMap::HeightInRows()
+    {
+    return (iRows);
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::CreateScrollBarAndIconRowL()
+// This actually creates the scroll bar sets the number of
+// pages and rows on a page to be shown
+// -----------------------------------------------------------------------------
+//
+void CLmkIconMap::CreateScrollBarAndIconRowL()
+    {
+    __ASSERT_DEBUG(iExtension, Panic(KLmkPanicInvalidResourceData));
+
+    __ASSERT_ALWAYS(iConsArray, Panic(KLmkPanicInvalidResourceData));
+
+    iRows = ((iConsArray->Count() - 1) / iMaxColumns) + 1;
+    iFirstVisibleRow = 0;
+    iAnimated = EFalse;
+    iCursorPos = TPoint(0, 0);
+    iNumPages = (iRows / iExtension->iMaxVisibleRows) + (iRows
+            % iExtension->iMaxVisibleRows ? 1 : 0);
+    iCurrentPage = 1;
+
+    // Create and set the scb visible even though there is nothing to scroll
+    delete iSBFrame;
+    iSBFrame = NULL;
+
+    if (AknLayoutUtils::PenEnabled())
+        {
+        iSBFrame = new (ELeave) CEikScrollBarFrame(this, this, ETrue);
+        }
+    else
+        {
+        iSBFrame = new (ELeave) CEikScrollBarFrame(this, NULL, ETrue);
+        }
+    // Decide which type of scrollbar is shown
+    CAknAppUi* appUi = iAvkonAppUi;
+    if (AknLayoutUtils::DefaultScrollBarType(appUi)
+            == CEikScrollBarFrame::EDoubleSpan)
+        {
+        // For EDoubleSpan type scrollbar
+        if (AknLayoutUtils::PenEnabled())
+            {
+            iSBFrame->CreateDoubleSpanScrollBarsL(ETrue, EFalse, ETrue,
+                    EFalse); // window owning scrollbar
+            }
+        else
+            {
+            iSBFrame->CreateDoubleSpanScrollBarsL(EFalse, EFalse, ETrue,
+                    EFalse); // non-window owning scrollbar
+            }
+        iSBFrame->SetTypeOfVScrollBar(CEikScrollBarFrame::EDoubleSpan);
+        }
+    else
+        {
+        // For EArrowHead type scrollbar
+        iSBFrame->SetTypeOfVScrollBar(CEikScrollBarFrame::EArrowHead);
+        }
+
+    iSBFrame->SetScrollBarVisibilityL(CEikScrollBarFrame::EOff,
+            CEikScrollBarFrame::EAuto);
+    iSBFrame->VerticalScrollBar()->SetMopParent(iExtension);
+    UpdateScrollIndicatorL();
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::SetIndex
+// set the reference of the selected icon index from the table
+// -----------------------------------------------------------------------------
+//
+void CLmkIconMap::SetIndex(TInt& aIconIndex)
+    {
+    iIconIndex = &aIconIndex;
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::MinimumSize
+//
+// -----------------------------------------------------------------------------
+//
+TSize CLmkIconMap::MinimumSize()
+    {
+    iIsMirrored = AknLayoutUtils::LayoutMirrored();
+    CountMaxColumnsAndCellSizes();
+
+    TRect rect;
+    // Used the set rect, but resolution changes cannot be handled when it is used
+
+    TAknLayoutRect dialogLayRect;
+
+    // Main pane without softkeys
+    TRect mainPaneRect;
+    if (!AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane,
+            mainPaneRect))
+        {
+        mainPaneRect = iAvkonAppUi->ClientRect();
+        }
+
+    // Dialog layout, check variety first
+    TAknLayoutScalableParameterLimits iconMapDialogVariety =
+            AknLayoutScalable_Avkon::popup_grid_graphic_window_ParamLimits();
+
+    // Calc the variety
+    TInt maxVariety = iconMapDialogVariety.LastVariety();
+
+    // Check the CBA, if the orientation is not landscape
+    // there is not so much varieties
+    AknLayoutUtils::TAknCbaLocation location = AknLayoutUtils::CbaLocation();
+    TInt maxVarietyOffset = 0; // the offset for the certain cba location variety
+    TInt varietyOffset = maxVariety + 1; // the number of varieties
+
+    // landscape variety number must be calculated offset == number of varieties
+    // same applies to the variety number for the biggest sized layout for the variety
+    if (Layout_Meta_Data::IsLandscapeOrientation())
+        {
+        varietyOffset = (maxVariety + 1) / KAknSctCBaButtonDirections; // the offset for one variety
+        }
+
+    // for right and left cba buttons the max variety is not zero
+    // the varities are ordered by the location of the cba and the descending order
+    // e.g the biggest sized layout first, the smallest last
+    if (location == AknLayoutUtils::EAknCbaLocationRight)
+        {
+        maxVarietyOffset = varietyOffset;
+        }
+    else if (location == AknLayoutUtils::EAknCbaLocationLeft)
+        {
+        maxVarietyOffset = varietyOffset + varietyOffset; // 2*
+        }
+
+    TInt varietyNumber = varietyOffset - iRows - 1;
+
+    // if more lines than possible to show, use the default
+    // (the biggest grid) variety
+    if (varietyNumber < 0)
+        varietyNumber = 0;
+    // if zero rows, use the minimum
+    else if (iRows <= 0)
+        varietyNumber -= 1;
+
+    //add the varietyoffset
+    varietyNumber += maxVarietyOffset;
+
+    if (Layout_Meta_Data::IsLandscapeOrientation() && (location
+            == AknLayoutUtils::EAknCbaLocationRight))
+        {
+        varietyNumber = 10;
+        }
+    else
+        {
+        if (iRows == 0)
+            {
+            varietyNumber = 5;
+            }
+        else
+            {
+            varietyNumber = 3;
+            }
+        }
+    // Layout the dialog size
+    dialogLayRect.LayoutRect(mainPaneRect,
+            AknLayoutScalable_Avkon::popup_grid_graphic_window(varietyNumber));
+
+    // Layout the grid
+    TAknLayoutRect gridWithScrollLayRect;
+    gridWithScrollLayRect.LayoutRect(dialogLayRect.Rect(),
+            AknLayoutScalable_Avkon::listscroll_popup_graphic_pane());
+
+    return TSize(dialogLayRect.Rect().Width(),
+            gridWithScrollLayRect.Rect().Height());
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::ActivateL()
+// This method is needed to set correct initial value to scroll indicator.
+// -----------------------------------------------------------------------------
+//
+void CLmkIconMap::ActivateL()
+    {
+    CCoeControl::ActivateL();
+    if (iRows > Extension()->iMaxVisibleRows)
+        {
+        UpdateScrollIndicatorL();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::OfferKeyEventL
+// Handles all the Keypad events
+// -----------------------------------------------------------------------------
+//
+TKeyResponse CLmkIconMap::OfferKeyEventL(const TKeyEvent& aKeyEvent,
+        TEventCode /*aModifiers*/)
+    {
+    TUint code = aKeyEvent.iCode;
+
+    switch (code)
+        {
+        case EKeyLeftArrow:
+        case '4':
+            MoveCursorL(-1, 0);
+            break;
+        case EKeyRightArrow:
+        case '6':
+            MoveCursorL(1, 0);
+            break;
+        case EKeyUpArrow:
+        case '2':
+            MoveCursorL(0, -1);
+            break;
+        case EKeyDownArrow:
+        case '8':
+            MoveCursorL(0, 1);
+            break;
+        case EKeyOK:
+        case '5':
+        case EKeySpace:
+        case EKeyEnter:
+            {
+            if (iConsArray)
+                {
+                TInt ret = iMaxColumns * (iFirstVisibleRow + iCursorPos.iY)
+                        + iCursorPos.iX;
+                if (ret <= iConsArray->Count())
+                    {
+                    *iIconIndex = ret;
+                    }
+                else
+                    {
+                    *iIconIndex = -1;
+                    }
+                }
+
+            }
+            break;
+        default:
+            return EKeyWasNotConsumed;
+
+        }
+    return EKeyWasConsumed;
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::InputCapabilities()
+//
+// -----------------------------------------------------------------------------
+//
+TCoeInputCapabilities CLmkIconMap::InputCapabilities() const
+    {
+    return TCoeInputCapabilities(TCoeInputCapabilities::EAllText);
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::SizeChanged()
+// Control position of this control is registered for skin library when necessary
+// in CEikDialogPage::SetDataPosition, so we do not do that in this method.
+// -----------------------------------------------------------------------------
+//
+void CLmkIconMap::SizeChanged()
+    {
+    // Get the layout
+
+    // Main pane without softkeys
+    TRect mainPaneRect;
+
+    if (!AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane,
+            mainPaneRect))
+        {
+        mainPaneRect = iAvkonAppUi->ClientRect();
+        }
+
+    // Dialog layout, check variety first
+    TAknLayoutScalableParameterLimits iconMapDialogVariety =
+            AknLayoutScalable_Avkon::popup_grid_graphic_window_ParamLimits();
+
+    TInt maxVariety = iconMapDialogVariety.LastVariety();
+
+    // Check the CBA, if the orientation is not landscape
+    // there is not so much varieties
+    AknLayoutUtils::TAknCbaLocation location = AknLayoutUtils::CbaLocation();
+    TInt maxVarietyOffset = 0; // the offset for the certain cba location variety
+    TInt varietyOffset = maxVariety + 1;
+
+    // landscape variety number must be calculated offset == number of varieties
+    // same applies to the variety number for the biggest sized layout for the variety
+    if (Layout_Meta_Data::IsLandscapeOrientation())
+        {
+        varietyOffset = (maxVariety + 1) / KAknSctCBaButtonDirections; // the offset for one variety
+        }
+
+    // for right and left cba buttons the max variety is not zero
+    // the varities are ordered by the location of the cba and the descending order
+    // e.g the biggest sized layout first, the smallest last
+    if (location == AknLayoutUtils::EAknCbaLocationRight)
+        {
+        maxVarietyOffset = varietyOffset;
+        }
+    else if (location == AknLayoutUtils::EAknCbaLocationLeft)
+        {
+        maxVarietyOffset = varietyOffset + varietyOffset; // 2*
+        }
+
+    TInt varietyNumber = varietyOffset - iRows - 1;
+
+    // if more lines than possible to show, use the default
+    // (the biggest grid) variety
+    if (varietyNumber < 0)
+        varietyNumber = 0;
+    // if zero rows, use the minimum
+    else if (iRows <= 0)
+        varietyNumber -= 1;
+
+    //add the varietyoffset
+    varietyNumber += maxVarietyOffset;
+
+    if (Layout_Meta_Data::IsLandscapeOrientation() && (location
+            == AknLayoutUtils::EAknCbaLocationRight))
+        {
+        varietyNumber = 10;
+        }
+    else
+        {
+        if (iRows == 0)
+            {
+            varietyNumber = 5;
+            }
+        else
+            {
+            varietyNumber = 3;
+            }
+
+        }
+
+    TAknLayoutRect popupGridLayRect;
+    popupGridLayRect.LayoutRect(mainPaneRect,
+            AknLayoutScalable_Avkon::popup_grid_graphic_window(varietyNumber));
+
+    // Calculate the size relatively
+    TRect relativeDialog(TPoint(0, 0), popupGridLayRect.Rect().Size());
+
+    // Get the layout of the actual icon grid with scrollbar
+    TAknLayoutRect gridWithScrollLayRect;
+    gridWithScrollLayRect.LayoutRect(relativeDialog,
+            AknLayoutScalable_Avkon::listscroll_popup_graphic_pane());
+
+    // Then the grid area without scrollbar
+    // NOTE: The grid with scroll bar is used as reference
+    TAknLayoutRect gridLayRect;
+    gridLayRect.LayoutRect(gridWithScrollLayRect.Rect(),
+            AknLayoutScalable_Avkon::grid_graphic_popup_pane(0));
+
+    // Different parent if SCT inside editing menu.
+    TRect contentRect = gridLayRect.Rect();
+
+    // The x coordinate is 3 pixels to right and y coordinate 3 pixels up
+    // so substract from x coordinate and add to y coordinate
+    if (iIsMirrored)
+        {
+        iOffset = TPoint(contentRect.iBr.iX - KHorizontalDialogMargin
+                - iGridItemWidth + 1, contentRect.iTl.iY
+                - KVerticalDialogMargin + 1);
+        iGridTopLeft.iX = contentRect.iBr.iX - KHorizontalDialogMargin
+                - (iMaxColumns * iGridItemWidth);
+        iGridTopLeft.iY = contentRect.iTl.iY - KVerticalDialogMargin;
+        }
+    else // not mirrored
+        {
+        iOffset = TPoint(contentRect.iTl.iX - KHorizontalDialogMargin + 1,
+                contentRect.iTl.iY - KVerticalDialogMargin + 1);
+        iGridTopLeft.iX = contentRect.iTl.iX - KHorizontalDialogMargin;
+        iGridTopLeft.iY = contentRect.iTl.iY - KVerticalDialogMargin;
+        }
+
+    // The last, update background context
+    if (Extension()->iBgContext)
+        {
+        TInt bgVariety = 0;
+        if (Layout_Meta_Data::IsLandscapeOrientation())
+            bgVariety = 1;
+
+        TAknLayoutRect innerRect;
+        innerRect.LayoutRect(relativeDialog,
+                AknLayoutScalable_Avkon::bg_popup_window_pane_g1(bgVariety));
+
+        Extension()->iBgContext->SetFrameRects(relativeDialog,
+                innerRect.Rect());
+        }
+    TRAPD(err, UpdateScrollIndicatorL());
+    if (err)
+        return;
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::HandleResourceChange()
+//
+// -----------------------------------------------------------------------------
+//
+void CLmkIconMap::HandleResourceChange(TInt aType)
+    {
+    if (aType == KEikDynamicLayoutVariantSwitch)
+        {
+        // save the old info for the magnitudes of the SCT grid
+        TInt oldMaxColumns = iMaxColumns;
+        //TInt oldMaxRows = 0;
+        //oldMaxRows = iRows;
+        // calculate the new magnitudes
+        DoLayout();
+
+        // then calculate the index position of the cursor in the icon table
+        // and update the x and y positions for the new grid with it
+
+        TInt oldCursorPosition = (iFirstVisibleRow + iOldCursorPos.iY)
+                * oldMaxColumns + iOldCursorPos.iX;
+
+        TInt currentCursorPosition = (iFirstVisibleRow + iCursorPos.iY)
+                * oldMaxColumns + iCursorPos.iX;
+
+        // the new first row is the top row on the page where the new focus is
+        iFirstVisibleRow = Extension()->iMaxVisibleRows
+                * (currentCursorPosition / (iMaxColumns
+                        * Extension()->iMaxVisibleRows));
+
+        // the cursor positions are relative to current page
+        iCursorPos.iY = (currentCursorPosition - (iMaxColumns
+                * iFirstVisibleRow)) / iMaxColumns;
+        iCursorPos.iX = currentCursorPosition - (iMaxColumns
+                * iFirstVisibleRow) - (iMaxColumns * iCursorPos.iY);
+
+        iOldCursorPos.iY = (oldCursorPosition - (iMaxColumns
+                * iFirstVisibleRow)) / iMaxColumns;
+        iOldCursorPos.iX = oldCursorPosition - (iMaxColumns
+                * iFirstVisibleRow) - (iMaxColumns * iOldCursorPos.iY);
+        }
+
+    if (aType == KAknsMessageSkinChange)
+        {
+        iOffscreenBgDrawn = EFalse;
+        }
+    CCoeControl::HandleResourceChange(aType);
+
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::Draw()
+//
+// -----------------------------------------------------------------------------
+//
+void CLmkIconMap::Draw(const TRect& /*aRect*/) const
+    {
+
+    TInt cursorPos = 0;
+    CWindowGc& gc = SystemGc();
+
+    MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+    MAknsControlContext* cc = AknsDrawUtils::ControlContext(this);
+
+    TRect rect = Rect();
+
+    // Main pane without softkeys
+    TRect mainPaneRect;
+    if (!AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane,
+            mainPaneRect))
+        {
+        mainPaneRect = iAvkonAppUi->ClientRect();
+        }
+
+    // Dialog layout, check variety first
+    TAknLayoutScalableParameterLimits iconMapDialogVariety =
+            AknLayoutScalable_Avkon::popup_grid_graphic_window_ParamLimits();
+
+    // The variety starts from 0 so add +1
+    TInt maxVariety = iconMapDialogVariety.LastVariety();
+
+    // Check the CBA, if the orientation is not landscape
+    // there is not so much varieties
+    AknLayoutUtils::TAknCbaLocation location = AknLayoutUtils::CbaLocation();
+    TInt maxVarietyOffset = 0; // the offset for the certain cba location variety
+    TInt varietyOffset = maxVariety + 1;
+
+    // landscape variety number must be calculated offset == number of varieties
+    // same applies to the variety number for the biggest sized layout for the variety
+    if (Layout_Meta_Data::IsLandscapeOrientation())
+        {
+        varietyOffset = (maxVariety + 1) / KAknSctCBaButtonDirections; // the offset for one variety
+        }
+
+    // for right and left cba buttons the max variety is not zero
+    // the varities are ordered by the location of the cba and the descending order
+    // e.g the biggest sized layout first, the smallest last
+    if (location == AknLayoutUtils::EAknCbaLocationRight)
+        {
+        maxVarietyOffset = varietyOffset;
+        }
+    else if (location == AknLayoutUtils::EAknCbaLocationLeft)
+        {
+        maxVarietyOffset = varietyOffset + varietyOffset; // 2*
+        }
+
+    TInt varietyNumber = varietyOffset - iRows - 1;
+
+    // if more lines than possible to show, use the default
+    // (the biggest grid) variety
+    if (varietyNumber < 0)
+        varietyNumber = 0;
+    // if zero rows, use the minimum
+    else if (iRows <= 0)
+        varietyNumber -= 1;
+
+    //add the varietyoffset
+    varietyNumber += maxVarietyOffset;
+
+    if (Layout_Meta_Data::IsLandscapeOrientation() && (location
+            == AknLayoutUtils::EAknCbaLocationRight))
+        {
+        varietyNumber = 10;
+        }
+    else
+        {
+        varietyNumber = 3;
+        }
+    // Layout the dialog size
+    TAknLayoutRect dialogLayRect;
+    dialogLayRect.LayoutRect(mainPaneRect,
+            AknLayoutScalable_Avkon::popup_grid_graphic_window(varietyNumber));
+
+    // Get the missing height for the background
+    TInt backgroundHeightOffset = dialogLayRect.Rect().Height() - rect.iBr.iY;
+
+    rect.iBr.iY += backgroundHeightOffset;
+
+    // Check if we got an offscreen bitmap allocated for skin background and
+    // there is bitmap background in the current skin.
+    if (iOffscreenBg && iHasBitmapBackground)
+        {
+        DrawOffscreenBackgroundIfRequired();
+        gc.BitBlt(rect.iTl, iOffscreenBg);
+        }
+    else
+        {
+        AknsDrawUtils::Background(skin, cc, this, gc, rect);
+        }
+
+    TInt numberOfIconsToBeDrawn = iConsArray->Count();
+    numberOfIconsToBeDrawn -= (iFirstVisibleRow * iMaxColumns);
+    if (numberOfIconsToBeDrawn > 0)
+        {
+        if (numberOfIconsToBeDrawn > (Extension()->iMaxVisibleRows
+                * iMaxColumns))
+            {
+            numberOfIconsToBeDrawn = Extension()->iMaxVisibleRows
+                    * iMaxColumns;
+            }
+        __ASSERT_DEBUG( numberOfIconsToBeDrawn >= 1, Panic( KLmkPanicOutOfRange ) );
+
+        gc.SetPenStyle(CGraphicsContext::ESolidPen);
+        gc.SetBrushStyle(CGraphicsContext::ENullBrush);
+        gc.SetPenSize(TSize(1, 1));
+
+        // 2) Draw the grid
+        const TSize gridItemRectSize(iGridItemWidth + 1, iGridItemHeight + 1);
+
+        TInt numberOfGridCellsToBeDrawn = numberOfIconsToBeDrawn;
+
+        TRgb colorLine = AKN_LAF_COLOR(219);
+        AknsUtils::GetCachedColor(skin, colorLine, KAknsIIDQsnLineColors,
+                EAknsCIQsnLineColorsCG5);
+        TRgb colorRecentLine = AKN_LAF_COLOR(215);
+        AknsUtils::GetCachedColor(skin, colorRecentLine,
+                KAknsIIDQsnLineColors, EAknsCIQsnLineColorsCG7);
+
+        // default pen color
+        gc.SetPenColor(colorLine);
+
+        TInt fullRows = numberOfGridCellsToBeDrawn / iMaxColumns;
+
+        // how many left after the full rows
+        numberOfGridCellsToBeDrawn -= fullRows * iMaxColumns;
+
+        TPoint pos = iGridTopLeft;
+
+        TInt endX = pos.iX + iGridItemWidth * iMaxColumns + 1;
+        TInt endY = pos.iY + iGridItemHeight * fullRows;
+
+        TInt ii = 0;
+
+        if (fullRows)
+            {
+            // Draw full vertical lines
+            for (ii = 0; ii <= iMaxColumns; ii++)
+                {
+                gc.SetPenColor(colorLine);
+                gc.SetPenSize(TSize(1, 1));
+                gc.DrawLine(pos, TPoint(pos.iX, endY));
+                pos.iX += iGridItemWidth;
+                }
+
+            pos = iGridTopLeft;
+
+            // Draw full horizontal lines
+            for (ii = 0; ii <= fullRows; ii++)
+                {
+                gc.SetPenSize(TSize(1, 1));
+                gc.SetPenColor(colorLine);
+                gc.DrawLine(pos, TPoint(endX, pos.iY));
+                pos.iY += iGridItemHeight;
+                }
+            gc.SetPenColor(colorLine);
+            gc.SetPenSize(TSize(1, 1));
+            }
+
+        if (numberOfGridCellsToBeDrawn)
+            {
+            // Remaining cells in the last, non-full row
+            pos = iOffset;
+            pos.iX--; // iOffset is cell area topLeft, grid is not included in it
+            pos.iY--;
+
+            pos.iY += iGridItemHeight * fullRows;
+
+            for (ii = 0; ii < numberOfGridCellsToBeDrawn; ii++)
+                {
+                gc.DrawRect(TRect(pos, gridItemRectSize));
+
+                if (iIsMirrored)
+                    pos.iX -= iGridItemWidth;
+                else
+                    // not mirrored
+                    pos.iX += iGridItemWidth;
+                }
+            }
+
+        TInt iconIndex = (iCurrentPage - 1) * (iMaxColumns
+                * Extension()->iMaxVisibleRows);
+        TInt lCnt = iConsArray->Count();
+        cursorPos = iCursorPos.iX + iCursorPos.iY * iMaxColumns;
+        if (lCnt > 0)
+            {
+            TRect cellRect(TPoint(0, 0), TSize(iGridItemWidth - 1,
+                    iGridItemHeight - 1));
+            for (TInt j = iconIndex, i = 0; j < lCnt && (i
+                    < numberOfIconsToBeDrawn); j++, i++)
+                {
+                DrawItem(gc, CursorRect(i), j, (cursorPos == i), EFalse);
+                }
+            }
+
+        }
+    iDrawnBefore = ETrue;
+    gc.DiscardFont();
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::DrawItem()
+//
+// -----------------------------------------------------------------------------
+//
+void CLmkIconMap::DrawItem(CWindowGc& aGc, const TRect& aSctPosition,
+        TInt aIconIndex, TBool aHighlighted, TBool aDrawBackground) const
+    {
+    MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+    MAknsControlContext* cc = AknsDrawUtils::ControlContext(this);
+
+    TBool skins = AknsDrawUtils::Background(skin, cc, aGc, aSctPosition);
+    TRgb color;
+    if (!skins)
+        aGc.SetBrushStyle(CGraphicsContext::ESolidBrush);
+    if (aHighlighted)
+        {
+        TRgb colorHightLightRect = AKN_LAF_COLOR(215);
+        AknsUtils::GetCachedColor(skin, colorHightLightRect,
+                KAknsIIDQsnLineColors, EAknsCIQsnLineColorsCG7);
+        aGc.SetPenColor(colorHightLightRect);
+        aGc.DrawRect(aSctPosition);
+
+        // Shrink by one pixel in all directions.
+        TRect innerRect = aSctPosition;
+        innerRect.Shrink(1, 1);
+
+        color = AKN_LAF_COLOR(210);
+        AknsUtils::GetCachedColor(skin, color, KAknsIIDQsnHighlightColors,
+                EAknsCIQsnHighlightColorsCG1);
+        aGc.SetBrushColor(color);
+        aGc.Clear(innerRect);
+        }
+    else if (aDrawBackground)
+        {
+        TRect innerRect = aSctPosition;
+        aGc.SetBrushColor(AKN_LAF_COLOR(0));
+        if (!skins)
+            aGc.Clear(innerRect);
+        else
+            AknsDrawUtils::Background(skin, cc, this, aGc, innerRect);
+        }
+
+    if (iConsArray)
+        {
+        TInt lCnt = iConsArray->Count();
+        if (lCnt > 0 && aIconIndex < lCnt && aIconIndex >= 0)
+            {
+            TRect cellRect(TPoint(0, 0), TSize(iGridItemWidth - 1,
+                    iGridItemHeight - 1));
+
+            CGulIcon* bitmap = NULL;
+            bitmap = iConsArray->At(aIconIndex);
+            TInt numIconsInaPage = Extension()->iMaxVisibleRows * iMaxColumns;
+            TInt cellIndex = aIconIndex;
+            if (aIconIndex >= numIconsInaPage)
+                {
+                cellIndex = aIconIndex % numIconsInaPage;
+                }
+            aGc.BitBltMasked(CursorPoint(cellIndex), bitmap->Bitmap(),
+                    cellRect, bitmap->Mask(), EFalse);
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::DrawCursor()
+// Optimizes drawing. Only cursor is drawn.
+// -----------------------------------------------------------------------------
+void CLmkIconMap::DrawCursor() const
+    {
+    // Whole Icon Map has to be drawn at least once.
+    // If the user presses arrow key before Icon Map has been drawn,
+    // only cursor position is drawn without this check.
+    if (!iDrawnBefore)
+        {
+        DrawNow();
+        }
+    // Only redraw old and new cursor position cells
+    ActivateGc();
+    CWindowGc& gc = SystemGc();
+
+    TInt cursorPos = iOldCursorPos.iX + iOldCursorPos.iY * iMaxColumns;
+    if (cursorPos >= 0)
+        {
+        DrawCell(cursorPos, EFalse);
+
+        cursorPos = iCursorPos.iX + iCursorPos.iY * iMaxColumns;
+        DrawCell(cursorPos, ETrue);
+        }
+
+    gc.DiscardFont();
+    DeactivateGc();
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::DrawCell
+// -----------------------------------------------------------------------------
+//
+void CLmkIconMap::DrawCell(TInt aCursorPos, TBool aHighLighted) const
+    {
+    // calculate icon index
+    TInt iconIndex = aCursorPos + iFirstVisibleRow * iMaxColumns;
+
+    // If we are only redrawing for animations, no need to draw non-animated items.
+    TRect rect = CursorRect(aCursorPos);
+
+    Window().Invalidate(rect);
+    Window().BeginRedraw(rect);
+    DrawItem(SystemGc(), rect, iconIndex, aHighLighted, ETrue);
+    Window().EndRedraw();
+    SystemGc().DiscardFont();
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::CursorRect
+// -----------------------------------------------------------------------------
+//
+TRect CLmkIconMap::CursorRect(TInt aCursorPos) const
+    {
+    TPoint pos = iOffset;
+
+    if (iIsMirrored)
+        {
+        pos.iX -= (aCursorPos % iMaxColumns) * iGridItemWidth;
+        }
+    else // Not mirrored
+        {
+        pos.iX += (aCursorPos % iMaxColumns) * iGridItemWidth;
+        }
+
+    pos.iY += (aCursorPos / iMaxColumns) * iGridItemHeight;
+    return TRect(pos, TSize(iGridItemWidth - 1, iGridItemHeight - 1));
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::CursorPoint
+// -----------------------------------------------------------------------------
+//
+TPoint CLmkIconMap::CursorPoint(TInt aCursorPos) const
+    {
+    TPoint pos = iOffset;
+
+    if (iIsMirrored)
+        {
+        pos.iX -= (aCursorPos % iMaxColumns) * iGridItemWidth;
+        }
+    else // Not mirrored
+        {
+        pos.iX += (aCursorPos % iMaxColumns) * iGridItemWidth;
+        }
+
+    pos.iY += (aCursorPos / iMaxColumns) * iGridItemHeight;
+    return pos;
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::MoveCursorL
+// -----------------------------------------------------------------------------
+//
+void CLmkIconMap::MoveCursorL(TInt aDeltaX, TInt aDeltaY)
+    {
+    __ASSERT_DEBUG((aDeltaX <= 1) && (aDeltaX >= -1) && (aDeltaY <= 1)
+            && (aDeltaY >= -1) && ((aDeltaX * aDeltaY) == 0), Panic(
+            KLmkPanicOutOfRange));
+
+    if (iIsMirrored)
+        aDeltaX = -aDeltaX;
+
+    if ((iConsArray->Count() < 8))
+        return;
+
+    iOldCursorPos = iCursorPos;
+    TInt oldFirstVisibleRow = iFirstVisibleRow;
+
+    TInt globalYPos = iCursorPos.iY + iFirstVisibleRow;
+    TInt lastColumnOnLastRow = ((iConsArray->Count() - 1) % iMaxColumns);
+
+    TInt skipicon = aDeltaX != 0 ? 1 : 0;
+
+    if (aDeltaX < 0)
+        {
+        // Cursor was moved to left.
+        if (iCursorPos.iX > skipicon - 1)
+            {
+            iCursorPos.iX -= skipicon;
+            }
+        else
+            {
+            if (skipicon > iMaxColumns)
+                {
+                globalYPos--;
+                iCursorPos.iX = iMaxColumns;
+                }
+            // Go to previous line
+            globalYPos--;
+            if (globalYPos < 0)
+                {
+                // Cursor was on the first line - go to last line.
+                globalYPos = iRows - 1;
+                // x - position to the last item on the last row.
+                iCursorPos.iX = lastColumnOnLastRow;
+                }
+            else
+                {
+                // x - position to last column.
+                iCursorPos.iX = iMaxColumns - skipicon;
+                }
+            }
+        }
+
+    if (aDeltaX > 0)
+        {
+        // Cursor was moved to right.
+        if (globalYPos < iRows - 1)
+            {
+            // Not in the last row.
+            if (iCursorPos.iX < iMaxColumns - skipicon)
+                {
+                // If not on the last columns, move cursor to next column.
+                iCursorPos.iX += skipicon;
+                }
+            else
+                {
+                // Cursor was on last column,
+                // move to first column of the next line.
+                iCursorPos.iX = 0;
+                globalYPos++;
+                }
+            }
+        else
+            {
+            // Currently on the last row.
+            if (iCursorPos.iX < lastColumnOnLastRow)
+                {
+                // If there are more items on this row, move cursor to next item.
+                iCursorPos.iX++;
+                }
+            else
+                {
+                // No more item on the current row.
+                // Move to first item on the first row.
+                iCursorPos.iX = 0;
+                globalYPos = 0;
+                }
+            }
+        }
+
+    if (aDeltaY < 0)
+        {
+        iCursorPos.iX -= skipicon;
+        if (iCursorPos.iX < 0)
+            {
+            iCursorPos.iX += (iMaxColumns - 1);
+            globalYPos--;
+            }
+        // Cursor was moved to up.
+        if (globalYPos > 0)
+            {
+            // Cursor was not on the first line - move it to previous row.
+            globalYPos--;
+            }
+        else
+            {
+            // Move cursot to last to row.
+            globalYPos = iRows - 1;
+            if (iCursorPos.iX > lastColumnOnLastRow)
+                {
+                // No items in the current column on the last row -
+                // move cursor to last item on the row.
+                iCursorPos.iX = lastColumnOnLastRow;
+                }
+            }
+        }
+
+    if (aDeltaY > 0)
+        {
+        iCursorPos.iX = (iCursorPos.iX + skipicon) % iMaxColumns;
+        globalYPos += (iCursorPos.iX + skipicon) / iMaxColumns;
+        // Cursor was moved to down.
+        if (globalYPos < iRows - 1)
+            {
+            // Cursor is not on the last row. Move cursor to next row.
+            globalYPos++;
+            if (globalYPos == iRows - 1 && iCursorPos.iX
+                    > lastColumnOnLastRow)
+                {
+                // No items in the current column on the last row -
+                // move cursor to last item on the row.
+                iCursorPos.iX = lastColumnOnLastRow;
+                }
+            }
+        else
+            {
+            // Cursor was at the last row - move it to the first row.
+            globalYPos = 0;
+            }
+        }
+    iCursorPos.iY = globalYPos - iFirstVisibleRow;
+
+    if (globalYPos < iFirstVisibleRow)
+        {
+        // Cursor was moved from the top row.
+        if (globalYPos <= 0)
+            {
+            iFirstVisibleRow = 0;
+            iCursorPos = TPoint(iCursorPos.iX, 0);
+            }
+        else
+            {
+            // If cursor was moved up out of the visible area - show it again.
+            iFirstVisibleRow -= Extension()->iMaxVisibleRows;
+            iCursorPos = TPoint(iCursorPos.iX, Extension()->iMaxVisibleRows
+                    - 1);
+            }
+        }
+
+    if (globalYPos > iFirstVisibleRow + Extension()->iMaxVisibleRows - 1)
+        {
+        if (globalYPos == iRows - 1)
+            {
+            // When cursor has moved from the top line,
+            // it is adjusted to a page boundary.
+            iCursorPos = TPoint(iCursorPos.iX, (iRows - 1)
+                    % Extension()->iMaxVisibleRows);
+            iFirstVisibleRow = ((iRows - 1) / Extension()->iMaxVisibleRows)
+                    * Extension()->iMaxVisibleRows;
+            }
+        else
+            {
+            // If cursor was moved down out of the visible area - show it again.
+            iFirstVisibleRow += Extension()->iMaxVisibleRows;
+            iCursorPos = TPoint(iCursorPos.iX, 0);
+            }
+        }
+
+    //TInt increment(1);
+    //if (aDeltaY < 0 || aDeltaX < 0)
+    //    {
+    ////    increment = -1;
+    //    }
+    if ((iRows > Extension()->iMaxVisibleRows) && (iOldCursorPos.iY
+            + oldFirstVisibleRow != iCursorPos.iY + iFirstVisibleRow))
+        {
+        UpdateScrollIndicatorL();
+        }
+
+    if (oldFirstVisibleRow == iFirstVisibleRow)
+        {
+        // Draw only cursor if the view to the content was not scrolled.
+        DrawCursor();
+        }
+    else
+        {
+        DrawNow();
+        }
+
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::UpdateScrollIndicatorL()
+//
+// -----------------------------------------------------------------------------
+//
+void CLmkIconMap::UpdateScrollIndicatorL()
+    {
+    if (!iSBFrame)
+        {
+        return;
+        }
+    TEikScrollBarModel hSbarModel;
+    TEikScrollBarModel vSbarModel;
+
+    TEikScrollBarFrameLayout layout;
+
+    // Main pane without softkeys
+    TRect mainPaneRect;
+    if (!AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane,
+            mainPaneRect))
+        {
+        mainPaneRect = iAvkonAppUi->ClientRect();
+        }
+
+    // Dialog layout, check variety first
+    TAknLayoutScalableParameterLimits iconMapDialogVariety =
+            AknLayoutScalable_Avkon::popup_grid_graphic_window_ParamLimits();
+
+    TInt maxVariety = iconMapDialogVariety.LastVariety();
+
+    // Check the CBA, if the orientation is not landscape
+    // there is not so much varieties
+    AknLayoutUtils::TAknCbaLocation location = AknLayoutUtils::CbaLocation();
+    TInt maxVarietyOffset = 0; // the offset for the certain cba location variety
+    TInt varietyOffset = maxVariety + 1;
+
+    // landscape variety number must be calculated offset == number of varieties
+    // same applies to the variety number for the biggest sized layout for the variety
+    if (Layout_Meta_Data::IsLandscapeOrientation())
+        {
+        varietyOffset = (maxVariety + 1) / KAknSctCBaButtonDirections; // the offset for one variety
+        }
+
+    // for right and left cba buttons the max variety is not zero
+    // the varities are ordered by the location of the cba and the descending order
+    // e.g the biggest sized layout first, the smallest last
+    if (location == AknLayoutUtils::EAknCbaLocationRight)
+        {
+        maxVarietyOffset = varietyOffset;
+        }
+    else if (location == AknLayoutUtils::EAknCbaLocationLeft)
+        {
+        maxVarietyOffset = varietyOffset + varietyOffset; // 2*
+        }
+
+    TInt varietyNumber = varietyOffset - iRows - 1;
+
+    // if more lines than possible to show, use the default
+    // (the biggest grid) variety
+    if (varietyNumber < 0)
+        varietyNumber = 0;
+    // if zero rows, use the minimum
+    else if (iRows <= 0)
+        varietyNumber -= 1;
+
+    //add the varietyoffset
+    varietyNumber += maxVarietyOffset;
+
+    if (Layout_Meta_Data::IsLandscapeOrientation() && (location
+            == AknLayoutUtils::EAknCbaLocationRight))
+        {
+        varietyNumber = 10;
+        }
+    else
+        {
+        varietyNumber = 3;
+        }
+    // Layout the dialog size
+    TAknLayoutRect dialogLayRect;
+    dialogLayRect.LayoutRect(mainPaneRect,
+            AknLayoutScalable_Avkon::popup_grid_graphic_window(varietyNumber));
+
+    TRect dialogRect = dialogLayRect.Rect();
+
+    // Get the layout of the actual icon grid with scrollbar
+    TAknLayoutRect gridWithScrollLayRect;
+
+    gridWithScrollLayRect.LayoutRect(TRect(TPoint(0, 0), TSize(
+            dialogRect.Size())),
+            AknLayoutScalable_Avkon::listscroll_popup_graphic_pane());
+
+    // Calculate the relative rect for the grid
+    TRect parent = gridWithScrollLayRect.Rect();
+
+    TAknWindowComponentLayout scrollbarLayout =
+            AknLayoutScalable_Avkon::scroll_pane_cp5();
+
+    iCurrentPage = (iFirstVisibleRow / Extension()->iMaxVisibleRows) + 1;
+
+    vSbarModel.iScrollSpan = iNumPages * Extension()->iMaxVisibleRows;
+    vSbarModel.iThumbSpan = Extension()->iMaxVisibleRows;
+
+    if (iSBFrame && iSBFrame->TypeOfVScrollBar()
+            == CEikScrollBarFrame::EDoubleSpan)
+        {
+        // For EDoubleSpan type scrollbar
+        vSbarModel.iThumbPosition = (iCurrentPage - 1)
+                * Extension()->iMaxVisibleRows;
+        TAknDoubleSpanScrollBarModel hDsSbarModel(hSbarModel);
+        TAknDoubleSpanScrollBarModel vDsSbarModel(vSbarModel);
+
+        // The y coordinate must be sifted 3 pixels up and x 3 to left
+        parent.iTl.iY -= KVerticalDialogMargin;
+        parent.iBr.iY -= KVerticalDialogMargin;
+        parent.iTl.iX -= KHorizontalDialogMargin;
+        parent.iBr.iX -= KHorizontalDialogMargin;
+
+        layout.iTilingMode = TEikScrollBarFrameLayout::EInclusiveRectConstant;
+        iSBFrame->Tile(&vDsSbarModel);
+        AknLayoutUtils::LayoutVerticalScrollBar(iSBFrame, parent,
+                scrollbarLayout);
+        iSBFrame->SetVFocusPosToThumbPos(vDsSbarModel.FocusPosition());
+        }
+    else
+        {
+        // For EArrowHead type scrollbar
+        vSbarModel.iThumbPosition = iCursorPos.iY + iFirstVisibleRow;
+        iSBFrame->TileL(&hSbarModel, &vSbarModel, parent, parent, layout);
+        iSBFrame->SetVFocusPosToThumbPos(vSbarModel.iThumbPosition);
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::Reserved_1()
+//
+// -----------------------------------------------------------------------------
+//
+void CLmkIconMap::Reserved_1()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::Reserved_2()
+//
+// -----------------------------------------------------------------------------
+//
+void CLmkIconMap::Reserved_2()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::DrawOffscreenBackgroundIfRequired
+//
+// -----------------------------------------------------------------------------
+//
+void CLmkIconMap::DrawOffscreenBackgroundIfRequired() const
+    {
+    if (iOffscreenBg && iHasBitmapBackground)
+        {
+        if (!iOffscreenBgDrawn)
+            {
+            TRect mainPaneRect;
+            if (!AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane,
+                    mainPaneRect))
+                {
+                mainPaneRect = iAvkonAppUi->ClientRect();
+                }
+
+            // Dialog layout, check variety first
+            TAknLayoutScalableParameterLimits
+                    iconMapDialogVariety =
+                            AknLayoutScalable_Avkon::popup_grid_graphic_window_ParamLimits();
+
+            TInt maxVariety = iconMapDialogVariety.LastVariety();
+
+            // Check the CBA, if the orientation is not landscape
+            // there is not so much varieties
+            AknLayoutUtils::TAknCbaLocation location =
+                    AknLayoutUtils::CbaLocation();
+            TInt maxVarietyOffset = 0; // the offset for the certain cba location variety
+            TInt varietyOffset = maxVariety + 1;
+
+            // landscape variety number must be calculated offset == number of varieties
+            // same applies to the variety number for the biggest sized layout for the variety
+            if (Layout_Meta_Data::IsLandscapeOrientation())
+                {
+                varietyOffset = (maxVariety + 1) / KAknSctCBaButtonDirections; // the offset for one variety
+                }
+
+            // for right and left cba buttons the max variety is not zero
+            // the varities are ordered by the location of the cba and the descending order
+            // e.g the biggest sized layout first, the smallest last
+            if (location == AknLayoutUtils::EAknCbaLocationRight)
+                {
+                maxVarietyOffset = varietyOffset;
+                }
+            else if (location == AknLayoutUtils::EAknCbaLocationLeft)
+                {
+                maxVarietyOffset = varietyOffset + varietyOffset; // 2*
+                }
+            TInt varietyNumber = varietyOffset - iRows - 1;
+
+            // if more lines than possible to show, use the default
+            // (the biggest grid) variety
+            if (varietyNumber < 0)
+                varietyNumber = 0;
+            // if zero rows, use the minimum
+            else if (iRows <= 0)
+                varietyNumber -= 1;
+
+            //add the varietyoffset
+            varietyNumber += maxVarietyOffset;
+
+            TAknLayoutRect popupGridLayRect;
+            popupGridLayRect.LayoutRect(mainPaneRect,
+                    AknLayoutScalable_Avkon::popup_grid_graphic_window(5));
+
+            TRect popupGridRect = popupGridLayRect.Rect();
+
+            // set the top left height as the control starting point
+            popupGridRect.iTl.iY = Rect().iTl.iY;
+
+            //if(popupGridRect.iBr.iY < mainPaneRect.iBr.iY)
+            //	popupGridRect.iBr.iY = mainPaneRect.iBr.iY
+            MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+            MAknsControlContext* cc = AknsDrawUtils::ControlContext(this);
+
+            // draw to upper left corner, and normalize the retangle to
+            // fact that the dialog starts from coordinates (0,0),
+            // so the y-coordinate is correct (heading pane)
+            // but x must be set to zero
+            TPoint point = TPoint(0, 0);
+            popupGridRect.Move(-popupGridRect.iTl.iX, 0);
+
+            AknsDrawUtils::DrawBackground(skin, cc, this, *iBitmapGc, point,
+                    popupGridRect, KAknsDrawParamDefault);
+
+            iOffscreenBgDrawn = ETrue;
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::ComponentControl(TInt aIndex) const
+// Return the controll pointer
+// -----------------------------------------------------------------------------
+//
+CCoeControl* CLmkIconMap::ComponentControl(TInt aIndex) const
+    {
+    if (aIndex == 0 && iSBFrame && iSBFrame->TypeOfVScrollBar()
+            == CEikScrollBarFrame::EDoubleSpan)
+        {
+        return iSBFrame->VerticalScrollBar();
+        }
+    else
+        {
+        return NULL;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::CountComponentControls()
+// Return no of controll to be placed on the container control
+// -----------------------------------------------------------------------------
+//
+TInt CLmkIconMap::CountComponentControls() const
+    {
+    if (iSBFrame && iSBFrame->TypeOfVScrollBar()
+            == CEikScrollBarFrame::EDoubleSpan)
+        {
+        return 1;
+        }
+    else
+        {
+        return 0;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::CountMaxColumnsAndCellSizes
+// Counts no of columns and the cell size will be displayed in the icon table
+// -----------------------------------------------------------------------------
+//
+void CLmkIconMap::CountMaxColumnsAndCellSizes()
+    {
+
+    TRect cellRect; // retangle of one item in grid
+    TRect gridRect; // retangle of the grid contaning the items
+
+    // 1. Get the layout
+
+    // Get the parent rect
+    TRect mainPaneRect;
+    if (!AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane,
+            mainPaneRect))
+        {
+        mainPaneRect = iAvkonAppUi->ClientRect();
+        }
+
+    // Calculate the layout of the whole popup with the biggest possible -> 0
+    // Dialog layout, check variety first
+
+    // Get the layout rect of the dialog
+
+    // Check variety first
+    TAknLayoutScalableParameterLimits iconMapDialogVariety =
+            AknLayoutScalable_Avkon::popup_grid_graphic_window_ParamLimits();
+
+    TInt maxVariety = iconMapDialogVariety.LastVariety();
+
+    // Check the CBA, if the orientation is not landscape
+    // there is not so much varieties
+    AknLayoutUtils::TAknCbaLocation location = AknLayoutUtils::CbaLocation();
+    TInt maxVarietyOffset = 0; // the offset for the certain cba location variety
+    TInt varietyOffset = maxVariety + 1; // the number of varieties
+
+    // landscape variety number must be calculated offset == number of varieties
+    // same applies to the variety number for the biggest sized layout for the variety
+    if (Layout_Meta_Data::IsLandscapeOrientation())
+        {
+        varietyOffset = (maxVariety + 1) / KAknSctCBaButtonDirections; // the offset for one variety
+        }
+
+    if (location == AknLayoutUtils::EAknCbaLocationRight)
+        {
+        maxVarietyOffset = varietyOffset;
+        }
+    else if (location == AknLayoutUtils::EAknCbaLocationLeft)
+        {
+        maxVarietyOffset = varietyOffset + varietyOffset; // 2*
+        }
+
+    TAknLayoutRect popupGridLayRect;
+    popupGridLayRect.LayoutRect(mainPaneRect,
+            AknLayoutScalable_Avkon::popup_grid_graphic_window(
+                    maxVarietyOffset));
+
+    // Get the layout of the actual icon grid with scrollbar
+    TAknLayoutRect gridWithScrollLayRect;
+    gridWithScrollLayRect.LayoutRect(popupGridLayRect.Rect(),
+            AknLayoutScalable_Avkon::listscroll_popup_graphic_pane());
+
+    // Then the grid area without scrollbar
+    // NOTE: The grid with scroll bar is used as reference
+    TAknLayoutRect gridLayRect;
+    gridLayRect.LayoutRect(gridWithScrollLayRect.Rect(),
+            AknLayoutScalable_Avkon::grid_graphic_popup_pane(0));
+
+    // Different parent if SCT inside editing menu.
+    TRect rect = Rect();
+    gridRect = gridLayRect.Rect();
+    // cell size, AGAIN 7 item
+    TAknLayoutRect cellLayRect;
+    cellLayRect.LayoutRect(gridRect,
+            AknLayoutScalable_Avkon::cell_graphic_popup_pane(0, 0, 0));
+
+    cellRect = cellLayRect.Rect();
+
+    // 2. Calculate width related
+    // - item width
+    // - max number of columns
+
+    // Width of the items area
+    TInt gridWidth = gridRect.Width();
+
+    // Width of one item
+    TInt cellWidth = cellRect.Width();
+
+    // ensure the item width and store it
+    TAknLayoutRect secondCellLayRect;
+    secondCellLayRect.LayoutRect(gridRect,
+            AknLayoutScalable_Avkon::cell_graphic_popup_pane(0, 1, 0));
+
+    iGridItemWidth = secondCellLayRect.Rect().iTl.iX
+            - cellLayRect.Rect().iTl.iX;
+
+    if (iGridItemWidth < 0)
+        {
+        // The result is negative with lay file data if the layout is mirrored.
+        iGridItemWidth = -iGridItemWidth;
+        }
+
+    // Calculate the amount of columns
+    iMaxColumns = gridWidth / cellWidth;
+
+    // 2. Calculate height related
+    // - item height
+    // - max number of rows
+
+    // Get the grid height
+    // NOTE: in landscape the LAF is wrong so use the main panes height
+    TInt gridHeight = gridRect.Height();
+
+    // get the item height
+    TInt cellHeight = cellRect.Height();
+
+    // calculate the number of items fitting to grid
+    Extension()->iMaxVisibleRows = 3;//gridHeight / cellHeight;
+
+
+    // Store the item height
+    TAknLayoutRect secondRowLayRect;
+    secondRowLayRect.LayoutRect(gridLayRect.Rect(),
+            AknLayoutScalable_Avkon::cell_graphic_popup_pane(0, 0, 1));
+
+    iGridItemHeight = secondRowLayRect.Rect().iTl.iY
+            - cellLayRect.Rect().iTl.iY;
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::HandleScrollEventL
+// Handles the different scroll events so that the map reacts accordingly.
+// -----------------------------------------------------------------------------
+//
+void CLmkIconMap::HandleScrollEventL(CEikScrollBar* aScrollBar,
+        TEikScrollEvent aEventType)
+    {
+    TBool update = EFalse;
+
+    switch (aEventType)
+        {
+        case EEikScrollUp:
+        case EEikScrollPageUp:
+            {
+            // nothing done if we are already on the first page.
+            if (iFirstVisibleRow != 0)
+                {
+                iFirstVisibleRow -= Extension()->iMaxVisibleRows;
+                update = ETrue;
+                }
+            UpdateScrollIndicatorL();
+            }
+            break;
+        case EEikScrollDown:
+        case EEikScrollPageDown:
+            {
+            // nothing done if we are already on the last page.
+            if (iFirstVisibleRow != (iRows / Extension()->iMaxVisibleRows)
+                    * Extension()->iMaxVisibleRows)
+                {
+                iFirstVisibleRow += Extension()->iMaxVisibleRows;
+                update = ETrue;
+                }
+            UpdateScrollIndicatorL();
+            }
+            break;
+        case EEikScrollThumbDragVert:
+            {
+            TInt thumbPosition;
+            TInt halfPage = Extension()->iMaxVisibleRows / 2;
+            // Ask which type of scrollbar is shown
+            //CAknAppUi* appUi = iAvkonAppUi;
+            TBool isDoubleSpan = CEikScrollBarFrame::EDoubleSpan
+                    == iSBFrame->TypeOfVScrollBar();
+            if (isDoubleSpan)
+                {
+                thumbPosition
+                        = static_cast<const TAknDoubleSpanScrollBarModel*> (aScrollBar->Model())->FocusPosition();
+                }
+            else
+                {
+                thumbPosition = aScrollBar->Model()->iThumbPosition;
+                }
+
+            // If the slider is in the range of less then a half page from a possible correct thumb position.
+            // thus 0 <= iFirstVisibleRow - thumbPosition < halfPage. Or in the other direction:
+            // 0 <= thumbPosition - iFirstVisibleRow < halfPage
+            if (!((0 <= iFirstVisibleRow - thumbPosition && iFirstVisibleRow
+                    - thumbPosition < halfPage) || (0 <= thumbPosition
+                    - iFirstVisibleRow && thumbPosition - iFirstVisibleRow
+                    < halfPage)))
+                {
+                TReal toRound = thumbPosition
+                        / (TReal) Extension()->iMaxVisibleRows;
+                if (toRound * 2 > (TInt) toRound * 2 + 1)
+                    {
+                    toRound++;
+                    }
+                iFirstVisibleRow = (TInt) toRound
+                        * Extension()->iMaxVisibleRows;
+                iCurrentPage = (iFirstVisibleRow
+                        / Extension()->iMaxVisibleRows) + 1;
+                update = ETrue;
+                }
+            }
+            break;
+        case EEikScrollThumbReleaseVert:
+            {
+            UpdateScrollIndicatorL();
+            }
+            break;
+        case EEikScrollLeft: // flow through
+        case EEikScrollRight: // flow through
+        case EEikScrollPageLeft: // flow through
+        case EEikScrollPageRight: // flow through
+        case EEikScrollThumbDragHoriz: // flow through
+        case EEikScrollThumbReleaseHoriz: // flow through
+            // do nothing
+            break;
+        default:
+            // do nothing
+            break;
+        }
+
+    // If we have moved down to the last page we check that the cursor is in a place where it can be
+    // drawn.
+    if (iFirstVisibleRow == (iRows / Extension()->iMaxVisibleRows)
+            * Extension()->iMaxVisibleRows)
+        {
+        // the old cursor is set to a "safe" position where it at least can be.
+        iOldCursorPos.iX = 0;
+        iOldCursorPos.iY = 0;
+        // if the last page has only one line which isn't filled complitely.
+        if (iConsArray->Count() % iMaxColumns - 1 < iCursorPos.iX && iRows
+                % Extension()->iMaxVisibleRows == 1)
+            {
+            TInt xVal = iConsArray->Count() % iMaxColumns - 1;
+            if (xVal >= 0)
+                iCursorPos.iX = xVal;
+            }
+        // If the cursor is in a position where it would go unto a spot with out
+        // a icon when scrolled.
+        if (iCursorPos.iY + iFirstVisibleRow >= iRows)
+            {
+            if (iConsArray->Count() % iMaxColumns > iCursorPos.iX)
+                {
+                TInt yVal = iRows - 1 - iFirstVisibleRow;
+                if (yVal >= 0)
+                    iCursorPos.iY = yVal;
+                }
+            else
+                {
+                TInt yVal = iRows - 2 - iFirstVisibleRow;
+                if (yVal >= 0)
+                    iCursorPos.iY = yVal;
+                }
+            }
+        // If the cursor is actually on the last row, but is still in the
+        // area where there is now icons. (the rest of the last row)
+        if (iConsArray->Count() <= (iFirstVisibleRow + iCursorPos.iY)
+                * iMaxColumns + iCursorPos.iX && iCursorPos.iY
+                + iFirstVisibleRow + 1 == iRows)
+            {
+            iCursorPos.iY--;
+            }
+        // if the corrections did not help and the cursor is in the area
+        // where there is a valid row, but no icons anymore
+        }
+
+    // to avoid flicker we draw only if there really was something new to draw.
+    if (update)
+        {
+        if (Extension()->iObserver)
+            {
+            Extension()->iObserver->HandleControlEventL(this,
+                    MCoeControlObserver::EEventRequestFocus);
+            }
+        DrawDeferred();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::Extension
+// Asserts that extension object has been created.
+// -----------------------------------------------------------------------------
+//
+CLmkIconMapExtension* CLmkIconMap::Extension() const
+    {
+    __ASSERT_ALWAYS(iExtension, Panic(KLmkPanicNullPointer));
+    return iExtension;
+    }
+
+#ifdef RD_SCALABLE_UI_V2
+//--------------------------------------------------------------------------
+// void CLmkIconMap::HandlePointerEventL()
+//--------------------------------------------------------------------------
+void CLmkIconMap::HandlePointerEventL(const TPointerEvent& aPointerEvent)
+    {
+    if (AknLayoutUtils::PenEnabled())
+        {
+        TInt newGridX; // For the whole
+        TInt newGridY; // For the whole grid.
+        TInt yInPixels = aPointerEvent.iPosition.iY - iGridTopLeft.iY;
+        newGridY = yInPixels / iGridItemHeight;
+        if ((aPointerEvent.iPosition.iX - iGridTopLeft.iX) < 0)
+            {
+            newGridX = -1;
+            }
+        else
+            {
+            newGridX = (aPointerEvent.iPosition.iX - iGridTopLeft.iX)
+                    / iGridItemWidth;
+            }
+        TInt previousRows = (iRows / iExtension->iMaxVisibleRows)
+                * iExtension->iMaxVisibleRows;
+        TUint lastRowsLength = iConsArray->Count() % iMaxColumns;
+
+        // The pointer has been set down or dragged into the area of the grid. (it might be in
+        // the "white space" at the end of the grid)
+        if ((yInPixels >= 0 && yInPixels < iGridItemHeight
+                * iExtension->iMaxVisibleRows) &&
+        // When the pointer is in rows except the recent icon row
+                ((((newGridY + iFirstVisibleRow) != 0) && newGridX
+                        < iMaxColumns && newGridX >= 0) ||
+                // When the pointer is in the recent icon row
+                        ((newGridY + iFirstVisibleRow == 0) && (newGridX
+                                < iMaxColumns))))
+            {
+            // For any action to be taken, the pointer event must either be a Button1Down or a drag event
+            // which has originated from a Button1Down in to the grid.
+            if (aPointerEvent.iType == TPointerEvent::EButton1Down)
+                {
+                TUint globalY = newGridY + iFirstVisibleRow;
+                // The user tapps a cell which has no icon. it is ignored.
+                if (iConsArray->Count() > globalY * iMaxColumns + newGridX)
+                    {
+                    //If icon is already selected then on single tap it should change the icon.
+                    if (iCursorPos.iY == newGridY && iCursorPos.iX
+                            == newGridX)
+                        {
+#ifdef RD_TACTILE_FEEDBACK
+                        // The user tapps a cell which has icon, selection has been accepted
+                        MTouchFeedback* feedback = MTouchFeedback::Instance();
+                        if (feedback)
+                            {
+                            feedback->InstantFeedback(this,
+                                    ETouchFeedbackBasic);
+                            }
+#endif //RD_TACTILE_FEEDBACK
+                        //iIsChangeIcon = ETrue;
+                        }
+                    else if (iCursorPos.iX + (iCursorPos.iY
+                                    + iFirstVisibleRow) * iMaxColumns
+                            < iConsArray->Count())
+                        {
+#ifdef RD_TACTILE_FEEDBACK
+                        // The user tapps a cell which has icon, send feedback if position has changed
+                        MTouchFeedback* feedback = MTouchFeedback::Instance();
+                        const TBool feedbackNeeded = (iCursorPos.iY
+                                != newGridY) || (iCursorPos.iX != newGridX);
+                        if (feedback && feedbackNeeded)
+                            {
+                            feedback->InstantFeedback(this,
+                                    ETouchFeedbackBasic);
+                            }
+#endif //RD_TACTILE_FEEDBACK
+                        iOldCursorPos = iCursorPos;
+                        iCursorPos.iY = newGridY;
+                        iCursorPos.iX = newGridX;
+                        DrawCursor();
+                        }
+                    else
+                        {
+                        iOldCursorPos = iCursorPos;
+                        iCursorPos.iY = newGridY;
+                        iCursorPos.iX = newGridX;
+                        DrawCursor();
+                        }
+                    }
+                }
+            else if (aPointerEvent.iType == TPointerEvent::EDrag)
+                {
+                //Handle drag event only if the icon is not already selected, if already selected then do nothing for EDrag event
+                if (iCursorPos.iY != newGridY || iCursorPos.iX != newGridX)
+                    {
+                    //iIsChangeIcon = EFalse;
+                    TUint globalY = newGridY + iFirstVisibleRow;
+                    // The user tapps a cell which has no icon. it is ignored.
+                    if (iConsArray->Count() > globalY * iMaxColumns
+                            + newGridX)
+                        {
+                        if (iCursorPos.iX
+                                + (iCursorPos.iY + iFirstVisibleRow)
+                                * iMaxColumns < iConsArray->Count())
+                            {
+#ifdef RD_TACTILE_FEEDBACK
+                            // While dragging cell is changed, give sensitive feedback
+                            MTouchFeedback* feedback =
+                            MTouchFeedback::Instance();
+                            const TBool feedbackNeeded = (iCursorPos.iY
+                                    != newGridY) || (iCursorPos.iX
+                                    != newGridX);
+                            if (feedback && feedbackNeeded)
+                                {
+                                feedback->InstantFeedback(this,
+                                        ETouchFeedbackSensitive);
+                                }
+#endif //RD_TACTILE_FEEDBACK
+                            iOldCursorPos = iCursorPos;
+                            iCursorPos.iY = newGridY;
+                            iCursorPos.iX = newGridX;
+                            DrawCursor();
+                            }
+                        else
+                            {
+                            iOldCursorPos.iX = 0;
+                            iOldCursorPos.iY = 0;
+                            }
+                        }
+                    }
+
+                }
+            else if (aPointerEvent.iType == TPointerEvent::EButton1Up)
+                {
+                //if (iIsChangeIcon)
+
+                    {
+                    iExtension->iObserver->HandleControlEventL(this,
+                            MCoeControlObserver::EEventStateChanged);
+                    //iIsChangeIcon = EFalse;
+                    }
+                }
+            }
+        // Events: Drag and repeat pointer events which are not on the scrollbar are handled here.
+
+        else if (iConsArray->Count() > iMaxColumns
+                * iExtension->iMaxVisibleRows && newGridX < iMaxColumns
+                && newGridX >= 0 && newGridY < iExtension->iMaxVisibleRows
+                && newGridY >= 0)
+            {
+            TRect ignoreUpRect(TPoint(KMinTInt, KMinTInt), TPoint(KMaxTInt,
+                            iGridTopLeft.iY));
+            TRect ignoreDownRect(TPoint(KMinTInt, (iGridTopLeft.iY
+                                    + iGridItemHeight * iExtension->iMaxVisibleRows)),
+                    TPoint(KMaxTInt, KMaxTInt));
+            // Drag events
+            if (aPointerEvent.iType == TPointerEvent::EDrag
+                    || aPointerEvent.iType == TPointerEvent::EButtonRepeat)
+                {
+                // The pointer is dragged upwards from map
+                if (aPointerEvent.iPosition.iY < iGridTopLeft.iY
+                        && aPointerEvent.iPosition.iX < iGridTopLeft.iX) //scroll up
+                    {
+                    // focus on first page
+                    if (iFirstVisibleRow == 0)
+                        {
+                        iFirstVisibleRow = previousRows;
+                        // if the last page contains only one partial row.
+                        if (lastRowsLength - 1 < iCursorPos.iX && iRows
+                                % iExtension->iMaxVisibleRows == 1)
+                            {
+                            iCursorPos.iX = lastRowsLength - 1;
+                            }
+                        }
+                    // focus on some other page than first
+                    else
+                        {
+                        iFirstVisibleRow -= iExtension->iMaxVisibleRows;
+                        }
+                    // For odd reason the user has been able to induce upward dragging with out moving
+                    // up through the grid.
+                    if (iCursorPos.iY + iExtension->iMaxVisibleRows
+                            != iFirstVisibleRow)
+                        {
+                        iCursorPos.iY = 0;
+                        }
+                    UpdateScrollIndicatorL();
+                    if (iExtension->iObserver)
+                        {
+                        iExtension->iObserver->HandleControlEventL(this,
+                                MCoeControlObserver::EEventRequestFocus);
+                        }
+                    DrawDeferred();
+                    }
+                // the pointer is dragged downwards from the map.
+                else if (yInPixels >= iGridItemHeight
+                        * iExtension->iMaxVisibleRows) //scroll down
+                    {
+                    // The focus is on the last page
+                    if (iFirstVisibleRow == previousRows)
+                        {
+                        iFirstVisibleRow = 0;
+                        iCursorPos.iY = iExtension->iMaxVisibleRows - 1;
+                        }
+                    // The focus is on some other page than the last one.
+                    else
+                        {
+                        iFirstVisibleRow += iExtension->iMaxVisibleRows;
+                        // if the next page is the last page
+                        if (iFirstVisibleRow == previousRows)
+                            {
+                            // the old cursor is set to a "safe" position where it at least can be.
+                            iOldCursorPos.iX = 0;
+                            iOldCursorPos.iY = 0;
+
+                            // if the last page has only one line which isn't filled complitely.
+                            if (lastRowsLength - 1 < iCursorPos.iX && iRows
+                                    % iExtension->iMaxVisibleRows == 1)
+                                {
+                                iCursorPos.iX = lastRowsLength - 1;
+                                }
+                            // If the cursor is in a position where it would go unto a spot with out
+                            // a icon when scrolled.
+                            if (lastRowsLength > iCursorPos.iX)
+                                {
+                                //
+                                iCursorPos.iY = iRows - 1 - iFirstVisibleRow;
+                                }
+                            else
+                                {
+                                //
+                                iCursorPos.iY = iRows - 2 - iFirstVisibleRow;
+                                }
+                            }
+                        }
+                    UpdateScrollIndicatorL();
+                    if (iExtension->iObserver)
+                        {
+                        iExtension->iObserver->HandleControlEventL(this,
+                                MCoeControlObserver::EEventRequestFocus);
+                        }
+                    DrawDeferred();
+                    }
+                }
+            }
+
+        else // For a non window owning scrollbar.
+            {
+            CCoeControl::HandlePointerEventL(aPointerEvent);
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CLmkIconMap::SetObserver
+// Sets the observer.
+// -----------------------------------------------------------------------------
+//
+void CLmkIconMap::SetObserver( MCoeControlObserver* aObserver )
+    {
+    if (iExtension)
+        {
+        iExtension->iObserver = aObserver;
+        }
+    }
+
+#endif //RD_SCALABLE_UI_V2
+//  End of File