uifw/ganes/src/HgVgMediaWallRenderer.cpp
changeset 0 2f259fa3e83a
child 10 9f56a4e1b8ab
child 14 3320e4e6e8bb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/ganes/src/HgVgMediaWallRenderer.cpp	Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,1142 @@
+/*
+* 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 "HgVgMediaWallRenderer.h"
+#include "HgVgHelper.h"
+#include "HgConstants.h"
+#include "HgVgConstants.h"
+
+#include <VG/vgu.h>
+#include <ganes/HgVgItem.h>
+#include <AknUtils.h>
+#include <layoutmetadata.cdl.h>
+#include <AknLayout2ScalableDef.h>
+#include <AknsDrawUtils.h>
+#include <e32math.h>
+
+using namespace HgVgConstants;
+
+const VGfloat KColorByteToFloat(255.0f);
+// Ending position of the left album stack
+const VGfloat KLeftStackEndX(-1.04);//-235.0f);
+// Ending position of the right album stack
+const VGfloat KRightStackStartX(1.04);//235.0f);
+
+// Space between albums in stacks
+const VGfloat KSpaceBetween(1.04);//235);
+
+const TInt KGroundHeightFactor(2);
+const TInt KNumGroundGradientValues(4);
+const VGfloat KGroundGradient[] = {
+        0.0f, 0.0f, 0.0f, 1.0f
+};
+const TInt KGroundVerticesHint(4);
+const TInt KGroundSegmentsHint(4);
+const VGfloat KGroundScale(1.0f);
+const VGfloat KGroundBias(0.0f);
+
+const VGfloat KFov(PI/2);
+
+const VGfloat KFlipAngle(PI);
+
+const VGfloat KQuadVerts[] =
+            {
+                    -1.0f, -1.0f, 0.0f,
+                    1.0f, -1.0f, 0.0f,
+                    1.0f, 1.0f, 0.0f,
+                    -1.0f, 1.0f, 0.0f
+            };
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CHgVgCoverflowRenderer::NewL()
+// -----------------------------------------------------------------------------
+//
+CHgVgMediaWallRenderer* CHgVgMediaWallRenderer::NewL(TInt aMaxQuads, const TRect& aRect, 
+        const TRect& aFrontRect, TReal aZOffset )
+    {
+    CHgVgMediaWallRenderer* self = new (ELeave) CHgVgMediaWallRenderer( aRect, 
+            aFrontRect, aZOffset);
+    CleanupStack::PushL( self );
+    self->ConstructL(aMaxQuads);
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CHgVgMediaWallRenderer::ConstructL()
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CHgVgMediaWallRenderer::ConstructL (TInt aMaxQuads)
+    {
+    for (TInt i = 0; i < aMaxQuads; i++)
+        {
+        TQuad* q = new (ELeave)TQuad;
+        q->iItemIndex = -1;
+        iQuads.Append(q);
+        }
+    CreateGround();
+    }
+
+// -----------------------------------------------------------------------------
+// CHgVgMediaWallRenderer::CHgVgMediaWallRenderer()
+// C++ default constructor can NOT contain any code, that might leave.
+// -----------------------------------------------------------------------------
+//
+CHgVgMediaWallRenderer::CHgVgMediaWallRenderer(
+        const TRect& aWindowRect, 
+        const TRect& aFrontRect, 
+        TReal aZOffset) :
+        iRect(aWindowRect),
+        iReflectionsEnabled(ETrue), 
+        iSelectedItemIndex(KSelectedItemIndex),
+        iLeftStackEndX(KLeftStackEndX),
+        iRightStackStartX(KRightStackStartX),
+        iSpaceBetween(KSpaceBetween),
+        iFov(KFov),
+        iFlipAngle(KFlipAngle)
+    {
+    AdjustSettingsBasedOnRects(aFrontRect, aZOffset);
+    }
+        
+// -----------------------------------------------------------------------------
+// CHgVgScrollBar::~CHgVgScrollBar()
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CHgVgMediaWallRenderer::~CHgVgMediaWallRenderer ( )
+    {
+    if (iDefaultImage != VG_INVALID_HANDLE)
+        vgDestroyImage(iDefaultImage);
+    
+    if (iChildBlurImage != VG_INVALID_HANDLE)
+        vgDestroyImage(iChildBlurImage);
+    
+    if (iBlurImage != VG_INVALID_HANDLE)
+        vgDestroyImage(iBlurImage);
+    
+    vgDestroyPaint(iGroundPaint);
+    vgDestroyPath(iGroundPath);
+    
+    iQuads.ResetAndDestroy();
+    iSortedQuads.Reset();
+    }
+
+// -----------------------------------------------------------------------------
+// CHgMediaWallRenderer::SetDefaultImage()
+// Setter for default image used to draw quads.
+// -----------------------------------------------------------------------------
+//
+void CHgVgMediaWallRenderer::SetDefaultIconL(const CGulIcon& aIcon)
+    {    
+    iDefaultImage = HgVgHelper::CreateVgImageFromIconL(aIcon);
+    }
+
+// -----------------------------------------------------------------------------
+// CHgMediaWallRenderer::SetCameraPosition()
+// Setter for camera position modifier.
+// -----------------------------------------------------------------------------
+//
+void CHgVgMediaWallRenderer::SetCameraPosition(TReal aX, TReal aY, TReal aZ)
+    {
+    iCameraX = aX;
+    iCameraY = aY;
+    iCameraZ = aZ;
+    }
+
+// -----------------------------------------------------------------------------
+// CHgMediaWallRenderer::SetCameraRotation()
+// -----------------------------------------------------------------------------
+//
+void CHgVgMediaWallRenderer::SetCameraRotation(TReal aAngle)
+    {
+    iCameraRotation = aAngle;
+    }
+
+// -----------------------------------------------------------------------------
+// CHgVgScrollBar::SortQuads
+// Sorts quads from iQuads to iSortedQuads.
+// -----------------------------------------------------------------------------
+//
+void CHgVgMediaWallRenderer::SortQuads(TInt aNumQuads)
+    {
+    
+    iSortedQuads.Reset();
+    
+    for(TInt i = 0; i < aNumQuads; ++i)
+        {
+        iSortedQuads.Append(iQuads[i]);
+        }
+    
+    for (TInt i = 1; i < aNumQuads; i++)
+        {
+        for (int j = 0; j < aNumQuads; j++)
+            {
+            if( iSortedQuads[i]->iZ > iSortedQuads[j]->iZ )
+                {
+                TQuad* q1 = iSortedQuads[i];
+                TQuad* q2 = iSortedQuads[j];
+                iSortedQuads[i] = q2;
+                iSortedQuads[j] = q1;
+                }
+            }
+        }
+        
+    }
+
+
+// -----------------------------------------------------------------------------
+// CHgVgScrollBar::GetItemIndex
+// gets index of the item under pointer position.
+// -----------------------------------------------------------------------------
+//
+TInt CHgVgMediaWallRenderer::GetItemIndex(const TPoint& aPointerPosition) const
+    {
+    for (TInt i = 0; i < iSortedQuads.Count(); i++)
+        {
+        VGfloat* verts = iSortedQuads[iSortedQuads.Count()-i-1]->iPoints;
+        TRect rect;
+        HgVgHelper::CalculateBoundingRect(rect, verts, 4, iRect);
+        if (rect.Contains(aPointerPosition))
+            {
+            TInt index = iSortedQuads.Count()-i-1;
+            return iSortedQuads[index]->iItemIndex;
+            }
+        }
+    return KErrNotFound;    
+    }
+
+
+// -----------------------------------------------------------------------------
+// CHgVgScrollBar::TransformQuads
+// Draws quads using OpenVG.
+// -----------------------------------------------------------------------------
+//
+void CHgVgMediaWallRenderer::TransformQuads(TInt aNumVisibleQuads,
+        TBool aMirrored, VGfloat aFov, CHgVgMediaWall::THgVgOpeningAnimationType aOpeningAnimationType)
+    {
+
+    VGfloat scW = (VGfloat) iRect.Width();
+    VGfloat scH = (VGfloat) iRect.Height();
+        
+    VGfloat imW = (VGfloat)iImageSize.iWidth;
+    VGfloat imH = (VGfloat)iImageSize.iHeight;
+  
+    // construct mirror matrix
+    HgVgHelper::TMatrix mirrorMatrix;
+    mirrorMatrix.Scale(1, -1, 1);
+
+    // construct camera rotation matrix
+    HgVgHelper::TMatrix cameraRotMatrix;    
+    if (iFlipXY)
+        {
+        cameraRotMatrix.RotationX(iCameraRotation);
+        }
+    else
+        {
+        cameraRotMatrix.RotationY(iCameraRotation);
+        }
+
+    // mat[0] = transform
+    // mat[1] = mirrored transform
+    HgVgHelper::TMatrix mat[2];
+    
+    VGfloat cameraX = iCameraBaseX + iCameraX;
+    VGfloat cameraY = iCameraBaseY + iCameraY;
+    VGfloat cameraZ = iCameraBaseZ + iCameraZ;
+    
+    if (iFlipXY)
+        {
+        VGfloat foobar = cameraX;
+        cameraX = cameraY;
+        cameraY = foobar;
+        }
+        
+    // scaling matrix is used to set correct size for the 
+    // quad by image size
+    VGfloat hImW = (VGfloat)KWorldQuadWidth * 0.5f;
+    VGfloat hImH = (VGfloat)imH * (KWorldQuadWidth / imW) * 0.5f;
+    VGfloat oldHImH = hImH;
+    
+    // flips image upside down
+    HgVgHelper::TMatrix scaleMatrix;
+    scaleMatrix.Scale(hImW, -hImH, 1); // negative scale because our all images are updaside down.
+
+    TBool deform = 
+            (aOpeningAnimationType == CHgVgMediaWall::EHgVgOpeningAnimationFlipToFront) ||
+            (aOpeningAnimationType == CHgVgMediaWall::EHgVgOpeningAnimationZoomToFront);
+    
+    for (TInt j = 0; j < aNumVisibleQuads; j++)
+        {
+        TQuad* q = iQuads[j];
+                                
+        if (q->iFlipped && deform)
+            {
+            // animate scaling to flipped rect size
+            VGfloat newH = (VGfloat)iFlippedHeight * (KWorldQuadWidth / iFlippedWidth) * 0.5f;
+            hImH = HgVgHelper::Lerp(hImH, newH, iBlurAlpha);
+            mat[0].Identity();
+            mat[0].Scale(hImW, -hImH, 1);
+            }
+        else
+            {
+            // restore old normal half image height
+            hImH = oldHImH;
+            mat[0] = scaleMatrix;        
+            }
+
+        // rotMatrix rotates by quads angle
+        HgVgHelper::TMatrix rotMatrix;
+        rotMatrix.RotationY(-q->iAngle);
+
+        // trMatrix translates by quads position
+        HgVgHelper::TMatrix trMatrix;
+        trMatrix.Translation(q->iX, q->iY + hImH, q->iZ);
+                                
+        // then rotate
+        if (q->iAngle != 0)
+            {
+            mat[0].Multiply(rotMatrix);
+            }
+        
+        // then translate to position
+        mat[0].Multiply(trMatrix);
+                
+        // construct mirroring matrix
+        if (aMirrored)
+            {
+            mat[1] = mat[0];
+            mat[1].Multiply(mirrorMatrix);
+            }
+        
+        // construct camera translation matrix
+        HgVgHelper::TMatrix cameraMatrix;
+        cameraMatrix.Translation(-cameraX, -cameraY - hImH, -cameraZ);
+
+        // apply camera movement
+        mat[0].Multiply(cameraMatrix);
+
+        // apply camera rotation hack
+        mat[0].Multiply(cameraRotMatrix);
+        
+        // apply to mirror matrix also
+        if (aMirrored)
+            {
+            mat[1].Multiply(cameraMatrix);
+            mat[1].Multiply(cameraRotMatrix);
+            }
+
+        // transform all points by resulting transformation matrix
+        // and project to screen coordinates.
+        TInt count = aMirrored ? 2 : 1;
+        for (TInt k = 0; k < count; k++)            
+            {
+            VGfloat* tverts = NULL;
+            VGfloat* tm = NULL; 
+            
+            if (k == 0)
+                {
+                tverts = q->iPoints;
+                tm = q->iTM;
+                }
+            else
+                {
+                tverts = q->iMirroredPoints;
+                tm = q->iMirroredTM;
+                }
+
+            for (TInt i = 0; i < 4; i++)
+                {
+                
+                HgVgHelper::TVertex v;
+    
+                v.iX = KQuadVerts[i*3+0];
+                v.iY = KQuadVerts[i*3+1];
+                v.iZ = KQuadVerts[i*3+2];
+    
+                v.TransformPoint(mat[k]);
+                
+                v.ProjectPoint(scW, scH, aFov);
+                
+                tverts[i*2+0] = v.iScreenX;
+                tverts[i*2+1] = v.iScreenY;
+                
+                }
+
+            VGImage image = q->iNoImage ? iDefaultImage : q->iImage;
+            VGfloat pxWidth = vgGetParameteri(image, VG_IMAGE_WIDTH);
+            VGfloat pxHeight = vgGetParameteri(image, VG_IMAGE_HEIGHT); 
+            
+            // use screen coordinates to build warp matrix
+            // for rendering the image
+            vguComputeWarpQuadToQuad(tverts[0], tverts[1], tverts[2], tverts[3],
+                    tverts[4], tverts[5], tverts[6], tverts[7], 0, 0, pxWidth, 0,
+                    pxWidth, pxHeight, 0, pxHeight, tm);
+
+            }
+        }    
+    }
+
+// -----------------------------------------------------------------------------
+// CHgVgScrollBar::DrawQuads
+// Draws quads using OpenVG.
+// -----------------------------------------------------------------------------
+//
+void CHgVgMediaWallRenderer::DrawQuads(TBool aDrawMirrored)
+    {    
+
+    VGfloat values[] = { 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0 };
+                
+    vgSeti(VG_COLOR_TRANSFORM, VG_TRUE);
+    
+    for (TInt j = 0; j < iSortedQuads.Count(); j++)
+        {
+        TQuad* q = iSortedQuads[j];
+        
+        if (q->iAlpha < 0.01f)
+            continue;
+
+        values[3] = q->iAlpha;
+        
+        vgSetfv(VG_COLOR_TRANSFORM_VALUES, 8, values);
+        
+        if (q->iZ < 0)
+            continue;
+        
+        DrawQuad(q, aDrawMirrored);
+        
+        }
+
+    vgSeti(VG_COLOR_TRANSFORM, VG_FALSE);
+
+    }
+
+// -----------------------------------------------------------------------------
+// CHgVgMediaWallRenderer::DrawQuad
+// -----------------------------------------------------------------------------
+//
+void CHgVgMediaWallRenderer::DrawQuad(CHgVgMediaWallRenderer::TQuad* q, TBool aDrawMirrored)
+    {
+    vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+    vgLoadIdentity();
+    
+    //vgTranslate(iOffset.iX, iOffset.iY);
+
+    VGImage image = q->iImage;
+    if (q->iNoImage)
+        {
+        image = iDefaultImage;
+        }
+
+    if (aDrawMirrored)
+        {
+        vgMultMatrix(q->iMirroredTM);
+        }
+    else
+        {
+        vgMultMatrix(q->iTM);
+        if ((iBlurImage != VG_INVALID_HANDLE) && (iChildBlurImage != VG_INVALID_HANDLE) && q->iFlipped)
+            {
+            vgGaussianBlur(iChildBlurImage, image, iBlurDeviationX*iBlurAlpha, 
+                    iBlurDeviationY*iBlurAlpha, VG_TILE_PAD);
+            image = iChildBlurImage;
+            }
+        }
+    
+    
+    vgDrawImage(image);    
+    }
+
+
+// -----------------------------------------------------------------------------
+// CHgVgScrollBar::Draw()
+// -----------------------------------------------------------------------------
+//
+void CHgVgMediaWallRenderer::Draw(RPointerArray<CHgVgItem>& aItems,
+        TInt aSelectedIndex, TReal aNextIndex,
+        TReal aViewPosition,
+        TReal aAnimationAlpha,
+        CHgVgMediaWall::THgVgAnimationState aState, 
+        CHgVgMediaWall::THgVgOpeningAnimationType aSelectionAnimationType, 
+        CHgVgMediaWall::THgVgMediaWallStyle /*aStyle*/,
+        TReal aStartIndex)
+    { 
+    
+    TInt itemsOnScreen = 0;
+    itemsOnScreen = SetupQuads(aItems,
+            aSelectedIndex, aNextIndex,
+            aViewPosition,
+            aAnimationAlpha,
+            aState, aSelectionAnimationType, aStartIndex);
+    
+    TransformAndDraw(itemsOnScreen, aSelectionAnimationType);
+    }
+
+
+// ---------------------------------------------------------------------------
+// CHgVgMediaWallRenderer::DrawGrid()
+// ---------------------------------------------------------------------------
+//     
+void CHgVgMediaWallRenderer::DrawGrid(
+        TInt aRowCount, 
+        RPointerArray<CHgVgItem>& aItems, 
+        TReal aViewX, TReal aViewY, 
+        TInt aCurItem, TInt aPrevItem, 
+        TReal aAnimationAlpha,
+        CHgVgMediaWall::THgVgAnimationState aAnimationState, 
+        TInt aPickedItem, 
+        CHgVgMediaWall::THgVgOpeningAnimationType aAnimationType)
+    {
+    TInt itemsOnScreen = 0;
+
+    for (TInt i = 0; i < aRowCount; i++)
+        {
+        SetupQuadsToRow(i, aRowCount, itemsOnScreen, 
+                aItems, aViewX, aViewY, aCurItem, aPrevItem, 
+                aAnimationAlpha, aAnimationState, aPickedItem,
+                aAnimationType);
+        }
+    
+    TransformAndDraw(itemsOnScreen, aAnimationType);
+    }
+
+
+TReal CHgVgMediaWallRenderer::GetWorldSpaceRowHeight() const
+    {
+    // TODO: replace these macig numbers
+    return (120.0 / 90.0 * 0.25 + 0.02);
+    }
+
+
+// ---------------------------------------------------------------------------
+// CHgVgCoverflowRenderer::CreateGround()
+// ---------------------------------------------------------------------------
+//     
+void CHgVgMediaWallRenderer::CreateGround()
+{
+    // Create path and paint for drawing ground plane
+    
+    iGroundPath = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, KGroundScale, KGroundBias, 
+            KGroundVerticesHint, KGroundSegmentsHint, (unsigned int)VG_PATH_CAPABILITY_ALL);
+    
+    vguRect(iGroundPath, 0, 0, 1, 1);
+        
+    VGfloat gradientStops[] = {
+            0, 0.0f, 0.0f, 0.0f, 1.0f,
+            0.01f, 0.0f, 0.0f, 0.0f, 0.95f,
+            1.0f, 0.0f, 0.0f, 0.0f, 0.0f
+    };
+    
+    VGfloat groundColor[4];
+    GetGroundColorFromSkin(groundColor);
+
+    gradientStops[1] = groundColor[0]; 
+    gradientStops[2] = groundColor[1]; 
+    gradientStops[3] = groundColor[2]; 
+    
+    gradientStops[6] = groundColor[0]; 
+    gradientStops[7] = groundColor[1]; 
+    gradientStops[8] = groundColor[2]; 
+
+    gradientStops[11] = groundColor[0]; 
+    gradientStops[12] = groundColor[1]; 
+    gradientStops[13] = groundColor[2]; 
+
+    iGroundPaint = vgCreatePaint();
+            
+    vgSetParameteri(iGroundPaint, VG_PAINT_TYPE, 
+        VG_PAINT_TYPE_LINEAR_GRADIENT);
+        
+    vgSetParameterfv(iGroundPaint, VG_PAINT_LINEAR_GRADIENT,
+        KNumGroundGradientValues, KGroundGradient);
+    
+    vgSetParameteri(iGroundPaint, VG_PAINT_COLOR_RAMP_SPREAD_MODE,
+            VG_COLOR_RAMP_SPREAD_PAD);
+    
+    vgSetParameterfv(iGroundPaint, VG_PAINT_COLOR_RAMP_STOPS,
+        5*3, gradientStops);
+
+
+}
+
+// ---------------------------------------------------------------------------
+// CHgVgCoverflowRenderer::DrawGround()
+// ---------------------------------------------------------------------------
+//     
+void CHgVgMediaWallRenderer::DrawGround(TInt aWidth, TInt aHeight)
+    {
+    vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+    vgLoadIdentity();
+    //vgTranslate(iOffset.iX, iOffset.iY);
+    vgScale(aWidth, aHeight);
+    vgSetPaint(iGroundPaint, VG_FILL_PATH);            
+    vgDrawPath(iGroundPath, VG_FILL_PATH);
+    }
+
+
+
+// ---------------------------------------------------------------------------
+// CHgVgMediaWallRenderer::SetupQuadsToRow()
+// ---------------------------------------------------------------------------
+//
+void CHgVgMediaWallRenderer::SetupQuadsToRow(
+        TInt aRow,
+        TInt aRowCount,
+        TInt &aItemsOnScreen,
+        RPointerArray<CHgVgItem>& aItems,
+        TReal aViewX, TReal aViewY,
+        TInt aCurItem, TInt aPrevItem, 
+        TReal aAnimationAlpha,
+        CHgVgMediaWall::THgVgAnimationState aState, 
+        TInt aPickedItem, 
+        CHgVgMediaWall::THgVgOpeningAnimationType aAnimationType)
+    {
+        
+    if (aItems.Count() <= 0)
+        return;
+        
+    TReal src = aViewX;
+    TReal frac;
+    Math::Frac(frac, src);
+    VGfloat fDiff = frac;
+
+    TBool isSelectionToFocusedItem = 
+        (
+        (aState == CHgVgMediaWall::EHgVgMediaWallAnimationStateOpening) ||
+        (aState == CHgVgMediaWall::EHgVgMediaWallAnimationStateClosing) ||
+        (aState == CHgVgMediaWall::EHgVgMediaWallAnimationStateItemOpened)
+        ) &&
+        (aAnimationType != CHgVgMediaWall::EHgVgOpeningAnimationNone);
+
+    TReal selectionAnimationAlpha = aAnimationAlpha;
+    if (aState == CHgVgMediaWall::EHgVgMediaWallAnimationStateItemOpened)
+        selectionAnimationAlpha = 1.0f;
+
+    VGfloat leftIndex = (VGfloat)(iSelectedItemIndex - 1);
+    VGfloat leftX = iLeftStackEndX;
+    VGfloat step = iSpaceBetween;
+    
+    if (AknLayoutUtils::LayoutMirrored())
+        {
+        leftX = iRightStackStartX;
+        step = -step;
+        }
+
+    TInt i = 0;
+    
+    TInt currentRow = ((TInt)aViewX - (iSelectedItemIndex)) * aRowCount; 
+        
+    VGfloat zFar = iZNear;
+    VGfloat zNear = zFar - 0.8;
+    
+    TInt itemsOnRow = 0;
+    
+    TInt selX = aCurItem / 3;
+    TInt selY = aCurItem % 3;
+        
+    TReal div = (TReal)(iQuads.Count()/aRowCount/2-1);
+    
+    while (itemsOnRow < (iQuads.Count()/aRowCount))
+        {
+                                            
+        TInt itemIndex = currentRow + i * 3 + aRow;
+        
+        if (itemIndex < 0)
+            {
+            i++;
+            continue;
+            }
+        
+        // all items drawn and at the end of the list, lets bail out.
+        if (itemIndex >= aItems.Count())
+            {
+            break;
+            }
+
+        TQuad* q = iQuads[aItemsOnScreen + itemsOnRow];        
+
+        q->iZ = zFar;
+        q->iAngle = 0;
+        q->iFlipped = EFalse;
+        
+        VGfloat fi = (VGfloat)i - fDiff;
+                        
+        q->iX = leftX - step * (leftIndex - fi);
+        q->iAlpha = 1;
+        
+        q->iItemIndex = itemIndex;
+        
+        if  (aItems[itemIndex]->VgImage() == VG_INVALID_HANDLE)
+            {
+            q->iNoImage = ETrue;
+            }
+        else
+            {
+            q->iNoImage = EFalse;
+            q->iImage = aItems[itemIndex]->VgImage();
+            }
+
+                        
+        VGfloat imW = (VGfloat) iImageSize.iWidth;
+        VGfloat imH = (VGfloat) iImageSize.iHeight;
+
+        // width is constant but same aspect ratio must be preserved
+        VGfloat worldImageHeight = imH * (KWorldQuadWidth / imW);
+        
+        q->iY = (2 - aRow) * (worldImageHeight + KSpaceBetweenGridItems);
+        
+        if (aCurItem != KErrNotFound && itemIndex == aCurItem)
+            {
+            TReal alphaX = 1.0 - Min(Abs(aViewX - (TReal)selX), 1);
+            TReal alphaY = 1.0 - Min(Abs(aViewY - (TReal)selY), 1);
+
+            q->iZ = HgVgHelper::Lerp(zFar, zNear, Min(alphaX, alphaY));            
+            }
+        else if (aPrevItem != KErrNotFound && itemIndex == aPrevItem)
+            {
+            TReal alphaX = 1.0 - Min(Abs(aViewX - (TReal)selX), 1);
+            TReal alphaY = 1.0 - Min(Abs(aViewY - (TReal)selY), 1);
+            
+            q->iZ = HgVgHelper::Lerp(zFar, zNear, 1.0f - Min(alphaX, alphaY));
+            }
+        
+        q->iAlpha = HgVgHelper::Lerp(1, 0, Max(0.0, (Abs(q->iX)-1.0) / div));         
+
+        if (isSelectionToFocusedItem && (itemIndex == aPickedItem))
+            {
+            q->iAlpha = 1;
+            q->iFlipped = ETrue;
+            iBlurAlpha = selectionAnimationAlpha;
+            ApplyOpeningAnimation(q, selectionAnimationAlpha, zFar, 
+                    CHgVgMediaWall::EHgVgMediaWallStyleGrid, 
+                    aAnimationType);
+            }
+        
+        if (iFlipXY)
+            {
+            VGfloat temp = q->iX;
+            q->iX = q->iY;
+            q->iY = -temp;
+            }
+        
+        i++;
+        itemsOnRow++;
+        }
+        
+    aItemsOnScreen += itemsOnRow;
+    
+    }
+
+
+
+// ---------------------------------------------------------------------------
+// CHgVgMediaWallRenderer::SetupQuads()
+// ---------------------------------------------------------------------------
+//
+TInt CHgVgMediaWallRenderer::SetupQuads(RPointerArray<CHgVgItem>& aItems,
+        TInt aSelectedIndex, TReal aNextIndex,
+        VGfloat aViewPosition,
+        VGfloat aAnimationAlpha,
+        CHgVgMediaWall::THgVgAnimationState aState, 
+        CHgVgMediaWall::THgVgOpeningAnimationType aOpeningAnimationType, 
+        TReal aStartIndex)
+    {
+    
+    
+    if (aItems.Count() <= 0)
+        return 0;
+           
+    VGfloat selectionAnimationAlpha = aAnimationAlpha;
+
+    TBool isSelectionToFocusedItem = 
+        ((aState == CHgVgMediaWall::EHgVgMediaWallAnimationStateOpening) ||
+        (aState == CHgVgMediaWall::EHgVgMediaWallAnimationStateClosing) ||
+        (aState == CHgVgMediaWall::EHgVgMediaWallAnimationStateItemOpened)) &&
+        (aOpeningAnimationType != CHgVgMediaWall::EHgVgOpeningAnimationNone);
+
+    if (aState == CHgVgMediaWall::EHgVgMediaWallAnimationStateItemOpened)
+        selectionAnimationAlpha = 1.0f;
+        
+    TReal src = aViewPosition;
+    TReal frac;
+    Math::Frac(frac, src);
+    VGfloat fDiff = frac;
+            
+    VGfloat leftIndex = (VGfloat)(iSelectedItemIndex - 1);
+    VGfloat leftX = iLeftStackEndX;
+    VGfloat step = iSpaceBetween;
+
+    // support mirrored layouts (right-to-left reading)
+    if (AknLayoutUtils::LayoutMirrored())
+        {
+        leftX = -iLeftStackEndX;
+        step = -step;
+        }
+    
+    TInt i = 0;
+    TInt itemsOnScreen = 0;
+    TInt currentRow = (TInt)aViewPosition - KSelectedItemIndex;
+        
+    while (itemsOnScreen < iQuads.Count())
+        {
+        TInt itemIndex = currentRow + i;
+
+        // not really an item
+        if (itemIndex < 0)
+            {
+            i++;
+            continue;
+            }
+        
+        // got past all items
+        if (itemIndex  >= aItems.Count())
+            {
+            break;
+            }
+
+        // setup quads to represent coverflow
+        TQuad* q = iQuads[itemsOnScreen];        
+
+        q->iY = 0;
+        q->iZ = iZFar;
+        q->iAngle = 0;
+
+        q->iFlipped = EFalse;
+
+        VGfloat fi = (VGfloat)i - fDiff;
+        
+        q->iX = leftX - step * (leftIndex - fi);
+        
+        
+        if (aStartIndex != aNextIndex)
+            {
+            // if start and next index are not same, we can just interpolate
+            // items at these indices.
+            if (itemIndex == (TInt)aStartIndex ||
+                    itemIndex == (TInt)aNextIndex)
+                {
+                q->iZ = HgVgHelper::Lerp((VGfloat)iZNear, (VGfloat)iZFar, Abs(q->iX / leftX));
+                q->iZ = Min(q->iZ, (VGfloat)iZFar);            
+                }
+            }
+        else
+            {
+            // in this case we are just dragging and startindex and left index are
+            // same so we need to interpolate z for all items coming/leaving center 
+            // of the screen.
+            q->iZ = HgVgHelper::Lerp((VGfloat)iZNear, (VGfloat)iZFar, Abs(q->iX / leftX));
+            q->iZ = Min(q->iZ, (VGfloat)iZFar);                    
+            }
+        
+        // calculate alpha so that items further are more transparent.
+        q->iAlpha = HgVgHelper::Lerp(1, 0, Max(0.0, (Abs(q->iX)-2.0) / (TReal)(iQuads.Count()/2-2)));         
+                    
+        q->iItemIndex = itemIndex;
+        
+        // setup image to quad from item
+        if  (aItems[itemIndex]->VgImage() == VG_INVALID_HANDLE)
+            {
+            q->iNoImage = ETrue;
+            }
+        else
+            {
+            q->iNoImage = EFalse;
+            q->iImage = aItems[itemIndex]->VgImage();
+            }
+
+        // apply opening animation to item if needed
+        if (isSelectionToFocusedItem && (itemIndex == aSelectedIndex))
+            {
+            q->iAlpha = 1;
+            q->iFlipped = ETrue;
+            iBlurAlpha = selectionAnimationAlpha;
+            ApplyOpeningAnimation(q, selectionAnimationAlpha, q->iZ, 
+                    CHgVgMediaWall::EHgVgMediaWallStyleCoverflowFullScreen, 
+                    aOpeningAnimationType);
+            }
+
+        i++;
+        itemsOnScreen++;
+        }
+        
+    return itemsOnScreen;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CHgVgMediaWallRenderer::ApplyFlipAnimation()
+// ---------------------------------------------------------------------------
+//
+void CHgVgMediaWallRenderer::ApplyOpeningAnimation(CHgVgMediaWallRenderer::TQuad* aQuad, 
+        TReal aAnimationAlpha, TReal aZNear, CHgVgMediaWall::THgVgMediaWallStyle /*aMediaWallStyle*/, 
+        CHgVgMediaWall::THgVgOpeningAnimationType aAnimationStyle)
+    {
+    VGfloat wz = 0.0f;
+    VGfloat wy = (iCameraBaseY + iCameraY);
+    VGfloat wx = (iCameraBaseX + iCameraX);
+    VGfloat angle = 0;
+    
+    if (aAnimationStyle == CHgVgMediaWall::EHgVgOpeningAnimationFlipToFront)
+        {    
+        wz = iFlippedZ;    
+        angle = iFlipAngle;
+        wx += iFlippedX;
+        wy += iFlippedY;
+        }
+    else if (aAnimationStyle == CHgVgMediaWall::EHgVgOpeningAnimationZoomToFront)
+        {
+        wz = iFlippedZ;    
+        wx += iFlippedX;
+        wy += iFlippedY;    
+        }
+    
+    if (iBlurImage != VG_INVALID_HANDLE)
+        {
+        VGImage image = aQuad->iNoImage ? iDefaultImage : aQuad->iImage;
+        UpdateBlurChildImage(image);
+        }
+
+    aQuad->iZ = HgVgHelper::Lerp(aZNear, wz, aAnimationAlpha);                
+    aQuad->iX = HgVgHelper::Lerp(aQuad->iX, wx, aAnimationAlpha);
+    aQuad->iY = HgVgHelper::Lerp(aQuad->iY, wy, aAnimationAlpha);
+    aQuad->iAngle = -aAnimationAlpha * angle;
+    }
+
+// ---------------------------------------------------------------------------
+// CHgVgMediaWallRenderer::GetGroundColorFromSkin()
+// ---------------------------------------------------------------------------
+//
+void CHgVgMediaWallRenderer::GetGroundColorFromSkin(VGfloat* aColor)
+    {
+    TRgb color(KRgbBlack);
+    // get text color from skin
+    if ( AknsUtils::AvkonSkinEnabled() )
+        {
+        // this does not modify color unless it gets a correct one
+        // no real need to check errors
+        AknsUtils::GetCachedColor( 
+                AknsUtils::SkinInstance(),
+                color,
+                KAknsIIDQsnTextColors,
+                EAknsCIQsnTextColorsCG6 );
+        }
+    
+    if (color.Blue() < 128)
+        color = KRgbWhite;
+    else
+        color = KRgbBlack;
+    
+    aColor[0] = (VGfloat)color.Red() / KColorByteToFloat;
+    aColor[1] = (VGfloat)color.Green() / KColorByteToFloat;
+    aColor[2] = (VGfloat)color.Blue() / KColorByteToFloat;
+    aColor[3] = 1.0f;
+    }
+
+// ---------------------------------------------------------------------------
+// CHgVgMediaWallRenderer::HandleSkinChange()
+// ---------------------------------------------------------------------------
+//
+void CHgVgMediaWallRenderer::HandleSkinChange()
+    {
+    vgDestroyPaint(iGroundPaint);
+    vgDestroyPath(iGroundPath);
+    CreateGround();    
+    }
+
+// ---------------------------------------------------------------------------
+// CHgVgMediaWallRenderer::AdjustSettingsBaseOnFrontRect()
+// ---------------------------------------------------------------------------
+//
+void CHgVgMediaWallRenderer::AdjustSettingsBasedOnRects(const TRect& aFrontRect, 
+        TReal aZOffset)
+    {
+    
+    // size of the images should be the same as given for aFrontRect
+    iImageSize = aFrontRect.Size();
+    
+    // calculate screen center point
+    TPoint center(iRect.Width()/2, iRect.Height()/2);
+        
+    // near z coordinate is calculated so that the size of the quad at front matches
+    // aFrontRect
+    iZNear = GetZInWorldSpaceBasedOnWidth(aFrontRect.Width());
+    iZFar = iZNear + aZOffset;
+
+    // width is always constant
+    VGfloat ImW = KWorldQuadWidth;
+    // height is altered by image aspect ratio
+    VGfloat ImH = (VGfloat)(iImageSize.iHeight) * (KWorldQuadWidth / (VGfloat)iImageSize.iWidth);    
+    
+    // camera coordinates are altered so that the front quad 
+    // is at correct place
+    VGfloat deltaX = aFrontRect.Center().iX - center.iX;
+    VGfloat deltaY = aFrontRect.Center().iY - center.iY;
+
+    iCameraBaseX = ImW * (deltaX / (VGfloat)iImageSize.iWidth);
+    iCameraBaseY = ImH * (deltaY / (VGfloat)iImageSize.iHeight);
+    iCameraBaseZ = 0;
+
+    }
+
+
+void CHgVgMediaWallRenderer::TransformAndDraw(TInt itemsOnScreen, 
+        CHgVgMediaWall::THgVgOpeningAnimationType aOpeningAnimationType)
+    {
+/*    
+    vgSeti( VG_SCISSORING, VG_TRUE );
+    VGfloat rects[4];
+    rects[0]= 0;
+    rects[1]= 0;
+    rects[2]= iRect.Width();
+    rects[3]= iRect.Height();
+    vgSetfv( VG_SCISSOR_RECTS, 4, rects );
+*/    
+    vgSeti( VG_SCISSORING, VG_FALSE );    
+
+    if (itemsOnScreen > 0)
+        {    
+
+        // draw reflections
+        
+        TransformQuads(itemsOnScreen, 
+                iReflectionsEnabled, iFov, aOpeningAnimationType);
+
+        SortQuads(itemsOnScreen);
+        
+        if (iReflectionsEnabled)
+            DrawQuads(ETrue);
+    
+        DrawGround(iRect.Width(), iRect.Height() / KGroundHeightFactor);
+    
+        DrawQuads(EFalse);
+                
+        }
+    else
+        {
+       
+        // if no items exists, just draw ground plane.
+        DrawGround(iRect.Width(), iRect.Height() / KGroundHeightFactor);
+        
+        }
+    
+    //vgSeti( VG_SCISSORING, VG_FALSE );    
+
+    }
+
+void CHgVgMediaWallRenderer::SetReflections(TBool aEnabled)
+    {
+    iReflectionsEnabled = aEnabled;
+    }
+
+TBool CHgVgMediaWallRenderer::ReflectionsEnabled() const
+    {
+    return iReflectionsEnabled;
+    }
+
+TSize CHgVgMediaWallRenderer::ImageSize() const
+    {
+    return iImageSize;
+    }
+
+
+void CHgVgMediaWallRenderer::SetFlippedRect(const TRect& aFlippedRect)
+    {
+    iFlippedWidth = aFlippedRect.Width();
+    iFlippedHeight = aFlippedRect.Height();
+    iFlippedZ = GetZInWorldSpaceBasedOnWidth(aFlippedRect.Width());
+    TPoint center = iRect.Center();
+    
+    VGfloat ImW = KWorldQuadWidth;
+    VGfloat ImH = (VGfloat)(iImageSize.iHeight) * (KWorldQuadWidth / (VGfloat)iImageSize.iWidth);    
+    VGfloat deltaX = aFlippedRect.Center().iX - center.iX;
+    VGfloat deltaY = aFlippedRect.Center().iY - center.iY;
+    
+    iFlippedY = -ImH * (deltaY / (VGfloat)aFlippedRect.Height());
+    iFlippedX = ImW * (deltaX / (VGfloat)aFlippedRect.Width());
+    }
+
+VGfloat CHgVgMediaWallRenderer::GetZInWorldSpaceBasedOnWidth(VGfloat aWidth)
+    {
+    
+    // calculate screen center point
+    TPoint center(iRect.Width()/2, iRect.Height()/2);
+    
+    // Z-coordinate is set so that the front quad has 
+    // the correct size
+    TReal hw = iRect.Width() * 0.5f;
+    TReal alpha = iFov / 2.0f;
+    TReal tanAlpha;
+    Math::Tan(tanAlpha, alpha);
+    TReal d = hw / tanAlpha;    
+
+    return (d * (-KWorldQuadWidth/2)) / ((TReal)(center.iX - aWidth/2) - hw);    
+
+    }
+
+void CHgVgMediaWallRenderer::SetFlipAngle(TReal aAngle)
+    {
+    iFlipAngle = aAngle;
+    }
+
+
+void CHgVgMediaWallRenderer::EnableBlurOnFlip(TBool aEnabled, TReal aBlurX, TReal aBlurY)
+    {
+    if (iBlurImage != VG_INVALID_HANDLE)
+        {        
+        vgDestroyImage(iBlurImage);
+        iBlurImage = VG_INVALID_HANDLE;
+        }
+    if (aEnabled)
+        {
+        iBlurDeviationX = aBlurX;
+        iBlurDeviationY = aBlurY;
+        iBlurImage = vgCreateImage(VG_sRGBA_8888_PRE, iImageSize.iWidth, iImageSize.iHeight, 
+                VG_IMAGE_QUALITY_NONANTIALIASED);
+        }
+    }
+
+void CHgVgMediaWallRenderer::UpdateBlurChildImage(VGImage aImage)
+    {
+    VGint width = vgGetParameteri(aImage, VG_IMAGE_WIDTH);
+    VGint height = vgGetParameteri(aImage, VG_IMAGE_HEIGHT);
+
+    if (iBlurImageWidth != width || iBlurImageHeight != height)
+        {                
+        vgDestroyImage(iChildBlurImage);            
+        iChildBlurImage = vgChildImage(iBlurImage, 0, 0, width, height);    
+        iBlurImageWidth = width;
+        iBlurImageHeight = height;
+        }    
+    }
+
+
+void CHgVgMediaWallRenderer::SetOffset(const TPoint& aOffset)
+    {
+    iOffset = aOffset;
+    }
+
+void CHgVgMediaWallRenderer::EnableFlipXY(TBool aEnabled)
+    {
+    iFlipXY = aEnabled;
+    }
+
+// End of File