photosgallery/viewframework/visuallistmanager/src/glxitemvisual.cpp
author Simon Howkins <simonh@symbian.org>
Mon, 29 Nov 2010 11:47:03 +0000
branchRCL_3
changeset 78 dbcb928abe9c
parent 60 5b3385a43d68
permissions -rw-r--r--
Adjusted to avoid exports, etc, from a top-level bld.inf

/*
* Copyright (c) 2008-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:    Item visual container
*
*/




/**
 * @internal reviewed 04/07/2007 by M Byrne
 */

#include "glxitemvisual.h"

#include <alf/alfanchorlayout.h>
#include <alf/alfcontrol.h>
#include <alf/alfdecklayout.h>
#include <AknUtils.h>
#include <alf/alfimagevisual.h>
#include <alf/alfimagebrush.h>
#include <alf/alfdisplay.h>
#include <alf/alfenv.h>
#include <alf/alftexture.h>
#include <mpxmediageneraldefs.h>
#include <imageconversion.h>

#include <glxlog.h>
#include <glxtracer.h>

#include <glxassert.h>
#include <glxuiutility.h>
#include <glxmedia.h>
#include <glxmediageneraldefs.h>
#include <glxtexturemanager.h>
#include <glxthumbnailattributeinfo.h>
#include <mglxmedialist.h>
#include <glxthumbnailutility.h>
#include <alf/alftransformation.h>
#include "mglxvisualobjectstatusobserver.h"

const TInt KGlxOpacityFadeDuration = 400;
const TInt KGlxForegroundAnchorOrdinal = 2;

// -----------------------------------------------------------------------------
// Constructor. Inlined to save a few bits of rom
// -----------------------------------------------------------------------------
inline CGlxVisualObject::CGlxVisualObject( MGlxMediaList& aMediaList)
    : iMediaList( aMediaList )
    {
    // No implementation
    }

// -----------------------------------------------------------------------------
// NewLC
// -----------------------------------------------------------------------------
CGlxVisualObject* CGlxVisualObject::NewLC( 
            MGlxVisualObjectParameterFactory& aFactory,MGlxMediaList& aMediaList)
    {
    TRACER("CGlxVisualObject::NewLC");
    CGlxVisualObject* self = new ( ELeave ) CGlxVisualObject( aMediaList);
    CleanupStack::PushL( self );
    self->ConstructL( aFactory );
    return self;
    }

// -----------------------------------------------------------------------------
// Destructor
// -----------------------------------------------------------------------------
CGlxVisualObject::~CGlxVisualObject()
    {
    TRACER("CGlxVisualObject::~CGlxVisualObject");
    iForegroundIconAnchors.Close();
    iBackgroundIconAnchors.Close();
    
    while ( iZoomTiles.Count() )
        {
        RemoveZoomTile(0);
        }
    iZoomTiles.Close();

	if ( iUiUtility && iImageValid )
        {
        // Clean up the texture from the texture manager
        iUiUtility->GlxTextureManager().RemoveTexture( iImage.Texture() );
        }

    if ( iVisual )
        {
        iVisual->RemoveAndDestroyAllD();
        }
        delete iAnimatedTexture;
    if ( iUiUtility )
        {
        iUiUtility->Close();
        }
    }

// -----------------------------------------------------------------------------
// ConstructL
// -----------------------------------------------------------------------------
void CGlxVisualObject::ConstructL( MGlxVisualObjectParameterFactory& aFactory) 
    {
    TRACER("CGlxVisualObject::ConstructL");
    iUiUtility = CGlxUiUtility::UtilityL();
    // create the visual with parents layout
    iVisual = CAlfAnchorLayout::AddNewL(aFactory.VisualOwner(),
                                        aFactory.Layout());
    iVisual->EnableTransformationL();
    
    // create background underlay anchor layout 
    //to act as a black screen and avoid overlapping images                                      
    iBackgroundOverlayVisual = 
        CAlfImageVisual::AddNewL( aFactory.VisualOwner(), iVisual); 
    CAlfTexture& backgroundTexture = 
    	iUiUtility->GlxTextureManager().CreateFlatColourTextureL(KRgbBlack);
    iBackgroundOverlayVisual->SetClipping(ETrue);	
    iBackgroundOverlayVisual->SetImage(TAlfImage(backgroundTexture));	
    // create main visual
    iMainVisual = 
        CAlfAnchorLayout::AddNewL( aFactory.VisualOwner(), iVisual );    
                                        
    // create the child image visual
    iImageVisual = 
        CAlfImageVisual::AddNewL( aFactory.VisualOwner(), iMainVisual );
	iImageVisual->SetScaleMode(CAlfImageVisual::EScaleNormal);
    // Turn on clipping only if cover-mode has been chosen
    iImageVisual->SetClipping(ETrue);

	User::LeaveIfError( iMainVisual->SetRelativeAnchorRect(
  	0, EAlfAnchorOriginLeft, EAlfAnchorOriginTop, TAlfRealPoint(),
	 EAlfAnchorOriginRight, EAlfAnchorOriginBottom, TAlfRealPoint() ) );

	// get screen size
	SetVisible(EFalse);
	TSize screenSize = iUiUtility->DisplaySize();
    RefreshLayout( screenSize );	
    }
        
