--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/ganes/src/HgGrid.cpp Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,792 @@
+/*
+* Copyright (c) 2009 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:
+*
+*/
+
+
+// INCLUDE FILES
+#include <ganes/HgGrid.h>
+#include <ganes/HgItem.h>
+
+#include "HgLayoutData.h"
+#include "HgIndicatorManager.h"
+#include "HgDrawUtils.h"
+
+
+#include <aknphysics.h>
+
+#include "HgConstants.h"
+
+#include <AknIconUtils.h>
+#include <avkon.mbg>
+#include <AknUtils.h>
+#include <AknsUtils.h>
+#include <AknsDrawUtils.h>
+#include <AknsConstants.h>
+#include <gulicon.h>
+#include <AknUtils.h>
+
+#include <layoutmetadata.cdl.h>
+#include <aknlayoutscalable_apps.cdl.h>
+#include <aknlayoutscalable_avkon.cdl.h>
+
+using namespace AknLayoutScalable_Apps;
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CHgGrid::NewL()
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CHgGrid* CHgGrid::NewL (
+ const TRect& aRect,
+ TInt aItemCount,
+ CGulIcon* aDefaultIcon,
+ RWsSession* aSession )
+ {
+ CHgGrid* self = new ( ELeave ) CHgGrid(
+ aItemCount,
+ aDefaultIcon);
+ CleanupStack::PushL (self );
+ self->ConstructL( aRect, aSession );
+ CleanupStack::Pop (self );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CHgGrid::ConstructL()
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CHgGrid::ConstructL (const TRect& aRect, RWsSession* aSession )
+ {
+ TAknLayoutScalableParameterLimits limits = cell_gallery2_pane_ParamLimits(0);
+ TInt cols = limits.LastColumn() + 1;
+ iLayoutData = CHgGridLayoutData::NewL( cols );
+
+ CHgScroller::ConstructL( aRect, aSession );
+
+ // Activate the window, which makes it ready to be drawn
+ ActivateL ( );
+ }
+
+// -----------------------------------------------------------------------------
+// CHgGrid::CHgGrid()
+// C++ default constructor can NOT contain any code, that might leave.
+// -----------------------------------------------------------------------------
+//
+CHgGrid::CHgGrid(
+ TInt aItemCount,
+ CGulIcon* aDefaultIcon )
+: CHgScroller( aItemCount, aDefaultIcon )
+ {
+ // No implementation required
+ }
+
+// -----------------------------------------------------------------------------
+// CHgGrid::~CHgGrid()
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CHgGrid::~CHgGrid ( )
+ {
+ delete iLayoutData;
+ }
+
+// -----------------------------------------------------------------------------
+// CHgGrid::PreferredImageSize()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TSize CHgGrid::PreferredImageSize()
+ {
+ TAknLayoutRect gridAppPane;
+ TAknLayoutRect gridItem;
+ TAknLayoutRect gridImage;
+
+ gridAppPane.LayoutRect( TRect(), grid_gallery2_pane(0));
+ gridItem.LayoutRect( gridAppPane.Rect(), cell_gallery2_pane(1, 0, 0));
+ gridImage.LayoutRect(gridItem.Rect(), cell_gallery2_pane_g2(1));
+
+ return gridImage.Rect().Size();
+ }
+
+// -----------------------------------------------------------------------------
+// CHgGrid::InitItemsL()
+// -----------------------------------------------------------------------------
+//
+void CHgGrid::InitItemsL()
+ {
+ for(TInt i = 0; i < iItemCount; ++i)
+ {
+ iItems.Append( CHgItem::NewL() );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CHgGrid::DoDraw()
+// -----------------------------------------------------------------------------
+//
+void CHgGrid::DoDraw (const TRect& /*aRect*/) const
+ {
+ // Get the standard graphics context
+ TInt xdiff = (iViewPosition.iX-(iWidth/2))% (iLandscapeScrolling ? iRowHeight : iRowWidth);
+ TInt ydiff = (iViewPosition.iY-(iHeight/2))%( iLandscapeScrolling ? iRowWidth : iRowHeight);
+
+ if( iItemCount == 0 )
+ {
+ TRgb color( KRgbBlack );
+ if ( AknsUtils::AvkonSkinEnabled() )
+ {
+ AknsUtils::GetCachedColor( AknsUtils::SkinInstance(),
+ color,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG6 );
+ }
+ if( iEmptyText )
+ iDrawUtils->DrawEmptyText(SystemGc(), Rect(), *iEmptyText, color);
+ }
+ else
+ {
+ TAknLayoutRect gridAppPane;
+ gridAppPane.LayoutRect( GridRect(), iLayoutData->ItemLayout() );
+
+ if( iLandscapeScrolling )
+ {
+ if( AknLayoutUtils::LayoutMirrored() )
+ {
+ for(TInt i = iCurrentRow; i < iCols; ++i)
+ {
+ TInt xPos = - (((i-iCurrentRow)*iRowHeight) - xdiff);
+ if( i < 0 )
+ continue;
+ else if( xPos < -iWidth )
+ break;
+
+ DrawRows( i, gridAppPane.Rect(), xPos );
+ }
+ }
+ else
+ {
+ for(TInt i = iCurrentRow; i < iCols; ++i)
+ {
+ TInt xPos = ((i-iCurrentRow)*iRowHeight) - xdiff;
+ if( i < 0 )
+ continue;
+ else if( xPos > iWidth )
+ break;
+
+ DrawRows( i, gridAppPane.Rect(), xPos );
+ }
+ }
+ }
+ else
+ {
+ for(TInt i = iCurrentRow; i < iRows; ++i)
+ {
+ TInt yPos = ((i-iCurrentRow)*iRowHeight) - ydiff;
+ if( i < 0 )
+ continue;
+ else if( yPos > iHeight )
+ break;
+
+ DrawCols( i, gridAppPane.Rect(), yPos );
+ }
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CHgGrid::DrawRows()
+// -----------------------------------------------------------------------------
+//
+void CHgGrid::DrawRows( TInt aCol, const TRect& aRect, TInt aXPos ) const
+ {
+ for(TInt j = 0; j < iRows; ++j)
+ {
+ TInt index = aCol*iRows + j;
+ if( index < iItems.Count())
+ {
+ TAknLayoutRect gridItem;
+ gridItem.LayoutRect( aRect,iLayoutData->ColumnLayout(j) );
+
+ TRect rect(gridItem.Rect());
+ rect.Move( aXPos, 0 );
+
+ DrawItem( index, rect );
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CHgGrid::DrawCols()
+// -----------------------------------------------------------------------------
+//
+void CHgGrid::DrawCols(TInt aRow, const TRect& aRect, TInt aYPos) const
+ {
+ for(TInt j = 0; j < iCols; ++j)
+ {
+ TInt index = aRow*iCols + j;
+ if( index < iItems.Count())
+ {
+ TAknLayoutRect gridItem;
+ gridItem.LayoutRect( aRect,iLayoutData->ColumnLayout(j) );
+
+ TRect rect(gridItem.Rect());
+ rect.Move( 0, aYPos );
+
+ DrawItem( index, rect );
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CHgGrid::DoDraw()
+// -----------------------------------------------------------------------------
+//
+void CHgGrid::DrawItem(TInt aIndex, const TRect& aRect ) const
+ {
+ CHgItem* item = iItems[aIndex];
+ CGulIcon* icon = item->Icon() ? item->Icon() : iDefaultIcon;
+
+ if( aIndex == iSelectedIndex )
+ {
+ DrawHighlight(aRect);
+ }
+
+ CWindowGc& gc = SystemGc();
+
+ iDrawUtils->DrawImage(gc, aRect, iLayoutData->IconLayout(), *icon);
+
+ // Draw the indicators.
+ iIndicatorManager->DrawIndicators(
+ gc,
+ aRect,
+ item->Flags(),
+ iLayoutData->FirstIndicatorLayout(),
+ iLayoutData->SecondIndicatorLayout() );
+ }
+
+// -----------------------------------------------------------------------------
+// CHgGrid::HandleSizeChanged()
+// -----------------------------------------------------------------------------
+//
+void CHgGrid::HandleSizeChanged ( )
+ {
+ iLandscapeScrolling = Layout_Meta_Data::IsLandscapeOrientation() && iLandScapeScrollingSupported;
+
+ TInt oldCount = iLandscapeScrolling ? iRows : iCols;
+
+ CalculateSizes();
+
+ if( iLandscapeScrolling )
+ {
+ iCols = iItemCount / iRows;
+ if(iItemCount%iRows)
+ {
+ ++iCols; // partially filled col
+ }
+
+ iItemsOnScreen = iWidth / iRowHeight;
+ if((iWidth % iRowHeight))
+ iItemsOnScreen += 2;
+ else
+ iItemsOnScreen++;
+
+ iItemsOnScreen *= iRows;
+
+ if( oldCount != iRows )
+ {
+ FitTopItemToView( iCurrentRow*oldCount );
+ }
+ }
+ else
+ {
+ iRows = iItemCount / iCols;
+ if(iItemCount%iCols)
+ {
+ ++iRows; // partially filled row
+ }
+
+ iItemsOnScreen = iHeight / iRowHeight;
+ if((iHeight % iRowHeight))
+ iItemsOnScreen += 2;
+ else
+ iItemsOnScreen++;
+
+ iItemsOnScreen *= iCols;
+
+ if( oldCount != iCols )
+ {
+ FitTopItemToView( iCurrentRow*oldCount );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CHgGrid::CalculateSizes()
+// -----------------------------------------------------------------------------
+//
+void CHgGrid::CalculateSizes()
+ {
+ // Count number of visible rows
+ // First is checked if 3x4 or 4x3 items fits to the grid.
+ TInt variety = Layout_Meta_Data::IsLandscapeOrientation() ? 1 : 0;
+
+ TAknLayoutScalableParameterLimits limits = cell_gallery2_pane_ParamLimits(variety);
+ iCols = limits.LastColumn() + 1;
+ iRows = limits.LastRow() + 1;
+
+ iLayoutData->ChangeCols( iCols );
+
+ iLayoutData->SetBaseLayout(main_gallery2_pane(0));
+ iLayoutData->SetItemLayout(grid_gallery2_pane(variety));
+ iLayoutData->SetIconLayout(cell_gallery2_pane_g2(variety));
+
+ for(TInt i = 0; i < iCols; ++i)
+ {
+ if( iLandscapeScrolling )
+ {
+ iLayoutData->SetColumnLayout(i, cell_gallery2_pane(variety, 0, i));
+ }
+ else
+ {
+ iLayoutData->SetColumnLayout(i, cell_gallery2_pane(variety, i, 0));
+ }
+ }
+ iLayoutData->SetFirstIndicatorLayout(cell_gallery2_pane_g5(variety));
+ iLayoutData->SetSecondIndicatorLayout(cell_gallery2_pane_g4(variety));
+
+ TAknLayoutRect gridAppPane;
+ TAknLayoutRect gridItem;
+ TAknLayoutRect gridImage;
+
+ gridAppPane.LayoutRect( GridRect(), iLayoutData->ItemLayout());
+ gridItem.LayoutRect( gridAppPane.Rect(), iLayoutData->ColumnLayout(0));
+ gridImage.LayoutRect( gridItem.Rect(), iLayoutData->IconLayout());
+
+ if( iLandscapeScrolling )
+ {
+ iRowHeight = gridItem.Rect().Width();
+ iRowWidth = gridItem.Rect().Height();
+ }
+ else
+ {
+ iRowHeight = gridItem.Rect().Height();
+ iRowWidth = gridItem.Rect().Width();
+ }
+
+ iImageSize = gridImage.Rect().Size();
+
+ TAknLayoutRect indicator;
+ indicator.LayoutRect( gridItem.Rect(), iLayoutData->FirstIndicatorLayout() );
+ iIndicatorSize = indicator.Rect().Size();
+ }
+
+// -----------------------------------------------------------------------------
+// CHgGrid::GetSelected()
+// -----------------------------------------------------------------------------
+//
+TInt CHgGrid::GetSelected( TPoint aPosition ) const
+ {
+ TAknLayoutRect gridAppPane;
+ gridAppPane.LayoutRect( GridRect(), iLayoutData->ItemLayout());
+ aPosition -= gridAppPane.Rect().iTl;
+
+ TInt index = 0;
+ if( iLandscapeScrolling )
+ {
+ TInt y = aPosition.iY + ((iViewPosition.iY - (iHeight/2)) % iRowWidth);
+ y /= iRowWidth;
+ TInt x = 0;
+ if( AknLayoutUtils::LayoutMirrored() )
+ {
+ x = aPosition.iX - ((iViewPosition.iX - (iWidth/2)) % iRowHeight);
+
+ if(x < 0) // to correct the division
+ x-= iRowHeight;
+ x /= iRowHeight;
+ x = ((iWidth / iRowHeight) - 1) - x; // mirrored correction to x
+ }
+ else
+ {
+ x = aPosition.iX + ((iViewPosition.iX - (iWidth/2)) % iRowHeight);
+ x /= iRowHeight;
+ }
+ index = (iCurrentRow*iRows) + (x*iRows) + y;
+ }
+ else
+ {
+ TInt x = aPosition.iX + ((iViewPosition.iX - (iWidth/2)) % iRowWidth);
+ TInt y = aPosition.iY + ((iViewPosition.iY - (iHeight/2)) % iRowHeight);
+ x /= iRowWidth;
+ y /= iRowHeight;
+
+ if( AknLayoutUtils::LayoutMirrored() )
+ {
+ x = (iCols - 1) - x;
+ }
+
+ index = (iCurrentRow*iCols) + (y*iCols) + x;
+ }
+
+
+ return index >= iItems.Count() || index < 0 ? KErrNotFound : index;
+ }
+
+// -----------------------------------------------------------------------------
+// CHgGrid::TotalSize()
+// -----------------------------------------------------------------------------
+//
+TSize CHgGrid::TotalSize() const
+ {
+ return iLandscapeScrolling ? TSize( iCols*iRowHeight, iHeight ) : TSize(iWidth, iRows*iRowHeight);
+ }
+
+// -----------------------------------------------------------------------------
+// CHgGrid::DrawHighlight()
+// -----------------------------------------------------------------------------
+//
+void CHgGrid::DrawHighlight( const TRect& aOuterRect ) const
+ {
+ TRect innerRect( aOuterRect );
+ innerRect.Shrink(2,2);
+
+ CWindowGc& gc = SystemGc();
+
+ if( HasHighlight() )
+ {
+ if( iPointerDown && !iPanning && iFocusedIndex != KErrNotFound && iSelectionToFocusedItem )
+ {
+ AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(),
+ gc,
+ aOuterRect,
+ innerRect,
+ KAknsIIDQsnFrGridPressed,
+ KAknsIIDQsnFrGridCenterPressed );
+ }
+ else
+ {
+ AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(),
+ gc,
+ aOuterRect,
+ innerRect,
+ KAknsIIDQsnFrGrid,
+ KAknsIIDQsnFrGridCenter );
+ }
+ }
+ else if( iPointerDown && !iPanning )
+ {
+ AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(),
+ gc,
+ aOuterRect,
+ innerRect,
+ KAknsIIDQsnFrGrid,
+ KAknsIIDQsnFrGridCenter );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CHgGrid::DoHandleKeyEvent()
+// -----------------------------------------------------------------------------
+//
+TBool CHgGrid::DoHandleKeyEvent( const TKeyEvent& aEvent )
+ {
+ TBool ret = ETrue;
+ switch( aEvent.iCode )
+ {
+ case EKeyUpArrow:
+ HandleUpArrow();
+ break;
+ case EKeyDownArrow:
+ HandleDownArrow();
+ break;
+ case EKeyLeftArrow:
+ HandleLeftArrow();
+ break;
+ case EKeyRightArrow:
+ HandleRightArrow();
+ break;
+ default:
+ ret = EFalse;
+ break;
+ }
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CHgGrid::HandleDownArrow()
+// -----------------------------------------------------------------------------
+//
+void CHgGrid::HandleDownArrow()
+ {
+ if( iSelectedIndex == KErrNotFound )
+ {
+ SelectDefaultItem();
+ }
+ else
+ {
+ if( iLandscapeScrolling )
+ {
+ ChangeSelectedIndex( 1 );
+ }
+ else
+ {
+ ChangeSelectedIndex( iCols );
+ }
+ FitSelectionToView();
+ SelectionChanged();
+ DrawDeferred();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CHgGrid::GridRect()
+// -----------------------------------------------------------------------------
+//
+TRect CHgGrid::GridRect() const
+ {
+ TAknLayoutRect listscrollAppPane;
+ listscrollAppPane.LayoutRect( Rect(), iLayoutData->BaseLayout());
+ return listscrollAppPane.Rect();
+ }
+
+// -----------------------------------------------------------------------------
+// CHgGrid::HandleUpArrow()
+// -----------------------------------------------------------------------------
+//
+void CHgGrid::HandleUpArrow()
+ {
+ if( iSelectedIndex == KErrNotFound )
+ {
+ SelectDefaultItem();
+ }
+ else
+ {
+ if( iLandscapeScrolling )
+ {
+ ChangeSelectedIndex( -1 );
+ }
+ else
+ {
+ ChangeSelectedIndex( -iCols );
+ }
+ FitSelectionToView();
+ SelectionChanged();
+ DrawDeferred();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CHgGrid::HandleRightArrow()
+// -----------------------------------------------------------------------------
+//
+void CHgGrid::HandleRightArrow()
+ {
+ if( iSelectedIndex == KErrNotFound )
+ {
+ SelectDefaultItem();
+ }
+ else
+ {
+ if( iLandscapeScrolling )
+ {
+ TInt change = AknLayoutUtils::LayoutMirrored() ? -iRows : iRows;
+ ChangeSelectedIndex( change );
+ }
+ else
+ {
+ ChangeSelectedIndex( 1 );
+ }
+ FitSelectionToView();
+ SelectionChanged();
+ DrawDeferred();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CHgGrid::HandleLeftArrow()
+// -----------------------------------------------------------------------------
+//
+void CHgGrid::HandleLeftArrow()
+ {
+ if( iSelectedIndex == KErrNotFound )
+ {
+ SelectDefaultItem();
+ }
+ else
+ {
+ if( iLandscapeScrolling )
+ {
+ TInt change = AknLayoutUtils::LayoutMirrored() ? iRows : -iRows;
+ ChangeSelectedIndex( change );
+ }
+ else
+ {
+ ChangeSelectedIndex( -1 );
+ }
+ FitSelectionToView();
+ SelectionChanged();
+ DrawDeferred();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CHgGrid::FitSelectionToView()
+// -----------------------------------------------------------------------------
+//
+void CHgGrid::FitSelectionToView()
+ {
+ const TInt index = iLandscapeScrolling ?
+ iSelectedIndex/iRows : iSelectedIndex/iCols;
+ FitRowToView( index );
+ }
+
+// -----------------------------------------------------------------------------
+// CHgGrid::SelectDefaultItem()
+// -----------------------------------------------------------------------------
+//
+void CHgGrid::SelectDefaultItem()
+ {
+ iSelectedIndex = CurrentIndex();
+ FitSelectionToView();
+ DrawDeferred();
+ }
+
+// -----------------------------------------------------------------------------
+// CHgGrid::CurrentIndex()
+// -----------------------------------------------------------------------------
+//
+TInt CHgGrid::CurrentIndex()
+ {
+ return iLandscapeScrolling ? iCurrentRow * iRows : iCurrentRow * iCols;
+ }
+
+// -----------------------------------------------------------------------------
+// CHgGrid::IsDisplayed()
+// -----------------------------------------------------------------------------
+//
+TBool CHgGrid::IsDisplayed( TInt aIndex )
+ {
+ TInt start = CurrentIndex();
+ TInt end = start + iItemsOnScreen;
+ return aIndex >= start && aIndex < end;
+ }
+
+// -----------------------------------------------------------------------------
+// CHgGrid::FitTopItemToView()
+// -----------------------------------------------------------------------------
+//
+void CHgGrid::FitTopItemToView( TInt aIndex )
+ {
+ if( iLandscapeScrolling )
+ {
+ // Higlighted item is set to top of the list
+ const TInt newCol = aIndex/iRows;
+ TInt newPos = newCol*iRowWidth + iWidth/2;
+
+ if( ItemsOnScreen() >= iItems.Count() )
+ {
+ newPos = iWidth/2;
+ }
+ else
+ {
+ const TInt endMid = TotalSize().iWidth - iWidth/2;
+ if( newPos > endMid )
+ {
+ // We are presenting last items in the list
+ newPos = endMid;
+ }
+ }
+
+ iViewPosition.iX = newPos;
+ }
+ else
+ {
+ // Higlighted item is set to top of the list
+ const TInt newRow = aIndex/iCols;
+ TInt newPos = newRow*iRowHeight + iHeight/2;
+
+ if( ItemsOnScreen() >= iItems.Count() )
+ {
+ newPos = iHeight/2;
+ }
+ else
+ {
+ const TInt endMid = TotalSize().iHeight - iHeight/2;
+ if( newPos > endMid )
+ {
+ // We are presenting last items in the list
+ newPos = endMid;
+ }
+ }
+
+ iViewPosition.iY = newPos;
+ }
+
+ HandleViewPositionChanged();
+ }
+
+// -----------------------------------------------------------------------------
+// CHgGrid::SetLandscapeScrollingSupport()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CHgGrid::SetLandscapeScrollingSupport( TBool aSupportLandscapeScrolling )
+ {
+ iLandScapeScrollingSupported = aSupportLandscapeScrolling;
+ }
+
+void CHgGrid::ChangeSelectedIndex( TInt aMove )
+ {
+ TInt nextIndex = 0;
+ if( iSelectedIndex + aMove > iItems.Count() - 1 )
+ {
+ // go to beginning
+ nextIndex = 0;
+ }
+ else if( iSelectedIndex + aMove < 0 )
+ {
+ // go to end
+ nextIndex = iItems.Count() - 1;
+ }
+ else
+ {
+ nextIndex = iSelectedIndex + aMove;
+ }
+
+ if( iSelectionMode == ESelectionMark )
+ {
+ Mark( iSelectedIndex );
+ Mark( nextIndex );
+ }
+ else if( iSelectionMode == ESelectionUnMark )
+ {
+ UnMark( iSelectedIndex );
+ UnMark( nextIndex );
+ }
+
+ iSelectedIndex = nextIndex;
+ }
+
+// End of File