menufw/menufwui/mmwidgets/src/mmgrid.cpp
branchRCL_3
changeset 83 5456b4e8b3a8
child 88 3321d3e205b6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/menufw/menufwui/mmwidgets/src/mmgrid.cpp	Wed Sep 01 12:32:46 2010 +0100
@@ -0,0 +1,1045 @@
+/*
+* Copyright (c) 2007 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:
+*  Version     : %version: MM_106 % << Don't touch! Updated by Synergy at check-out.
+*
+*/
+
+
+#include <AknsDrawUtils.h>
+#include <layoutmetadata.cdl.h>
+#include "mmgrid.h"
+#include "mmgridmodel.h"
+#include "mmlistboxitemdrawer.h"
+#include "mmgridview.h"
+#include "mmtemplatelibrary.h"
+#include "mmlistboxmodel.h"
+#include "mmmarqueeadapter.h"
+#include "mmwidgetsconstants.h"
+#include "mmwidgetcontainer.h"
+#include "hnsuitemodel.h"
+#include "mmdraweranimator.h"
+
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+#include <aknlistloadertfx.h>
+#include <aknlistboxtfxinternal.h>
+#endif
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+CMmGrid::CMmGrid()
+    {
+    // No implementation required
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+CMmGrid::~CMmGrid()
+    {
+    delete iRedrawTimer;
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+CMmGrid* CMmGrid::NewLC( const CCoeControl* aParent, TInt aFlags,
+        CMmTemplateLibrary* aTemplateLibrary)
+    {
+    CMmGrid* self = new (ELeave)CMmGrid();
+    CleanupStack::PushL(self);
+    self->ConstructL( aParent, aFlags, aTemplateLibrary );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+CMmGrid* CMmGrid::NewL( const CCoeControl* aParent, TInt aFlags,
+        CMmTemplateLibrary* aTemplateLibrary )
+    {
+    CMmGrid* self = CMmGrid::NewLC( aParent, aFlags, aTemplateLibrary );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// If a parent to the supplied control has its Gc set, this function will find
+// it and return it. (Copied from EIKLBX.CPP, needed by CMmGrid::Draw)
+// -----------------------------------------------------------------------------
+//
+LOCAL_C CWindowGc* ReplaceGcWithCustomGc( const CEikListBox* aListBox )
+    {
+    const CCoeControl* parent = aListBox;
+    CWindowGc* customGc;
+    while(parent)
+        {
+        customGc = parent->GetGc();
+        if ( customGc )
+            {
+            CListItemDrawer* itemDrawer = aListBox->View()->ItemDrawer();
+            CWindowGc* originalGc = itemDrawer->Gc();
+            if ( customGc == originalGc )
+                {
+                return NULL;
+                }
+            else
+                {
+                itemDrawer->SetGc( customGc );
+                return originalGc;
+                }
+            }
+        parent = parent->Parent();
+        }
+    return NULL;
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::Draw(const TRect& aRect) const
+    {
+    if ( View()->RedrawDisabled () || !IsVisible () )
+        {
+        return;
+        }
+    iMmDrawer->SetNumberOfColsInView(
+            static_cast<CMmGridView*>(iView)->NumberOfColsInView() );
+
+    // If a parent has a custom gc, draw listbox using that gc
+    CWindowGc* replacedGc = ReplaceGcWithCustomGc( this );
+
+    CWindowGc* gc = iItemDrawer->Gc();
+    TGulBorder::TColors borderColors;
+    iBorder.Draw(*gc, Rect(), borderColors);
+
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+    MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal(
+            static_cast<CMmGridView*>(iView)->Gc() );
+    TBool effects = transApi && !transApi->EffectsDisabled();
+    if ( effects )
+        {
+        // ViewRect might have been moved to the right to prevent grid items
+        // from overlapping the scrollbar in mirrored layout.
+        // However, we still have to draw scrollbar background, thus the
+        // rectangle object passed to MAknListBoxTfxInternal::BeginRedraw must
+        // be placed at (0, 0) so that it covers the area where scrollbar is
+        // drawn.
+        TRect r( View()->ViewRect().Size() );
+        transApi->BeginRedraw( MAknListBoxTfxInternal::EListView, r );
+        transApi->StartDrawing( MAknListBoxTfxInternal::EListView );
+        }
+#endif // RD_UI_TRANSITION_EFFECTS_LIST
+
+    ClearMargins();
+    RedrawScrollbarBackground();
+
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+    if ( effects )
+        {
+        transApi->StopDrawing();
+        }
+#endif // RD_UI_TRANSITION_EFFECTS_LIST
+    iView->Draw(&aRect);
+
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+    if ( effects )
+        {
+        transApi->EndViewRedraw( aRect );
+        }
+#endif // RD_UI_TRANSITION_EFFECTS_LIST
+
+    if ( replacedGc )
+        {
+        // Stop using the custom gc
+        iItemDrawer->SetGc( replacedGc );
+        }
+    }
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::DrawView()
+    {
+    iDisableChildComponentDrawing = ETrue;
+    DrawNow(Rect());
+    iDisableChildComponentDrawing = EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::CreateItemDrawerL()
+    {
+    iItemDrawer = iMmDrawer;
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::CreateItemDrawerL( CMmTemplateLibrary* aTemplateLibrary )
+    {
+    CFormattedCellListBoxData* data=CFormattedCellGridData::NewL();
+    CleanupStack::PushL(data);
+
+    iMmDrawer = CMmListBoxItemDrawer::NewL(
+        MmModel()->MmListBoxModel(), iEikonEnv->NormalFont(), data, EGrid,
+        aTemplateLibrary );
+    iItemDrawer = iMmDrawer;
+    data->SetControl( this );
+    CleanupStack::Pop( data );
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::HandleScrollEventL( CEikScrollBar* aScrollBar,
+        TEikScrollEvent aEventType )
+    {
+    if ( aEventType == EEikScrollThumbDragVert && !iScrollbarThumbIsBeingDragged )
+        {
+        iScrollbarThumbIsBeingDragged = ETrue;
+        static_cast<CMmListBoxItemDrawer*>(
+                View()->ItemDrawer() )->EnableCachedDataUse( ETrue );
+        iRedrawTimer->Start( KScrollingRedrawInterval, KScrollingRedrawInterval,
+                TCallBack( &CMmGrid::RedrawTimerCallback, static_cast<TAny*>( this ) ) );
+        }
+    else if ( aEventType == EEikScrollThumbReleaseVert )
+        {
+        iScrollbarThumbIsBeingDragged = EFalse;
+        static_cast<CMmListBoxItemDrawer*>(
+                View()->ItemDrawer() )->EnableCachedDataUse( EFalse );
+        // The view will be redrawn with cache disabled when ProcessScrollEventL
+        // calls the base class's HandleScrollEventL method -- no need to
+        // explicitly redraw the view.
+        iRedrawTimer->Cancel();
+        }
+
+    if ( !iScrollbarThumbIsBeingDragged )
+        {
+        ProcessScrollEventL( aScrollBar, aEventType );
+        }
+    else
+        {
+        __ASSERT_DEBUG( aEventType == EEikScrollThumbDragVert, User::Invariant() );
+        ++iSkippedScrollbarEventsCount;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// Clearing ELeftDownInViewRect flag before invoking the base class
+// HandlePointerEventL method effectively prevents that method from doing most
+// of the things it would normally do in response to EButton1Down event.
+// This flag is explicitly cleared to achieve two things:
+// 1. Prevent kinetic scrolling (flick) in edit mode.
+// 2. Prevent highlight removal when popup menu is displayed.
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::HandlePointerEventInEditModeL( const TPointerEvent& aPointerEvent )
+    {
+    CMmWidgetContainer* parent = static_cast<CMmWidgetContainer*>( Parent() );
+    if ( aPointerEvent.iType == TPointerEvent::EButton1Down )
+        {
+        iButton1DownPos = aPointerEvent.iPosition;
+        }
+    else if ( aPointerEvent.iType == TPointerEvent::EButton1Up )
+        {
+        TPoint dragDelta = iButton1DownPos - aPointerEvent.iPosition;
+        if ( Abs( dragDelta.iY ) > KDragTreshold || parent->LongTapInProgress() )
+            {
+            iListBoxFlags &= ~ELeftDownInViewRect;
+            }
+        }
+
+    TInt itemUnderPointerIndex = KErrNotFound;
+    if ( aPointerEvent.iType == TPointerEvent::EButton1Up ||
+            aPointerEvent.iType == TPointerEvent::EButton1Down )
+        {
+        TBool highlightWasVisible = parent->IsHighlightVisible();
+        CAknGrid::HandlePointerEventL( aPointerEvent );
+        // Tricky: Do not allow the base class implementation of HandlePointerEventL
+        //         to remove the highlight on EButton1Up event when context menu
+        //         is displayed for an item
+        if ( aPointerEvent.iType == TPointerEvent::EButton1Up &&
+                highlightWasVisible && parent->LongTapInProgress()
+                && !parent->IsHighlightVisible() )
+            {
+            ItemDrawer()->ClearFlags( CListItemDrawer::ESingleClickDisabledHighlight );
+            }
+        }
+    else if ( View()->XYPosToItemIndex(
+            aPointerEvent.iPosition, itemUnderPointerIndex ) )
+        {
+        if ( CurrentItemIndex() != itemUnderPointerIndex )
+            {
+            CMmWidgetContainer* parent = static_cast<CMmWidgetContainer*>( Parent() );
+            if ( parent->IsNoItemDragged() )
+                {
+                if ( ItemDrawer()->Flags() & CListItemDrawer::EPressedDownState )
+                    {
+                    ItemDrawer()->ClearFlags( CListItemDrawer::EPressedDownState );
+                    iView->DrawItem( CurrentItemIndex() );
+                    }
+                }
+            else
+                {
+                iView->SetCurrentItemIndex( itemUnderPointerIndex );
+                iView->DrawItem(itemUnderPointerIndex);
+                }
+            }
+        }
+
+    HandleScrollingInEditMode( aPointerEvent );
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::HandlePointerEventInNormalModeL( const TPointerEvent& aPointerEvent )
+    {
+    CAknGrid::HandlePointerEventL(aPointerEvent);
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::HandleScrollingInEditMode( const TPointerEvent& aPointerEvent )
+    {
+    if ( aPointerEvent.iType == TPointerEvent::EDrag
+            || aPointerEvent.iType == TPointerEvent::EButtonRepeat )
+        {
+        TInt nextScrollDelay = ScrollIfNeeded( aPointerEvent );
+        if ( nextScrollDelay )
+            {
+            TRect ignoreDragRect(
+                TPoint(aPointerEvent.iParentPosition.iX - MmEffects::KDragIgnoreRectValue,
+                    aPointerEvent.iParentPosition.iY - MmEffects::KDragIgnoreRectValue),
+                TPoint(aPointerEvent.iParentPosition.iX + MmEffects::KDragIgnoreRectValue,
+                    aPointerEvent.iParentPosition.iY + MmEffects::KDragIgnoreRectValue));
+
+            Window().CancelPointerRepeatEventRequest();
+            Window().RequestPointerRepeatEvent( nextScrollDelay, ignoreDragRect );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TBool CMmGrid::IsPointerInTopScrollingThreshold(
+            const TPointerEvent& aPointerEvent ) const
+    {
+    TInt topScrollingTreshold = Rect().iTl.iY
+        + ( MmGrid::KFocusScrollingThreshold
+            * TReal( View()->ItemSize().iHeight ) );
+
+    return ( aPointerEvent.iPosition.iY < topScrollingTreshold );
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TBool CMmGrid::IsPointerInBottomScrollingThreshold(
+            const TPointerEvent& aPointerEvent ) const
+    {
+    TInt bottomScrollingTreshold = Rect().iBr.iY
+        - ( MmGrid::KFocusScrollingThreshold
+            * TReal( View()->ItemSize().iHeight ) );
+
+    return ( aPointerEvent.iPosition.iY > bottomScrollingTreshold );
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::ScrollWithoutRedraw( TInt distanceInPixels )
+    {
+    CAknGridView* view = static_cast<CAknGridView*>( iView );
+    const TInt rowHeight = ItemHeight();
+    const TInt numOfCols = view->NumberOfColsInView();
+    const TInt itemCount = iModel->NumberOfItems();
+    TInt totalNumberOfRows = itemCount / numOfCols;
+    if ( itemCount % numOfCols )
+        {
+        ++totalNumberOfRows;
+        }
+    const TInt topItemRowIndex = TopItemIndex() / numOfCols;
+
+    // desired view position relative to the first item in grid (always positive)
+    TInt desiredViewPosition = rowHeight * topItemRowIndex - VerticalItemOffset();
+
+    desiredViewPosition += distanceInPixels;
+
+    const TInt viewPositionMin = 0;
+    const TInt viewPositionMax =
+    Max( 0, ( totalNumberOfRows * rowHeight ) - view->ViewRect().Height() );
+
+    desiredViewPosition = Min( desiredViewPosition, viewPositionMax );
+    desiredViewPosition = Max( desiredViewPosition, viewPositionMin );
+
+    ASSERT( desiredViewPosition >= 0 );
+
+    TInt newTopItemIndex = ( desiredViewPosition / rowHeight ) * numOfCols;
+    TInt newVerticalOffset = -( desiredViewPosition % rowHeight );
+    SetTopItemIndex( newTopItemIndex );
+    SetVerticalItemOffset( newVerticalOffset );
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TInt CMmGrid::ScrollIfNeeded( const TPointerEvent& aPointerEvent )
+    {
+    CAknGridView* view = static_cast<CAknGridView*>( View() );
+    TInt nextScrollDelay = 0;
+
+    TBool readyForScrolling = iMmDrawer->GetAnimator()->IsReadyForNewAnimation()
+    && iMmDrawer->GetFloatingItemCount() != 0;
+
+  if ( IsPointerInTopScrollingThreshold( aPointerEvent ) )
+    {
+    // scroll up by one row
+    TInt newCurrentItemIndex = CurrentItemIndex() - view->NumberOfColsInView();
+        if ( newCurrentItemIndex < 0 )
+            {
+            newCurrentItemIndex = CurrentItemIndex();
+            }
+
+       nextScrollDelay = MmEffects::KEditModeScrollingDelayFactor *
+       Max( 1, aPointerEvent.iPosition.iY - Rect().iTl.iY );
+
+    if ( readyForScrolling )
+      {
+      ScrollWithoutRedraw( -iItemHeight );
+      View()->SetCurrentItemIndex( newCurrentItemIndex );
+      }
+    }
+  else if ( IsPointerInBottomScrollingThreshold( aPointerEvent) )
+    {
+    TInt newCurrentItemIndex = CurrentItemIndex() + view->NumberOfColsInView();
+    if ( newCurrentItemIndex > iModel->NumberOfItems() - 1 )
+      {
+      newCurrentItemIndex = CurrentItemIndex();
+      }
+
+    nextScrollDelay = MmEffects::KEditModeScrollingDelayFactor *
+      Max( 1, Rect().iBr.iY - aPointerEvent.iPosition.iY );
+
+    if ( readyForScrolling )
+      {
+      ScrollWithoutRedraw( iItemHeight );
+      View()->SetCurrentItemIndex( newCurrentItemIndex );
+      }
+    }
+
+    return nextScrollDelay;
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::HandlePointerEventL(const TPointerEvent& aPointerEvent)
+    {
+//    if ( aPointerEvent.iType == TPointerEvent::EButton1Down &&
+//            iMmDrawer->CachedDataUseIsEnabled() )
+//        {
+//        // Touching the screen stops flick but avkon does not send us
+//        // MEikListBoxObserver::EEventFlickStopped event in such case.
+//        // Thus this little hack:
+//        iMmDrawer->EnableCachedDataUse( EFalse );
+//        DrawView();
+//        }
+
+    CMmWidgetContainer* parent = static_cast<CMmWidgetContainer*>( Parent() );
+    if ( parent->IsEditMode() )
+        {
+        HandlePointerEventInEditModeL( aPointerEvent );
+        }
+    else
+        {
+        HandlePointerEventInNormalModeL( aPointerEvent );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::HandleOverridenHighlightDrawing( const TPointerEvent& aPointerEvent,
+        TInt aIndexBefore, TInt aIndexAfter )
+    {
+    // In grid our behaviour is a little different than defalt avkon.
+    // It is required to clean the highlight after the finger has been raised,
+    // and simulate the tap effect, when an item that has an invisible
+    // highlight is tapped again.
+    TBool effects (EFalse);
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+        MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal(
+                iMmDrawer->Gc() );
+        effects = transApi && !transApi->EffectsDisabled();
+#endif
+    if (effects)
+        {
+        CMmWidgetContainer* parent = static_cast< CMmWidgetContainer* > ( Parent() );
+        if ( aIndexBefore == aIndexAfter
+                && !parent->IsEditMode()
+                && aPointerEvent.iType == TPointerEvent::EButton1Down )
+            {
+            DrawItem( aIndexAfter );
+
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+            MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal(
+                    iMmDrawer->Gc() );
+             if ( transApi )
+                 {
+                 transApi->SetMoveType( MAknListBoxTfxInternal::EListTap);
+                 transApi->Draw( Rect() );
+                 }
+#endif
+            }
+        else if ( aIndexBefore == aIndexAfter
+                && aPointerEvent.iType == TPointerEvent::EButton1Up
+                && !parent->IsHighlightVisible())
+            {
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+            MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal(
+                    iMmDrawer->Gc() );
+             if ( transApi )
+                 {
+                 transApi->Draw( Rect() );
+                 }
+#endif
+            }
+        }
+
+    }
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::FixViewForMirroredLayout()
+    {
+    TInt scrollbarWidth = ScrollBarOffset() +
+            ScrollBarFrame()->VerticalScrollBar()->Rect().Width();
+    TRect r( View()->ViewRect() );
+    TInt currentShift = r.iTl.iX;
+    TBool scrollbarVisible = ScrollBarFrame()->VerticalScrollBar()->IsVisible();
+    TBool layoutMirrored = AknLayoutUtils::LayoutMirrored();
+
+    if ( layoutMirrored )
+        {
+        // Extra width, which results from the fact that it is not always
+        // possible to divide screen width by the number of columns without
+        // a non-zero remainder. This makes the distance of grid items from
+        // scrollbar in mirrored layout exactly the same as in normal layout.
+        scrollbarWidth += ( r.Width() - scrollbarWidth ) %
+            ( (CAknGridView*) View() )->NumberOfColsInView();
+        }
+
+    if ( layoutMirrored && scrollbarVisible && currentShift != scrollbarWidth )
+        {
+        // shift view rect to the right
+        r.Move( scrollbarWidth - currentShift, 0 );
+        View()->SetViewRect( r );
+        }
+    else if ( ( !layoutMirrored || !scrollbarVisible ) && currentShift != 0 )
+        {
+        // restore view rect to its normal position
+        r.Move( -currentShift, 0 );
+        View()->SetViewRect( r );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::ConstructL( const CCoeControl* aParent, TInt aFlags,
+        CMmTemplateLibrary* aTemplateLibrary )
+    {
+    iDisableChildComponentDrawing = EFalse;
+    iModel = iMmModel = CMmGridModel::NewL();
+    CreateItemDrawerL(aTemplateLibrary);
+    CAknGrid::ConstructL( aParent, aFlags );
+    iMmDrawer->SetView( this );
+
+    //set initial value so avkon does not panic
+    if ( Layout_Meta_Data::IsLandscapeOrientation() )
+        {
+        iViewLayout = TSize( MmGrid::K4By3LayoutX, MmGrid::K4By3LayoutY );
+        }
+    else
+        {
+        iViewLayout = TSize( MmGrid::K3By4LayoutX, MmGrid::K3By4LayoutY );
+        }
+
+    DoSetupLayoutL();
+    iRedrawTimer = CPeriodic::NewL( EPriorityRealTime );
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+CListBoxView* CMmGrid::MakeViewClassInstanceL()
+    {
+    return CMmGridView::NewL();
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+CMmGridModel* CMmGrid::MmModel()
+    {
+    return iMmModel;
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TKeyResponse CMmGrid::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
+    {
+    TKeyEvent eventCopy( aKeyEvent );
+    if ( AknLayoutUtils::LayoutMirrored() )
+        {
+        if ( eventCopy.iCode == EKeyLeftArrow )
+            {
+            eventCopy.iCode = EKeyRightArrow;
+            }
+        else if ( eventCopy.iCode == EKeyRightArrow )
+            {
+            eventCopy.iCode = EKeyLeftArrow;
+            }
+        }
+    return CAknGrid::OfferKeyEventL( eventCopy, aType );
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::HandleViewRectSizeChangeL()
+    {
+    if ( !AknLayoutUtils::LayoutMirrored() )
+        {
+        CAknGrid::HandleViewRectSizeChangeL();
+        }
+    else
+        {
+        // for mirrored layout this function should do
+        // exactly the same things as CAknGrid::HandleViewRectSizeChangeL
+        // would do for normal layout
+        iView->CalcBottomItemIndex();
+        if ( CurrentItemIndex() >= 0 )
+            {
+            AdjustTopItemIndex();
+            iView->CalcDataWidth();
+            UpdateScrollBarsL();
+            iView->CalcBottomItemIndex();
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::AdjustTopItemIndex() const
+    {
+    CAknGridView* view = static_cast<CAknGridView*>( iView );
+    const TInt numOfCols = view->NumberOfColsInView();
+    const TInt numOfRows = view->NumberOfRowsInView();
+    const TInt itemCount = iModel->NumberOfItems();
+
+    ASSERT( numOfCols > 0 );
+
+    TInt lastRow = 0;
+    if ( itemCount > 0 )
+        {
+        lastRow = ( itemCount - 1 ) / numOfCols;
+        }
+    TInt maxPossibleTopRow = Max( 0, lastRow - numOfRows + 1 );
+
+    TInt topRow = TopItemIndex() / numOfCols;
+
+    if( !( TopItemIndex() % numOfCols == 0
+            && topRow <= maxPossibleTopRow ) )
+        {
+        topRow = Min( topRow, maxPossibleTopRow );
+        SetTopItemIndex( topRow * numOfCols );
+        }
+
+    // prevent problems with view being scrolled up beyond limits
+    if ( topRow == maxPossibleTopRow && VerticalItemOffset() < 0 )
+        {
+        TRAP_IGNORE(
+                ( ( CMmWidgetContainer* ) Parent() )->AlignBottomOfViewL() );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::DoHandleResourceChangeL( TSize& aCellSize,
+        TSize& aViewLayout )
+    {
+    TBool cond = Layout_Meta_Data::IsLandscapeOrientation();
+    TRAPD( err, DoHandleResourceChangeL( cond, aCellSize, aViewLayout ) );
+    if ( err == KErrNotFound )
+        {
+        aViewLayout = iViewLayout;
+        aCellSize = TSize (1,1);
+        }
+    else if ( err == KErrNoMemory )
+        {
+        User::Leave( KErrNoMemory );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::DoHandleResourceChangeL( TBool aIsLandscape, TSize& aCellSize,
+        TSize& aViewLayout )
+    {
+    CHnSuiteModel* model = iMmModel->MmListBoxModel()->GetSuiteModel();
+    const TDesC8& templ = (model) ? model->GetTemplate() : KNullDesC8();
+    aCellSize = iMmDrawer->TemplateLibrary()->GetSize(
+        EGrid, templ, aIsLandscape, EFalse, iView->ViewRect() );
+    aViewLayout = iMmDrawer->TemplateLibrary()->GetLayoutSizeL(
+        EGrid, templ, aIsLandscape );
+    iViewLayout = aViewLayout;
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::SetItemDrawerAndViewBgContext(
+        CAknsBasicBackgroundControlContext * aBgContext )
+    {
+    iMmDrawer->SetBgContext (aBgContext);
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TBool CMmGrid::HandleScrollbarVisibilityChangeL()
+    {
+    TBool ret = EFalse;
+    if ( AllItemsFitInViewRect() )
+        {
+        if ( ScrollBarFrame()->VerticalScrollBar()->IsVisible()
+             || iMmDrawer->TemplateLibrary()->GetScrollbarVisibility() )
+            {
+            ScrollBarFrame()->VerticalScrollBar()->MakeVisible( EFalse );
+            iMmDrawer->SetScrollbarVisibilityL( EFalse );
+            SetTopItemIndex( 0 );
+            iCurrentTopItemIndex = 0;
+            ret = ETrue;
+            }
+        }
+    else if ( !ScrollBarFrame()->VerticalScrollBar()->IsVisible()
+            || !iMmDrawer->TemplateLibrary()->GetScrollbarVisibility() )
+        {
+        ScrollBarFrame()->VerticalScrollBar()->MakeVisible( ETrue );
+        iMmDrawer->SetScrollbarVisibilityL( ETrue );
+        ret = ETrue;
+        }
+
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+
+TBool CMmGrid::AllItemsFitInViewRect()
+    {
+    if ( iMmModel->NumberOfItems() <= iViewLayout.iWidth * iViewLayout.iHeight
+            || iViewLayout == TSize(0,0) )
+        {
+        return ETrue;
+        }
+    else
+        {
+        return EFalse;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::UpdateScrollBarsL()
+    {
+    TBool visibilityChanged = HandleScrollbarVisibilityChangeL();
+    if (ScrollBarFrame()->VerticalScrollBar()->IsVisible())
+        {
+        CMmWidgetContainer* widget = static_cast< CMmWidgetContainer* >(Parent());
+        if( widget->IsEditMode() && widget->WidgetPositionCache().iValid )
+            {
+            static_cast<CMmGridView*> ( View() )->SetItemOffsetInPixels(
+                    widget->WidgetPositionCache().iVerticalItemOffset );
+            }
+        CAknGrid::UpdateScrollBarsL();
+        }
+    iCurrentTopItemIndex = TopItemIndex();
+    iMmDrawer->TemplateLibrary()->SetScrollbarWidthL(
+            ScrollBarFrame()->VerticalScrollBar()->Rect().Width() + ScrollBarOffset() );
+    FixViewForMirroredLayout();
+    if ( visibilityChanged )
+        {
+        CMmGridView* view = static_cast<CMmGridView*>( iView );
+        view->UpdateItemHeightAndWidth();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::SetMarqueeAdapter( CMmMarqueeAdapter* aAdapter )
+    {
+    iMarqueeAdapter = aAdapter;
+    }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::SetupLayout()
+    {
+    TRAP_IGNORE( DoSetupLayoutL() );
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::DoSetupLayoutL()
+    {
+    TSize cellSize;
+    TSize viewLayout;
+    DoHandleResourceChangeL( cellSize, viewLayout );
+//  The mirrored layout arabic item lineout ( right to left )
+//  is handled by CMmGridView::ItemPos( TInt aItemIndex )
+//  and CMmGridView::XYPosToItemIndex( TPoint aPosition, TInt& aItemIndex )
+    SetLayoutL( EFalse, ETrue /*!AknLayoutUtils::LayoutMirrored()*/, ETrue, viewLayout.iWidth,
+        viewLayout.iHeight, cellSize, 0, 0 );
+    iMmDrawer->SetNumberOfColsInView(
+            static_cast<CMmGridView*>(iView)->NumberOfColsInView() );
+    // setting the top item index when changing orientation
+    TInt cols( static_cast<CMmGridView*>(iView)->NumberOfColsInView() );
+    SetTopItemIndex( ( (TInt) ( iCurrentTopItemIndex / cols ) ) * cols );
+    UpdateScrollBarsL();
+    AknsUtils::RegisterControlPosition( iMmDrawer->FormattedCellData()->Control() );
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TInt CMmGrid::ScrollBarOffset()
+    {
+    TInt offset = 0;
+    if ( ScrollBarFrame()->ScrollBarExists( CEikScrollBar::EVertical ) )
+        {
+        if ( AknLayoutUtils::LayoutMirrored() )
+            {
+            offset = ScrollBarFrame()->VerticalScrollBar()->Position().iX;
+            }
+        else
+            {
+            offset = View()->ViewRect().Width()
+                    - ( ScrollBarFrame()->VerticalScrollBar()->Position().iX
+                        + ScrollBarFrame()->VerticalScrollBar()->Rect().Width() );
+            }
+        }
+    return offset;
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::RedrawScrollbarBackground() const
+    {
+    TRect viewRect( View()->ViewRect() );
+    if ( viewRect.iTl.iX > 0 )
+        {
+        TRect scrollbarRect( TPoint( 0, 0 ),
+                TSize( viewRect.iTl.iX, viewRect.Height() ) );
+
+        CWindowGc* gc = iItemDrawer->Gc();
+        CMmListBoxItemDrawer* itemDrawer =
+                static_cast<CMmListBoxItemDrawer*>( iItemDrawer );
+        MAknsSkinInstance *skin = AknsUtils::SkinInstance();
+        CCoeControl* control = itemDrawer->FormattedCellData()->Control();
+        MAknsControlContext *cc = AknsDrawUtils::ControlContext( control );
+        if( gc )
+            {
+            if ( control )
+                {
+                AknsDrawUtils::Background( skin, cc, control, *gc, scrollbarRect );
+                }
+            else
+                {
+                gc->SetBrushColor( BackColor() );
+                gc->Clear( scrollbarRect );
+                }
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::ProcessScrollEventL( CEikScrollBar* aScrollBar,
+            TEikScrollEvent aEventType )
+    {
+    CAknGrid::HandleScrollEventL( aScrollBar, aEventType );
+    iCurrentTopItemIndex = TopItemIndex();
+
+    // setting default highlight in order not to overwrite the top item index
+    // set before in the SetLayout method
+    CMmWidgetContainer* parent = static_cast< CMmWidgetContainer* > ( Parent() );
+    if (!parent->IsHighlightVisible())
+         {
+         parent->SetDefaultHighlightL( EFalse );
+
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+         MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal(
+                 static_cast<CMmGridView*>(iView)->Gc() );
+         TBool effects = transApi && !transApi->EffectsDisabled();
+         if ( effects && aEventType == EEikScrollPageUp ||
+                 aEventType == EEikScrollPageDown )
+             {
+             DrawNow();
+             }
+#endif
+
+         }
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::HandleRedrawTimerEventL()
+    {
+    if ( iSkippedScrollbarEventsCount )
+        {
+        ProcessScrollEventL( ScrollBarFrame()->VerticalScrollBar(),
+                EEikScrollThumbDragVert );
+        }
+    iSkippedScrollbarEventsCount = 0;
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TInt CMmGrid::RedrawTimerCallback( TAny* aPtr )
+    {
+    CMmGrid* self = static_cast<CMmGrid*>( aPtr );
+    TRAP_IGNORE( self->HandleRedrawTimerEventL() );
+    // Do not bother returning a meaningful error code, CPeriodic will ignore it
+    // anyway.
+    return 0;
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::SetVerticalItemOffset(TInt aOffset)
+  {
+  static_cast<CMmGridView*> (View())->SetItemOffsetInPixels(aOffset);
+  UpdateScrollBarThumbs();
+  }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TInt CMmGrid::VerticalItemOffset() const
+  {
+  return static_cast<CMmGridView*> (View())->VerticalItemOffset();
+  }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::SetItemHeight( TInt aItemHeight )
+  {
+  iItemHeight = aItemHeight;
+  }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::UpdateScrollBarThumbs()
+    {
+    CAknGrid::UpdateScrollBarThumbs();
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TInt CMmGrid::CountComponentControls() const
+    {
+    TInt componentControls(0);
+    if ( !iDisableChildComponentDrawing )
+      {
+        componentControls = CAknGrid::CountComponentControls();
+      }
+    return componentControls;
+    }
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMmGrid::SetDisableChildComponentDrawing( TBool aDisable )
+    {
+    iDisableChildComponentDrawing = aDisable;
+    }
+//End of file