--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/widgetmodel/alfwidgetmodel/src/alfvisualtemplate.cpp Thu Dec 17 08:56:02 2009 +0200
@@ -0,0 +1,671 @@
+/*
+* 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: Visual template class for alfred widget model.
+* This class creates and updates visual tree.
+*
+*/
+
+
+
+
+//INCLUDES
+#include <algorithm>
+#include <assert.h>
+#include <alf/alfcontrol.h>
+#include <alf/alfbrush.h>
+#include <alf/alfvisualfactory.h>
+#include <alf/alfbrusharray.h>
+#include <utf.h>
+#include <alf/alfimagevisual.h>
+#include <alf/alftexture.h>
+#include <alf/alfenv.h>
+#include <alf/alfexceptions.h>
+#include "alf/alfperf.h"
+#include <osn/osnnew.h>
+#include <alf/ialfelement.h>
+#include "alf/alfvisualtemplate.h"
+#include "alf/alfvarianttype.h"
+#include "alf/ialfattributesetter.h"
+#include "alf/alfattributecontainer.h"
+#include "alf/alfattribute.h"
+
+// The number of attribute setters is usually between 1 and 5
+static const int KAttributeArrayGranularity = 4;
+static const int KContainerArrayGranularity = 4;
+
+namespace Alf
+ {
+
+struct DeleteTemplate
+{
+ void operator()(const IAlfVisualTemplate* aTemplate) const
+ {
+ delete aTemplate;
+ }
+};
+
+// -----------------------------------------------------------------------------
+// Helper function to iterate through a visual template hierarchy and
+// investigate whether a given visual template exists in it.
+// -----------------------------------------------------------------------------
+bool existsInHierarchy(IAlfVisualTemplate& aRoot, const IAlfVisualTemplate& aTemplate)
+ {
+ // Check the template against the root node.
+ if(&aTemplate == &aRoot)
+ {
+ return true;
+ }
+
+ // Iterate through all the root's children
+ for(int i = 0; i < aRoot.numChildTemplates(); ++i)
+ {
+ if(existsInHierarchy(aRoot.childTemplate(i), aTemplate))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// ---------------------------------------------------------------------------
+// Description : Constructor
+// ---------------------------------------------------------------------------
+OSN_EXPORT AlfVisualTemplate* AlfVisualTemplate::create()
+ {
+ return new( EMM ) AlfVisualTemplate;
+ }
+
+// ---------------------------------------------------------------------------
+// Description : Constructor
+// ---------------------------------------------------------------------------
+OSN_EXPORT AlfVisualTemplate* AlfVisualTemplate::create(TAlfVisualType aType)
+ {
+ return new( EMM ) AlfVisualTemplate( aType );
+ }
+
+// ---------------------------------------------------------------------------
+// Description : Constructor
+// ---------------------------------------------------------------------------
+OSN_EXPORT AlfVisualTemplate* AlfVisualTemplate::create(TAlfLayoutType aType)
+ {
+ return new( EMM ) AlfVisualTemplate( aType );
+ }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// ---------------------------------------------------------------------------
+// Description : Constructor
+// ---------------------------------------------------------------------------
+OSN_EXPORT AlfVisualTemplate::AlfVisualTemplate():
+ mVisualType(EAlfVisualTypeVisual),
+ mAttributeArray(KAttributeArrayGranularity),
+ mContainerArray(KContainerArrayGranularity),
+ mSelectOneChild(false),
+ mOwner(0),
+ mParent(0)
+ {
+ }
+
+// ---------------------------------------------------------------------------
+// Description : Constructor
+// ---------------------------------------------------------------------------
+OSN_EXPORT AlfVisualTemplate::AlfVisualTemplate(TAlfVisualType aType):
+ mVisualType(aType),
+ mAttributeArray(KAttributeArrayGranularity),
+ mContainerArray(KContainerArrayGranularity),
+ mSelectOneChild(false),
+ mOwner(0),
+ mParent(0)
+ {
+ }
+
+// ---------------------------------------------------------------------------
+// Description : Constructor
+// ---------------------------------------------------------------------------
+OSN_EXPORT AlfVisualTemplate::AlfVisualTemplate(TAlfLayoutType aType):
+ mVisualType(-1 - aType),
+ mAttributeArray(KAttributeArrayGranularity),
+ mContainerArray(KContainerArrayGranularity),
+ mSelectOneChild(false),
+ mOwner(0),
+ mParent(0)
+ {
+ }
+
+// ---------------------------------------------------------------------------
+// Description : Destructor
+// ---------------------------------------------------------------------------
+OSN_EXPORT AlfVisualTemplate::~AlfVisualTemplate()
+ {
+ mBrushArray.clear();
+ mAttributeArray.clear();
+ mContainerArray.clear();
+
+ // Remove this visual template from it's parent or owner
+ if(parent())
+ {
+ parent()->removeChildTemplate(*this);
+ }
+ if(owner())
+ {
+ owner()->removeVisualTemplate();
+ }
+
+ // Destroy child visual templates in two passes, since destructor of a child
+ // visual template could affect the content of the this visual template's child vector.
+ vector<IAlfVisualTemplate*> children(mChildren);
+ mChildren.clear();
+ for_each(children.begin(), children.end(), DeleteTemplate());
+ }
+
+// ---------------------------------------------------------------------------
+// Description : Set the owner element.
+// ---------------------------------------------------------------------------
+OSN_EXPORT void AlfVisualTemplate::setOwner(IAlfElement* aOwner) throw()
+ {
+ if(aOwner != mOwner)
+ {
+ // Remove this visual template from it's parent. Parent and owner are
+ // mutually exclusive properties on a visual template.
+ if(aOwner && (parent() != 0))
+ {
+ parent()->removeChildTemplate(*this);
+ }
+
+ // Set the owner of this visual template.
+ mOwner = aOwner;
+ }
+ }
+
+OSN_EXPORT IAlfElement* AlfVisualTemplate::owner() const throw()
+ {
+ return mOwner;
+ }
+
+// ---------------------------------------------------------------------------
+// Description : Set the name of the visual, i.e., the tag.
+// ---------------------------------------------------------------------------
+OSN_EXPORT void AlfVisualTemplate::setName(const char* aName)
+ {
+ mVisualName = UString(aName);
+ }
+
+// ---------------------------------------------------------------------------
+// Description : Get the name of the visual, i.e., the tag.
+// ---------------------------------------------------------------------------
+OSN_EXPORT const char* AlfVisualTemplate::name() const throw()
+ {
+ return mVisualName.getUtf8();
+ }
+
+// ---------------------------------------------------------------------------
+// Description : Add a child visual template.
+// ---------------------------------------------------------------------------
+OSN_EXPORT void AlfVisualTemplate::addChildTemplate(IAlfVisualTemplate& aChild)
+ {
+ insertChildTemplate(aChild, mChildren.size());
+ }
+
+// ---------------------------------------------------------------------------
+// Description : Inserts a child visual template at given index
+// ---------------------------------------------------------------------------
+OSN_EXPORT void AlfVisualTemplate::insertChildTemplate(IAlfVisualTemplate& aChild, int aIndex)
+ {
+ if(!(aIndex >=0 && aIndex <= mChildren.size()))
+ ALF_THROW(AlfException, EInvalidArrayIndex, "AlfVisualTemplate::insertChildTemplate() - Index out of bounds.");
+
+ // Verify that the given argument is valid
+ if(existsInHierarchy(*this, aChild))
+ {
+ ALF_THROW(AlfException, EInvalidHierarchy, "AlfVisualTemplate::insertChildTemplate() - Adding a child visual template that is already in the hierarchy.");
+ }
+ if(existsInHierarchy(aChild, *this))
+ {
+ ALF_THROW(AlfException, EInvalidHierarchy, "AlfVisualTemplate::insertChildTemplate() - Attempt to create a recursive visual template tree.");
+ }
+ if(layoutType() < 0)
+ {
+ ALF_THROW(AlfException, EInvalidHierarchy, "AlfVisualTemplate::insertChildTemplate() - Attempt to add a child visual into a non-layout visual template.");
+ }
+
+ // Insert child visual template to the array
+ mChildren.insert(mChildren.begin() + aIndex, &aChild);
+
+ // Remove child from previous hierarchy and add it under this visual template.
+ if(aChild.parent())
+ {
+ // Visual template cannot have a parent and owner at the same time.
+ assert(aChild.owner() == 0);
+ aChild.parent()->removeChildTemplate(aChild);
+ }
+ if(aChild.owner())
+ {
+ // Visual template cannot have a parent and owner at the same time.
+ assert(aChild.parent() == 0);
+ aChild.owner()->removeVisualTemplate();
+ }
+
+ // Set a new parent for this visual template.
+ aChild.setParent(this);
+ }
+
+// ---------------------------------------------------------------------------
+// Description : Destroyes a child visual template at given index
+// ---------------------------------------------------------------------------
+OSN_EXPORT void AlfVisualTemplate::destroyChildTemplate(int aIndex) throw()
+ {
+ // Remove and destroy a child template by the given index
+ if(aIndex >=0 && aIndex < mChildren.size())
+ {
+ IAlfVisualTemplate* child = mChildren[aIndex];
+ removeChildTemplate(*child);
+ delete child;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Description : Destroyes a child visual template.with the given name
+// ---------------------------------------------------------------------------
+OSN_EXPORT void AlfVisualTemplate::destroyChildTemplate(const char* aName) throw()
+ {
+ // Search through the children for the given name.
+ for(int i = 0; i < mChildren.size() ;i++)
+ {
+ if(!strcmp(mChildren[i]->name(), aName))
+ {
+ // Remove and destroy the found child visual template
+ IAlfVisualTemplate* child = mChildren[i];
+ removeChildTemplate(*child);
+ delete child;
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Description : Get the number of child visual templates.
+// ---------------------------------------------------------------------------
+OSN_EXPORT int AlfVisualTemplate::numChildTemplates() const throw()
+ {
+ return mChildren.size();
+ }
+
+// ---------------------------------------------------------------------------
+// Description : Get a child visual template.
+// ---------------------------------------------------------------------------
+OSN_EXPORT IAlfVisualTemplate& AlfVisualTemplate::childTemplate(int aIndex) const
+ {
+ if((aIndex < 0) || (aIndex >= numChildTemplates()))
+ {
+ ALF_THROW(AlfException, EInvalidArrayIndex, "AlfVisualTemplate::childTemplate() - Index out of bounds.");
+ }
+ return *mChildren[aIndex];
+ }
+
+// -----------------------------------------------------------------------------
+// Description : Add a new visual attribute setter. The ownership is not passed.
+// -----------------------------------------------------------------------------
+OSN_EXPORT void AlfVisualTemplate::addAttributeSetter(
+ IAlfAttributeSetter* aSetter, AlfAttributeContainer* aContainer )
+ {
+ mAttributeArray.resize(mAttributeArray.count()+1);
+ mContainerArray.resize(mContainerArray.count()+1);
+
+ mAttributeArray.insert(mAttributeArray.count(),aSetter);
+ mContainerArray.insert(mContainerArray.count(),aContainer);
+ }
+
+// -----------------------------------------------------------------------------
+// Description : Get the number of visual attribute setters.
+// -----------------------------------------------------------------------------
+OSN_EXPORT int AlfVisualTemplate::numAttributeSetters() const throw()
+ {
+ return mAttributeArray.count();
+ }
+
+// -----------------------------------------------------------------------------
+// Description : Get a visual attribute setter.
+// -----------------------------------------------------------------------------
+OSN_EXPORT IAlfAttributeSetter& AlfVisualTemplate::attributeSetter(int aIndex) const
+ {
+ if((aIndex < 0) || (aIndex >= mAttributeArray.count()))
+ {
+ ALF_THROW(AlfException, EInvalidArrayIndex, "AlfVisualTemplate::attributeSetter() - Index out of bounds.");
+ }
+ return *mAttributeArray[aIndex];
+ }
+
+// -----------------------------------------------------------------------------
+// Description :
+// -----------------------------------------------------------------------------
+OSN_EXPORT AlfAttributeContainer& AlfVisualTemplate::attributeContainer(int aIndex) const
+ {
+ if((aIndex < 0) || (aIndex >= mContainerArray.count()))
+ {
+ ALF_THROW(AlfException, EInvalidArrayIndex, "AlfVisualTemplate::attributeContainer() - Index out of bounds.");
+ }
+ return *mContainerArray[aIndex];
+ }
+
+// -----------------------------------------------------------------------------
+// Description : Update an existing visual tree with new values
+// -----------------------------------------------------------------------------
+OSN_EXPORT CAlfVisual* AlfVisualTemplate::updateVisualTree(IAlfMap* aData, IAlfMap* aOldData, CAlfVisual& aVisual)
+ {
+
+ CAlfVisual* retVisual = &aVisual;
+ // Update the attributes.
+ for (int i = 0; i < mAttributeArray.count(); ++i)
+ {
+ try
+ {
+ ALF_PERF_START( perfdata, "AlfVisualTemplate-updateVisualTree-SetAttributeValue")
+ mAttributeArray[i]->setAttributeValue(aVisual, mContainerArray[i], aData);
+ ALF_PERF_STOP( perfdata, "AlfVisualTemplate-updateVisualTree-setAttributeValue")
+ }
+ catch (...)
+ {
+ ALF_THROW(AlfAttributeException,EInvalidAttributeValue,"AlfVisualTemplate")
+ }
+ }
+ // Pass to children
+ if (mChildren.size())
+ {
+ int ind = selectedChildInd( aData );
+ if (ind >= 0 && ind < mChildren.size())
+ {
+ CAlfLayout *layout = (CAlfLayout *)&aVisual;
+ int indOld = selectedChildInd( aOldData );
+ if ( ind == indOld )
+ {
+ mChildren[ind]->updateVisualTree( aData, aOldData, *layout );
+ }
+ else
+ {
+ CAlfControl& c(aVisual.Owner());
+
+ //new visual tree is created. Replaces the current (now old) layout,
+ //which is removed from its parent and destroyed.
+ //new layout is returned from the function.
+ CAlfLayout* parentLayout = layout->Layout();
+ TInt ind = parentLayout->FindVisual(layout);
+ parentLayout->Remove(layout);
+ layout->RemoveAndDestroyAllD();
+ CAlfLayout* newLayout = (CAlfLayout *) createVisualTree(c, aData, parentLayout, ind);
+ retVisual = newLayout;
+ }
+ }
+ else
+ {
+ CAlfLayout *layout = (CAlfLayout *)&aVisual;
+ for (int i = 0; i < mChildren.size(); ++i)
+ {
+ mChildren[i]->updateVisualTree(aData, aOldData, layout->Visual(i));
+ }
+ }
+ }
+ return retVisual;
+ }
+
+// -----------------------------------------------------------------------------
+// Description : create a new visual tree and initialize the visuals
+// -----------------------------------------------------------------------------
+OSN_EXPORT CAlfVisual* AlfVisualTemplate::createVisualTree(CAlfControl& aControl,
+ IAlfMap* aData, CAlfLayout* aParentLayout, int aLayoutIndex)
+ {
+ // create the visual
+ CAlfVisual *result = NULL;
+ CAlfLayout *layout = NULL;
+ if (!mSelectOneChild)
+ {
+ if (mVisualType < 0)
+ {
+ ALF_PERF_START( perfdata, "AlfVisualTemplate-createVisualTree-NewLayout")
+ // create layout
+ result = layout = AlfVisualFactory::NewLayoutL(
+ (TAlfLayoutType)(-1 - mVisualType), aParentLayout, aControl, aControl.Env());
+ ALF_PERF_STOP( perfdata, "AlfVisualTemplate-createVisualTree-NewLayout")
+ if (!result)
+ {
+ ALF_THROW(AlfVisualException,ECanNotCreateVisual,"AlfVisualTemplate")
+ }
+ }
+ else
+ {
+ // create visual
+ ALF_PERF_START( perfdata, "AlfVisualTemplate-createVisualTree-NewVisual")
+ result = AlfVisualFactory::NewVisualL(
+ (TAlfVisualType)mVisualType, aParentLayout, aControl, aControl.Env());
+ ALF_PERF_STOP( perfdata, "AlfVisualTemplate-createVisualTree-NewVisual")
+ if (!result)
+ {
+ ALF_THROW(AlfVisualException,ECanNotCreateVisual,"AlfVisualTemplate")
+ }
+
+ //Add the brushes to the visual
+ result->EnableBrushesL(true);
+ for (int i=0; i < mBrushArray.count(); i++)
+ {
+ result->Brushes()->AppendL(mBrushArray[i], EAlfDoesNotHaveOwnership);
+ }
+ }
+ if (aParentLayout &&
+ aLayoutIndex >= 0 && aLayoutIndex <= aParentLayout->Count())
+ {
+ //when aConstructedWithParentInformation- parameter is ETrue,
+ //no message sent to server
+ aParentLayout->Append(result, ETrue);
+
+ //reorder, if needed.
+ if (aLayoutIndex != aParentLayout->Count() - 1)
+ {
+ aParentLayout->Reorder(*result, aLayoutIndex);
+ }
+ }
+ aControl.Append(result);
+
+ if (mVisualName.isNull())
+ mVisualName = UString("");
+ result->SetTagL(TPtrC8((unsigned char*)mVisualName.getUtf8()));
+
+ // Set the attributes
+ for (int i = 0; i < mAttributeArray.count(); ++i)
+ {
+ try
+ {
+ ALF_PERF_START( perfdata, "AlfVisualTemplate-createVisualTree-setAttributeValue")
+ // set dirtines of all attribute in createvisualtree
+ for(int j = 0; j < mContainerArray[i]->attributeCount() ;j++ )
+ {
+ mContainerArray[i]->getAttribute(j).setDirty(true);
+ }
+ mAttributeArray[i]->setAttributeValue(*result, mContainerArray[i], aData);
+ ALF_PERF_STOP( perfdata, "AlfVisualTemplate-createVisualTree-setAttributeValue")
+ }
+ catch (...)
+ {
+ ALF_THROW(AlfAttributeException,EInvalidAttributeValue,"AlfVisualTemplate")
+ }
+ }
+ }
+
+ // Pass to children
+ int ind = selectedChildInd( aData );
+ if (ind >= 0 && ind < mChildren.size())
+ {
+ result = mChildren[ind]->createVisualTree(aControl, aData, aParentLayout, aLayoutIndex);
+ }
+ else if (!mSelectOneChild)
+ {
+ for (int i = 0; i < mChildren.size(); ++i)
+ {
+ mChildren[i]->createVisualTree(aControl, aData, layout, i);
+ }
+ }
+ return result;
+ }
+
+// -----------------------------------------------------------------------------
+// reads and returns selected ind from data, if set. If not set returns -1.
+// -----------------------------------------------------------------------------
+int AlfVisualTemplate::selectedChildInd( IAlfMap* aData )
+ {
+ int ind = -1;
+ if (aData && mSelectOneChild)
+ {
+ IAlfVariantType* data = aData->item(mChildIndFieldName);
+
+ //field value contains index to child array.
+ //if field contains no data and template has only one
+ // child, assume it's the child wanted.
+ bool valueIsEmpty = false;
+ if (!data)
+ {
+ valueIsEmpty = true;
+ }
+ else
+ {
+ switch ( data->type() )
+ {
+ case IAlfVariantType::EInt:
+ ind = data->integer();
+ break;
+ default:
+ break;
+ }
+ }
+ if ( valueIsEmpty && mChildren.size() == 1 )
+ {
+ ind = 0;
+ }
+ }
+ return ind;
+ }
+
+// -----------------------------------------------------------------------------
+// Description : Removes a visual template from the child array without
+// destroying the child template object.
+// -----------------------------------------------------------------------------
+void AlfVisualTemplate::removeChildTemplate(IAlfVisualTemplate& aChild) throw()
+ {
+ std::vector<IAlfVisualTemplate*>::iterator it = find(mChildren.begin(), mChildren.end(), &aChild);
+ if(it != mChildren.end())
+ {
+ mChildren.erase(it);
+ aChild.setParent(0);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// Description : Returns the parent visual template object
+// -----------------------------------------------------------------------------
+OSN_EXPORT IAlfVisualTemplate* AlfVisualTemplate::parent() const throw()
+ {
+ return mParent;
+ }
+
+// -----------------------------------------------------------------------------
+// Description : Set the visual type
+// -----------------------------------------------------------------------------
+OSN_EXPORT void AlfVisualTemplate::setParent(IAlfVisualTemplate* aParent) throw()
+ {
+ mParent = aParent;
+ }
+
+// -----------------------------------------------------------------------------
+// Description : Set the visual type
+// -----------------------------------------------------------------------------
+OSN_EXPORT void AlfVisualTemplate::setVisualType(TAlfVisualType aType)
+ {
+ mVisualType = aType;
+ }
+
+// -----------------------------------------------------------------------------
+// Description : Get the visual type
+// -----------------------------------------------------------------------------
+OSN_EXPORT int AlfVisualTemplate::visualType() const throw()
+ {
+ return mVisualType;
+ }
+// -----------------------------------------------------------------------------
+// Description : Set the layout type
+// -----------------------------------------------------------------------------
+OSN_EXPORT void AlfVisualTemplate::setLayoutType(TAlfLayoutType aType)
+ {
+ mVisualType = -1 - aType;
+ }
+
+// -----------------------------------------------------------------------------
+// Description : Get the layout type
+// -----------------------------------------------------------------------------
+OSN_EXPORT int AlfVisualTemplate::layoutType() const throw()
+ {
+ return -1 - mVisualType;
+ }
+
+// -----------------------------------------------------------------------------
+// Description : Adds brush to the brush array.
+// -----------------------------------------------------------------------------
+OSN_EXPORT void AlfVisualTemplate::addBrush(CAlfBrush& aBrush)
+ {
+ mBrushArray.resize(mBrushArray.count()+1);
+ mBrushArray.insert(mBrushArray.count(),&aBrush);
+ }
+
+// -----------------------------------------------------------------------------
+// Description : Get the munber of brushes
+// -----------------------------------------------------------------------------
+OSN_EXPORT int AlfVisualTemplate::numBrushes() const
+ {
+ return mBrushArray.count();
+ }
+
+// -----------------------------------------------------------------------------
+// Description : Get a Brush
+// -----------------------------------------------------------------------------
+OSN_EXPORT CAlfBrush& AlfVisualTemplate::brush(int aIndex) const
+ {
+ return *mBrushArray[aIndex];
+ }
+
+
+// -----------------------------------------------------------------------------
+// Description : puts the class in to selected child mode.
+// -----------------------------------------------------------------------------
+OSN_EXPORT void AlfVisualTemplate::setSelectChildMode(bool aSelectChild,
+ const UString& aChildIndFieldName )
+ {
+ mSelectOneChild = aSelectChild;
+ mChildIndFieldName = aChildIndFieldName;
+ }
+
+
+// ---------------------------------------------------------------------------
+// From class IAlfInterfaceBase.
+// Getter for interfaces provided by the visual template.
+// ---------------------------------------------------------------------------
+//
+OSN_EXPORT IAlfInterfaceBase* AlfVisualTemplate::makeInterface( const IfId& aType )
+ {
+ UString param(aType.mImplementationId);
+ if (param == IAlfVisualTemplate::type().mImplementationId)
+ {
+ return static_cast<IAlfVisualTemplate*>(this);
+ }
+ return NULL;
+ }
+
+ } //Alf