diff -r 5f0182e07bfb -r 5456b4e8b3a8 menufw/menufwui/mmwidgets/src/mmgrid.cpp --- /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 +#include +#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 +#include +#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(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(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( + View()->ItemDrawer() )->EnableCachedDataUse( ETrue ); + iRedrawTimer->Start( KScrollingRedrawInterval, KScrollingRedrawInterval, + TCallBack( &CMmGrid::RedrawTimerCallback, static_cast( this ) ) ); + } + else if ( aEventType == EEikScrollThumbReleaseVert ) + { + iScrollbarThumbIsBeingDragged = EFalse; + static_cast( + 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( 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( 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( 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( 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( 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( 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 ( View() )->SetItemOffsetInPixels( + widget->WidgetPositionCache().iVerticalItemOffset ); + } + CAknGrid::UpdateScrollBarsL(); + } + iCurrentTopItemIndex = TopItemIndex(); + iMmDrawer->TemplateLibrary()->SetScrollbarWidthL( + ScrollBarFrame()->VerticalScrollBar()->Rect().Width() + ScrollBarOffset() ); + FixViewForMirroredLayout(); + if ( visibilityChanged ) + { + CMmGridView* view = static_cast( 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(iView)->NumberOfColsInView() ); + // setting the top item index when changing orientation + TInt cols( static_cast(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( 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(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( 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 (View())->SetItemOffsetInPixels(aOffset); + UpdateScrollBarThumbs(); + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +TInt CMmGrid::VerticalItemOffset() const + { + return static_cast (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