widgetmodel/alfwidgetmodel/src/alfmeshvisualattributesetter.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:23:18 +0100
branchRCL_3
changeset 20 0e9bb658ef58
parent 0 e83bab7cf002
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201033 Kit: 201035

/*
* Copyright (c) 2007 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:   Implements attributesetters for MeshVisual.
*
*/



#include "alf/alfattribute.h"
#include "alf/alfmeshvisualattributesetter.h"
#include "alf/alfattributevaluetype.h"
#include <alf/alfvisual.h>
#include <alf/alfattributeexception.h>
#include <alf/alfvisualexception.h>
#include "alf/alfattributecontainer.h"
#include <libc/string.h>
#include <osn/ustring.h>
#include "alf/attrproperty.h"
#include <uiacceltk/HuiRealPoint.h>

#include <alf/alfmeshvisual.h>
#include <alf/alftexture.h>
#include <utf.h>
#include <alf/alfenv.h>
#include <alf/alfdataexception.h>
#include <alf/alfdisplay.h>

#include <alf/alfbrusharray.h>
#include <alf/alfframebrush.h>


#include <alf/alfeventhandler.h>
#include <alf/alfevent.h>
#include <osn/alfptrvector.h>


using namespace osncore;

using namespace duiuimodel::meshvisualattributes;
using namespace duiuimodel::commonvisualattributes;

