diff -r 000000000000 -r 094583676ce7 wvuing/wvuiave/AppSrc/CCASmileIconGrid.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wvuing/wvuiave/AppSrc/CCASmileIconGrid.cpp Thu Dec 17 08:41:52 2009 +0200 @@ -0,0 +1,713 @@ +/* +* 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: Grid for smile icons +* +*/ + + +// INCLUDE FILES +#include "CCASmileIconGrid.h" +#include "IMSmileUtilityNG.hrh" +#include "layoutDebugPrint.h" +#include "mcatapeventobserver.h" +#include "catouchutils.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +// CONSTANTS +// Max amount of rows and colums in grid +const TInt KMaxGridColumnCount( 7 ); +const TInt KMaxGridRowCount( 7 ); + +// ================= MEMBER FUNCTIONS ======================= + +// Two-phased constructor. +CCASmileIconGrid* CCASmileIconGrid::NewL( CEikDialog* aParent, + const RPointerArray& aIconArray ) + { + CCASmileIconGrid* self = new ( ELeave ) CCASmileIconGrid( aParent, + aIconArray ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// destructor +CCASmileIconGrid::~CCASmileIconGrid() + { + } + +// C++ constructor can NOT contain any code, that +// might leave. +// +CCASmileIconGrid::CCASmileIconGrid( CEikDialog* aParent, + const RPointerArray& aIconArray ) + : iParent( aParent ), iIconArray( aIconArray ) + { + } + +// default constructor can leave. +void CCASmileIconGrid::ConstructL() + { + iIconCount = iIconArray.Count(); + + iIsMirrored = ETrue ; + SetContainerWindowL( *iParent ); + } + + +// --------------------------------------------------------- +// CCASmileIconGrid::MoveCursor +// Move cursor and redraw highlight. +// Called when arrow-key is pressed. +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCASmileIconGrid::MoveCursor( TInt aKeyCode ) + { + iPrevCursorPos = iCursorPos; + + switch ( aKeyCode ) + { + case EKeyLeftArrow: + { + if ( AknLayoutUtils::LayoutMirrored() ) + { + iCursorPos++; + if ( iCursorPos >= iIconCount ) + { + iCursorPos = 0; + } + } + else + { + iCursorPos--; + if ( iCursorPos < 0 ) + { + iCursorPos = iIconCount - 1; + } + } + break; + } + case EKeyRightArrow: + { + if ( AknLayoutUtils::LayoutMirrored() ) + { + iCursorPos--; + if ( iCursorPos < 0 ) + { + iCursorPos = iIconCount - 1; + } + } + else + { + iCursorPos++; + if ( iCursorPos >= iIconCount ) + { + iCursorPos = 0; + } + } + break; + } + case EKeyUpArrow: + { + if ( iCursorPos < iMaxColumns ) + { + iCursorPos += ( iRowCount * iMaxColumns ) - 1; + + if ( iCursorPos >= iIconCount ) + { + iCursorPos -= iMaxColumns; + } + + if ( iCursorPos < 0 ) + { + iCursorPos = iIconCount - 1; + } + } + else + { + iCursorPos -= iMaxColumns; + } + break; + } + case EKeyDownArrow: + { + if ( iCursorPos < ( iIconCount - iMaxColumns ) ) + { + iCursorPos += iMaxColumns; + } + else + { + iCursorPos %= iMaxColumns; + iCursorPos++; + if ( iCursorPos >= iMaxColumns || + iCursorPos >= iIconCount ) + { + iCursorPos = 0; + } + } + break; + } + default: + { + return; + } + } + + DrawNow(); + } + +// --------------------------------------------------------- +// CCASmileIconGrid::SelectedBitmapId +// Called when OK-key or Select-softkey is pressed. +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCASmileIconGrid::SelectedBitmapId() + { + return iCursorPos; + } + +// --------------------------------------------------------- +// CCASmileIconGrid::HeightInRows +// Return row count of grid. +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCASmileIconGrid::HeightInRows() + { + return iRowCount; + } + +// --------------------------------------------------------- +// CCASmileIconGrid::SetLayout +// Set layout of identifier grid. +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCASmileIconGrid::SetLayout() + { + iIsMirrored = AknLayoutUtils::LayoutMirrored() ; + + // popup_grid_graphic_window (Parent) + TRect parentRect( iParent->Rect() ); + LAYOUT_DP_RECT( "CCASmileIconGrid popup_grid_graphic_window (parent)", + parentRect ); + + // listscroll_popup_graphic_pane (this compoment) + TAknLayoutRect listLayoutRect; + listLayoutRect.LayoutRect( + parentRect, + AknLayoutScalable_Avkon::listscroll_popup_graphic_pane() ); + LAYOUT_DP_RECT( "CCASmileIconGrid listscroll_popup_graphic_pane", + listLayoutRect.Rect() ); + + // grid_graphic_popup_pane + TAknLayoutRect gridLayoutRect; + gridLayoutRect.LayoutRect( + listLayoutRect.Rect(), + AknLayoutScalable_Avkon::grid_graphic_popup_pane( 0 ) ); + LAYOUT_DP_RECT( "CCASmileIconGrid grid_graphic_popup_pane", + gridLayoutRect.Rect() ); + + // cell_graphic_popup_pane (upper left cell) + TAknLayoutRect oneCellRect; + oneCellRect.LayoutRect( + gridLayoutRect.Rect(), + AknLayoutScalable_Avkon::cell_graphic_popup_pane( 0, 0, 0 ) ); + LAYOUT_DP_RECT( "CCASmileIconGrid cell_graphic_popup_pane", + oneCellRect.Rect() ); + + iFirstCell = oneCellRect.Rect(); + iCellWidth = iFirstCell.Width(); + iCellHeight = iFirstCell.Height(); + + TAknLayoutRect myIconRect; + myIconRect.LayoutRect( + iFirstCell, + AknLayoutScalable_Avkon::cell_graphic2_pane_g5( 0 ) ); + + iIconSize = myIconRect.Rect().Size(); + } + +// --------------------------------------------------------- +// CCASmileIconGrid::MinimumSize +// Return minimum size to use the control. +// (other items were commented in a header). +// --------------------------------------------------------- +// +TSize CCASmileIconGrid::MinimumSize() + { + TAknLayoutRect gridRect; + gridRect.LayoutRect( + iParent->Rect(), + AknLayoutScalable_Avkon::listscroll_popup_graphic_pane() ); + + LAYOUT_DP_RECT( "CCASmileIconGrid::MinimumSize()", gridRect.Rect() ); + return gridRect.Rect().Size(); + } + +// --------------------------------------------------------- +// CCASmileIconGrid::SizeChanged +// Control rectangle is set. +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCASmileIconGrid::SizeChanged() + { + LAYOUT_DP_RECT( "CCASmileIconGrid::SizeChanged CCoeControl", Rect() ); + SetLayout(); + + TInt iconCount( iIconArray.Count() ); + for ( TInt i = 0; i < iconCount; i++ ) + { + AknIconUtils::SetSize( iIconArray[i]->Bitmap(), + iIconSize ); + + } + } + +// --------------------------------------------------------- +// CCASmileIconGrid::HandleResourceChange +// Notifier for changing layout +// (other items were commented in a header). +// --------------------------------------------------------- +// + +void CCASmileIconGrid::HandleResourceChange( TInt aType ) + { + if ( aType == KEikDynamicLayoutVariantSwitch ) + { + SetLayout(); + } + else + { + CCoeControl::HandleResourceChange( aType ); + } + } + + +// --------------------------------------------------------- +// CCASmileIconGrid::Draw +// Drawing control. +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCASmileIconGrid::Draw( const TRect& /* aRect */ ) const + { + CWindowGc& gc = SystemGc(); + + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + MAknsControlContext* cc = AknsDrawUtils::ControlContext( this ); + + if ( !iDragEvent ) + { + //draw the grid + gc.SetPenStyle( CGraphicsContext::ESolidPen ); + gc.SetBrushStyle( CGraphicsContext::ENullBrush ); + gc.SetPenSize( TSize( 1, 1 ) ); + gc.SetPenColor( AKN_LAF_COLOR( 215 ) ); + + // For some reason the dialog does not draw it's background + // completely, so we'll have to do it here. + // This should work with bgRect = Rect(), but it doesn't. + // Change this if you know how it should be done. + TRect bgRect = iParent->Rect(); + bgRect.iTl.iY = Rect().iTl.iY; + // --- + + TBool skins = AknsDrawUtils::Background( skin, cc, this, gc, bgRect ); + + if ( !skins ) + { + TRgb color = AKN_LAF_COLOR( 0 ); + AknsUtils::GetCachedColor( skin, color, KAknsIIDQsnIconColors, EAknsCIQsnIconColorsCG1 ); + gc.SetBrushColor( color ); + gc.Clear( bgRect ); + } + + TInt lastRowIconsCount = iIconCount % iMaxColumns; + if ( lastRowIconsCount == 0 && iIconCount > 0 ) + { + // last row is full + lastRowIconsCount = iMaxColumns; + } + + TInt i( 0 ); + + if ( !iIsMirrored ) + { + //draw horizontal lines + for ( i = 0; i <= iRowCount; ++i ) + { + TPoint startPoint( iFirstCell.iTl ); + TPoint endPoint( iFirstCell.iTl ); + startPoint.iY += i * iCellHeight; + endPoint.iY += i * iCellHeight; + endPoint.iX += ( ( i == iRowCount ) || ( i == 0 && iRowCount == 1 ) + ? ( lastRowIconsCount ) + * iCellWidth : iMaxColumns * iCellWidth ); + // add 1 pixel to remove the gap from bottom right corners + ++endPoint.iX; + gc.DrawLine( startPoint, endPoint ); + } + + //draw vertical lines + for ( i = 0; i <= iMaxColumns; ++i ) + { + TPoint startPoint( iFirstCell.iTl ); + TPoint endPoint( iFirstCell.iTl ); + startPoint.iX += i * iCellWidth; + endPoint.iX += i * iCellWidth; + endPoint.iY += ( i <= lastRowIconsCount ? + iCellHeight * iRowCount : iCellHeight * ( iRowCount - 1 ) ); + gc.DrawLine( startPoint, endPoint ); + } + } + else + { + //draw horizontal lines + for ( i = 0; i <= iRowCount; ++i ) + { + TPoint startPoint( iFirstCell.iBr.iX, iFirstCell.iTl.iY ); + TPoint endPoint( iFirstCell.iBr.iX, iFirstCell.iTl.iY ); + startPoint.iY += i * iCellHeight; + endPoint.iY += i * iCellHeight; + endPoint.iX -= ( ( i == iRowCount ) || ( i == 0 && iRowCount == 1 ) + ? ( lastRowIconsCount ) + * iCellWidth : iMaxColumns * iCellWidth ); + // sub 1 pixel to remove the gap from bottom left corners + --endPoint.iX; + gc.DrawLine( startPoint, endPoint ); + } + + //draw vertical lines + for ( i = 0; i <= iMaxColumns; ++i ) + { + TPoint startPoint( iFirstCell.iBr.iX, iFirstCell.iTl.iY ); + TPoint endPoint( iFirstCell.iBr.iX, iFirstCell.iTl.iY ); + startPoint.iX -= i * iCellWidth; + endPoint.iX -= i * iCellWidth; + endPoint.iY += ( i <= lastRowIconsCount ? + iCellHeight * iRowCount : iCellHeight * ( iRowCount - 1 ) ); + gc.DrawLine( startPoint, endPoint ); + } + + } + + //draw icons + for ( i = 0; i < iIconCount; ++i ) + { + DrawItem( gc, skins, skin, cc, i, i == iCursorPos ); + } + } + else + { + // only selection changed, highlight new pos + DrawItem( gc, cc != NULL, skin, cc, iCursorPos, ETrue ); + // and clear old + DrawItem( gc, cc != NULL, skin, cc, iPrevCursorPos, EFalse ); + } + } + +// --------------------------------------------------------- +// CCASmileIconGrid::DrawItem +// (other items were commented in a header). +// --------------------------------------------------------- +void CCASmileIconGrid::DrawItem( CWindowGc& aGc, + TBool aSkinEnabled, + MAknsSkinInstance* aSkin, + MAknsControlContext* aSkinCc, + TInt aIndex, TBool aSelected ) const + { + //lets count currect cell + TRect myRect = iFirstCell; + TPoint offset; + + if ( !iIsMirrored ) + { + offset.iX = ( aIndex % iMaxColumns ) * iCellWidth; + } + else + { + offset.iX = -( ( aIndex % iMaxColumns ) * iCellWidth ); + } + + offset.iY = aIndex / iMaxColumns * iCellHeight; + + myRect.Move( offset ); + + // don't draw bg/highlight over borderlines + TRect myHighLightRect = myRect; + myHighLightRect.iTl.iX++; + myHighLightRect.iTl.iY++; + + if ( aSelected ) + { + // HIGHLIGHT + if ( !aSkinEnabled ) + { + aGc.SetBrushStyle( CGraphicsContext::ESolidBrush ); + } + + TRgb color = AKN_LAF_COLOR( 210 ); + AknsUtils::GetCachedColor( aSkin, color, KAknsIIDQsnIconColors, + EAknsCIQsnComponentColorsCG17 ); + aGc.SetBrushColor( color ); + aGc.Clear( myHighLightRect ); + } + else + { + TRgb color = AKN_LAF_COLOR( 0 ); + AknsUtils::GetCachedColor( aSkin, color, KAknsIIDQsnIconColors, + EAknsCIQsnIconColorsCG1 ); + aGc.SetBrushColor( color ); + if ( aSkinEnabled ) + { + AknsDrawUtils::Background( aSkin, aSkinCc, aGc, myHighLightRect ); + } + else + { + aGc.DrawRect( myHighLightRect ); + } + } + + TAknWindowLineLayout myIconLayout( AknLayoutScalable_Avkon::cell_graphic2_pane_g5( 0 ) ); + + TAknLayoutRect myIconRect; + myIconRect.LayoutRect( myRect, myIconLayout ); + + if ( aIndex < iIconArray.Count() ) + { + myIconRect.DrawImage( aGc, + iIconArray[ aIndex ]->Bitmap(), + iIconArray[ aIndex ]->Mask() ); + } + } + +// --------------------------------------------------------- +// CCASmileIconGrid::HandlePointerEventL +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCASmileIconGrid::HandlePointerEventL( + const TPointerEvent& aPointerEvent ) + { + if ( !CATouchUtils::PenEnabled() ) + { + // Ignore event + return; + } + + TInt oldSelection = iCursorPos; + TPoint hitPos = aPointerEvent.iPosition; + // Pointer useless when using the Hebrew or other Arib language. + TInt xPos; + + // Convert XY position to linear cursor position + if ( !iIsMirrored ) + { + hitPos -= iFirstCell.iTl; + + xPos = hitPos.iX / iCellWidth; + } + // If the layout is mirrored, calculate it in another way. + else + { + hitPos.iX -= iFirstCell.iBr.iX; + hitPos.iY -= iFirstCell.iTl.iY; + + xPos = -hitPos.iX / iCellWidth; + } + TInt yPos = hitPos.iY / iCellHeight; + TInt newSelection = yPos * iMaxColumns + xPos; + + // Validate the item, check whether it is correct. + TBool validItem; + if ( !iIsMirrored ) + { + // Check that the selection is inside the grid + validItem = xPos <= iMaxColumns - 1 && + Rng( 0, newSelection, iIconCount - 1 ) && + hitPos.iX >= 0 && + hitPos.iY >= 0; + } + else + { + // Check that the selection is inside the grid + validItem = xPos <= iMaxColumns - 1 && + Rng( 0, newSelection, iIconCount - 1 ) && + hitPos.iX <= 0 && + hitPos.iY >= 0; + } + if ( !validItem ) + { + // not valid point --> ignore event + return; + } + + // Only update if something new was selected + if ( newSelection != oldSelection ) + { + // New valid item + iPrevCursorPos = iCursorPos; + iCursorPos = newSelection; + iDragEvent = ETrue; + DrawDeferred(); + iDragEvent = EFalse; + } + + // Notify observer + if ( iTapObserver && + aPointerEvent.iType == TPointerEvent::EButton1Up ) + { + // Smiley was tapped + iTapObserver->HandleTapEventL( MCATapEventObserver::ESingleTap, + iTapControlId ); + } + + if ( aPointerEvent.iType == TPointerEvent::EButton1Down ) + { + // enable dragging when button1 is down + EnableDragEvents(); + // single tap has to insert the smiley. + // this code is not required + // Window().SetPointerGrab( ETrue ); + + // and make sure that we get the dragging events + // ClaimPointerGrab( ETrue ); + } + + CCoeControl::HandlePointerEventL( aPointerEvent ); + } + +// ----------------------------------------------------------------------------- +// CCASmileIconGrid::SetTapObserver +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCASmileIconGrid::SetTapObserver( MCATapEventObserver* aObserver, + TUint aId ) + { + iTapObserver = aObserver; + iTapControlId = aId; + } + +// ----------------------------------------------------------------------------- +// CCASmileIconGrid::SetViewableWindowWidth +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCASmileIconGrid::SetViewableWindowWidth( TInt aViewableWidth ) + { + TRect parentRect( iParent->Rect() ); + LAYOUT_DP_RECT( "CCASmileIconGrid popup_grid_graphic_window (parent)", + parentRect ); + + // listscroll_popup_graphic_pane (this compoment) + TAknLayoutRect listLayoutRect; + listLayoutRect.LayoutRect( + parentRect, + AknLayoutScalable_Avkon::listscroll_popup_graphic_pane() ); + LAYOUT_DP_RECT( "CCASmileIconGrid listscroll_popup_graphic_pane", + listLayoutRect.Rect() ); + + // grid_graphic_popup_pane + TAknLayoutRect gridLayoutRect; + gridLayoutRect.LayoutRect( + listLayoutRect.Rect(), + AknLayoutScalable_Avkon::grid_graphic_popup_pane( 0 ) ); + LAYOUT_DP_RECT( "CCASmileIconGrid grid_graphic_popup_pane", + gridLayoutRect.Rect() ); + + // cell_graphic_popup_pane (upper left cell) + TAknLayoutRect oneCellRect; + oneCellRect.LayoutRect( + gridLayoutRect.Rect(), + AknLayoutScalable_Avkon::cell_graphic_popup_pane( 0, 0, 0 ) ); + LAYOUT_DP_RECT( "CCASmileIconGrid cell_graphic_popup_pane", + oneCellRect.Rect() ); + + TInt cellWidth = oneCellRect.Rect().Width(); + + iMaxColumns = aViewableWidth / cellWidth; + + iRowCount = iIconCount / iMaxColumns; + + if ( iIconCount % iMaxColumns ) + { + iRowCount++; + } + + if ( iIconCount < 0 || + iRowCount > KMaxGridRowCount ) + { + User::Leave( KErrArgument ); + } + } + +// ----------------------------------------------------------------------------- +// CCASmileIconGrid::GetFirstCellRect +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TRect CCASmileIconGrid::GetFirstCellRect() + { + // Dim a empty rect. + TRect aRect; + aRect.SetRect( 0, 0, 0, 0 ); + // popup_grid_graphic_window (Parent) + TRect parentRect( aRect );/* iParent->Rect() ); */ + LAYOUT_DP_RECT( "CCASmileIconGrid popup_grid_graphic_window (parent)", + parentRect ); + + // listscroll_popup_graphic_pane (this compoment) + TAknLayoutRect listLayoutRect; + listLayoutRect.LayoutRect( + parentRect, + AknLayoutScalable_Avkon::listscroll_popup_graphic_pane() ); + LAYOUT_DP_RECT( "CCASmileIconGrid listscroll_popup_graphic_pane", + listLayoutRect.Rect() ); + + // grid_graphic_popup_pane + TAknLayoutRect gridLayoutRect; + gridLayoutRect.LayoutRect( + listLayoutRect.Rect(), + AknLayoutScalable_Avkon::grid_graphic_popup_pane( 0 ) ); + LAYOUT_DP_RECT( "CCASmileIconGrid grid_graphic_popup_pane", + gridLayoutRect.Rect() ); + + // cell_graphic_popup_pane (upper left cell) + TAknLayoutRect oneCellRect; + oneCellRect.LayoutRect( + gridLayoutRect.Rect(), + AknLayoutScalable_Avkon::cell_graphic_popup_pane( 0, 0, 0 ) ); + LAYOUT_DP_RECT( "CCASmileIconGrid cell_graphic_popup_pane", + oneCellRect.Rect() ); + + return oneCellRect.Rect(); + } +// End of File