// -----------------------------------------------------------------------------
// SetScaleMode
// -----------------------------------------------------------------------------
//
EXPORT_C void CGlxVisualObject::SetScaleMode(CAlfImageVisual::TScaleMode aMode)
    {
    TRACER("CGlxVisualObject::SetScaleMode");
    iImageVisual->SetScaleMode(aMode);
    }
    
// -----------------------------------------------------------------------------
// Reset state of the object as if it had just been constructed
// -----------------------------------------------------------------------------
//
void CGlxVisualObject::Reset() 
    {
    TRACER("CGlxVisualObject::Reset");
    SetVisible(EFalse);
    StopAnimation();
    iAnimateWhenAttributesAvailable = EFalse;
    iUiUtility->GlxTextureManager().RemoveTexture(iImage.Texture());
    }

// -----------------------------------------------------------------------------
// Remove and delete all child visuals of the layout
// @param aLayout layout to reset
// -----------------------------------------------------------------------------
//	
void CGlxVisualObject::ResetLayout( CAlfVisual& /*aVisual*/ )
    {
    //to be used when layouts are back
    // until no visuals left
    }
    
// -----------------------------------------------------------------------------
// Visual
// -----------------------------------------------------------------------------
CAlfVisual* CGlxVisualObject::Visual()
	{
	TRACER("CGlxVisualObject::Visual");
	return iVisual;
	}
    
// -----------------------------------------------------------------------------
// SetVisible
// -----------------------------------------------------------------------------
void CGlxVisualObject::SetVisible( TBool aVisible )
    {
    TRACER("CGlxVisualObject::SetVisible");
    if(aVisible)
	    {
	    iVisual->SetOpacity(  TAlfTimedValue(1.0 , 0 ));	
	    }
    else
	    {
	    iVisual->SetOpacity( TAlfTimedValue(0.0, 0 ));	
	    }
    
    }

// -----------------------------------------------------------------------------
// SetIndex
// -----------------------------------------------------------------------------
void CGlxVisualObject::SetIndex( TInt aIndex )
	{
	TRACER("CGlxVisualObject::SetIndex");
	GLX_LOG_INFO1("CGlxVisualObject::SetIndex %d",aIndex);
	iIndex = aIndex;
	}

// -----------------------------------------------------------------------------
// SetImage
// -----------------------------------------------------------------------------
void CGlxVisualObject::SetImage( TAlfImage aImage )
	{
	TRACER("CGlxVisualObject::SetImage");
	iImageVisual->SetImage( aImage );
	iImage = aImage;
	iImageValid = ETrue;
	}

// -----------------------------------------------------------------------------
// Image
// -----------------------------------------------------------------------------
TAlfImage CGlxVisualObject::Image()
	{
	TRACER("CGlxVisualObject::Image");
	return iImage;
	}

// -----------------------------------------------------------------------------
// RefreshLayout
// the visual list has requested us to refresh the layout
// -----------------------------------------------------------------------------
void CGlxVisualObject::RefreshLayout( TSize /*aScreenSize*/ )
	{
	TRACER("CGlxVisualObject::RefreshLayout");
    // get texture manager
    CGlxTextureManager& textureMgr = iUiUtility->GlxTextureManager();
    // get new size, note that this is synchronous c/s call
	TSize visSize = Visual()->Size().ValueNow().AsSize();

	// check if visual size has changed since last time
	if( visSize != iVisSize )
	    {
	    // store size
	    iVisSize = visSize;
	    
	    // get the media id and id space id for this index
	    TGlxMedia item = iMediaList.Item( iIndex );
	    TGlxIdSpaceId idspace = iMediaList.IdSpaceId( iIndex );

        // check if there was a better thumbnail available
        if( textureMgr.TextureNeedsUpdating( item, idspace, visSize ) )
            {
            // need to update the texture
            TRAP_IGNORE(CAlfTexture& texture = 
                textureMgr.CreateThumbnailTextureL( 
                    item, idspace, visSize, this );
            // set the new texture in place
        	SetImage( TAlfImage( texture ) ));
            }
        
        // update positions of overlay icons            
        UpdateIconAnchors( Image().Texture(), visSize );             
	    }
	}

