--- /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