uifw/ganes/src/HgScrollBufferManager.cpp
branchRCL_3
changeset 20 d48ab3b357f1
--- /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);
+            }
+        }
+    }
+