// -----------------------------------------------------------------------------
// HandleAttributesAvailableL
// -----------------------------------------------------------------------------
//
void CGlxVisualObject::HandleAttributesAvailableL(
    const TGlxIdSpaceId& aIdSpaceId, const TGlxMedia& aItem,
    const RArray<TMPXAttribute>& /*aAttributes*/)
    {
    TRACER("CGlxVisualObject::HandleAttributesAvailableL");
    TBool animate = ( EHasDefaultIcon == Status() );

    // get texture manager
    CGlxTextureManager& textureMgr = iUiUtility->GlxTextureManager();
    // get new size, note that this is synchronous c/s call          
    TSize visSize = iUiUtility->DisplaySize();

    // check if there was a better thumbnail available
    if( textureMgr.TextureNeedsUpdating( aItem, aIdSpaceId, visSize ) )
        {
        // need to update the texture
        CAlfTexture& texture = 
            textureMgr.CreateThumbnailTextureL( 
                aItem, aIdSpaceId, visSize, this );
        // set the new texture in place
    	SetImage( TAlfImage( texture ) );

        // update positions of overlay icons 
        UpdateIconAnchors( Image().Texture(), visSize );             

        if ( animate && iObserver )
            {
            iObserver->ThumbnailLoadedL( *this );
            }
        }

    if ( iAnimateWhenAttributesAvailable )
        {
        TryAnimateL(aItem);
        }

    }

// -----------------------------------------------------------------------------
// StartAnimation
// -----------------------------------------------------------------------------
void CGlxVisualObject::StartAnimation( CAlfTexture& aAnimatedTexture )
    {
    TRACER("CGlxVisualObject::StartAnimation");
    // if we have an old texture
    if ( iAnimatedTexture )
        {
        // release the old texture
        iUiUtility->GlxTextureManager().RemoveTexture( *iAnimatedTexture );
        iAnimatedTexture = NULL;
        }
    // store the texture pointer so that we can stop it without a 
    // reference to the texture
    iAnimatedTexture = &aAnimatedTexture;

    // start the animation
    aAnimatedTexture.StartAnimation();
    // set the image to the visual
    iImageVisual->SetImage( TAlfImage( aAnimatedTexture ) );
    }
    
// -----------------------------------------------------------------------------
// StopAnimation
// -----------------------------------------------------------------------------
void CGlxVisualObject::StopAnimation()
    {
    TRACER("CGlxVisualObject::StopAnimation");
    if ( iAnimatedTexture )
        {
        iImageVisual->SetImage( iImage );

        // stop the animation
        iAnimatedTexture->StopAnimation();
        
        // release the texture
        iUiUtility->GlxTextureManager().RemoveTexture( *iAnimatedTexture );
        iAnimatedTexture = NULL;
        }
    }
    
// -----------------------------------------------------------------------------
// SetAnimateWhenAttributesAvailable
// -----------------------------------------------------------------------------
void CGlxVisualObject::SetAnimateWhenAttributesAvailable(TBool aFlag)
    {
    TRACER("CGlxVisualObject::SetAnimateWhenAttributesAvailable");
    iAnimateWhenAttributesAvailable = aFlag;
    }

// -----------------------------------------------------------------------------
// TryAnimateL
// -----------------------------------------------------------------------------
//
void CGlxVisualObject::TryAnimateL(const TGlxMedia& aItem)
    {
    TRACER("CGlxVisualObject::TryAnimateL");
    TInt frameCount = 0;
    TSize mediaItemSize( KErrNotFound, KErrNotFound );
    aItem.GetDimensions( mediaItemSize );
    if ( aItem.GetFrameCount( frameCount ) )
        {
        const TDesC& uri = aItem.Uri();
        if (frameCount > 1 && uri.Length() > 0)
            {
            // create the animated texture from the URI
    		CAlfTexture& animTexture =
    		   iUiUtility->GlxTextureManager().CreateAnimatedGifTextureL( uri, mediaItemSize,
    		           aItem, aItem.IdSpaceId());
            StartAnimation( animTexture );
    		}
        SetAnimateWhenAttributesAvailable(EFalse);
		}
    else
        {
        SetAnimateWhenAttributesAvailable(ETrue);
        }
    }

// -----------------------------------------------------------------------------
// RemoveOldZoomTiles
// -----------------------------------------------------------------------------
//
void CGlxVisualObject::RemoveOldZoomTiles(const TGlxMedia& aItem)
    {
    TRACER("CGlxVisualObject::RemoveOldZoomTiles");
    const CGlxMedia* properties = aItem.Properties();
    TInt firstPosition = iZoomTiles.Count();

    for ( TInt i = iZoomTiles.Count() - 1; i >= 0; i-- )
        {
        if ( !(properties && properties->IsSupported(TMPXAttribute(
                        KGlxMediaIdThumbnail, iZoomTiles[i].iAttributeId))) )
            {
            RemoveZoomTile(i);
            firstPosition = i;
            }
        }

    ReanchorZoomTiles( firstPosition );
    }

