uifw/AvKon/aknphysics/src/aknphysicsrestrictor.cpp
changeset 0 2f259fa3e83a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/AvKon/aknphysics/src/aknphysicsrestrictor.cpp	Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,457 @@
+/*
+* 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:  Restrictor of AknPhysics
+*
+*/
+
+
+#include <e32debug.h>
+
+#include "aknphysicsrestrictor.h"
+#include "aknphysicsparameterprovider.h"
+
+const TReal KNotRestrictedSegment( 1.0 );
+const TInt KEmptySpaceFactor( 100 );
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CAknPhysicsRestrictor::NewL
+// ---------------------------------------------------------------------------
+//
+CAknPhysicsRestrictor* CAknPhysicsRestrictor::NewL(
+    CAknPhysicsParameterProvider* aProvider )
+    {
+    CAknPhysicsRestrictor* self = CAknPhysicsRestrictor::NewLC( aProvider );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CAknPhysicsRestrictor::NewLC
+// ---------------------------------------------------------------------------
+//
+CAknPhysicsRestrictor* CAknPhysicsRestrictor::NewLC( 
+    CAknPhysicsParameterProvider* aProvider )
+    {
+    CAknPhysicsRestrictor* self = 
+        new ( ELeave ) CAknPhysicsRestrictor( aProvider );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CAknPhysicsRestrictor::~CAknPhysicsRestrictor
+// ---------------------------------------------------------------------------
+//
+CAknPhysicsRestrictor::~CAknPhysicsRestrictor()
+    {
+    }
+
+
+// ---------------------------------------------------------------------------
+// CAknPhysicsRestrictor::UpdatePhysicsEnvironment
+// ---------------------------------------------------------------------------
+//
+void CAknPhysicsRestrictor::UpdatePhysicsEnvironment( const TSize& aWorldSize,
+                                                      const TSize& aViewSize,
+                                                      const TBool& aLandscape )
+    {
+    iWorldSize = aWorldSize;
+    iViewSize = aViewSize;
+    iLandscape = aLandscape;
+    CalculateViewLimits();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknPhysicsRestrictor::ViewTopPosition()
+// -----------------------------------------------------------------------------
+//
+TInt CAknPhysicsRestrictor::ViewTopPosition() const
+    {
+    TInt topPosition( 0 );
+
+    if ( iLandscape )
+        {
+        topPosition = iViewSize.iWidth/2;
+        }
+    else
+        {
+        topPosition = iViewSize.iHeight/2;
+        }
+    return topPosition;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknPhysicsRestrictor::ViewBottomPosition()
+// -----------------------------------------------------------------------------
+//
+TInt CAknPhysicsRestrictor::ViewBottomPosition() const
+    {
+    TInt bottomPosition( 0 );
+
+    // If world size smaller than view size, bottom position is same as top
+    // position
+    if ( iLandscape && iViewSize.iWidth >= iWorldSize.iWidth
+        || !iLandscape && iViewSize.iHeight >= iWorldSize.iHeight )
+        {
+        bottomPosition = ViewTopPosition();        
+        }
+        
+    // Otherwise calculate bottom position according to world size
+    else
+        {
+        if ( iLandscape )
+            {
+            bottomPosition = iWorldSize.iWidth - iViewSize.iWidth / 2;
+            }
+        else
+            {
+            bottomPosition = iWorldSize.iHeight - iViewSize.iHeight / 2;
+            }   
+        }
+    return bottomPosition;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknPhysicsRestrictor::PositionRevealsEmptySpace()
+// -----------------------------------------------------------------------------
+//
+TBool CAknPhysicsRestrictor::PositionRevealsEmptySpace( TPoint& aPosition )
+    {
+    TInt startTop( ViewTopPosition() );
+    TInt endBottom( ViewBottomPosition() );
+    TInt* positionCoordinate;
+
+    if ( iLandscape )
+        {
+        positionCoordinate = &aPosition.iX;
+        }
+    else
+        {
+        positionCoordinate = &aPosition.iY;
+        }
+
+    if ( aPosition == TPoint()
+        || *positionCoordinate >= startTop && *positionCoordinate <= endBottom )
+        {
+        return EFalse;
+        }
+    
+    if ( *positionCoordinate < startTop || WorldFitsToView() )
+        {
+        *positionCoordinate = startTop;
+        }
+    else
+        {
+        *positionCoordinate = endBottom;
+        }
+    return ETrue;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknPhysicsRestrictor::AllowedViewPosition()
+// -----------------------------------------------------------------------------
+//
+TBool CAknPhysicsRestrictor::AllowedViewPosition( TPoint& aPosition )
+    {
+    // No restrictions to empty space, view position always allowed
+    if ( !iEmptySpaceRestricted )
+        {
+        return ETrue;
+        }
+    
+    TBool allow( EFalse );
+
+    TInt *coord;
+    if ( iLandscape )
+        {
+        coord = &aPosition.iX;
+        }
+    else
+        {
+        coord = &aPosition.iY;
+        }
+
+    // View position is allowed
+    if ( *coord >= iPositionTopLimit && *coord <= iPositionBottomLimit )
+        {
+        allow = ETrue;
+        iViewReachedLimit = EFalse;
+        }
+
+    // View has reached the limit for the first time - adjust the position
+    // exactly to limit position
+    else if ( !iViewReachedLimit )
+        {
+        allow = ETrue;
+        iViewReachedLimit = ETrue;
+        if ( *coord < iPositionTopLimit )
+            {
+            *coord = iPositionTopLimit;
+            }
+        else
+            {
+            *coord = iPositionBottomLimit;
+            }
+        }
+
+    // Else view has already reached the limit, view position is not allowed
+    // and no need to notify physics observer
+
+    return allow;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknPhysicsRestrictor::AdjustDragPoint()
+// -----------------------------------------------------------------------------
+//
+void CAknPhysicsRestrictor::AdjustDragPoint( TPoint& aDragPoint )
+    {
+    if ( iViewReachedLimit )
+        {
+        iViewReachedLimit = EFalse;
+
+        TInt *coord;
+        if ( iLandscape )
+            {
+            coord = &aDragPoint.iX;
+            }
+        else
+            {
+            coord = &aDragPoint.iY;
+            }
+
+        if ( *coord < 0 )
+            {
+            *coord = -iEmptySpaceArea;
+            }
+        else
+            {
+            *coord = iEmptySpaceArea;
+            }
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknPhysicsRestrictor::WorldSize()
+// -----------------------------------------------------------------------------
+//
+TSize CAknPhysicsRestrictor::WorldSize() const
+    {
+    return iWorldSize;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknPhysicsRestrictor::WorldSize()
+// -----------------------------------------------------------------------------
+//
+TBool CAknPhysicsRestrictor::WorldInLandscape() const
+    {
+    return iLandscape;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknPhysicsRestrictor::ParameterProvider()
+// -----------------------------------------------------------------------------
+//
+CAknPhysicsParameterProvider* CAknPhysicsRestrictor::ParameterProvider() const
+    {
+    return iProvider;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknPhysicsRestrictor::PositionToViewTop()
+// -----------------------------------------------------------------------------
+//
+void CAknPhysicsRestrictor::PositionToViewTop( TPoint& aPosition ) const
+    {
+    TInt topPos( ViewTopPosition() );
+    if ( iLandscape )
+        {
+        aPosition.iX = topPos;
+        }
+    else
+        {
+        aPosition.iY = topPos;
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknPhysicsRestrictor::PositionToViewBottom()
+// -----------------------------------------------------------------------------
+//
+void CAknPhysicsRestrictor::PositionToViewBottom( TPoint& aPosition ) const
+    {
+    TInt bottomPos( ViewBottomPosition() );
+
+    if ( iLandscape )
+        {
+        aPosition.iX = bottomPos;
+        }
+    else
+        {
+        aPosition.iY = bottomPos;
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknPhysicsRestrictor::PositionIsOutOfBoundaries()
+// -----------------------------------------------------------------------------
+//
+TBool CAknPhysicsRestrictor::PositionIsOutOfBoundaries( 
+    const TPoint& aPosition, const TBool& aTopCollision ) const
+    {
+    TInt startTop( ViewTopPosition() );
+    TInt endBottom( ViewBottomPosition() );
+    TInt positionCoordinate;
+
+    if ( iLandscape )
+        {
+        positionCoordinate = aPosition.iX;
+        }
+    else
+        {
+        positionCoordinate = aPosition.iY;
+        }
+        
+
+    if ( aTopCollision && positionCoordinate > startTop )
+        {
+        positionCoordinate = startTop;
+        return ETrue;
+        }
+    else if ( !aTopCollision && positionCoordinate < endBottom )
+        {
+        positionCoordinate = endBottom;
+        return ETrue;
+        }
+    return EFalse;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CAknPhysicsRestrictor::CAknPhysicsRestrictor
+// ---------------------------------------------------------------------------
+//
+CAknPhysicsRestrictor::CAknPhysicsRestrictor(
+    CAknPhysicsParameterProvider* aProvider )
+    : 
+    iWorldSize( 0, 0 ),
+    iViewSize( 0, 0 ),
+    iLandscape( EFalse ),
+    iPositionTopLimit( 0 ),
+    iPositionBottomLimit( 0 ),
+    iEmptySpaceArea( 0 ),
+    iProvider( aProvider ),
+    iViewReachedLimit( EFalse ),
+    iEmptySpaceRestricted( EFalse )
+    {
+    }
+
+
+// ---------------------------------------------------------------------------
+// CAknPhysicsRestrictor::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CAknPhysicsRestrictor::ConstructL()
+    {
+    }
+
+
+// ---------------------------------------------------------------------------
+// CAknPhysicsRestrictor::CalculateViewLimits
+// ---------------------------------------------------------------------------
+//
+void CAknPhysicsRestrictor::CalculateViewLimits()
+    {
+    if ( !iProvider )
+        {
+        return;
+        }
+        
+    TInt viewHeight( iViewSize.iHeight );
+    TInt worldHeight( iWorldSize.iHeight );
+    TReal emptySegment( KNotRestrictedSegment );
+
+    if ( iLandscape )
+        {
+        viewHeight = iViewSize.iWidth;
+        worldHeight = iWorldSize.iWidth;
+        }
+        
+    // Calculate bottom limit
+    if ( viewHeight > worldHeight )
+        {
+        emptySegment = 
+        	( TReal ) iProvider->ShortListEmptySpace() / KEmptySpaceFactor;
+        iEmptySpaceArea = 
+            worldHeight * ( emptySegment );
+        iPositionBottomLimit = viewHeight / 2 + iEmptySpaceArea;
+        }
+    else
+        {
+        emptySegment = 
+        	( TReal ) iProvider->LongListEmptySpace() / KEmptySpaceFactor;
+        iEmptySpaceArea = 
+            viewHeight * ( emptySegment );
+        iPositionBottomLimit = worldHeight - viewHeight / 2 + iEmptySpaceArea;
+        }
+
+    // Calculate top limit
+    iPositionTopLimit = viewHeight / 2 - iEmptySpaceArea;
+    
+    // Check if empty space is really restricted
+    if ( emptySegment == KNotRestrictedSegment )
+        {
+        iEmptySpaceRestricted = EFalse;
+        }
+    else
+        {
+        iEmptySpaceRestricted = ETrue;
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CAknPhysicsRestrictor::WorldFitsToView
+// ---------------------------------------------------------------------------
+//
+TBool CAknPhysicsRestrictor::WorldFitsToView()
+    {
+    if ( iLandscape && iWorldSize.iWidth < iViewSize.iWidth )
+        {
+        return ETrue;
+        }
+    else if ( !iLandscape && iWorldSize.iHeight < iViewSize.iHeight )
+        {
+        return ETrue;
+        }
+    return EFalse;
+    }
+