menufw/menufwui/mmwidgets/src/mmgrid.cpp
branchRCL_3
changeset 83 5456b4e8b3a8
child 88 3321d3e205b6
equal deleted inserted replaced
82:5f0182e07bfb 83:5456b4e8b3a8
       
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *  Version     : %version: MM_106 % << Don't touch! Updated by Synergy at check-out.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 #include <AknsDrawUtils.h>
       
    21 #include <layoutmetadata.cdl.h>
       
    22 #include "mmgrid.h"
       
    23 #include "mmgridmodel.h"
       
    24 #include "mmlistboxitemdrawer.h"
       
    25 #include "mmgridview.h"
       
    26 #include "mmtemplatelibrary.h"
       
    27 #include "mmlistboxmodel.h"
       
    28 #include "mmmarqueeadapter.h"
       
    29 #include "mmwidgetsconstants.h"
       
    30 #include "mmwidgetcontainer.h"
       
    31 #include "hnsuitemodel.h"
       
    32 #include "mmdraweranimator.h"
       
    33 
       
    34 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
    35 #include <aknlistloadertfx.h>
       
    36 #include <aknlistboxtfxinternal.h>
       
    37 #endif
       
    38 
       
    39 // -----------------------------------------------------------------------------
       
    40 //
       
    41 // -----------------------------------------------------------------------------
       
    42 //
       
    43 CMmGrid::CMmGrid()
       
    44     {
       
    45     // No implementation required
       
    46     }
       
    47 
       
    48 // -----------------------------------------------------------------------------
       
    49 //
       
    50 // -----------------------------------------------------------------------------
       
    51 //
       
    52 CMmGrid::~CMmGrid()
       
    53     {
       
    54     delete iRedrawTimer;
       
    55     }
       
    56 
       
    57 // -----------------------------------------------------------------------------
       
    58 //
       
    59 // -----------------------------------------------------------------------------
       
    60 //
       
    61 CMmGrid* CMmGrid::NewLC( const CCoeControl* aParent, TInt aFlags,
       
    62         CMmTemplateLibrary* aTemplateLibrary)
       
    63     {
       
    64     CMmGrid* self = new (ELeave)CMmGrid();
       
    65     CleanupStack::PushL(self);
       
    66     self->ConstructL( aParent, aFlags, aTemplateLibrary );
       
    67     return self;
       
    68     }
       
    69 
       
    70 // -----------------------------------------------------------------------------
       
    71 //
       
    72 // -----------------------------------------------------------------------------
       
    73 //
       
    74 CMmGrid* CMmGrid::NewL( const CCoeControl* aParent, TInt aFlags,
       
    75         CMmTemplateLibrary* aTemplateLibrary )
       
    76     {
       
    77     CMmGrid* self = CMmGrid::NewLC( aParent, aFlags, aTemplateLibrary );
       
    78     CleanupStack::Pop( self );
       
    79     return self;
       
    80     }
       
    81 
       
    82 // -----------------------------------------------------------------------------
       
    83 // If a parent to the supplied control has its Gc set, this function will find
       
    84 // it and return it. (Copied from EIKLBX.CPP, needed by CMmGrid::Draw)
       
    85 // -----------------------------------------------------------------------------
       
    86 //
       
    87 LOCAL_C CWindowGc* ReplaceGcWithCustomGc( const CEikListBox* aListBox )
       
    88     {
       
    89     const CCoeControl* parent = aListBox;
       
    90     CWindowGc* customGc;
       
    91     while(parent)
       
    92         {
       
    93         customGc = parent->GetGc();
       
    94         if ( customGc )
       
    95             {
       
    96             CListItemDrawer* itemDrawer = aListBox->View()->ItemDrawer();
       
    97             CWindowGc* originalGc = itemDrawer->Gc();
       
    98             if ( customGc == originalGc )
       
    99                 {
       
   100                 return NULL;
       
   101                 }
       
   102             else
       
   103                 {
       
   104                 itemDrawer->SetGc( customGc );
       
   105                 return originalGc;
       
   106                 }
       
   107             }
       
   108         parent = parent->Parent();
       
   109         }
       
   110     return NULL;
       
   111     }
       
   112 
       
   113 // -----------------------------------------------------------------------------
       
   114 //
       
   115 // -----------------------------------------------------------------------------
       
   116 //
       
   117 void CMmGrid::Draw(const TRect& aRect) const
       
   118     {
       
   119     if ( View()->RedrawDisabled () || !IsVisible () )
       
   120         {
       
   121         return;
       
   122         }
       
   123     iMmDrawer->SetNumberOfColsInView(
       
   124             static_cast<CMmGridView*>(iView)->NumberOfColsInView() );
       
   125 
       
   126     // If a parent has a custom gc, draw listbox using that gc
       
   127     CWindowGc* replacedGc = ReplaceGcWithCustomGc( this );
       
   128 
       
   129     CWindowGc* gc = iItemDrawer->Gc();
       
   130     TGulBorder::TColors borderColors;
       
   131     iBorder.Draw(*gc, Rect(), borderColors);
       
   132 
       
   133 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   134     MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal(
       
   135             static_cast<CMmGridView*>(iView)->Gc() );
       
   136     TBool effects = transApi && !transApi->EffectsDisabled();
       
   137     if ( effects )
       
   138         {
       
   139         // ViewRect might have been moved to the right to prevent grid items
       
   140         // from overlapping the scrollbar in mirrored layout.
       
   141         // However, we still have to draw scrollbar background, thus the
       
   142         // rectangle object passed to MAknListBoxTfxInternal::BeginRedraw must
       
   143         // be placed at (0, 0) so that it covers the area where scrollbar is
       
   144         // drawn.
       
   145         TRect r( View()->ViewRect().Size() );
       
   146         transApi->BeginRedraw( MAknListBoxTfxInternal::EListView, r );
       
   147         transApi->StartDrawing( MAknListBoxTfxInternal::EListView );
       
   148         }
       
   149 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
   150 
       
   151     ClearMargins();
       
   152     RedrawScrollbarBackground();
       
   153 
       
   154 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   155     if ( effects )
       
   156         {
       
   157         transApi->StopDrawing();
       
   158         }
       
   159 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
   160     iView->Draw(&aRect);
       
   161 
       
   162 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   163     if ( effects )
       
   164         {
       
   165         transApi->EndViewRedraw( aRect );
       
   166         }
       
   167 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
   168 
       
   169     if ( replacedGc )
       
   170         {
       
   171         // Stop using the custom gc
       
   172         iItemDrawer->SetGc( replacedGc );
       
   173         }
       
   174     }
       
   175 // -----------------------------------------------------------------------------
       
   176 //
       
   177 // -----------------------------------------------------------------------------
       
   178 //
       
   179 void CMmGrid::DrawView()
       
   180     {
       
   181     iDisableChildComponentDrawing = ETrue;
       
   182     DrawNow(Rect());
       
   183     iDisableChildComponentDrawing = EFalse;
       
   184     }
       
   185 
       
   186 // -----------------------------------------------------------------------------
       
   187 //
       
   188 // -----------------------------------------------------------------------------
       
   189 //
       
   190 void CMmGrid::CreateItemDrawerL()
       
   191     {
       
   192     iItemDrawer = iMmDrawer;
       
   193     }
       
   194 
       
   195 // -----------------------------------------------------------------------------
       
   196 //
       
   197 // -----------------------------------------------------------------------------
       
   198 //
       
   199 void CMmGrid::CreateItemDrawerL( CMmTemplateLibrary* aTemplateLibrary )
       
   200     {
       
   201     CFormattedCellListBoxData* data=CFormattedCellGridData::NewL();
       
   202     CleanupStack::PushL(data);
       
   203 
       
   204     iMmDrawer = CMmListBoxItemDrawer::NewL(
       
   205         MmModel()->MmListBoxModel(), iEikonEnv->NormalFont(), data, EGrid,
       
   206         aTemplateLibrary );
       
   207     iItemDrawer = iMmDrawer;
       
   208     data->SetControl( this );
       
   209     CleanupStack::Pop( data );
       
   210     }
       
   211 
       
   212 // -----------------------------------------------------------------------------
       
   213 //
       
   214 // -----------------------------------------------------------------------------
       
   215 //
       
   216 void CMmGrid::HandleScrollEventL( CEikScrollBar* aScrollBar,
       
   217         TEikScrollEvent aEventType )
       
   218     {
       
   219     if ( aEventType == EEikScrollThumbDragVert && !iScrollbarThumbIsBeingDragged )
       
   220         {
       
   221         iScrollbarThumbIsBeingDragged = ETrue;
       
   222         static_cast<CMmListBoxItemDrawer*>(
       
   223                 View()->ItemDrawer() )->EnableCachedDataUse( ETrue );
       
   224         iRedrawTimer->Start( KScrollingRedrawInterval, KScrollingRedrawInterval,
       
   225                 TCallBack( &CMmGrid::RedrawTimerCallback, static_cast<TAny*>( this ) ) );
       
   226         }
       
   227     else if ( aEventType == EEikScrollThumbReleaseVert )
       
   228         {
       
   229         iScrollbarThumbIsBeingDragged = EFalse;
       
   230         static_cast<CMmListBoxItemDrawer*>(
       
   231                 View()->ItemDrawer() )->EnableCachedDataUse( EFalse );
       
   232         // The view will be redrawn with cache disabled when ProcessScrollEventL
       
   233         // calls the base class's HandleScrollEventL method -- no need to
       
   234         // explicitly redraw the view.
       
   235         iRedrawTimer->Cancel();
       
   236         }
       
   237 
       
   238     if ( !iScrollbarThumbIsBeingDragged )
       
   239         {
       
   240         ProcessScrollEventL( aScrollBar, aEventType );
       
   241         }
       
   242     else
       
   243         {
       
   244         __ASSERT_DEBUG( aEventType == EEikScrollThumbDragVert, User::Invariant() );
       
   245         ++iSkippedScrollbarEventsCount;
       
   246         }
       
   247     }
       
   248 
       
   249 // -----------------------------------------------------------------------------
       
   250 // Clearing ELeftDownInViewRect flag before invoking the base class
       
   251 // HandlePointerEventL method effectively prevents that method from doing most
       
   252 // of the things it would normally do in response to EButton1Down event.
       
   253 // This flag is explicitly cleared to achieve two things:
       
   254 // 1. Prevent kinetic scrolling (flick) in edit mode.
       
   255 // 2. Prevent highlight removal when popup menu is displayed.
       
   256 // -----------------------------------------------------------------------------
       
   257 //
       
   258 void CMmGrid::HandlePointerEventInEditModeL( const TPointerEvent& aPointerEvent )
       
   259     {
       
   260     CMmWidgetContainer* parent = static_cast<CMmWidgetContainer*>( Parent() );
       
   261     if ( aPointerEvent.iType == TPointerEvent::EButton1Down )
       
   262         {
       
   263         iButton1DownPos = aPointerEvent.iPosition;
       
   264         }
       
   265     else if ( aPointerEvent.iType == TPointerEvent::EButton1Up )
       
   266         {
       
   267         TPoint dragDelta = iButton1DownPos - aPointerEvent.iPosition;
       
   268         if ( Abs( dragDelta.iY ) > KDragTreshold || parent->LongTapInProgress() )
       
   269             {
       
   270             iListBoxFlags &= ~ELeftDownInViewRect;
       
   271             }
       
   272         }
       
   273 
       
   274     TInt itemUnderPointerIndex = KErrNotFound;
       
   275     if ( aPointerEvent.iType == TPointerEvent::EButton1Up ||
       
   276             aPointerEvent.iType == TPointerEvent::EButton1Down )
       
   277         {
       
   278         TBool highlightWasVisible = parent->IsHighlightVisible();
       
   279         CAknGrid::HandlePointerEventL( aPointerEvent );
       
   280         // Tricky: Do not allow the base class implementation of HandlePointerEventL
       
   281         //         to remove the highlight on EButton1Up event when context menu
       
   282         //         is displayed for an item
       
   283         if ( aPointerEvent.iType == TPointerEvent::EButton1Up &&
       
   284                 highlightWasVisible && parent->LongTapInProgress()
       
   285                 && !parent->IsHighlightVisible() )
       
   286             {
       
   287             ItemDrawer()->ClearFlags( CListItemDrawer::ESingleClickDisabledHighlight );
       
   288             }
       
   289         }
       
   290     else if ( View()->XYPosToItemIndex(
       
   291             aPointerEvent.iPosition, itemUnderPointerIndex ) )
       
   292         {
       
   293         if ( CurrentItemIndex() != itemUnderPointerIndex )
       
   294             {
       
   295             CMmWidgetContainer* parent = static_cast<CMmWidgetContainer*>( Parent() );
       
   296             if ( parent->IsNoItemDragged() )
       
   297                 {
       
   298                 if ( ItemDrawer()->Flags() & CListItemDrawer::EPressedDownState )
       
   299                     {
       
   300                     ItemDrawer()->ClearFlags( CListItemDrawer::EPressedDownState );
       
   301                     iView->DrawItem( CurrentItemIndex() );
       
   302                     }
       
   303                 }
       
   304             else
       
   305                 {
       
   306                 iView->SetCurrentItemIndex( itemUnderPointerIndex );
       
   307                 iView->DrawItem(itemUnderPointerIndex);
       
   308                 }
       
   309             }
       
   310         }
       
   311 
       
   312     HandleScrollingInEditMode( aPointerEvent );
       
   313     }
       
   314 
       
   315 // -----------------------------------------------------------------------------
       
   316 //
       
   317 // -----------------------------------------------------------------------------
       
   318 //
       
   319 void CMmGrid::HandlePointerEventInNormalModeL( const TPointerEvent& aPointerEvent )
       
   320     {
       
   321     CAknGrid::HandlePointerEventL(aPointerEvent);
       
   322     }
       
   323 
       
   324 // -----------------------------------------------------------------------------
       
   325 //
       
   326 // -----------------------------------------------------------------------------
       
   327 //
       
   328 void CMmGrid::HandleScrollingInEditMode( const TPointerEvent& aPointerEvent )
       
   329     {
       
   330     if ( aPointerEvent.iType == TPointerEvent::EDrag
       
   331             || aPointerEvent.iType == TPointerEvent::EButtonRepeat )
       
   332         {
       
   333         TInt nextScrollDelay = ScrollIfNeeded( aPointerEvent );
       
   334         if ( nextScrollDelay )
       
   335             {
       
   336             TRect ignoreDragRect(
       
   337                 TPoint(aPointerEvent.iParentPosition.iX - MmEffects::KDragIgnoreRectValue,
       
   338                     aPointerEvent.iParentPosition.iY - MmEffects::KDragIgnoreRectValue),
       
   339                 TPoint(aPointerEvent.iParentPosition.iX + MmEffects::KDragIgnoreRectValue,
       
   340                     aPointerEvent.iParentPosition.iY + MmEffects::KDragIgnoreRectValue));
       
   341 
       
   342             Window().CancelPointerRepeatEventRequest();
       
   343             Window().RequestPointerRepeatEvent( nextScrollDelay, ignoreDragRect );
       
   344             }
       
   345         }
       
   346     }
       
   347 
       
   348 // -----------------------------------------------------------------------------
       
   349 //
       
   350 // -----------------------------------------------------------------------------
       
   351 //
       
   352 TBool CMmGrid::IsPointerInTopScrollingThreshold(
       
   353             const TPointerEvent& aPointerEvent ) const
       
   354     {
       
   355     TInt topScrollingTreshold = Rect().iTl.iY
       
   356         + ( MmGrid::KFocusScrollingThreshold
       
   357             * TReal( View()->ItemSize().iHeight ) );
       
   358 
       
   359     return ( aPointerEvent.iPosition.iY < topScrollingTreshold );
       
   360     }
       
   361 
       
   362 // -----------------------------------------------------------------------------
       
   363 //
       
   364 // -----------------------------------------------------------------------------
       
   365 //
       
   366 TBool CMmGrid::IsPointerInBottomScrollingThreshold(
       
   367             const TPointerEvent& aPointerEvent ) const
       
   368     {
       
   369     TInt bottomScrollingTreshold = Rect().iBr.iY
       
   370         - ( MmGrid::KFocusScrollingThreshold
       
   371             * TReal( View()->ItemSize().iHeight ) );
       
   372 
       
   373     return ( aPointerEvent.iPosition.iY > bottomScrollingTreshold );
       
   374     }
       
   375 
       
   376 // -----------------------------------------------------------------------------
       
   377 //
       
   378 // -----------------------------------------------------------------------------
       
   379 //
       
   380 void CMmGrid::ScrollWithoutRedraw( TInt distanceInPixels )
       
   381     {
       
   382     CAknGridView* view = static_cast<CAknGridView*>( iView );
       
   383     const TInt rowHeight = ItemHeight();
       
   384     const TInt numOfCols = view->NumberOfColsInView();
       
   385     const TInt itemCount = iModel->NumberOfItems();
       
   386     TInt totalNumberOfRows = itemCount / numOfCols;
       
   387     if ( itemCount % numOfCols )
       
   388         {
       
   389         ++totalNumberOfRows;
       
   390         }
       
   391     const TInt topItemRowIndex = TopItemIndex() / numOfCols;
       
   392 
       
   393     // desired view position relative to the first item in grid (always positive)
       
   394     TInt desiredViewPosition = rowHeight * topItemRowIndex - VerticalItemOffset();
       
   395 
       
   396     desiredViewPosition += distanceInPixels;
       
   397 
       
   398     const TInt viewPositionMin = 0;
       
   399     const TInt viewPositionMax =
       
   400     Max( 0, ( totalNumberOfRows * rowHeight ) - view->ViewRect().Height() );
       
   401 
       
   402     desiredViewPosition = Min( desiredViewPosition, viewPositionMax );
       
   403     desiredViewPosition = Max( desiredViewPosition, viewPositionMin );
       
   404 
       
   405     ASSERT( desiredViewPosition >= 0 );
       
   406 
       
   407     TInt newTopItemIndex = ( desiredViewPosition / rowHeight ) * numOfCols;
       
   408     TInt newVerticalOffset = -( desiredViewPosition % rowHeight );
       
   409     SetTopItemIndex( newTopItemIndex );
       
   410     SetVerticalItemOffset( newVerticalOffset );
       
   411     }
       
   412 
       
   413 // -----------------------------------------------------------------------------
       
   414 //
       
   415 // -----------------------------------------------------------------------------
       
   416 //
       
   417 TInt CMmGrid::ScrollIfNeeded( const TPointerEvent& aPointerEvent )
       
   418     {
       
   419     CAknGridView* view = static_cast<CAknGridView*>( View() );
       
   420     TInt nextScrollDelay = 0;
       
   421 
       
   422     TBool readyForScrolling = iMmDrawer->GetAnimator()->IsReadyForNewAnimation()
       
   423     && iMmDrawer->GetFloatingItemCount() != 0;
       
   424 
       
   425   if ( IsPointerInTopScrollingThreshold( aPointerEvent ) )
       
   426     {
       
   427     // scroll up by one row
       
   428     TInt newCurrentItemIndex = CurrentItemIndex() - view->NumberOfColsInView();
       
   429         if ( newCurrentItemIndex < 0 )
       
   430             {
       
   431             newCurrentItemIndex = CurrentItemIndex();
       
   432             }
       
   433 
       
   434        nextScrollDelay = MmEffects::KEditModeScrollingDelayFactor *
       
   435        Max( 1, aPointerEvent.iPosition.iY - Rect().iTl.iY );
       
   436 
       
   437     if ( readyForScrolling )
       
   438       {
       
   439       ScrollWithoutRedraw( -iItemHeight );
       
   440       View()->SetCurrentItemIndex( newCurrentItemIndex );
       
   441       }
       
   442     }
       
   443   else if ( IsPointerInBottomScrollingThreshold( aPointerEvent) )
       
   444     {
       
   445     TInt newCurrentItemIndex = CurrentItemIndex() + view->NumberOfColsInView();
       
   446     if ( newCurrentItemIndex > iModel->NumberOfItems() - 1 )
       
   447       {
       
   448       newCurrentItemIndex = CurrentItemIndex();
       
   449       }
       
   450 
       
   451     nextScrollDelay = MmEffects::KEditModeScrollingDelayFactor *
       
   452       Max( 1, Rect().iBr.iY - aPointerEvent.iPosition.iY );
       
   453 
       
   454     if ( readyForScrolling )
       
   455       {
       
   456       ScrollWithoutRedraw( iItemHeight );
       
   457       View()->SetCurrentItemIndex( newCurrentItemIndex );
       
   458       }
       
   459     }
       
   460 
       
   461     return nextScrollDelay;
       
   462     }
       
   463 
       
   464 // -----------------------------------------------------------------------------
       
   465 //
       
   466 // -----------------------------------------------------------------------------
       
   467 //
       
   468 void CMmGrid::HandlePointerEventL(const TPointerEvent& aPointerEvent)
       
   469     {
       
   470 //    if ( aPointerEvent.iType == TPointerEvent::EButton1Down &&
       
   471 //            iMmDrawer->CachedDataUseIsEnabled() )
       
   472 //        {
       
   473 //        // Touching the screen stops flick but avkon does not send us
       
   474 //        // MEikListBoxObserver::EEventFlickStopped event in such case.
       
   475 //        // Thus this little hack:
       
   476 //        iMmDrawer->EnableCachedDataUse( EFalse );
       
   477 //        DrawView();
       
   478 //        }
       
   479 
       
   480     CMmWidgetContainer* parent = static_cast<CMmWidgetContainer*>( Parent() );
       
   481     if ( parent->IsEditMode() )
       
   482         {
       
   483         HandlePointerEventInEditModeL( aPointerEvent );
       
   484         }
       
   485     else
       
   486         {
       
   487         HandlePointerEventInNormalModeL( aPointerEvent );
       
   488         }
       
   489     }
       
   490 
       
   491 // -----------------------------------------------------------------------------
       
   492 //
       
   493 // -----------------------------------------------------------------------------
       
   494 //
       
   495 void CMmGrid::HandleOverridenHighlightDrawing( const TPointerEvent& aPointerEvent,
       
   496         TInt aIndexBefore, TInt aIndexAfter )
       
   497     {
       
   498     // In grid our behaviour is a little different than defalt avkon.
       
   499     // It is required to clean the highlight after the finger has been raised,
       
   500     // and simulate the tap effect, when an item that has an invisible
       
   501     // highlight is tapped again.
       
   502     TBool effects (EFalse);
       
   503 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   504         MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal(
       
   505                 iMmDrawer->Gc() );
       
   506         effects = transApi && !transApi->EffectsDisabled();
       
   507 #endif
       
   508     if (effects)
       
   509         {
       
   510         CMmWidgetContainer* parent = static_cast< CMmWidgetContainer* > ( Parent() );
       
   511         if ( aIndexBefore == aIndexAfter
       
   512                 && !parent->IsEditMode()
       
   513                 && aPointerEvent.iType == TPointerEvent::EButton1Down )
       
   514             {
       
   515             DrawItem( aIndexAfter );
       
   516 
       
   517 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   518             MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal(
       
   519                     iMmDrawer->Gc() );
       
   520              if ( transApi )
       
   521                  {
       
   522                  transApi->SetMoveType( MAknListBoxTfxInternal::EListTap);
       
   523                  transApi->Draw( Rect() );
       
   524                  }
       
   525 #endif
       
   526             }
       
   527         else if ( aIndexBefore == aIndexAfter
       
   528                 && aPointerEvent.iType == TPointerEvent::EButton1Up
       
   529                 && !parent->IsHighlightVisible())
       
   530             {
       
   531 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   532             MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal(
       
   533                     iMmDrawer->Gc() );
       
   534              if ( transApi )
       
   535                  {
       
   536                  transApi->Draw( Rect() );
       
   537                  }
       
   538 #endif
       
   539             }
       
   540         }
       
   541 
       
   542     }
       
   543 // -----------------------------------------------------------------------------
       
   544 //
       
   545 // -----------------------------------------------------------------------------
       
   546 //
       
   547 void CMmGrid::FixViewForMirroredLayout()
       
   548     {
       
   549     TInt scrollbarWidth = ScrollBarOffset() +
       
   550             ScrollBarFrame()->VerticalScrollBar()->Rect().Width();
       
   551     TRect r( View()->ViewRect() );
       
   552     TInt currentShift = r.iTl.iX;
       
   553     TBool scrollbarVisible = ScrollBarFrame()->VerticalScrollBar()->IsVisible();
       
   554     TBool layoutMirrored = AknLayoutUtils::LayoutMirrored();
       
   555 
       
   556     if ( layoutMirrored )
       
   557         {
       
   558         // Extra width, which results from the fact that it is not always
       
   559         // possible to divide screen width by the number of columns without
       
   560         // a non-zero remainder. This makes the distance of grid items from
       
   561         // scrollbar in mirrored layout exactly the same as in normal layout.
       
   562         scrollbarWidth += ( r.Width() - scrollbarWidth ) %
       
   563             ( (CAknGridView*) View() )->NumberOfColsInView();
       
   564         }
       
   565 
       
   566     if ( layoutMirrored && scrollbarVisible && currentShift != scrollbarWidth )
       
   567         {
       
   568         // shift view rect to the right
       
   569         r.Move( scrollbarWidth - currentShift, 0 );
       
   570         View()->SetViewRect( r );
       
   571         }
       
   572     else if ( ( !layoutMirrored || !scrollbarVisible ) && currentShift != 0 )
       
   573         {
       
   574         // restore view rect to its normal position
       
   575         r.Move( -currentShift, 0 );
       
   576         View()->SetViewRect( r );
       
   577         }
       
   578     }
       
   579 
       
   580 // -----------------------------------------------------------------------------
       
   581 //
       
   582 // -----------------------------------------------------------------------------
       
   583 //
       
   584 void CMmGrid::ConstructL( const CCoeControl* aParent, TInt aFlags,
       
   585         CMmTemplateLibrary* aTemplateLibrary )
       
   586     {
       
   587     iDisableChildComponentDrawing = EFalse;
       
   588     iModel = iMmModel = CMmGridModel::NewL();
       
   589     CreateItemDrawerL(aTemplateLibrary);
       
   590     CAknGrid::ConstructL( aParent, aFlags );
       
   591     iMmDrawer->SetView( this );
       
   592 
       
   593     //set initial value so avkon does not panic
       
   594     if ( Layout_Meta_Data::IsLandscapeOrientation() )
       
   595         {
       
   596         iViewLayout = TSize( MmGrid::K4By3LayoutX, MmGrid::K4By3LayoutY );
       
   597         }
       
   598     else
       
   599         {
       
   600         iViewLayout = TSize( MmGrid::K3By4LayoutX, MmGrid::K3By4LayoutY );
       
   601         }
       
   602 
       
   603     DoSetupLayoutL();
       
   604     iRedrawTimer = CPeriodic::NewL( EPriorityRealTime );
       
   605     }
       
   606 
       
   607 // -----------------------------------------------------------------------------
       
   608 //
       
   609 // -----------------------------------------------------------------------------
       
   610 //
       
   611 CListBoxView* CMmGrid::MakeViewClassInstanceL()
       
   612     {
       
   613     return CMmGridView::NewL();
       
   614     }
       
   615 
       
   616 // -----------------------------------------------------------------------------
       
   617 //
       
   618 // -----------------------------------------------------------------------------
       
   619 //
       
   620 CMmGridModel* CMmGrid::MmModel()
       
   621     {
       
   622     return iMmModel;
       
   623     }
       
   624 
       
   625 // -----------------------------------------------------------------------------
       
   626 //
       
   627 // -----------------------------------------------------------------------------
       
   628 //
       
   629 TKeyResponse CMmGrid::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
       
   630     {
       
   631     TKeyEvent eventCopy( aKeyEvent );
       
   632     if ( AknLayoutUtils::LayoutMirrored() )
       
   633         {
       
   634         if ( eventCopy.iCode == EKeyLeftArrow )
       
   635             {
       
   636             eventCopy.iCode = EKeyRightArrow;
       
   637             }
       
   638         else if ( eventCopy.iCode == EKeyRightArrow )
       
   639             {
       
   640             eventCopy.iCode = EKeyLeftArrow;
       
   641             }
       
   642         }
       
   643     return CAknGrid::OfferKeyEventL( eventCopy, aType );
       
   644     }
       
   645 
       
   646 // -----------------------------------------------------------------------------
       
   647 //
       
   648 // -----------------------------------------------------------------------------
       
   649 //
       
   650 void CMmGrid::HandleViewRectSizeChangeL()
       
   651     {
       
   652     if ( !AknLayoutUtils::LayoutMirrored() )
       
   653         {
       
   654         CAknGrid::HandleViewRectSizeChangeL();
       
   655         }
       
   656     else
       
   657         {
       
   658         // for mirrored layout this function should do
       
   659         // exactly the same things as CAknGrid::HandleViewRectSizeChangeL
       
   660         // would do for normal layout
       
   661         iView->CalcBottomItemIndex();
       
   662         if ( CurrentItemIndex() >= 0 )
       
   663             {
       
   664             AdjustTopItemIndex();
       
   665             iView->CalcDataWidth();
       
   666             UpdateScrollBarsL();
       
   667             iView->CalcBottomItemIndex();
       
   668             }
       
   669         }
       
   670     }
       
   671 
       
   672 // -----------------------------------------------------------------------------
       
   673 //
       
   674 // -----------------------------------------------------------------------------
       
   675 //
       
   676 void CMmGrid::AdjustTopItemIndex() const
       
   677     {
       
   678     CAknGridView* view = static_cast<CAknGridView*>( iView );
       
   679     const TInt numOfCols = view->NumberOfColsInView();
       
   680     const TInt numOfRows = view->NumberOfRowsInView();
       
   681     const TInt itemCount = iModel->NumberOfItems();
       
   682 
       
   683     ASSERT( numOfCols > 0 );
       
   684 
       
   685     TInt lastRow = 0;
       
   686     if ( itemCount > 0 )
       
   687         {
       
   688         lastRow = ( itemCount - 1 ) / numOfCols;
       
   689         }
       
   690     TInt maxPossibleTopRow = Max( 0, lastRow - numOfRows + 1 );
       
   691 
       
   692     TInt topRow = TopItemIndex() / numOfCols;
       
   693 
       
   694     if( !( TopItemIndex() % numOfCols == 0
       
   695             && topRow <= maxPossibleTopRow ) )
       
   696         {
       
   697         topRow = Min( topRow, maxPossibleTopRow );
       
   698         SetTopItemIndex( topRow * numOfCols );
       
   699         }
       
   700 
       
   701     // prevent problems with view being scrolled up beyond limits
       
   702     if ( topRow == maxPossibleTopRow && VerticalItemOffset() < 0 )
       
   703         {
       
   704         TRAP_IGNORE(
       
   705                 ( ( CMmWidgetContainer* ) Parent() )->AlignBottomOfViewL() );
       
   706         }
       
   707     }
       
   708 
       
   709 // -----------------------------------------------------------------------------
       
   710 //
       
   711 // -----------------------------------------------------------------------------
       
   712 //
       
   713 void CMmGrid::DoHandleResourceChangeL( TSize& aCellSize,
       
   714         TSize& aViewLayout )
       
   715     {
       
   716     TBool cond = Layout_Meta_Data::IsLandscapeOrientation();
       
   717     TRAPD( err, DoHandleResourceChangeL( cond, aCellSize, aViewLayout ) );
       
   718     if ( err == KErrNotFound )
       
   719         {
       
   720         aViewLayout = iViewLayout;
       
   721         aCellSize = TSize (1,1);
       
   722         }
       
   723     else if ( err == KErrNoMemory )
       
   724         {
       
   725         User::Leave( KErrNoMemory );
       
   726         }
       
   727     }
       
   728 
       
   729 // -----------------------------------------------------------------------------
       
   730 //
       
   731 // -----------------------------------------------------------------------------
       
   732 //
       
   733 void CMmGrid::DoHandleResourceChangeL( TBool aIsLandscape, TSize& aCellSize,
       
   734         TSize& aViewLayout )
       
   735     {
       
   736     CHnSuiteModel* model = iMmModel->MmListBoxModel()->GetSuiteModel();
       
   737     const TDesC8& templ = (model) ? model->GetTemplate() : KNullDesC8();
       
   738     aCellSize = iMmDrawer->TemplateLibrary()->GetSize(
       
   739         EGrid, templ, aIsLandscape, EFalse, iView->ViewRect() );
       
   740     aViewLayout = iMmDrawer->TemplateLibrary()->GetLayoutSizeL(
       
   741         EGrid, templ, aIsLandscape );
       
   742     iViewLayout = aViewLayout;
       
   743     }
       
   744 
       
   745 // -----------------------------------------------------------------------------
       
   746 //
       
   747 // -----------------------------------------------------------------------------
       
   748 //
       
   749 void CMmGrid::SetItemDrawerAndViewBgContext(
       
   750         CAknsBasicBackgroundControlContext * aBgContext )
       
   751     {
       
   752     iMmDrawer->SetBgContext (aBgContext);
       
   753     }
       
   754 
       
   755 // -----------------------------------------------------------------------------
       
   756 //
       
   757 // -----------------------------------------------------------------------------
       
   758 //
       
   759 TBool CMmGrid::HandleScrollbarVisibilityChangeL()
       
   760     {
       
   761     TBool ret = EFalse;
       
   762     if ( AllItemsFitInViewRect() )
       
   763         {
       
   764         if ( ScrollBarFrame()->VerticalScrollBar()->IsVisible()
       
   765              || iMmDrawer->TemplateLibrary()->GetScrollbarVisibility() )
       
   766             {
       
   767             ScrollBarFrame()->VerticalScrollBar()->MakeVisible( EFalse );
       
   768             iMmDrawer->SetScrollbarVisibilityL( EFalse );
       
   769             SetTopItemIndex( 0 );
       
   770             iCurrentTopItemIndex = 0;
       
   771             ret = ETrue;
       
   772             }
       
   773         }
       
   774     else if ( !ScrollBarFrame()->VerticalScrollBar()->IsVisible()
       
   775             || !iMmDrawer->TemplateLibrary()->GetScrollbarVisibility() )
       
   776         {
       
   777         ScrollBarFrame()->VerticalScrollBar()->MakeVisible( ETrue );
       
   778         iMmDrawer->SetScrollbarVisibilityL( ETrue );
       
   779         ret = ETrue;
       
   780         }
       
   781 
       
   782     return ret;
       
   783     }
       
   784 
       
   785 // -----------------------------------------------------------------------------
       
   786 //
       
   787 // -----------------------------------------------------------------------------
       
   788 //
       
   789 
       
   790 TBool CMmGrid::AllItemsFitInViewRect()
       
   791     {
       
   792     if ( iMmModel->NumberOfItems() <= iViewLayout.iWidth * iViewLayout.iHeight
       
   793             || iViewLayout == TSize(0,0) )
       
   794         {
       
   795         return ETrue;
       
   796         }
       
   797     else
       
   798         {
       
   799         return EFalse;
       
   800         }
       
   801     }
       
   802 
       
   803 // -----------------------------------------------------------------------------
       
   804 //
       
   805 // -----------------------------------------------------------------------------
       
   806 //
       
   807 void CMmGrid::UpdateScrollBarsL()
       
   808     {
       
   809     TBool visibilityChanged = HandleScrollbarVisibilityChangeL();
       
   810     if (ScrollBarFrame()->VerticalScrollBar()->IsVisible())
       
   811         {
       
   812         CMmWidgetContainer* widget = static_cast< CMmWidgetContainer* >(Parent());
       
   813         if( widget->IsEditMode() && widget->WidgetPositionCache().iValid )
       
   814             {
       
   815             static_cast<CMmGridView*> ( View() )->SetItemOffsetInPixels(
       
   816                     widget->WidgetPositionCache().iVerticalItemOffset );
       
   817             }
       
   818         CAknGrid::UpdateScrollBarsL();
       
   819         }
       
   820     iCurrentTopItemIndex = TopItemIndex();
       
   821     iMmDrawer->TemplateLibrary()->SetScrollbarWidthL(
       
   822             ScrollBarFrame()->VerticalScrollBar()->Rect().Width() + ScrollBarOffset() );
       
   823     FixViewForMirroredLayout();
       
   824     if ( visibilityChanged )
       
   825         {
       
   826         CMmGridView* view = static_cast<CMmGridView*>( iView );
       
   827         view->UpdateItemHeightAndWidth();
       
   828         }
       
   829     }
       
   830 
       
   831 // -----------------------------------------------------------------------------
       
   832 //
       
   833 // -----------------------------------------------------------------------------
       
   834 //
       
   835 void CMmGrid::SetMarqueeAdapter( CMmMarqueeAdapter* aAdapter )
       
   836     {
       
   837     iMarqueeAdapter = aAdapter;
       
   838     }
       
   839 
       
   840 
       
   841 // -----------------------------------------------------------------------------
       
   842 //
       
   843 // -----------------------------------------------------------------------------
       
   844 //
       
   845 void CMmGrid::SetupLayout()
       
   846     {
       
   847     TRAP_IGNORE( DoSetupLayoutL() );
       
   848     }
       
   849 
       
   850 // -----------------------------------------------------------------------------
       
   851 //
       
   852 // -----------------------------------------------------------------------------
       
   853 //
       
   854 void CMmGrid::DoSetupLayoutL()
       
   855     {
       
   856     TSize cellSize;
       
   857     TSize viewLayout;
       
   858     DoHandleResourceChangeL( cellSize, viewLayout );
       
   859 //  The mirrored layout arabic item lineout ( right to left )
       
   860 //  is handled by CMmGridView::ItemPos( TInt aItemIndex )
       
   861 //  and CMmGridView::XYPosToItemIndex( TPoint aPosition, TInt& aItemIndex )
       
   862     SetLayoutL( EFalse, ETrue /*!AknLayoutUtils::LayoutMirrored()*/, ETrue, viewLayout.iWidth,
       
   863         viewLayout.iHeight, cellSize, 0, 0 );
       
   864     iMmDrawer->SetNumberOfColsInView(
       
   865             static_cast<CMmGridView*>(iView)->NumberOfColsInView() );
       
   866     // setting the top item index when changing orientation
       
   867     TInt cols( static_cast<CMmGridView*>(iView)->NumberOfColsInView() );
       
   868     SetTopItemIndex( ( (TInt) ( iCurrentTopItemIndex / cols ) ) * cols );
       
   869     UpdateScrollBarsL();
       
   870     AknsUtils::RegisterControlPosition( iMmDrawer->FormattedCellData()->Control() );
       
   871     }
       
   872 
       
   873 // -----------------------------------------------------------------------------
       
   874 //
       
   875 // -----------------------------------------------------------------------------
       
   876 //
       
   877 TInt CMmGrid::ScrollBarOffset()
       
   878     {
       
   879     TInt offset = 0;
       
   880     if ( ScrollBarFrame()->ScrollBarExists( CEikScrollBar::EVertical ) )
       
   881         {
       
   882         if ( AknLayoutUtils::LayoutMirrored() )
       
   883             {
       
   884             offset = ScrollBarFrame()->VerticalScrollBar()->Position().iX;
       
   885             }
       
   886         else
       
   887             {
       
   888             offset = View()->ViewRect().Width()
       
   889                     - ( ScrollBarFrame()->VerticalScrollBar()->Position().iX
       
   890                         + ScrollBarFrame()->VerticalScrollBar()->Rect().Width() );
       
   891             }
       
   892         }
       
   893     return offset;
       
   894     }
       
   895 
       
   896 // -----------------------------------------------------------------------------
       
   897 //
       
   898 // -----------------------------------------------------------------------------
       
   899 //
       
   900 void CMmGrid::RedrawScrollbarBackground() const
       
   901     {
       
   902     TRect viewRect( View()->ViewRect() );
       
   903     if ( viewRect.iTl.iX > 0 )
       
   904         {
       
   905         TRect scrollbarRect( TPoint( 0, 0 ),
       
   906                 TSize( viewRect.iTl.iX, viewRect.Height() ) );
       
   907 
       
   908         CWindowGc* gc = iItemDrawer->Gc();
       
   909         CMmListBoxItemDrawer* itemDrawer =
       
   910                 static_cast<CMmListBoxItemDrawer*>( iItemDrawer );
       
   911         MAknsSkinInstance *skin = AknsUtils::SkinInstance();
       
   912         CCoeControl* control = itemDrawer->FormattedCellData()->Control();
       
   913         MAknsControlContext *cc = AknsDrawUtils::ControlContext( control );
       
   914         if( gc )
       
   915             {
       
   916             if ( control )
       
   917                 {
       
   918                 AknsDrawUtils::Background( skin, cc, control, *gc, scrollbarRect );
       
   919                 }
       
   920             else
       
   921                 {
       
   922                 gc->SetBrushColor( BackColor() );
       
   923                 gc->Clear( scrollbarRect );
       
   924                 }
       
   925             }
       
   926         }
       
   927     }
       
   928 
       
   929 // -----------------------------------------------------------------------------
       
   930 //
       
   931 // -----------------------------------------------------------------------------
       
   932 //
       
   933 void CMmGrid::ProcessScrollEventL( CEikScrollBar* aScrollBar,
       
   934             TEikScrollEvent aEventType )
       
   935     {
       
   936     CAknGrid::HandleScrollEventL( aScrollBar, aEventType );
       
   937     iCurrentTopItemIndex = TopItemIndex();
       
   938 
       
   939     // setting default highlight in order not to overwrite the top item index
       
   940     // set before in the SetLayout method
       
   941     CMmWidgetContainer* parent = static_cast< CMmWidgetContainer* > ( Parent() );
       
   942     if (!parent->IsHighlightVisible())
       
   943          {
       
   944          parent->SetDefaultHighlightL( EFalse );
       
   945 
       
   946 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   947          MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal(
       
   948                  static_cast<CMmGridView*>(iView)->Gc() );
       
   949          TBool effects = transApi && !transApi->EffectsDisabled();
       
   950          if ( effects && aEventType == EEikScrollPageUp ||
       
   951                  aEventType == EEikScrollPageDown )
       
   952              {
       
   953              DrawNow();
       
   954              }
       
   955 #endif
       
   956 
       
   957          }
       
   958     }
       
   959 
       
   960 // -----------------------------------------------------------------------------
       
   961 //
       
   962 // -----------------------------------------------------------------------------
       
   963 //
       
   964 void CMmGrid::HandleRedrawTimerEventL()
       
   965     {
       
   966     if ( iSkippedScrollbarEventsCount )
       
   967         {
       
   968         ProcessScrollEventL( ScrollBarFrame()->VerticalScrollBar(),
       
   969                 EEikScrollThumbDragVert );
       
   970         }
       
   971     iSkippedScrollbarEventsCount = 0;
       
   972     }
       
   973 
       
   974 // -----------------------------------------------------------------------------
       
   975 //
       
   976 // -----------------------------------------------------------------------------
       
   977 //
       
   978 TInt CMmGrid::RedrawTimerCallback( TAny* aPtr )
       
   979     {
       
   980     CMmGrid* self = static_cast<CMmGrid*>( aPtr );
       
   981     TRAP_IGNORE( self->HandleRedrawTimerEventL() );
       
   982     // Do not bother returning a meaningful error code, CPeriodic will ignore it
       
   983     // anyway.
       
   984     return 0;
       
   985     }
       
   986 
       
   987 // -----------------------------------------------------------------------------
       
   988 //
       
   989 // -----------------------------------------------------------------------------
       
   990 //
       
   991 void CMmGrid::SetVerticalItemOffset(TInt aOffset)
       
   992   {
       
   993   static_cast<CMmGridView*> (View())->SetItemOffsetInPixels(aOffset);
       
   994   UpdateScrollBarThumbs();
       
   995   }
       
   996 
       
   997 // -----------------------------------------------------------------------------
       
   998 //
       
   999 // -----------------------------------------------------------------------------
       
  1000 //
       
  1001 TInt CMmGrid::VerticalItemOffset() const
       
  1002   {
       
  1003   return static_cast<CMmGridView*> (View())->VerticalItemOffset();
       
  1004   }
       
  1005 
       
  1006 // -----------------------------------------------------------------------------
       
  1007 //
       
  1008 // -----------------------------------------------------------------------------
       
  1009 //
       
  1010 void CMmGrid::SetItemHeight( TInt aItemHeight )
       
  1011   {
       
  1012   iItemHeight = aItemHeight;
       
  1013   }
       
  1014 
       
  1015 // -----------------------------------------------------------------------------
       
  1016 //
       
  1017 // -----------------------------------------------------------------------------
       
  1018 //
       
  1019 void CMmGrid::UpdateScrollBarThumbs()
       
  1020     {
       
  1021     CAknGrid::UpdateScrollBarThumbs();
       
  1022     }
       
  1023 
       
  1024 // -----------------------------------------------------------------------------
       
  1025 //
       
  1026 // -----------------------------------------------------------------------------
       
  1027 //
       
  1028 TInt CMmGrid::CountComponentControls() const
       
  1029     {
       
  1030     TInt componentControls(0);
       
  1031     if ( !iDisableChildComponentDrawing )
       
  1032       {
       
  1033         componentControls = CAknGrid::CountComponentControls();
       
  1034       }
       
  1035     return componentControls;
       
  1036     }
       
  1037 // -----------------------------------------------------------------------------
       
  1038 //
       
  1039 // -----------------------------------------------------------------------------
       
  1040 //
       
  1041 void CMmGrid::SetDisableChildComponentDrawing( TBool aDisable )
       
  1042     {
       
  1043     iDisableChildComponentDrawing = aDisable;
       
  1044     }
       
  1045 //End of file