// -----------------------------------------------------------------------------
// AddNewZoomTilesL
// -----------------------------------------------------------------------------
//
void CGlxVisualObject::AddNewZoomTilesL(TGlxIdSpaceId aIdSpaceId,
            const TGlxMedia& aItem, const RArray<TMPXAttribute>& aAttributes)
    {
    TRACER("CGlxVisualObject::AddNewZoomTilesL");
    // Get dimension if we don't already have it
    if ( (iDimensions.iWidth == 0 || iDimensions.iHeight == 0) )
        {
        // Ignore success/failure return, test dimension instead
        aItem.GetDimensions(iDimensions);
        }

    if ( iDimensions.iWidth == 0 || iDimensions.iHeight == 0 )
        {
        return;
        }

    TInt firstPosition = iZoomTiles.Count();

    // Check new attributes for cropped thumbnails
    TInt count = aAttributes.Count();
    for ( TInt i = 0; i < count; i++ )
        {
        TMPXAttribute attr(aAttributes[i]);

        if ( KGlxMediaIdThumbnail == attr.ContentId()
            && !GlxIsFullThumbnailAttribute( attr.AttributeId() ) )
            {
            const CGlxThumbnailAttribute* thumbnail = 
                                          aItem.ThumbnailAttribute( attr );
            if ( thumbnail )
                {
                TInt position = AddZoomTileL( aItem, attr, aIdSpaceId,
                                                thumbnail->iCroppingRect );

                if ( position < firstPosition )
                    {
                    firstPosition = position;
                    }
                }
            }
        }

    ReanchorZoomTiles( firstPosition );
    }

// -----------------------------------------------------------------------------
// RemoveZoomTile
// -----------------------------------------------------------------------------
//
void CGlxVisualObject::RemoveZoomTile(TInt aIndex)
    {
    TRACER("CGlxVisualObject::RemoveZoomTile");
    __ASSERT_ALWAYS(0 <= aIndex && aIndex < iZoomTiles.Count(),
                                            Panic(EGlxPanicIllegalArgument));

    CAlfImageVisual* visual = iZoomTiles[aIndex].iVisual;
	const TAlfImage& image = visual->Image();
	if( image.HasTexture() )
	    {
        iUiUtility->GlxTextureManager().RemoveTexture( image.Texture() );
	    }
	iVisual->Owner().Remove(visual);   // Caller gets ownership of the visual
    delete visual;
    iZoomTiles.Remove(aIndex);
    }

// ---------------------------------------------------------------------------
// AddZoomTileL
// ---------------------------------------------------------------------------
//
TInt CGlxVisualObject::AddZoomTileL(
                    const TGlxMedia& /*aItem*/, const TMPXAttribute& aAttribute,
                    TGlxIdSpaceId /*aIdSpaceId*/, const TRect& aCroppingRect )
    {
    TRACER("CGlxVisualObject::AddZoomTileL");
    // Reserve space for new tile
    iZoomTiles.ReserveL( iZoomTiles.Count() + 1 );

    // Extract zoom level field from attribute ID
    TInt zoomLevel = GlxZoomedThumbnailZoomLevel( aAttribute.AttributeId() );
    TInt position = 0;
    // Lowest zoom level goes to highest position (front)
    while ( position < iZoomTiles.Count()
            && zoomLevel < iZoomTiles[position].iZoomLevel )
        {
        position++;
        }

    CAlfImageVisual* visual = CAlfImageVisual::AddNewL(
                            static_cast<CAlfControl&>( iMainVisual->Owner() ),
                            iMainVisual );
    CleanupStack::PushL(visual);

    // Set temporary anchor to reserve space in anchors array
    TInt ordinal = iMainVisual->ChildOrdinal( iMainVisual->Count() - 1 );
    User::LeaveIfError( iMainVisual->SetRelativeAnchorRect( ordinal,
            EAlfAnchorOriginLeft, EAlfAnchorOriginTop, TAlfRealPoint(),
            EAlfAnchorOriginLeft, EAlfAnchorOriginTop, TAlfRealPoint() ) );

    // Move new visual to correct position
    iMainVisual->Reorder(*visual, position + 1);   // Full image thumbnail is position 0

    TReal32 imageWidth = iDimensions.iWidth;
    TReal32 imageHeight = iDimensions.iHeight;

    TZoomTile tile;
    tile.iVisual = visual;
    tile.iAttributeId = aAttribute.AttributeId();
    tile.iZoomLevel = zoomLevel;
    tile.iTopLeft.iX = aCroppingRect.iTl.iX / imageWidth;
    tile.iTopLeft.iY = aCroppingRect.iTl.iY / imageHeight;
    tile.iBottomRight.iX = aCroppingRect.iBr.iX / imageWidth;
    tile.iBottomRight.iY = aCroppingRect.iBr.iY / imageHeight;
    // Shouldn't leave due to reservation above
    iZoomTiles.InsertL(tile, position);
    CleanupStack::Pop(visual);

    return position;
    }

