--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/ganes/src/HgScrollBufferManager.cpp Wed Sep 01 12:16:19 2010 +0100
@@ -0,0 +1,338 @@
+/*
+* 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 "HgScrollBufferManager.h"
+#include <ganes/HgScrollBufferObserverIface.h>
+
+#include <e32debug.h>
+
+// -----------------------------------------------------------------------------
+// CHgScrollBufferManager::NewL()
+// -----------------------------------------------------------------------------
+//
+CHgScrollBufferManager* CHgScrollBufferManager::NewL(
+ MHgScrollBufferObserver& aObserver,
+ TInt aBufferSize,
+ TInt aBufferTreshold,
+ TInt aInitialPosition,
+ TInt aTotalCount )
+ {
+ CHgScrollBufferManager* self = new (ELeave) CHgScrollBufferManager(
+ aObserver,
+ aBufferSize,
+ aBufferTreshold,
+ aInitialPosition,
+ aTotalCount );
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CHgScrollBufferManager::CHgScrollBufferManager()
+// -----------------------------------------------------------------------------
+//
+CHgScrollBufferManager::CHgScrollBufferManager(
+ MHgScrollBufferObserver& aObserver,
+ TInt aBufferSize,
+ TInt aBufferTreshold,
+ TInt aInitialPosition,
+ TInt aTotalCount )
+: CActive( CActive::EPriorityHigh ),
+ iObserver( aObserver ),
+ iBufferSize( aBufferSize ),
+ iBufferTreshold( aBufferTreshold ),
+ iBufferPosition( aInitialPosition ),
+ iTotalCount( aTotalCount )
+ {
+
+ }
+
+// -----------------------------------------------------------------------------
+// CHgScrollBufferManager::ConstructL()
+// -----------------------------------------------------------------------------
+//
+void CHgScrollBufferManager::ConstructL()
+ {
+ CActiveScheduler::Add(this);
+
+ iResetOrdered = ETrue;
+ ResetBuffer(iBufferPosition, iTotalCount);
+ }
+
+// -----------------------------------------------------------------------------
+// CHgScrollBufferManager::~CHgScrollBufferManager()
+// -----------------------------------------------------------------------------
+//
+CHgScrollBufferManager::~CHgScrollBufferManager()
+ {
+ Cancel();
+ }
+
+// -----------------------------------------------------------------------------
+// CHgScrollBufferManager::RunL()
+// -----------------------------------------------------------------------------
+//
+void CHgScrollBufferManager::RunL()
+ {
+ MHgScrollBufferObserver::THgScrollDirection direction = MHgScrollBufferObserver::EHgBufferNoMove;
+
+ if(iResetOrdered)
+ {
+ iResetOrdered = EFalse;
+ direction = MHgScrollBufferObserver::EHgBufferReset;
+ }
+ else
+ {
+ if(iDiff < 0)
+ {
+ iReleaseStart = iBufferPosition;
+ iRequestStart = iBufferPosition + iBufferSize;
+ direction = MHgScrollBufferObserver::EHgBufferScrollDown;
+ }
+ else if( iDiff > 0)
+ {
+ iReleaseStart = iBufferPosition + iBufferSize - iDiff;
+ iRequestStart = iBufferPosition - iDiff;
+ direction = MHgScrollBufferObserver::EHgBufferScrollUp;
+ }
+ }
+
+ // Release
+ TInt end = iReleaseStart + iReleaseCount < iTotalCount ?
+ iReleaseStart + iReleaseCount: iTotalCount;
+ end--;
+ if(end >= iReleaseStart )
+ {
+ iObserver.Release(iReleaseStart, end);
+ if(iOwner) iOwner->Release( iReleaseStart, end );
+ }
+
+ iReleaseCount = 0;
+
+ // Request
+ end = iRequestStart + iRequestCount < iTotalCount ?
+ iRequestStart + iRequestCount : iTotalCount;
+
+ end--;
+ if(end >= iRequestStart )
+ iObserver.Request(iRequestStart, end, direction);
+
+ iRequestCount = 0;
+
+ // Move Buffer
+ iBufferPosition -= iDiff;
+ // Reset Diff
+ iDiff = 0;
+ }
+
+// -----------------------------------------------------------------------------
+// CHgScrollBufferManager::DoCancel()
+// -----------------------------------------------------------------------------
+//
+void CHgScrollBufferManager::DoCancel()
+ {
+ // Nothing to do here
+ }
+
+// -----------------------------------------------------------------------------
+// CHgScrollBufferManager::RunError()
+// -----------------------------------------------------------------------------
+//
+TInt CHgScrollBufferManager::RunError( TInt /*aError*/ )
+ {
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CHgScrollBufferManager::SetPosition()
+// -----------------------------------------------------------------------------
+//
+void CHgScrollBufferManager::SetPosition( TInt aIndex )
+ {
+ // If all the items fit in the buffer no need to move the buffer
+ if(iTotalCount <= iBufferSize) return;
+
+ TBool forceUpdate = EFalse;
+ aIndex -= iBufferSize / 2; // normalize index to Buffer start
+
+ if(aIndex < 0)
+ {
+ aIndex = 0;
+ forceUpdate = ETrue;
+ }
+ else if( aIndex > iTotalCount - iBufferSize )
+ {
+ aIndex = iTotalCount - iBufferSize;
+ forceUpdate = ETrue;
+ }
+
+ iDiff = iBufferPosition - aIndex;
+
+ // Too large change reset whole buffer
+ if( iDiff >= iBufferSize || -iDiff >= iBufferSize || iResetOrdered )
+ {
+ ResetBuffer(aIndex + (iBufferSize/2), iTotalCount);
+ }
+ // Move Up
+ else if( iDiff >= iBufferTreshold )
+ {
+ iRequestCount = iDiff;
+ iReleaseCount = iDiff;
+ NotifyObserver();
+ }
+ // Move Down
+ else if( -iDiff >= iBufferTreshold )
+ {
+ iRequestCount = -iDiff;
+ iReleaseCount = -iDiff;
+ NotifyObserver();
+ }
+ // Top or bottom has been reached
+ else if( forceUpdate && iDiff )
+ {
+ TInt diff = iDiff < 0 ? -iDiff : iDiff;
+ iRequestCount = diff;
+ iReleaseCount = diff;
+ NotifyObserver();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CHgScrollBufferManager::SetTotalCount()
+// -----------------------------------------------------------------------------
+//
+void CHgScrollBufferManager::SetTotalCount( TInt aTotalCount )
+ {
+ iTotalCount = aTotalCount;
+ }
+
+// -----------------------------------------------------------------------------
+// CHgScrollBufferManager::SetBufferOwner()
+// -----------------------------------------------------------------------------
+//
+void CHgScrollBufferManager::SetBufferOwner( MHgBufferOwner& aOwner )
+ {
+ iOwner = &aOwner;
+ }
+
+// -----------------------------------------------------------------------------
+// CHgScrollBufferManager::ResetBuffer()
+// -----------------------------------------------------------------------------
+//
+void CHgScrollBufferManager::ResetBuffer( TInt aPosition, TInt aTotalCount)
+ {
+ if( !iResetOrdered )
+ {
+ // release Old buffer
+ iReleaseStart = iBufferPosition;
+ iReleaseCount = iBufferSize;
+ }
+
+ // set position and count
+ iBufferPosition = aPosition - (iBufferSize / 2);
+ iTotalCount = aTotalCount;
+ iDiff = 0;
+
+ if( iBufferPosition + iBufferSize > iTotalCount - 1 )
+ {
+ iBufferPosition = iTotalCount - iBufferSize;
+ }
+
+ if(iBufferPosition < 0 )
+ {
+ iBufferPosition = 0;
+ }
+
+ //request new Buffer
+ iRequestStart = iBufferPosition;
+ iRequestCount = iBufferSize;
+ iResetOrdered = ETrue;
+
+ NotifyObserver();
+ }
+
+// -----------------------------------------------------------------------------
+// CHgScrollBufferManager::NotifyObserver()
+// -----------------------------------------------------------------------------
+//
+void CHgScrollBufferManager::NotifyObserver()
+ {
+ if( !IsActive() )
+ {
+ SetActive();
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, KErrNone);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CHgScrollBufferManager::ItemChanged()
+// -----------------------------------------------------------------------------
+//
+void CHgScrollBufferManager::ItemCountChanged(
+ TInt aIndex,
+ TBool aRemoved,
+ TInt aNewTotalCount )
+ {
+ iTotalCount = aNewTotalCount;
+ if ( aIndex >= iBufferPosition && aIndex < iBufferPosition + iBufferSize )
+ {
+ // Change inside the buffer
+ MHgScrollBufferObserver::THgScrollDirection direction = MHgScrollBufferObserver::EHgBufferNoMove;
+ if( aRemoved )
+ {
+ // Release removed item ( Item deleted already from the owner )
+ iObserver.Release( aIndex, aIndex );
+ if( iTotalCount >= iBufferSize )
+ {
+ // There are more items to keep the buffer filled
+ if( iBufferPosition + iBufferSize <= iTotalCount )
+ {
+ // Requested from the end
+ iObserver.Request( iBufferPosition + iBufferSize - 1,
+ iBufferPosition + iBufferSize - 1, direction );
+ }
+ else if( iBufferPosition > 0 )
+ {
+ // Move buffer and request from the beginning
+ iBufferPosition--;
+ iObserver.Request( iBufferPosition, iBufferPosition, direction );
+ }
+ }
+ }
+ else
+ {
+ if( iTotalCount > iBufferSize )
+ {
+ // One item needs to be released
+ if( iBufferPosition + iBufferSize < iTotalCount )
+ {
+ // Release from the end of the buffer
+ iObserver.Release(iBufferPosition + iBufferSize, iBufferPosition + iBufferSize);
+ if(iOwner)
+ iOwner->Release(iBufferPosition + iBufferSize, iBufferPosition + iBufferSize);
+ }
+ }
+ // Request added item
+ iObserver.Request(aIndex, aIndex, direction);
+ }
+ }
+ }
+