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