// ---------------------------------------------------------------------------
// ReanchorZoomTiles
// ---------------------------------------------------------------------------
//    
void CGlxVisualObject::ReanchorZoomTiles( TInt aFirstPosition )
    {
    TRACER("CGlxVisualObject::ReanchorZoomTiles");
    TInt count = iZoomTiles.Count();
    for ( TInt i = aFirstPosition; i < count; i++ )
        {
        TZoomTile& tile( iZoomTiles[i] );
        TInt ordinal = iMainVisual->ChildOrdinal( i + 1 );

        TInt error = iMainVisual->SetRelativeAnchorRect( ordinal,
            EAlfAnchorOriginLeft, EAlfAnchorOriginTop, tile.iTopLeft,
            EAlfAnchorOriginLeft, EAlfAnchorOriginTop, tile.iBottomRight );
        if ( KErrNone != error )
            {
            // Should never fail since space was reserved in the anchor array
            GLX_LOG_WARNING1( "Failed to update anchor, error %d", error );
            __ASSERT_DEBUG( EFalse, Panic( EGlxPanicUnhandledError ) );
            }
        }
    }

// -----------------------------------------------------------------------------
// AddIconL
// -----------------------------------------------------------------------------
//    
void CGlxVisualObject::AddIconL( const CAlfTexture& aTexture, 
                        NGlxIconMgrDefs::TGlxIconPosition /*aIconPos*/, 
                        TBool /*aForeground*/, TBool /*aStretch*/, TInt /*aBorderMargin*/,
                                                TReal32 /*aWidth*/, TReal32 /*aHeight*/ )
    {
    TRACER("CGlxVisualObject::AddIconL");
    //currently foreground and background visuals are not being used
    //the implications needs to be studied
    //background visual is used mainly to provide a background for small visual objects
    //foreground visual is used to supply specialised icons for clips
    
    
    // Set image for corrupted thumbnail
      SetImage(TAlfImage( aTexture ));
   
    }

// -----------------------------------------------------------------------------
// RemoveIcon
// -----------------------------------------------------------------------------
//    
TBool CGlxVisualObject::RemoveIcon(  const CAlfTexture& aTexture )
    {
    TRACER("CGlxVisualObject::RemoveIcon");
    
   TInt visPos = FindExistingTexture( aTexture, ETrue );
    if( visPos != KErrNotFound )
        {       
        DoRemoveIcon( *iMainVisual, 
                            iForegroundIconAnchors, visPos );
        }
    else 
        {
        visPos = FindExistingTexture( aTexture, EFalse );        
        }
    
    return ( visPos != KErrNotFound );
    
    }

// -----------------------------------------------------------------------------
// SetIconVisibility
// -----------------------------------------------------------------------------
//        
void CGlxVisualObject::SetIconVisibility( const CAlfTexture& aTexture, TBool aVisible )
    {
    TRACER("CGlxVisualObject::SetIconVisibility");
    // find texture (assume it's a foreground visual)
    TInt pos = FindExistingTexture( aTexture, ETrue );
    if( pos != KErrNotFound )
        {
        CAlfVisual& vis = iMainVisual->Visual( pos );
        
        if( aVisible )
            {
            vis.SetOpacity( TAlfTimedValue( 1.0, KGlxOpacityFadeDuration ) );
            }
        else
            {
            vis.SetOpacity( TAlfTimedValue( 0.0, KGlxOpacityFadeDuration ) );
            }
        }
    }

// -----------------------------------------------------------------------------
// Status
// -----------------------------------------------------------------------------
//
CGlxVisualObject::TVisualStatus CGlxVisualObject::Status() const
    {
    TRACER("CGlxVisualObject::Status()");
    return iStatus;
    }

// -----------------------------------------------------------------------------
// SetStatus
// -----------------------------------------------------------------------------
//
void CGlxVisualObject::SetStatus( TVisualStatus aStatus )
    {
    TRACER("CGlxVisualObject::SetStatus");
    iStatus = aStatus;
    }

// -----------------------------------------------------------------------------
// SetObserver
// -----------------------------------------------------------------------------
//
TBool CGlxVisualObject::SetObserver( MGlxVisualObjectStatusObserver& aObserver )
    {
    TRACER("CGlxVisualObject::SetObserver");
    iObserver = &aObserver;
    return iImage.HasTexture();
    }

// -----------------------------------------------------------------------------
// TextureContentChangedL
// -----------------------------------------------------------------------------
//
void CGlxVisualObject::TextureContentChangedL( TBool aHasContent, CAlfTexture* /*aNewTexture */)
    {
    TRACER("CGlxVisualObject::TextureContentChangedL");
    if ( iObserver )
        {
        iObserver->VisualStatusChangedL( *this, iIndex, aHasContent );
        }
    }

