commonuisupport/grid/src/GRDMAP.CPP
changeset 0 2f259fa3e83a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/commonuisupport/grid/src/GRDMAP.CPP	Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,372 @@
+// Copyright (c) 1997-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 <s32strm.h>
+#include "GRDPANIC.H"
+#include "GRDMAP.H"
+
+
+RWriteStream& operator<<(RWriteStream& aStream,const TSizeElement &aElement)
+	{
+	aElement.ExternalizeL(aStream);
+	return aStream;
+	}
+
+RReadStream& operator>>(RReadStream &aStream,TSizeElement &aElement)
+	{
+	aElement.InternalizeL(aStream);
+	return aStream;
+	}
+
+void TSizeElement::ExternalizeL(RWriteStream& aStream) const
+	{
+	aStream.WriteInt32L(iId);
+	aStream.WriteInt32L(iValueInTwips);
+	}
+
+void TSizeElement::InternalizeL(RReadStream& aStream)
+	{
+	iId = aStream.ReadInt32L();
+	iValueInTwips = aStream.ReadInt32L();
+	}
+		
+//
+
+CSparseMap* CSparseMap::NewL()
+	{
+	CSparseMap* self = new(ELeave) CSparseMap();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+	}
+
+CSparseMap* CSparseMap::NewL(const CSparseMap* aSparseMap)
+	{
+	CSparseMap* self = new(ELeave) CSparseMap();
+	CleanupStack::PushL(self);
+	self->ConstructL(aSparseMap);
+	CleanupStack::Pop();
+	return self;
+	}
+
+void CSparseMap::ConstructL()
+//
+	{
+	iArray = new(ELeave) CArrayFixFlat<TSizeElement>(1);
+	}
+
+void CSparseMap::ConstructL(const CSparseMap* aSparseMap)
+	{
+	iArray = new(ELeave) CArrayFixFlat<TSizeElement>(1);
+	iDefaultValueInTwips=aSparseMap->iDefaultValueInTwips;
+	iDefaultValueInPixels=aSparseMap->iDefaultValueInPixels;
+	TInt end=aSparseMap->iArray->Count();
+	for (TInt ii=0;ii<end;ii++)
+		iArray->AppendL((*aSparseMap)[ii]);
+	}
+
+CSparseMap::CSparseMap()
+	: iDefaultValueInTwips(0),
+	iDefaultValueInPixels(0)
+	{
+	}
+
+CSparseMap::~CSparseMap()
+//
+	{
+	delete iArray;
+	}
+
+TInt CSparseMap::Count() const
+	{
+	return iArray->Count();
+	}
+
+void CSparseMap::SetL(TInt aId,TInt aValueInTwips,TInt aValueInPixels)
+//
+	{
+	TKeyArrayFix key(0,ECmpTInt);
+	TInt pos;
+	TSizeElement element;
+	element.iId = aId;
+	element.iValueInTwips = aValueInTwips;
+	element.iValueInPixels = aValueInPixels;
+	if (iDefaultValueInTwips==aValueInTwips && iDefaultValueInPixels==aValueInPixels)
+		{// remove it from the array if it is already there
+		if (iArray->FindIsq(element,key,pos)==0)
+			{// found
+			iArray->Delete(pos);
+			}
+		}
+	else
+		{
+		if (iArray->FindIsq(element,key,pos)==0)
+			{// found
+			(*iArray)[pos] = element;
+			}
+		else
+			{
+			iArray->InsertIsqL(element,key);
+			}
+		}
+	}
+
+TInt CSparseMap::DefaultValueInTwips() const
+	{
+	return iDefaultValueInTwips;
+	}
+
+TInt CSparseMap::DefaultValueInPixels() const
+	{
+	return iDefaultValueInPixels;
+	}
+
+void CSparseMap::SetDefaultValueInTwips(TInt aValueInTwips)
+//
+	{
+	iDefaultValueInTwips = aValueInTwips;
+/*	TInt end=iArray->Count();
+	for (TInt ii=0;ii<end;ii++)
+		{
+		if (*iArray)[ii]==iDefaultValue)
+			{
+			iArray->Delete(ii--);
+			end--;
+			}
+		} //!! Is this a valid optimization? */
+	}
+
+void CSparseMap::SetDefaultValueInPixels(TInt aValueInPixels)
+	{
+	__ASSERT_DEBUG(aValueInPixels,Panic(EGridMapDefaultValueIsZero));
+	iDefaultValueInPixels = aValueInPixels;
+	}
+
+TInt CSparseMap::ValueInTwips(TInt aId) const
+//
+	{
+	TInt pos;
+	if (FindId(aId,pos)==0)
+		{// found
+		return (*iArray)[pos].iValueInTwips;
+		}
+	return (iDefaultValueInTwips);
+	}
+
+TInt CSparseMap::ValueInPixels(TInt aId) const
+//
+	{
+	TInt pos;
+	if (FindId(aId,pos)==0)
+		{// found
+		return (*iArray)[pos].iValueInPixels;
+		}
+	return (iDefaultValueInPixels);
+	}
+
+void CSparseMap::ResetArray()
+	{
+	iArray->Reset();
+	}
+
+void CSparseMap::OpenCloseGap(TInt aStartId,TInt aShiftOffset,TInt aMaxId)
+//
+// +ve offsets opens a gap causing shifted ids that are greater than aMaxId to be deleted
+// -ve offsets close a gap causing shifted ids that are less than aStartId to be deleted
+	{
+	TInt pos;
+	FindId(aStartId,pos);
+	TInt count=iArray->Count();
+	for (;pos<count;pos++)
+		{
+		TInt& currentId=(*iArray)[pos].iId;
+		currentId+=aShiftOffset;
+		if (currentId<aStartId)
+			{
+			iArray->Delete(pos--);
+			count--;
+			}
+		else if (currentId>aMaxId)
+			{
+			iArray->Delete(pos,count-pos);	// All the rest
+			break;
+			}
+		}
+	}
+
+void CSparseMap::IdToDisplacement(TInt aId1,TInt aId2,TInt& aReturnDisp) const
+//
+// Returns the displacement in pixels between two id's. Skips over sections with default
+// value to minimize array accesses
+//
+	{
+	TInt direction=1;
+	if (aId2<aId1)
+		{
+		Mem::Swap(&aId1,&aId2,sizeof(TInt));
+		direction=-1;
+		}
+	TInt pos=0;
+	FindId(aId1,pos);
+	TInt maxPos=iArray->Count()-1;
+	TInt currentId;
+	if (pos>maxPos || (currentId=(*iArray)[pos].iId)>=aId2)
+		{
+		aReturnDisp=((aId2-aId1)*iDefaultValueInPixels*direction);
+		return;
+		}
+	aReturnDisp=((currentId-aId1)*iDefaultValueInPixels);
+	TInt newId;
+	FOREVER
+		{
+		aReturnDisp+=((*iArray)[pos].iValueInPixels);
+		pos++;
+		if (pos>maxPos || (newId=(*iArray)[pos].iId)>=aId2)
+			break;
+		aReturnDisp+=((newId-currentId-1)*iDefaultValueInPixels);
+		currentId=newId;
+		}
+	aReturnDisp+=((aId2-currentId-1)*iDefaultValueInPixels);
+	aReturnDisp*=direction;
+	}
+
+TBool CSparseMap::DisplacementToId(TInt aId,TInt aDisp,TInt& aReturnId) const
+//
+// Changes the returnId nearest to the given displacement in pixels from aId. Nearest in this sense
+// means rounded down to the lowest id. Returns ETrue if the displacement lands on an exact id.
+//
+	{
+	if (aDisp==0)
+		{
+		aReturnId=aId;
+		return ETrue;
+		}
+	__ASSERT_DEBUG(iDefaultValueInPixels,Panic(EGridMapDefaultValueIsZero));
+	TInt pos=0;
+	FindId(aId,pos);
+	TInt maxPos=iArray->Count()-1;
+	aReturnId=0;
+	TInt tempDisp=0;
+	if (aDisp>0)
+		{
+		if (pos<=maxPos)
+			{
+			aReturnId=(*iArray)[pos].iId;
+			tempDisp=(aReturnId-aId)*iDefaultValueInPixels;
+			}
+		if (pos>maxPos || tempDisp>aDisp)
+			{
+			aReturnId=aDisp/iDefaultValueInPixels+aId;
+			tempDisp=(aReturnId-aId)*iDefaultValueInPixels;
+			}
+		else
+			{
+			tempDisp+=(*iArray)[pos].iValueInPixels;
+			TInt newDisp=0;
+			TInt newId=0;
+			while (tempDisp<=aDisp)
+				{
+				aReturnId++;
+				pos++;
+				if (pos<=maxPos)
+					{
+					newId=(*iArray)[pos].iId;
+					newDisp=tempDisp+(newId-aReturnId)*iDefaultValueInPixels;
+					}
+				if (pos>maxPos || newDisp>aDisp)
+					{
+					TInt add = (aDisp-tempDisp)/iDefaultValueInPixels;
+					tempDisp+=add*iDefaultValueInPixels;
+					aReturnId+=add;
+					break;
+					}
+				aReturnId=newId;
+				tempDisp=newDisp+(*iArray)[pos].iValueInPixels;
+				}
+			}
+		}
+	else
+		{
+		pos--;
+		if (pos>=0)
+			{
+			aReturnId=(*iArray)[pos].iId;
+			tempDisp=(aReturnId-aId+1)*iDefaultValueInPixels;
+			}
+		if (pos<0 || tempDisp<aDisp)
+			{
+			aReturnId=aDisp/iDefaultValueInPixels+aId-1;
+			tempDisp=(aReturnId-aId+1)*iDefaultValueInPixels;
+			}
+		else
+			{
+			tempDisp-=(*iArray)[pos].iValueInPixels;
+			TInt newDisp=0;
+			TInt newId=0;
+			while (tempDisp>=aDisp)
+				{
+				pos--;
+				if (pos>=0)
+					{
+					newId=(*iArray)[pos].iId;
+					newDisp=tempDisp+(newId-aReturnId+1)*iDefaultValueInPixels;
+					}
+				if (pos<0 || newDisp<aDisp)
+					{
+					TInt add = (aDisp-tempDisp)/iDefaultValueInPixels-1;
+					tempDisp+=(add+1)*iDefaultValueInPixels;
+					aReturnId+=add;
+					break;
+					}
+				aReturnId=newId;
+				tempDisp=newDisp;
+				tempDisp-=(*iArray)[pos].iValueInPixels;
+				}
+			}
+		}
+	return (aDisp==tempDisp);
+	}
+
+TInt CSparseMap::FindId(TInt aId,TInt& aFindPos) const
+	{
+	TKeyArrayFix key(0,ECmpTInt);
+	TSizeElement element;
+	element.iId = aId;
+	return iArray->FindIsq(element,key,aFindPos);
+	} 
+
+const TSizeElement& CSparseMap::operator[](TInt aIndex) const
+	{
+	return (*iArray)[aIndex];
+	}
+
+TSizeElement& CSparseMap::operator[](TInt aIndex)
+	{
+	return (*iArray)[aIndex];
+	}
+
+void CSparseMap::ExternalizeL(RWriteStream& aStream) const
+	{
+	aStream.WriteInt32L(iDefaultValueInTwips);
+	aStream << *iArray;
+	}
+
+void CSparseMap::InternalizeL(RReadStream& aStream)
+	{
+	iDefaultValueInTwips = aStream.ReadInt32L();
+	aStream >> *iArray;
+	}
+