namespace Alf
    {

class AlfMeshVisualAttributeSetterImpl
    {
public:
    AlfMeshVisualAttributeSetterImpl();
    ~AlfMeshVisualAttributeSetterImpl();
public:
    //Keep track of loaded texture for imagevisuals.
    //Texture manager doesn't unload the texture from memory untill Env is deleted.
    //Hence need to unload them once attribute setter is deleted.
    AlfPtrVector<CAlfTexture> mLoadedTextures;
    //Env needed to access TextureManager while unloading textures.
    CAlfEnv* mEnv;
    };

AlfMeshVisualAttributeSetterImpl::AlfMeshVisualAttributeSetterImpl()
    {
    //Do not delete textures here as they may be in use by the visuals that have not been deleted.
    mEnv = CAlfEnv::Static();
    mLoadedTextures.setAutoDelete(false);
    }

AlfMeshVisualAttributeSetterImpl::~AlfMeshVisualAttributeSetterImpl()
    {
    //Unload all loaded textures created by this attributesetter to free up the memory.
    for (int i =0;i<mLoadedTextures.count();i++)
        {
        CAlfTexture* Texture = mLoadedTextures[i];
        mEnv->TextureManager().UnloadTexture(Texture->Id());
        }
    mLoadedTextures.clear();
    }

// ======== MEMBER FUNCTIONS ========

// ---------------------------------------------------------------------------
// Constructor.
// ---------------------------------------------------------------------------
//
OSN_EXPORT AlfMeshVisualAttributeSetter::AlfMeshVisualAttributeSetter()
    {
    mImpl.reset(new (EMM) AlfMeshVisualAttributeSetterImpl());
    }

// ---------------------------------------------------------------------------
// Destructor.
// ---------------------------------------------------------------------------
//
OSN_EXPORT AlfMeshVisualAttributeSetter::~AlfMeshVisualAttributeSetter()
    {
    }


// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
//
IAlfVariantType* AlfMeshVisualAttributeSetter::getData(AlfAttribute& aAttr, IAlfMap* aData)
    {
    IAlfVariantType* data = 0;
    const char* dataField = aAttr.getDataField();
    if (dataField)
        {
        data = aData->item(UString(dataField));
        }
    return data;
    }

// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
//
int AlfMeshVisualAttributeSetter::getTime(const AlfAttribute& aAttr, bool aImmediate)
    {
    int time = 0;
    if (!aImmediate)
        {
        time = aAttr.getTime();
        }

    return time;
    }

// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
//

void AlfMeshVisualAttributeSetter::handleDynamicDataAttribute(CAlfVisual & aVisual,
        AlfAttribute& aAttr, AlfAttributeContainer& aContainer, IAlfMap* aData)
    {
    if (!doHandleDynamicDataAttribute(aVisual, aAttr, aContainer, aData))
        {
        AlfCommonVisualAttributeSetter::handleDynamicDataAttribute(
            aVisual, aAttr, aContainer, aData);
        }
    }

// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
//
void AlfMeshVisualAttributeSetter::handleStaticDataAttribute(
    CAlfVisual &aVisual, AlfAttribute& aAttr,
    AlfAttributeContainer& aContainer, IAlfMap* aData)
    {
    CAlfMeshVisual* meshVisual = dynamic_cast<CAlfMeshVisual*>(&aVisual);
    if (!meshVisual)
        {
        ALF_THROW ( AlfDataException, ECommonError, "AlfMeshVisualAttributeSetter" )
        }
    if (!aData)  ALF_THROW ( AlfDataException, EInvalidVariantDataType, "AlfMeshVisualAttributeSetter" )

        const char* dataField = aAttr.getDataField();
    if ( !dataField )  ALF_THROW ( AlfDataException, EInvalidAttribute, "AlfMeshVisualAttributeSetter" )

        IAlfVariantType* data = aData->item ( UString(dataField));

    const char* attrName = aAttr.name();

    if (data)
        {
        if (!strcmp(attrName,KMeshType))
            {
            if (data->type() == IAlfVariantType::EInt)
                {
                int val = data->integer();
                TRAPD(err,meshVisual->CreateMeshL(val));
                if (err!=KErrNone)
                    {
                    ALF_THROW ( AlfDataException, err, "AlfMeshVisualAttributeSetter")
                    }
                }
            }
        else if (!strcmp(attrName, KImagePath))
            {
            if (data->type() == IAlfVariantType::EString)
                {
                TPtrC8 src;
                src.Set((TUint8*)data->string().getUtf8());

                HandleImagePathAttribute( src, meshVisual, primary );
                }
            }
        else if (!strcmp(attrName,KSecondaryImagePath))
            {
            if (data->type() == IAlfVariantType::EString)
                {
                TPtrC8 src;
                src.Set((TUint8*)data->string().getUtf8());

                HandleImagePathAttribute( src, meshVisual, secondary );
                }
            }
        else if (!strcmp(attrName,KSpecularImagePath))
            {
            if (data->type() == IAlfVariantType::EString)
                {
                TPtrC8 src;
                src.Set((TUint8*)data->string().getUtf8());

                HandleImagePathAttribute( src, meshVisual, specular );
                }
            }
        else
            {
            //check, if dynamic attribute(but set by user as static), if so, set attributes immediately.
            //If not, the function will call baseclass SetAttributeValue.
            if (!doHandleDynamicDataAttribute(aVisual, aAttr, aContainer, aData, true))
                {
                AlfCommonVisualAttributeSetter::handleStaticDataAttribute(
                    aVisual, aAttr, aContainer, aData);
                }
            }
        }
    }

// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
//
void AlfMeshVisualAttributeSetter::handleDynamicAttribute(CAlfVisual &aVisual,
        AlfAttribute& aAttr, AlfAttributeContainer& aContainer)
    {
    if (!doHandleDynamicAttribute(aVisual, aAttr, aContainer))
        {
        AlfCommonVisualAttributeSetter::handleDynamicAttribute(
            aVisual, aAttr, aContainer);
        }
    }

// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
//
void AlfMeshVisualAttributeSetter::handleStaticAttribute(
    CAlfVisual& aVisual, AlfAttribute& aAttr, AlfAttributeContainer& aContainer)
    {
    CAlfMeshVisual* meshVisual = dynamic_cast<CAlfMeshVisual*>(&aVisual);
    if(!meshVisual)
        {
        return;
        }
    const char* attrName = aAttr.name();

    // meshVisual attributes
    if (!strcmp(attrName,KMeshType))
        {
        int val = aAttr.intValue();
        TRAPD(err,meshVisual->CreateMeshL(val));
        if (err!=KErrNone)
            {
            ALF_THROW(AlfDataException, err, "AlfMeshVisualAttributeSetter");
            }
        }
    else if (!strcmp(attrName,KImagePath))
        {
        TPtrC8 src((TUint8*)aAttr.stringValue().getUtf8());        
        HandleImagePathAttribute( src, meshVisual, primary );
        }
    else if (!strcmp(attrName,KSecondaryImagePath))
        {
        TPtrC8 src((TUint8*)aAttr.stringValue().getUtf8());        
        HandleImagePathAttribute( src, meshVisual, secondary );
        }
    else if (!strcmp(attrName,KSpecularImagePath))
        {
        TPtrC8 src((TUint8*)aAttr.stringValue().getUtf8());        
        HandleImagePathAttribute( src, meshVisual, specular );
        }
    else
        {
        if (!doHandleDynamicAttribute(aVisual, aAttr, aContainer, true))
            {
            AlfCommonVisualAttributeSetter::handleStaticAttribute(aVisual, aAttr, aContainer);
            }
        }
    }


// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
//
OSN_EXPORT void AlfMeshVisualAttributeSetter::setAttributeValue(
    CAlfVisual &aVisual,
    AlfAttributeContainer* aContainer,
    IAlfMap* aData)
    {
    CAlfMeshVisual* meshVisual = dynamic_cast<CAlfMeshVisual*>(&aVisual);
    if (!meshVisual)
        {
        ALF_THROW ( AlfVisualException, EInvalidVisual, "AlfMeshVisualAttributeSetter")
        }

    AlfCommonVisualAttributeSetter::setAttributeValue(
        aVisual, aContainer, aData);
    }

// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
//
OSN_EXPORT TAlfCommand* AlfMeshVisualAttributeSetter::createCommand(
    CAlfVisual& /*aVisual*/, AlfAttributeContainer* /*aContainer*/,
    IAlfMap* /*aData*/, int /*aTransitionTime*/, CAlfVisual* /*aRefVisual*/)
    {
    TAlfCommand* cmd = 0;
    return cmd;
    }

// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
//
OSN_EXPORT void AlfMeshVisualAttributeSetter::createAndSendCommands(
    CAlfVisual& aVisual,
    AlfAttributeContainer* aContainer,
    CAlfVisual* aRefVisual )
    {

    // Call the base class implementation.It goes through its loop and checks if there are attributes
    // that it handles.
    AlfCommonVisualAttributeSetter::createAndSendCommands(
        aVisual,
        aContainer,
        aRefVisual );
    }

// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
//

bool AlfMeshVisualAttributeSetter::doHandleDynamicDataAttribute(CAlfVisual & aVisual,
        AlfAttribute& aAttr, AlfAttributeContainer& /*aContainer*/, IAlfMap* aData, bool aImmediate)
    {
    bool handled = true;

    if (!aData)
        {
        ALF_THROW ( AlfDataException, EInvalidVariantDataType, "AlfMeshVisualAttributeSetter" )
        }
    else
        {
        CAlfMeshVisual* meshVisual = dynamic_cast<CAlfMeshVisual*>(&aVisual);
        if(!meshVisual)
            {
            return false;
            }
        const char* attrName = aAttr.name();

        if ( !strcmp( attrName, KSecondaryAlpha ) )
            {
            const IAlfVariantType* data = getData(aAttr, aData);
            if (data && data->type() == IAlfVariantType::EReal)
                {
                TAlfTimedValue tVal(data->real(), getTime(aAttr, aImmediate));
                tVal.SetStyle(aAttr.getInterpolationStyle());
                tVal.SetMappingFunctionIdentifier( aAttr.getMappingFunctionId() );
                meshVisual->SetSecondaryAlpha( tVal );
                }
            }
        else if ( !strcmp( attrName, KYawAngle ) )
            {
            const IAlfVariantType* data = getData(aAttr, aData);
            if (data && data->type() == IAlfVariantType::EReal)
                {
                TAlfTimedValue tVal(data->real(), getTime(aAttr, aImmediate));
                tVal.SetStyle(aAttr.getInterpolationStyle());
                tVal.SetMappingFunctionIdentifier( aAttr.getMappingFunctionId() );
                meshVisual->SetYawAngle( tVal );
                }
            }
        else if ( !strcmp( attrName, KPitchAngle ) )
            {
            const IAlfVariantType* data = getData(aAttr, aData);
            if (data && data->type() == IAlfVariantType::EReal)
                {
                TAlfTimedValue tVal(data->real(), getTime(aAttr, aImmediate));
                tVal.SetStyle(aAttr.getInterpolationStyle());
                tVal.SetMappingFunctionIdentifier( aAttr.getMappingFunctionId() );
                meshVisual->SetPitchAngle( tVal );
                }
            }
        else if ( !strcmp( attrName, KScale ) )
            {
            const IAlfVariantType* data = getData(aAttr, aData);
            if (data && data->type() == IAlfVariantType::EReal)
                {
                TAlfTimedValue tVal(data->real(), getTime(aAttr, aImmediate));
                tVal.SetStyle(aAttr.getInterpolationStyle());
                tVal.SetMappingFunctionIdentifier( aAttr.getMappingFunctionId() );
                meshVisual->SetScale( tVal );
                }
            }
        else
            {
            handled = false;
            }
        }

    return handled;
    }

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
//
bool AlfMeshVisualAttributeSetter::doHandleDynamicAttribute(
    CAlfVisual &aVisual, AlfAttribute& aAttr,
    AlfAttributeContainer& /*aContainer*/, bool aImmediate)
    {
    CAlfMeshVisual* meshVisual = dynamic_cast<CAlfMeshVisual*>(&aVisual);
    if(!meshVisual)
        {
        return false;
        }

    const char* attrName = aAttr.name();
    bool handled = true;

    // KSecondaryAlpha
    if (!strcmp(attrName, KSecondaryAlpha))
        {
        TAlfTimedValue tVal(aAttr.getSourceValue()->realValue());
        tVal.SetTarget(aAttr.getTargetValue()->realValue(),getTime(aAttr, aImmediate));
        tVal.SetStyle( aAttr.getInterpolationStyle() );
        tVal.SetMappingFunctionIdentifier( aAttr.getMappingFunctionId() );
        meshVisual->SetSecondaryAlpha( tVal );
        }
    //KYawAngle
    else if (!strcmp(attrName, KYawAngle))
        {
        TAlfTimedValue tVal((TReal32)aAttr.getSourceValue()->realValue());
        tVal.SetTarget((TReal32)aAttr.getTargetValue()->realValue(),getTime(aAttr, aImmediate));
        tVal.SetStyle( aAttr.getInterpolationStyle() );
        tVal.SetMappingFunctionIdentifier( aAttr.getMappingFunctionId() );
        meshVisual->SetYawAngle( tVal );
        }
    //KPitchAngle
    else if (!strcmp(attrName, KPitchAngle))
        {
        TAlfTimedValue tVal((TReal32)aAttr.getSourceValue()->realValue());
        tVal.SetTarget((TReal32)aAttr.getTargetValue()->realValue(),getTime(aAttr, aImmediate));
        tVal.SetStyle( aAttr.getInterpolationStyle() );
        tVal.SetMappingFunctionIdentifier( aAttr.getMappingFunctionId() );
        meshVisual->SetPitchAngle( tVal );
        }
    //KScale
    else if (!strcmp(attrName,KScale))
        {
        TAlfTimedValue tVal((TReal32)aAttr.getSourceValue()->realValue());
        tVal.SetTarget((TReal32)aAttr.getTargetValue()->realValue(),getTime(aAttr, aImmediate));
        tVal.SetStyle( aAttr.getInterpolationStyle() );
        tVal.SetMappingFunctionIdentifier( aAttr.getMappingFunctionId());
        meshVisual->SetScale( tVal );
        }
    else // Call the base class implementation also.
        //It goes through the same loop again and checks if there are attributes that it handles.
        {
        handled = false;
        }

    return handled;
    }

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
//
void AlfMeshVisualAttributeSetter::HandleImagePathAttribute(
    const TPtrC8& aStringValue,
    CAlfMeshVisual* aVisual,
    imageCategory aImageCategory )
    {
    auto_ptr<HBufC> DesC;
    TRAPD( err, DesC.reset(CnvUtfConverter::ConvertToUnicodeFromUtf8L(aStringValue)));
    if ( err != KErrNone )
        {
        ALF_THROW( AlfDataException, err, "AlfMeshVisualAttributeSetter" );
        }

    // check if the texture is already loaded
    const TInt existingTextureId = aVisual->Env().TextureManager().TextureId(*(DesC.get()));
    if ( existingTextureId != KErrNotFound )
        {
        const CAlfTexture* texture = aVisual->Env().TextureManager().Texture( existingTextureId );

        if ( aImageCategory == primary )
            {
            aVisual->SetImage(TAlfImage(*texture));
            }
        else if ( aImageCategory == secondary )
            {
            aVisual->SetSecondaryImage(TAlfImage(*texture));
            }
        else // specular image
            {
            aVisual->SetSpecularImage(TAlfImage(*texture));
            }
        }
    else
        {
        mImpl->mLoadedTextures.resize(mImpl->mLoadedTextures.count()+1);

        CAlfTexture* texture = NULL;
        TRAP( err, texture = &(aVisual->Env().TextureManager().LoadTextureL(
            *(DesC.get()), EAlfTextureFlagDefault, KAlfAutoGeneratedTextureId)));

        if ( err != KErrNone )
            {
            ALF_THROW( AlfDataException, err, "AlfMeshVisualAttributeSetter" );
            }

        // This cannot fail because the array has already been resized
        mImpl->mLoadedTextures.insert(mImpl->mLoadedTextures.count(),texture);

        if ( aImageCategory == primary )
            {
            aVisual->SetImage(TAlfImage(*texture));
            }
        else if ( aImageCategory == secondary )
            {
            aVisual->SetSecondaryImage(TAlfImage(*texture));
            }
        else // specular image
            {
            aVisual->SetSpecularImage(TAlfImage(*texture));
            }
        }
    }


    }// Alf