// -----------------------------------------------------------------------------
// SetAnchors
// -----------------------------------------------------------------------------
//
void CGlxVisualObject::SetAnchors( TGlxIconAnchors& aAnchors, 
                        CAlfAnchorLayout& aLayout, TInt aPos, TBool aUseOffsets )
    {
    TRACER("CGlxVisualObject::SetAnchors");
    TAlfTimedPoint leftPoint = aAnchors.iTopLeftAnchor.iPosition;
    TAlfTimedPoint rightPoint = aAnchors.iBotRightAnchor.iPosition;
     
    if( aUseOffsets && 
        aAnchors.iTopLeftAnchor.iAnchorMetric == EAlfAnchorMetricRelativeToSize )
        {
        // update horizontal positions if there is a horizontal offset  
        if( aAnchors.iTopLeftAnchor.iAnchorHorizOrigin == EAlfAnchorOriginLeft )
            {
            leftPoint.iX.SetValueNow( leftPoint.iX.Target() + iHoriIconOffset );
            
            if( rightPoint.iX.Target() == 1.0)
                {
                rightPoint.iX.SetValueNow( rightPoint.iX.Target() - iHoriIconOffset );
                }
            
            }
        else if ( aAnchors.iTopLeftAnchor.iAnchorHorizOrigin == EAlfAnchorOriginRight )
            {
            if( leftPoint.iX.Target() == -1.0)
                {
                leftPoint.iX.SetValueNow( leftPoint.iX.Target() + iHoriIconOffset );
                }
                 
            rightPoint.iX.SetValueNow( rightPoint.iX.Target() - iHoriIconOffset );
            }
        else
            {
            
            }
        
        // update vertical positions if there is a vertical offset    
        if( aAnchors.iTopLeftAnchor.iAnchorVertiOrigin == EAlfAnchorOriginTop )
            {
            leftPoint.iY.SetValueNow( leftPoint.iY.Target() + iVertIconOffset );
            if( rightPoint.iY.Target() == 1.0)
                {
                rightPoint.iY.SetValueNow( rightPoint.iY.Target() - iVertIconOffset );
                }
            }
        else if ( aAnchors.iTopLeftAnchor.iAnchorHorizOrigin == EAlfAnchorOriginBottom )
            {
            if( leftPoint.iY.Target() == -1.0)
                {
                leftPoint.iY.SetValueNow( leftPoint.iY.Target() + iVertIconOffset );
                }
            rightPoint.iY.SetValueNow( rightPoint.iY.Target() - iVertIconOffset );
            }
        else
            {
            
            }               
        }
   
    
    aLayout.SetAnchor( EAlfAnchorTopLeft, aPos,
                    aAnchors.iTopLeftAnchor.iAnchorHorizOrigin, 
                    aAnchors.iTopLeftAnchor.iAnchorVertiOrigin,
                    aAnchors.iTopLeftAnchor.iAnchorMetric,
                    aAnchors.iTopLeftAnchor.iAnchorMetric,
                    leftPoint );
                    
    aLayout.SetAnchor( EAlfAnchorBottomRight, aPos,
                    aAnchors.iBotRightAnchor.iAnchorHorizOrigin, 
                    aAnchors.iBotRightAnchor.iAnchorVertiOrigin,
                    aAnchors.iBotRightAnchor.iAnchorMetric,
                    aAnchors.iBotRightAnchor.iAnchorMetric,
                    rightPoint );
                    
    aLayout.UpdateChildrenLayout();
    }

// -----------------------------------------------------------------------------
// GenerateAnchors
// -----------------------------------------------------------------------------
//    
void CGlxVisualObject::GenerateAnchors( TGlxIconAnchors& aAnchors,
                                        const CAlfTexture& aTexture, 
                                    NGlxIconMgrDefs::TGlxIconPosition aIconPos, 
                                            TInt aBorderMargin, TBool aStretch, 
                                            TReal32 aWidth, TReal32 aHeight )
    {
    TRACER("CGlxVisualObject::GenerateAnchors");
    // top-left anchor
    TGlxAnchorDetails topLeftAnchor;
    TGlxAnchorDetails bottomRightAnchor;
    
    if( aStretch)
        {
        topLeftAnchor.iAnchorMetric = EAlfAnchorMetricRelativeToSize;
        bottomRightAnchor.iAnchorMetric = EAlfAnchorMetricRelativeToSize;
        }
     else
        {
        topLeftAnchor.iAnchorMetric = EAlfAnchorMetricAbsolute;
        bottomRightAnchor.iAnchorMetric = EAlfAnchorMetricAbsolute;
        }
        
    TInt textureWidth = aTexture.Size().iWidth + aBorderMargin;
    TInt textureHeight = aTexture.Size().iHeight + aBorderMargin;
   
    // 
    switch( aIconPos )
        {
        case NGlxIconMgrDefs::EGlxIconTopLeft:
            {
            topLeftAnchor.iAnchorHorizOrigin = EAlfAnchorOriginLeft;
            topLeftAnchor.iAnchorVertiOrigin = EAlfAnchorOriginTop;
            
            bottomRightAnchor.iAnchorHorizOrigin = EAlfAnchorOriginLeft;
            bottomRightAnchor.iAnchorVertiOrigin = EAlfAnchorOriginTop;
            
            if( aStretch )
                {
                topLeftAnchor.iPosition = TAlfTimedPoint( 0, 0 );
                bottomRightAnchor.iPosition = TAlfTimedPoint( aWidth, aHeight );
                }
            else
                {
                topLeftAnchor.iPosition = 
                        TAlfTimedPoint( aBorderMargin, aBorderMargin );
                bottomRightAnchor.iPosition = 
                      TAlfTimedPoint( textureWidth,textureHeight);
                }
            
            break;
            }
        case NGlxIconMgrDefs::EGlxIconTopRight:
            {
            topLeftAnchor.iAnchorHorizOrigin = EAlfAnchorOriginRight;
            topLeftAnchor.iAnchorVertiOrigin = EAlfAnchorOriginTop;
            
            bottomRightAnchor.iAnchorHorizOrigin = EAlfAnchorOriginRight;
            bottomRightAnchor.iAnchorVertiOrigin = EAlfAnchorOriginTop;
            
            if( aStretch )
                {
                topLeftAnchor.iPosition = TAlfTimedPoint( -aWidth, 0.0 );
                bottomRightAnchor.iPosition = TAlfTimedPoint( 0.0, aHeight );
                }
            else
                {
                topLeftAnchor.iPosition = 
                    TAlfTimedPoint( -textureWidth, aBorderMargin );
                bottomRightAnchor.iPosition = 
                    TAlfTimedPoint( -aBorderMargin, textureHeight);
                }            
            break;
            }
        case NGlxIconMgrDefs::EGlxIconBottomLeft:
            {
            topLeftAnchor.iAnchorHorizOrigin = EAlfAnchorOriginLeft;
            topLeftAnchor.iAnchorVertiOrigin = EAlfAnchorOriginBottom;
            
            bottomRightAnchor.iAnchorHorizOrigin = EAlfAnchorOriginLeft;
            bottomRightAnchor.iAnchorVertiOrigin = EAlfAnchorOriginBottom;
           
            if( aStretch)
                {
                topLeftAnchor.iPosition = TAlfTimedPoint( aWidth, -aHeight );
                bottomRightAnchor.iPosition = TAlfTimedPoint( 0.0, 1.0 );
                }
            else
                {
                topLeftAnchor.iPosition = 
                    TAlfTimedPoint( aBorderMargin, -textureHeight );
                bottomRightAnchor.iPosition = 
                    TAlfTimedPoint( textureWidth, aBorderMargin );
                }  
                
            break;
            }
        case NGlxIconMgrDefs::EGlxIconBottomRight:
            {
            topLeftAnchor.iAnchorHorizOrigin = EAlfAnchorOriginRight;
            topLeftAnchor.iAnchorVertiOrigin = EAlfAnchorOriginBottom;
            
            bottomRightAnchor.iAnchorHorizOrigin = EAlfAnchorOriginRight;
            bottomRightAnchor.iAnchorVertiOrigin = EAlfAnchorOriginBottom;
                          
            if( aStretch)
                {
                topLeftAnchor.iPosition = TAlfTimedPoint( -aWidth, -aHeight );
                bottomRightAnchor.iPosition = TAlfTimedPoint( 0.0, 0.0 );
                }
            else
                {
                topLeftAnchor.iPosition = 
                    TAlfTimedPoint(  -textureWidth, -textureHeight );
                bottomRightAnchor.iPosition =
                    TAlfTimedPoint( -aBorderMargin, -aBorderMargin );
                }  
                
            break;
            }
        case NGlxIconMgrDefs::EGlxIconCentred:
            {
            topLeftAnchor.iAnchorHorizOrigin = EAlfAnchorOriginHCenter;
            topLeftAnchor.iAnchorVertiOrigin = EAlfAnchorOriginVCenter;
            
            bottomRightAnchor.iAnchorHorizOrigin = EAlfAnchorOriginHCenter;
            bottomRightAnchor.iAnchorVertiOrigin = EAlfAnchorOriginVCenter;
            
            if( aStretch)
                {
                topLeftAnchor.iPosition = TAlfTimedPoint( -aWidth/2, -aHeight/2 );
                bottomRightAnchor.iPosition = TAlfTimedPoint( aWidth/2, aHeight/2 );
                }
            else
                {
                topLeftAnchor.iPosition = 
                    TAlfTimedPoint( -textureWidth/2, -textureHeight/2 );
                bottomRightAnchor.iPosition = 
                    TAlfTimedPoint( textureWidth/2, textureHeight/2 );
                } 
                
            break;
            }
        default:
            {
            
            }
        };

    aAnchors.iTexture = &aTexture;
    aAnchors.iTopLeftAnchor = topLeftAnchor;
    aAnchors.iBotRightAnchor = bottomRightAnchor;
    }

// -----------------------------------------------------------------------------
// FindExistingTexture
// -----------------------------------------------------------------------------
// 
TInt CGlxVisualObject::FindExistingTexture( const CAlfTexture& aTexture,
                                            TBool aForeground )
    {
    TRACER("CGlxVisualObject::FindExistingTexture");
    TGlxIconAnchors icon;
    icon.iTexture = &aTexture;

    return ( aForeground )
            ? iForegroundIconAnchors.Find( icon, TGlxIconAnchors::Match )
            : iBackgroundIconAnchors.Find( icon, TGlxIconAnchors::Match );
    }

// -----------------------------------------------------------------------------
// DoRemoveIcon
// -----------------------------------------------------------------------------
//    
void CGlxVisualObject::DoRemoveIcon( CAlfAnchorLayout& aLayout, 
                        RArray<TGlxIconAnchors>& aAnchorsArray, TInt aPos )
    {
    TRACER("CGlxVisualObject::DoRemoveIcon");
    // First remove the icon visual
    if ( aPos < aLayout.Count() )
        {
        CAlfVisual* visual = &aLayout.Visual( aPos );
        visual->Owner().Remove( visual );
        delete visual;
        }

    // after an icon has been removed from layout the anchor for all icons with
    // positions in layout after that of removed icon will need to be updated
    // due to HUI issue.
    TInt count = aAnchorsArray.Count();
    
    if ( aPos < count )
        {
        // removed anchor information for icon that has been removed
        aAnchorsArray.Remove( aPos );
        
        count--;
        
        // reset anchors for remaining icons
        // only for icons with positions that were after 
        // removed icon
        for ( TInt i = aPos; i < count; i++ )
            {
            SetAnchors( aAnchorsArray[i], aLayout, i );
            }
        }
    }

// -----------------------------------------------------------------------------
// UpdateIconAnchors
// -----------------------------------------------------------------------------
//    
void CGlxVisualObject::UpdateIconAnchors( const CAlfTexture& aTexture, TSize aVisSize )
    {
    TRACER("CGlxVisualObject::UpdateIconAnchors");
    TInt iconCount = iForegroundIconAnchors.Count();
    
    // only proceed if there are foreground icons
    if( iconCount )  
        {
        TSize textureSize = aTexture.Size();
        
        iVertIconOffset = 0.0;
        iHoriIconOffset = 0.0;
        
        TReal32 visWidth = ( TReal32 )aVisSize.iWidth;
        TReal32 visHeight = ( TReal32 )aVisSize.iHeight;

        TReal32 textWidth = ( TReal32 )textureSize.iWidth;
        TReal32 textHeight = ( TReal32 )textureSize.iHeight;
        
        if( textWidth == 0 || textHeight == 0 )
            {
            return;
            }
        
        // compare aspect ratios between visual and texture
        // and calculate either horizontal or vertical offset
        if( (visWidth * textHeight ) < ( textWidth * visHeight ) )
            {
            TInt dispHeight = textHeight * visWidth/textWidth; 
            
            iVertIconOffset = ( visHeight - dispHeight ) /  visHeight;
            iVertIconOffset /= 2;
            }
        else
            {
            TInt dispWidth = textWidth * visHeight/textHeight;
            
            iHoriIconOffset = ( visWidth - dispWidth ) / visWidth;
            iHoriIconOffset /= 2;
            }
        }
    
    // move anchor positon of foreground anchor layout
    iVisual->SetRelativeAnchorRect( KGlxForegroundAnchorOrdinal, 
                EAlfAnchorOriginLeft, EAlfAnchorOriginTop, 
                TAlfRealPoint( iHoriIconOffset, iVertIconOffset),
                EAlfAnchorOriginRight, EAlfAnchorOriginBottom, 
                TAlfRealPoint( -iHoriIconOffset, - iVertIconOffset));  
    }

// ---------------------------------------------------------------------------
// TGlxIconAnchors::Match
// ---------------------------------------------------------------------------
//    
TBool CGlxVisualObject::TGlxIconAnchors::Match(
                const TGlxIconAnchors& aIcon1, const TGlxIconAnchors& aIcon2 )
    {
    TRACER("CGlxVisualObject::Match");
    return ( aIcon1.iTexture == aIcon2.iTexture );
    }